summaryrefslogtreecommitdiffstats
path: root/src/device
diff options
context:
space:
mode:
Diffstat (limited to 'src/device')
-rw-r--r--src/device/device_network.cpp14
-rw-r--r--[-rwxr-xr-x]src/device/device_network.h1
-rw-r--r--src/device/main.ino69
-rw-r--r--src/device/meson.build8
-rw-r--r--src/device/screen.cpp83
-rw-r--r--src/device/screen.h50
6 files changed, 207 insertions, 18 deletions
diff --git a/src/device/device_network.cpp b/src/device/device_network.cpp
index d7781a0..f2456d9 100644
--- a/src/device/device_network.cpp
+++ b/src/device/device_network.cpp
@@ -26,7 +26,7 @@
static struct netstate {
WiFiUDP udp;
- char udppacketbuffer[1500];
+ char udppacketbuffer[MTU];
char *udppacketcursor;
IPAddress daemon_ip;
bool acquired;
@@ -59,6 +59,17 @@ int udp_flush(void)
return state.udp.endPacket();
}
+size_t udp_get_data(char *buf, size_t size)
+{
+ size_t ret;
+ if (state.udp.available() != 0) {
+ ret = state.udp.read(buf, size);
+ } else {
+ ret = 0;
+ }
+ return ret;
+}
+
void discover_client(const int port)
{
IPAddress bcastip(255, 255, 255, 255);
@@ -100,4 +111,3 @@ static void udp_init_packet_expaddr(IPAddress ip, const int port)
memset(state.udppacketbuffer, 0, sizeof(state.udppacketbuffer));
state.udppacketcursor = state.udppacketbuffer;
}
-
diff --git a/src/device/device_network.h b/src/device/device_network.h
index d8f41a1..92af429 100755..100644
--- a/src/device/device_network.h
+++ b/src/device/device_network.h
@@ -31,6 +31,7 @@ void udp_init(const int port);
void udp_init_packet(const int port);
void udp_push(const void * const data, const size_t size);
int udp_flush(void);
+size_t udp_get_data(char *buf, size_t size);
void discover_client(const int port);
IPAddress *get_daemon_address(void);
diff --git a/src/device/main.ino b/src/device/main.ino
index 66e52e8..24cfb9c 100644
--- a/src/device/main.ino
+++ b/src/device/main.ino
@@ -27,6 +27,9 @@
#include "SSD1306Wire.h"
#include "DejaVu_Sans_Mono_13.h"
#include "device_network.h"
+#include "screen.h"
+#include "net.h"
+#include "tlv.h"
static const unsigned int internal_led = 2;
static unsigned int led_state = 0;
@@ -36,6 +39,16 @@ static void init_OLED(void);
unsigned int toggle_led(const int pin);
static int wifi_connect(const char * const ssid, const char * const password, const char doblink, const int ledpin);
static void blink_led(const int pin, const int ontime, const int offtime);
+void handle_tlv(const struct tlv *data);
+
+static struct progstate_t {
+ int ip_print_count = 5;
+ struct display_status ds = {0};
+ struct tlv_parser parser = {0};
+ struct tlv crr_data;
+ size_t bytes_read = 0;
+ char in_packet_buf[MTU];
+} progstate;
void setup(void)
{
@@ -64,27 +77,55 @@ void loop(void)
static String prefix;
static IPAddress ip_to_print;
static IPAddress *daemon_ip = NULL;
- static int print_dev_ip = 0;
static unsigned int delta = 2000; /* sleep length to use (ms) */
- /* static int dot_idx = 0; */
delay(delta);
- udp_init_packet(com_port);
- udp_push(clientmagic, sizeof(clientmagic));
- udp_flush();
+ /* Initial display of ip's. */
+ if (progstate.ip_print_count > 0) {
+ udp_init_packet(com_port);
+ udp_push(clientmagic, sizeof(clientmagic));
+ udp_flush();
+
+ if (!daemon_ip) {
+ daemon_ip = get_daemon_address();
+ }
- if (!daemon_ip) {
- daemon_ip = get_daemon_address();
+ prefix = (progstate.ip_print_count % 2) ? devstr : daemonstr;
+ ip_to_print = (progstate.ip_print_count) ? WiFi.localIP() : *daemon_ip;
+ display.clear();
+ display.drawString(0, 0, prefix);
+ display.drawString(0, 16, ip_to_print.toString());
+ display.display();
+ progstate.ip_print_count--;
+ } else { /* Dealing with tlv's one at a time. */
+ progstate.bytes_read = udp_get_data(progstate.in_packet_buf, sizeof(progstate.in_packet_buf));
+ if (progstate.bytes_read > 0) {
+ progstate.parser.data = progstate.in_packet_buf;
+ progstate.parser.offset = 0;
+ progstate.parser.size = progstate.bytes_read;
+ /* Ignore errors for now. */
+ while (tlv_get(&progstate.parser, &progstate.crr_data) == 0) {
+ handle_tlv(&progstate.crr_data);
+ }
+ }
+ display_update_scroll(&progstate.ds);
}
+}
- prefix = (print_dev_ip) ? devstr : daemonstr;
- ip_to_print = (print_dev_ip) ? WiFi.localIP() : *daemon_ip;
- display.clear();
- display.drawString(0, 0, prefix);
- display.drawString(0, 16, ip_to_print.toString());
- display.display();
- print_dev_ip = !print_dev_ip;
+void handle_tlv(const struct tlv *t)
+{
+ /* Currently just dealing with text.
+ * */
+ switch (t->type) {
+ case TEXT:
+ display_status_init(&display, &progstate.ds, (char *)t->data);
+ break;
+ default:
+ display.clear();
+ display.drawString(0, 0, "Fugg :DDD");
+ break;
+ }
}
static void init_OLED(void)
diff --git a/src/device/meson.build b/src/device/meson.build
index 625bd2d..7a0665c 100644
--- a/src/device/meson.build
+++ b/src/device/meson.build
@@ -35,10 +35,14 @@ if get_option('fwbuild')
cpus = '2'
endif
- fw_filenames = ['main.ino',
+ fw_filenames = [
+ 'main.ino',
'DejaVu_Sans_Mono_13.h',
'device_network.cpp',
- 'device_network.h']
+ 'device_network.h',
+ 'screen.cpp',
+ 'screen.h'
+ ]
fw_true_sources += files(fw_filenames)
fw_filenames += oledlibnames
fw_true_sources += oledlib
diff --git a/src/device/screen.cpp b/src/device/screen.cpp
new file mode 100644
index 0000000..2857161
--- /dev/null
+++ b/src/device/screen.cpp
@@ -0,0 +1,83 @@
+#include <time.h>
+#include <stdlib.h>
+#include <string.h>
+#include <OLEDDisplay.h>
+#include <Wire.h>
+#include "screen.h"
+
+void draw_lines(OLEDDisplay *screen, struct display_status *status);
+void update_lines(struct display_status *status);
+void init_msg(char *msg, size_t size);
+
+/* Effectively const. For type safety reasons. */
+static char NOTHING[] = {'\0'};
+
+void display_status_init(OLEDDisplay *screen, struct display_status *status, char *msg)
+{
+ status->delta = 2; /* Currently default */
+ status->screen = screen;
+ init_msg(msg, strlen(msg));
+ status->message = msg;
+ status->line_cursor = 0;
+ status->last_scroll_time = time(NULL);
+ update_lines(status);
+}
+
+/**
+ * Turns all whitespace into literal spaces to save screen real-estate and
+ * possible misinterpretation.
+ */
+void init_msg(char *msg, size_t size)
+{
+ size_t i;
+
+ for (i = 0; i < size; i++) {
+ switch (msg[i]) {
+ case '\n':
+ case '\t':
+ case '\r':
+ msg[i] = ' ';
+ break;
+ case '\0':
+ goto end;
+ default:
+ break;
+ }
+ }
+end:
+ return;
+}
+
+int display_update_scroll(struct display_status *status)
+{
+ time_t crr_time = time(NULL);
+ /* Only scroll lines once a delta, because --- duh! */
+ if (status->last_scroll_time - crr_time > status->delta) {
+ status->last_scroll_time += status->delta;
+ status->line_cursor++;
+ update_lines(status);
+ draw_lines(status->screen, status);
+ }
+ if (status->first_line == NOTHING && status->second_line == NOTHING) {
+ return END_OF_MESSAGE;
+ } else {
+ return 0;
+ }
+}
+
+void draw_lines(OLEDDisplay *screen, struct display_status *status)
+{
+ screen->clear();
+ screen->drawString(0, 0, status->first_line);
+ screen->drawString(0, SCREEN_HEIGHT / 2, status->second_line);
+}
+
+void update_lines(struct display_status *status)
+{
+ status->first_line = (status->line_cursor * SCREEN_MAX_CHARS < status->message_len)
+ ? status->message + status->line_cursor * SCREEN_MAX_CHARS
+ : NOTHING;
+ status->second_line = (status->line_cursor * SCREEN_MAX_CHARS < status->message_len)
+ ? status->message + (status->line_cursor + 1) * SCREEN_MAX_CHARS
+ : NOTHING;
+}
diff --git a/src/device/screen.h b/src/device/screen.h
new file mode 100644
index 0000000..5d0e3b3
--- /dev/null
+++ b/src/device/screen.h
@@ -0,0 +1,50 @@
+/**
+ * Simple API for scrolling lines. Keeps things simple by not even assuming
+ * which screen is being drawn on.
+ */
+
+#ifndef DEVICE_SCREEN_H
+#define DEVICE_SCREEN_H
+
+#include <time.h>
+#include <OLEDDisplay.h>
+#include <Wire.h>
+
+#define SCREEN_WIDTH (128)
+#define SCREEN_HEIGHT (32)
+#define FONT_WIDTH (8)
+#define SCREEN_MAX_CHARS (SCREEN_WIDTH / FONT_WIDTH)
+
+/**
+ * Struct that keeps track of the lines on the screen.
+ */
+struct display_status {
+ OLEDDisplay *screen; /* Screen to draw on. */
+ time_t delta; /* Seconds/Line */
+ time_t last_scroll_time; /* Last second the line was scrolled */
+ char *message; /* Entire message to be shown */
+ char *first_line; /* First line on display */
+ char *second_line; /* Second line on display */
+ size_t message_len; /* Length of the message */
+ size_t line_cursor; /* Index of the first line being displayed. */
+};
+
+/**
+ * Displays scrolling text on the screen.
+ */
+int display_update_scroll(struct display_status *status);
+
+#define END_OF_MESSAGE (1 << 0)
+/**
+ * Initialises display_status structure so it can be used for
+ * display_update_scroll.
+ *
+ * screen - screen to draw on
+ *
+ * status - structure to Initialise
+ *
+ * msg - message to scroll on the screen
+ */
+void display_status_init(OLEDDisplay *screen, struct display_status *status, char *msg);
+
+#endif /* DEVICE_SCREEN_H */ \ No newline at end of file