From 5466bceb0ed309868eaa894a2c20e0a9ea1ed26c Mon Sep 17 00:00:00 2001 From: jedi Date: Thu, 18 Nov 2021 07:37:20 +0100 Subject: [PATCH] implement syslog via websocket with 1k buffer --- firmware/log.cpp | 49 ++++++++++++++++++++++++++++++++++++++ firmware/log.h | 28 ++++++++++++++++++++++ firmware/system.c | 7 +++--- firmware/web.cpp | 48 +++++++++++++++++++++++++++---------- firmware/webdir/index.html | 20 +++++++++++++++- firmware/wifi.cpp | 5 ++-- 6 files changed, 139 insertions(+), 18 deletions(-) create mode 100644 firmware/log.cpp create mode 100644 firmware/log.h diff --git a/firmware/log.cpp b/firmware/log.cpp new file mode 100644 index 0000000..8b268d9 --- /dev/null +++ b/firmware/log.cpp @@ -0,0 +1,49 @@ +// +// Created by jedi on 18.11.21. +// + +#include "log.h" + +#include + +constexpr unsigned syslog_buffer_size = 1024; +char syslog_buf[syslog_buffer_size]; +volatile unsigned head = 0; +volatile unsigned streams = 0; + +extern "C" void syslog(const char *msg) { + printf("syslog> %s", msg); + while (char c = *msg++) { + syslog_buf[head++ % syslog_buffer_size] = c; + } + syslog_buf[head] = 0; +} + +unsigned syslog_current_tail() { + if(head < syslog_buffer_size) + return 0; + return head + 1 - syslog_buffer_size; +} + +unsigned syslog_data_after(unsigned local_tail) { + if(local_tail > head) + return 0; + return (head % syslog_buffer_size) - (local_tail % syslog_buffer_size); +} + +extern "C" int syslog_copy_out(char *out, int len, unsigned local_tail) { + unsigned cnt = 0; + while (cnt < syslog_data_after(local_tail) && cnt < len) { + out[cnt] = syslog_buf[local_tail % syslog_buffer_size + cnt]; + cnt++; + } + return cnt; +} + +extern "C" void syslog_attach() { + streams++; +} + +extern "C" void syslog_detach() { + streams--; +} \ No newline at end of file diff --git a/firmware/log.h b/firmware/log.h new file mode 100644 index 0000000..0cde491 --- /dev/null +++ b/firmware/log.h @@ -0,0 +1,28 @@ +// +// Created by jedi on 18.11.21. +// + +#ifndef FIRMWARE_LOG_H +#define FIRMWARE_LOG_H + +#ifdef __cplusplus +extern "C" { +#endif + +void syslog(const char *); + +unsigned syslog_current_tail(); + +unsigned syslog_data_after(unsigned); + +int syslog_copy_out(char *, int, unsigned); + +void syslog_attach(); + +void syslog_detach(); + +#ifdef __cplusplus +} +#endif + +#endif //FIRMWARE_LOG_H diff --git a/firmware/system.c b/firmware/system.c index b853792..d190606 100644 --- a/firmware/system.c +++ b/firmware/system.c @@ -4,6 +4,7 @@ #include "system.h" #include "crc32.h" +#include "log.h" #include #include @@ -39,7 +40,7 @@ void system_init_config() { uint32_t num_sectors; sysparam_init(base_addr, 0); if(sysparam_get_info(&base_addr, &num_sectors) != SYSPARAM_OK) { - printf("Warning: WiFi config, sysparam not initialized\n"); + syslog("Warning: WiFi config, sysparam not initialized\n"); num_sectors = 0x2000 / sdk_flashchip.sector_size; if(sysparam_create_area(base_addr, num_sectors, true) == SYSPARAM_OK) { sysparam_init(base_addr, 0); @@ -106,13 +107,13 @@ enum return_code system_otaflash_verify_and_switch(uint32_t len, uint32_t hash) rboot_digest_image(otaflash_context.base, min(len, MAX_IMAGE_SIZE), system_otaflash_verify_chunk, &digest); if(hash != digest) { - printf("OTA failed to verify firmware\r\n"); + syslog("OTA failed to verify firmware\r\n"); return CHECKSUM_MISMATCH; } vPortEnterCritical(); if(!rboot_set_current_rom(otaflash_context.slot)) { - printf("OTA Update failed to set new rboot slot\r\n"); + syslog("OTA Update failed to set new rboot slot\r\n"); vPortExitCritical(); return RBOOT_SWITCH_FAILED; } diff --git a/firmware/web.cpp b/firmware/web.cpp index 255149f..ed55e2d 100644 --- a/firmware/web.cpp +++ b/firmware/web.cpp @@ -6,6 +6,7 @@ #include "system.h" #include "lux.h" #include "wifi.h" +#include "log.h" #include #include @@ -36,16 +37,34 @@ void websocket_task(void *pvParameter) { size_t connstarttime = xTaskGetTickCount(); has_changed = {true, true, true}; + syslog_attach(); + unsigned local_log_tail = syslog_current_tail(); for (;;) { if(pcb == nullptr || pcb->state != ESTABLISHED) { - printf("Connection closed, deleting task\n"); + syslog("Connection closed, deleting task\n"); break; } + //Syslog + if(syslog_data_after(local_log_tail) != 0) { + char response[128]; + response[0] = 'L'; + size_t len = syslog_copy_out(&response[4], 124, local_log_tail); + response[1] = len; + ((uint16_t &) response[2]) = local_log_tail & 0xFFFF; + if(len < sizeof(response)) { + LOCK_TCPIP_CORE(); + websocket_write(pcb, (unsigned char *) response, len + 4, WS_BIN_MODE); + local_log_tail += len; + UNLOCK_TCPIP_CORE(); + } else + syslog("buffer too small -1\n"); + vTaskDelayMs(1000); + } + //Global Info if(has_changed.global) { - has_changed.global = false; timeval tv{}; gettimeofday(&tv, nullptr); size_t uptime = xTaskGetTickCount() * portTICK_PERIOD_MS / 1000; @@ -57,7 +76,7 @@ void websocket_task(void *pvParameter) { sysparam_get_string("hostname", &hostname); /* Generate response in JSON format */ - char response[160]; + char response[192]; size_t len = snprintf(response, sizeof(response), "{\"walltime\" : \"%d\"," "\"uptime\" : \"%d\"," @@ -71,22 +90,22 @@ void websocket_task(void *pvParameter) { if(len < sizeof(response)) { LOCK_TCPIP_CORE(); websocket_write(pcb, (unsigned char *) response, len, WS_TEXT_MODE); + has_changed.global = false; UNLOCK_TCPIP_CORE(); } else - printf("buffer too small 1"); - vTaskDelayMs(2000); + syslog("buffer too small 0\n"); + vTaskDelayMs(1000); } //Connection Info if(has_changed.connection) { - has_changed.connection = false; timeval tv{}; gettimeofday(&tv, nullptr); size_t connuptime = (xTaskGetTickCount() - connstarttime) * portTICK_PERIOD_MS / 1000; printf("conn %d: " IPSTR " <-> " IPSTR " \n", pcb->netif_idx, IP2STR(&pcb->local_ip), IP2STR(&pcb->remote_ip)); - char response[160]; + char response[192]; size_t len = snprintf(response, sizeof(response), "{\"connage\" : \"%d\"," "\"clientip\" : \"" IPSTR "\"" @@ -94,10 +113,11 @@ void websocket_task(void *pvParameter) { if(len < sizeof(response)) { LOCK_TCPIP_CORE(); websocket_write(pcb, (unsigned char *) response, len, WS_TEXT_MODE); + has_changed.connection = false; UNLOCK_TCPIP_CORE(); } else - printf("buffer too small 1"); - vTaskDelayMs(2000); + syslog("buffer too small 1\n"); + vTaskDelayMs(1000); } if(has_changed.wifi) { @@ -152,10 +172,10 @@ void websocket_task(void *pvParameter) { websocket_write(pcb, (unsigned char *) response, len, WS_TEXT_MODE); UNLOCK_TCPIP_CORE(); } else - printf("buffer too small 2"); + syslog("buffer too small 2\n"); } - vTaskDelayMs(2000); + vTaskDelayMs(1000); if(opmode == STATION_MODE || opmode == STATIONAP_MODE) { uint8_t hwaddr[6]; @@ -179,7 +199,7 @@ void websocket_task(void *pvParameter) { websocket_write(pcb, (unsigned char *) response, len, WS_TEXT_MODE); UNLOCK_TCPIP_CORE(); } else - printf("buffer too small 3"); + syslog("buffer too small 3\n"); } } @@ -187,6 +207,8 @@ void websocket_task(void *pvParameter) { vTaskDelayMs(500); } + syslog_detach(); + vTaskDelete(nullptr); } @@ -235,12 +257,14 @@ void websocket_cb(struct tcp_pcb *pcb, char *data, u16_t data_len, ret = OK; break; case 'D': // Disable LED + syslog("G\n"); signal_led(false); cmd = 'G'; ret = OK; val = 1; break; case 'E': // Enable LED + syslog("E\n"); signal_led(true); cmd = 'G'; ret = OK; diff --git a/firmware/webdir/index.html b/firmware/webdir/index.html index 0a7bf04..317dc10 100644 --- a/firmware/webdir/index.html +++ b/firmware/webdir/index.html @@ -63,6 +63,16 @@ +
+
+

Syslog

+
+
+
+

+                
+
+
@@ -181,6 +191,7 @@