diff --git a/Makefile b/Makefile
index edde199..afc9439 100644
--- a/Makefile
+++ b/Makefile
@@ -65,7 +65,7 @@ LIBS += esphttpd
# compiler flags using during compilation of source files
CFLAGS = -Os -ggdb -std=gnu99 -Werror -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \
-nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH \
- -Wno-address -Wno-unused -DHTTPD_MAX_BACKLOG_SIZE=8192 -DADMIN_PASSWORD=$(ADMIN_PASSWORD)
+ -Wno-address -Wno-unused -DHTTPD_MAX_BACKLOG_SIZE=4096 -DADMIN_PASSWORD=$(ADMIN_PASSWORD)
# linker flags used to generate the main object file
LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static
diff --git a/html_orig/_pages.php b/html_orig/_pages.php
index 8d99c1e..129cfd2 100644
--- a/html_orig/_pages.php
+++ b/html_orig/_pages.php
@@ -18,6 +18,9 @@ if (! function_exists('pg')) {
}
}
+pg('cfg_term', 'cfg', 'terminal', '/cfg/term');
+pg('term_set', 'api', '', '/cfg/term/set');
+
pg('cfg_wifi', 'cfg', 'wifi', '/cfg/wifi');
pg('cfg_wifi_conn', '', '', '/cfg/wifi/connecting');
pg('wifi_connstatus', 'api', '', '/cfg/wifi/connstatus');
@@ -27,9 +30,6 @@ pg('wifi_scan', 'api', '', '/cfg/wifi/scan');
pg('cfg_network', 'cfg', 'network', '/cfg/network');
pg('network_set', 'api', '', '/cfg/network/set');
-pg('cfg_term', 'cfg', 'terminal', '/cfg/term');
-pg('term_set', 'api', '', '/cfg/term/set');
-
pg('cfg_system', 'cfg', 'configure', '/cfg/system');
pg('system_set', 'api', '', '/cfg/system/set');
diff --git a/html_orig/lang/en.php b/html_orig/lang/en.php
index 679a72b..11d7030 100644
--- a/html_orig/lang/en.php
+++ b/html_orig/lang/en.php
@@ -36,6 +36,7 @@ return [
'term.default_fg_bg' => 'Text / background',
'term.buttons' => 'Button labels',
'term.theme' => 'Color scheme',
+ 'term.parser_tout_ms' => 'Parser timeout',
// terminal color labels
'color.0' => 'Black',
@@ -115,14 +116,13 @@ return [
'system.confirm_store_defaults' =>
'Enter admin password to confirm you want to store the current settings as defaults.',
'system.password' => 'Admin password:',
- 'system.restore_defaults' => 'Reset to default settings',
- 'system.write_defaults' => 'Save current settings as default',
- 'system.restore_hard' => 'Reset to firmware default settings',
+ 'system.restore_defaults' => 'Reset active settings to defaults',
+ 'system.write_defaults' => 'Save active settings as defaults',
+ 'system.restore_hard' => 'Reset active settings to firmware defaults',
'system.explain_persist' => '
ESPTerm contains two persistent memory banks, one for default and
one for active settings. Active settings can be stored as defaults
- by the administrator. Use the following button to revert all
- active settings to their stored default values.
+ by the administrator (password required).
',
'system.uart' => 'Serial Port',
'system.explain_uart' => '
diff --git a/html_orig/pages/cfg_term.php b/html_orig/pages/cfg_term.php
index e40863e..1a93ade 100644
--- a/html_orig/pages/cfg_term.php
+++ b/html_orig/pages/cfg_term.php
@@ -104,6 +104,12 @@
+
+
+
+ ms
+
+
diff --git a/html_orig/pages/term.php b/html_orig/pages/term.php
index 3677c2e..f723cd6 100644
--- a/html_orig/pages/term.php
+++ b/html_orig/pages/term.php
@@ -26,7 +26,7 @@
diff --git a/user/ansi_parser.c b/user/ansi_parser.c
index 7785042..feb687b 100644
--- a/user/ansi_parser.c
+++ b/user/ansi_parser.c
@@ -2,10 +2,11 @@
/* #line 1 "user/ansi_parser.rl" */
#include
#include "ansi_parser.h"
+#include "screen.h"
/* Ragel constants block */
-/* #line 9 "user/ansi_parser.c" */
+/* #line 10 "user/ansi_parser.c" */
static const char _ansi_actions[] = {
0, 1, 0, 1, 1, 1, 2, 1,
3, 1, 4, 1, 5, 1, 6, 1,
@@ -30,9 +31,21 @@ static const int ansi_en_OSC_body = 5;
static const int ansi_en_main = 1;
-/* #line 8 "user/ansi_parser.rl" */
+/* #line 9 "user/ansi_parser.rl" */
+static volatile int cs = -1;
+
+static ETSTimer resetTim;
+
+static void ICACHE_FLASH_ATTR
+resetParserCb(void *arg) {
+ if (cs != ansi_start) {
+ cs = ansi_start;
+ warn("Parser timeout, state reset");
+ }
+}
+
/**
* \brief Linear ANSI chars stream parser
*
@@ -49,8 +62,6 @@ static const int ansi_en_main = 1;
void ICACHE_FLASH_ATTR
ansi_parser(const char *newdata, size_t len)
{
- static int cs = -1;
-
// The CSI code is built here
static char csi_leading; //!< Leading char, 0 if none
static int csi_ni; //!< Number of the active digit
@@ -69,17 +80,24 @@ ansi_parser(const char *newdata, size_t len)
// Init Ragel on the first run
if (cs == -1) {
-/* #line 73 "user/ansi_parser.c" */
+/* #line 84 "user/ansi_parser.c" */
{
cs = ansi_start;
}
-/* #line 46 "user/ansi_parser.rl" */
+/* #line 57 "user/ansi_parser.rl" */
+ }
+
+ // schedule state reset
+ if (termconf->parser_tout_ms > 0) {
+ os_timer_disarm(&resetTim);
+ os_timer_setfn(&resetTim, resetParserCb, NULL);
+ os_timer_arm(&resetTim, termconf->parser_tout_ms, 0);
}
// The parser
-/* #line 83 "user/ansi_parser.c" */
+/* #line 101 "user/ansi_parser.c" */
{
const char *_acts;
unsigned int _nacts;
@@ -315,13 +333,13 @@ execFuncs:
while ( _nacts-- > 0 ) {
switch ( *_acts++ ) {
case 0:
-/* #line 58 "user/ansi_parser.rl" */
+/* #line 76 "user/ansi_parser.rl" */
{
apars_handle_plainchar((*p));
}
break;
case 1:
-/* #line 65 "user/ansi_parser.rl" */
+/* #line 83 "user/ansi_parser.rl" */
{
// Reset the CSI builder
csi_leading = csi_char = 0;
@@ -336,13 +354,13 @@ execFuncs:
}
break;
case 2:
-/* #line 78 "user/ansi_parser.rl" */
+/* #line 96 "user/ansi_parser.rl" */
{
csi_leading = (*p);
}
break;
case 3:
-/* #line 82 "user/ansi_parser.rl" */
+/* #line 100 "user/ansi_parser.rl" */
{
// x10 + digit
if (csi_ni < CSI_N_MAX) {
@@ -351,13 +369,13 @@ execFuncs:
}
break;
case 4:
-/* #line 89 "user/ansi_parser.rl" */
+/* #line 107 "user/ansi_parser.rl" */
{
csi_ni++;
}
break;
case 5:
-/* #line 93 "user/ansi_parser.rl" */
+/* #line 111 "user/ansi_parser.rl" */
{
csi_char = (*p);
@@ -367,14 +385,14 @@ execFuncs:
}
break;
case 6:
-/* #line 101 "user/ansi_parser.rl" */
+/* #line 119 "user/ansi_parser.rl" */
{
apars_handle_badseq();
{cs = 1;goto _again;}
}
break;
case 7:
-/* #line 118 "user/ansi_parser.rl" */
+/* #line 136 "user/ansi_parser.rl" */
{
csi_ni = 0;
@@ -390,20 +408,20 @@ execFuncs:
}
break;
case 8:
-/* #line 132 "user/ansi_parser.rl" */
+/* #line 150 "user/ansi_parser.rl" */
{
apars_handle_OSC_SetScreenSize(csi_n[0], csi_n[1]);
{cs = 1;goto _again;}
}
break;
case 9:
-/* #line 137 "user/ansi_parser.rl" */
+/* #line 155 "user/ansi_parser.rl" */
{
osc_buffer[osc_bi++] = (*p);
}
break;
case 10:
-/* #line 141 "user/ansi_parser.rl" */
+/* #line 159 "user/ansi_parser.rl" */
{
osc_buffer[osc_bi++] = '\0';
apars_handle_OSC_SetTitle(osc_buffer);
@@ -411,7 +429,7 @@ execFuncs:
}
break;
case 11:
-/* #line 147 "user/ansi_parser.rl" */
+/* #line 165 "user/ansi_parser.rl" */
{
osc_buffer[osc_bi++] = '\0';
apars_handle_OSC_SetButton(csi_n[0], osc_buffer);
@@ -419,7 +437,7 @@ execFuncs:
}
break;
case 12:
-/* #line 159 "user/ansi_parser.rl" */
+/* #line 177 "user/ansi_parser.rl" */
{
// Reset screen
apars_handle_RESET_cmd();
@@ -427,20 +445,20 @@ execFuncs:
}
break;
case 13:
-/* #line 165 "user/ansi_parser.rl" */
+/* #line 183 "user/ansi_parser.rl" */
{
apars_handle_saveCursorAttrs();
{cs = 1;goto _again;}
}
break;
case 14:
-/* #line 170 "user/ansi_parser.rl" */
+/* #line 188 "user/ansi_parser.rl" */
{
apars_handle_restoreCursorAttrs();
{cs = 1;goto _again;}
}
break;
-/* #line 444 "user/ansi_parser.c" */
+/* #line 462 "user/ansi_parser.c" */
}
}
goto _again;
@@ -458,7 +476,7 @@ _again:
while ( __nacts-- > 0 ) {
switch ( *__acts++ ) {
case 6:
-/* #line 101 "user/ansi_parser.rl" */
+/* #line 119 "user/ansi_parser.rl" */
{
apars_handle_badseq();
{cs = 1; if ( p == pe )
@@ -466,7 +484,7 @@ _again:
goto _again;}
}
break;
-/* #line 470 "user/ansi_parser.c" */
+/* #line 488 "user/ansi_parser.c" */
}
}
}
@@ -474,6 +492,6 @@ goto _again;}
_out: {}
}
-/* #line 190 "user/ansi_parser.rl" */
+/* #line 208 "user/ansi_parser.rl" */
}
diff --git a/user/ansi_parser.rl b/user/ansi_parser.rl
index 37c33bc..7c3f35d 100644
--- a/user/ansi_parser.rl
+++ b/user/ansi_parser.rl
@@ -1,5 +1,6 @@
#include
#include "ansi_parser.h"
+#include "screen.h"
/* Ragel constants block */
%%{
@@ -7,6 +8,18 @@
write data;
}%%
+static volatile int cs = -1;
+
+static ETSTimer resetTim;
+
+static void ICACHE_FLASH_ATTR
+resetParserCb(void *arg) {
+ if (cs != ansi_start) {
+ cs = ansi_start;
+ warn("Parser timeout, state reset");
+ }
+}
+
/**
* \brief Linear ANSI chars stream parser
*
@@ -23,8 +36,6 @@
void ICACHE_FLASH_ATTR
ansi_parser(const char *newdata, size_t len)
{
- static int cs = -1;
-
// The CSI code is built here
static char csi_leading; //!< Leading char, 0 if none
static int csi_ni; //!< Number of the active digit
@@ -45,6 +56,13 @@ ansi_parser(const char *newdata, size_t len)
%% write init;
}
+ // schedule state reset
+ if (termconf->parser_tout_ms > 0) {
+ os_timer_disarm(&resetTim);
+ os_timer_setfn(&resetTim, resetParserCb, NULL);
+ os_timer_arm(&resetTim, termconf->parser_tout_ms, 0);
+ }
+
// The parser
%%{
#/*
diff --git a/user/cgi_network.c b/user/cgi_network.c
index 9b451de..66bed17 100644
--- a/user/cgi_network.c
+++ b/user/cgi_network.c
@@ -28,9 +28,9 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
{
static ETSTimer timer;
- char buff[50];
+ char buff[20];
+ char redir_url_buf[100];
- char redir_url_buf[300];
char *redir_url = redir_url_buf;
redir_url += sprintf(redir_url, SET_REDIR_ERR);
// we'll test if anything was printed by looking for \0 in failed_keys_buf
@@ -201,7 +201,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
//Template code for the WLAN page.
httpd_cgi_state ICACHE_FLASH_ATTR tplNetwork(HttpdConnData *connData, char *token, void **arg)
{
- char buff[100];
+ char buff[20];
u8 mac[6];
if (token == NULL) {
diff --git a/user/cgi_persist.c b/user/cgi_persist.c
index 3a18c5d..92bfefd 100644
--- a/user/cgi_persist.c
+++ b/user/cgi_persist.c
@@ -20,7 +20,7 @@ verify_admin_pw(const char *pw)
httpd_cgi_state ICACHE_FLASH_ATTR
cgiPersistWriteDefaults(HttpdConnData *connData)
{
- char buff[50];
+ char buff[PASSWORD_LEN];
if (connData->conn == NULL) {
//Connection aborted. Clean up.
diff --git a/user/cgi_sockets.c b/user/cgi_sockets.c
index 45fc5c1..1b9283d 100644
--- a/user/cgi_sockets.c
+++ b/user/cgi_sockets.c
@@ -6,7 +6,7 @@
#include "uart_driver.h"
#include "screen.h"
-#define SOCK_BUF_LEN 2048
+#define SOCK_BUF_LEN 1024
static char sock_buff[SOCK_BUF_LEN];
volatile bool notify_available = true;
diff --git a/user/cgi_system.c b/user/cgi_system.c
index a834be1..f1c044c 100755
--- a/user/cgi_system.c
+++ b/user/cgi_system.c
@@ -61,8 +61,8 @@ httpd_cgi_state ICACHE_FLASH_ATTR
cgiSystemCfgSetParams(HttpdConnData *connData)
{
char buff[50];
+ char redir_url_buf[100];
- char redir_url_buf[300];
char *redir_url = redir_url_buf;
redir_url += sprintf(redir_url, SET_REDIR_ERR);
// we'll test if anything was printed by looking for \0 in failed_keys_buf
diff --git a/user/cgi_term_cfg.c b/user/cgi_term_cfg.c
index ccdb260..7026818 100644
--- a/user/cgi_term_cfg.c
+++ b/user/cgi_term_cfg.c
@@ -19,8 +19,9 @@ httpd_cgi_state ICACHE_FLASH_ATTR
cgiTermCfgSetParams(HttpdConnData *connData)
{
char buff[50];
+ char redir_url_buf[100];
+ int n, w, h;
- char redir_url_buf[300];
char *redir_url = redir_url_buf;
redir_url += sprintf(redir_url, SET_REDIR_ERR);
// we'll test if anything was printed by looking for \0 in failed_keys_buf
@@ -33,11 +34,11 @@ cgiTermCfgSetParams(HttpdConnData *connData)
// width and height must always go together so we can do max size validation
if (GET_ARG("term_width")) {
dbg("Default screen width: %s", buff);
- int w = atoi(buff);
+ w = atoi(buff);
if (w > 1) {
if (GET_ARG("term_height")) {
dbg("Default screen height: %s", buff);
- int h = atoi(buff);
+ h = atoi(buff);
if (h > 1) {
if (w * h <= MAX_SCREEN_SIZE) {
termconf->width = w;
@@ -63,20 +64,31 @@ cgiTermCfgSetParams(HttpdConnData *connData)
if (GET_ARG("default_bg")) {
dbg("Screen default BG: %s", buff);
- int color = atoi(buff);
- if (color >= 0 && color < 16) {
- termconf->default_bg = (u8) color;
+ n = atoi(buff);
+ if (n >= 0 && n < 16) {
+ termconf->default_bg = (u8) n;
} else {
warn("Bad color %s", buff);
redir_url += sprintf(redir_url, "default_bg,");
}
}
+ if (GET_ARG("parser_tout_ms")) {
+ dbg("Parser timeout: %s ms", buff);
+ n = atoi(buff);
+ if (n >= 0) {
+ termconf->parser_tout_ms = (u8) n;
+ } else {
+ warn("Bad timeout %s", buff);
+ redir_url += sprintf(redir_url, "parser_tout_ms,");
+ }
+ }
+
if (GET_ARG("default_fg")) {
dbg("Screen default FG: %s", buff);
- int color = atoi(buff);
- if (color >= 0 && color < 16) {
- termconf->default_fg = (u8) color;
+ n = atoi(buff);
+ if (n >= 0 && n < 16) {
+ termconf->default_fg = (u8) n;
} else {
warn("Bad color %s", buff);
redir_url += sprintf(redir_url, "default_fg,");
@@ -85,9 +97,9 @@ cgiTermCfgSetParams(HttpdConnData *connData)
if (GET_ARG("theme")) {
dbg("Screen color theme: %s", buff);
- int theme = atoi(buff);
- if (theme >= 0 && theme <= 5) { // ALWAYS ADJUST WHEN ADDING NEW THEME!
- termconf->theme = (u8) theme;
+ n = atoi(buff);
+ if (n >= 0 && n <= 5) { // ALWAYS ADJUST WHEN ADDING NEW THEME!
+ termconf->theme = (u8) n;
} else {
warn("Bad theme num: %s", buff);
redir_url += sprintf(redir_url, "theme,");
@@ -127,7 +139,7 @@ cgiTermCfgSetParams(HttpdConnData *connData)
httpd_cgi_state ICACHE_FLASH_ATTR
tplTermCfg(HttpdConnData *connData, char *token, void **arg)
{
-#define BUFLEN 100
+#define BUFLEN TERM_TITLE_LEN
char buff[BUFLEN];
char buff2[10];
@@ -144,6 +156,9 @@ tplTermCfg(HttpdConnData *connData, char *token, void **arg)
else if (streq(token, "term_height")) {
sprintf(buff, "%d", termconf->height);
}
+ else if (streq(token, "parser_tout_ms")) {
+ sprintf(buff, "%d", termconf->parser_tout_ms);
+ }
else if (streq(token, "theme")) {
sprintf(buff, "%d", termconf->theme);
}
diff --git a/user/cgi_wifi.c b/user/cgi_wifi.c
index 78c7720..67fb0c6 100644
--- a/user/cgi_wifi.c
+++ b/user/cgi_wifi.c
@@ -325,8 +325,8 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
static ETSTimer timer;
char buff[50];
+ char redir_url_buf[100]; // this is just barely enough - but it's split into two forms, so we never have error in all fields
- char redir_url_buf[300];
char *redir_url = redir_url_buf;
redir_url += sprintf(redir_url, SET_REDIR_ERR);
// we'll test if anything was printed by looking for \0 in failed_keys_buf
@@ -507,7 +507,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
//Template code for the WLAN page.
httpd_cgi_state ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg)
{
- char buff[100];
+ char buff[PASSWORD_LEN];
int x;
int connectStatus;
diff --git a/user/persist.c b/user/persist.c
index 14d9573..dd89036 100644
--- a/user/persist.c
+++ b/user/persist.c
@@ -17,23 +17,45 @@ static void ICACHE_FLASH_ATTR
apply_live_settings(void)
{
dbg("[Persist] Applying live settings...");
- terminal_apply_settings();
- wifimgr_apply_settings();
+
+ dbg("[Persist] > system");
sysconf_apply_settings();
+
+ dbg("[Persist] > wifi");
+ wifimgr_apply_settings();
+
+ dbg("[Persist] > terminal");
+ terminal_apply_settings();
+
+ dbg("[Persist] Live settings applied.");
// ...
}
static void ICACHE_FLASH_ATTR
restore_live_settings_to_hard_defaults(void)
{
+ dbg("[Persist] Restore to hard defaults...");
+
+ dbg("[Persist] > system");
+ sysconf_restore_defaults();
+
+ dbg("[Persist] > wifi");
wifimgr_restore_defaults();
+
+ dbg("[Persist] > terminal");
terminal_restore_defaults();
- sysconf_restore_defaults();
+
+ dbg("[Persist] Restored to hard defaults.");
// ...
}
//endregion
+const u32 wconf_at = (u32)&persist.defaults.wificonf - (u32)&persist.defaults;
+const u32 tconf_at = (u32)&persist.defaults.termconf - (u32)&persist.defaults;
+const u32 sconf_at = (u32)&persist.defaults.sysconf - (u32)&persist.defaults;
+const u32 cksum_at = (u32)&persist.defaults.checksum - (u32)&persist.defaults;
+
/**
* Compute CRC32. Adapted from https://github.com/esp8266/Arduino
* @param data
@@ -43,7 +65,9 @@ restore_live_settings_to_hard_defaults(void)
static uint32_t ICACHE_FLASH_ATTR
calculateCRC32(const uint8_t *data, size_t length)
{
- uint32_t crc = 0xffffffff + CHECKSUM_SALT;
+ // the salt here should ensure settings are wiped when the structure changes
+ // CHECKSUM_SALT can be adjusted manually to force a reset.
+ uint32_t crc = 0xffffffff + CHECKSUM_SALT + ((wconf_at << 16) ^ (tconf_at << 10) ^ (sconf_at << 5));
while (length--) {
uint8_t c = *data++;
for (uint32_t i = 0x80; i > 0; i >>= 1) {
@@ -81,13 +105,12 @@ persist_load(void)
{
info("[Persist] Loading stored settings from FLASH...");
- dbg("sizeof(AppConfigBundle) = %d bytes", sizeof(AppConfigBundle));
- dbg("> sizeof(WiFiConfigBundle) = %d bytes", sizeof(WiFiConfigBundle));
- dbg("> sizeof(TerminalConfigBundle) = %d bytes", sizeof(TerminalConfigBundle));
- dbg("> sizeof(SystemConfigBundle) = %d bytes", sizeof(SystemConfigBundle));
- dbg("> sizeof(checksum) = %d bytes", sizeof(uint32_t));
- dbg("> filler = %d bytes",
- sizeof(AppConfigBundle) - (sizeof(WiFiConfigBundle) + sizeof(TerminalConfigBundle) + sizeof(SystemConfigBundle)));
+ dbg("AppConfigBundle memory map:");
+ dbg("> WiFiConfigBundle at %4d (error %2d)", wconf_at, wconf_at - 0);
+ dbg("> SystemConfigBundle at %4d (error %2d)", sconf_at, sconf_at - WIFICONF_SIZE);
+ dbg("> TerminalConfigBundle at %4d (error %2d)", tconf_at, tconf_at - WIFICONF_SIZE - SYSCONF_SIZE);
+ dbg("> Checksum at %4d (error %2d)", cksum_at, cksum_at - (APPCONF_SIZE - 4));
+ dbg("> Total size = %d bytes (error %d)", sizeof(AppConfigBundle), APPCONF_SIZE - sizeof(AppConfigBundle));
bool hard_reset = false;
diff --git a/user/persist.h b/user/persist.h
index aa05e52..aba195b 100644
--- a/user/persist.h
+++ b/user/persist.h
@@ -16,15 +16,20 @@
// Changing this could be used to force-erase the config area
// after a firmware upgrade
-#define CHECKSUM_SALT 2
+#define CHECKSUM_SALT 3
#define APPCONF_SIZE 2048
/** Struct for current or default settings */
typedef struct { // the entire block should be 1024 bytes long (for compatibility across upgrades)
WiFiConfigBundle wificonf;
- TerminalConfigBundle termconf;
+ uint8_t _filler1[WIFICONF_SIZE - sizeof(WiFiConfigBundle)];
+
SystemConfigBundle sysconf;
+ uint8_t _filler3[SYSCONF_SIZE - sizeof(SystemConfigBundle)];
+
+ TerminalConfigBundle termconf;
+ uint8_t _filler2[TERMCONF_SIZE - sizeof(TerminalConfigBundle)];
// --- Space for future settings ---
// The size must be appropriately reduced each time something is added,
@@ -34,12 +39,12 @@ typedef struct { // the entire block should be 1024 bytes long (for compatibilit
// This ensures user settings are not lost each time they upgrade the firmware,
// which would lead to a checksum mismatch if the structure was changed and
// it grew to a different memory area.
- uint8_t filler[
+ uint8_t _filler_end[
APPCONF_SIZE
- sizeof(uint32_t) // checksum
- - sizeof(WiFiConfigBundle)
- - sizeof(TerminalConfigBundle)
- - sizeof(SystemConfigBundle)
+ - WIFICONF_SIZE
+ - SYSCONF_SIZE
+ - TERMCONF_SIZE
];
uint32_t checksum; // computed before write and tested on load. If it doesn't match, values are reset to hard defaults.
diff --git a/user/screen.c b/user/screen.c
index 88e023e..a7132c1 100644
--- a/user/screen.c
+++ b/user/screen.c
@@ -8,6 +8,9 @@
TerminalConfigBundle * const termconf = &persist.current.termconf;
TerminalConfigBundle termconf_scratch;
+#define W termconf_scratch.width
+#define H termconf_scratch.height
+
/**
* Restore hard defaults
*/
@@ -17,6 +20,7 @@ void terminal_restore_defaults(void)
termconf->default_fg = 7;
termconf->width = 26;
termconf->height = 10;
+ termconf->parser_tout_ms = 10;
sprintf(termconf->title, "ESPTerm");
for(int i=1; i <= 5; i++) {
sprintf(termconf->btn[i-1], "%d", i);
@@ -29,12 +33,16 @@ void terminal_restore_defaults(void)
void terminal_apply_settings(void)
{
memcpy(&termconf_scratch, termconf, sizeof(TerminalConfigBundle));
+ if (W*H >= MAX_SCREEN_SIZE) {
+ error("BAD SCREEN SIZE: %d rows x %d cols", H, W);
+ error("reverting terminal settings to default");
+ terminal_restore_defaults();
+ persist_store();
+ memcpy(&termconf_scratch, termconf, sizeof(TerminalConfigBundle));
+ }
screen_init();
}
-#define W termconf_scratch.width
-#define H termconf_scratch.height
-
/**
* Highest permissible value of the color attribute
*/
@@ -105,6 +113,7 @@ static volatile int notifyLock = 0;
static inline void
clear_range(unsigned int from, unsigned int to)
{
+ if (to >= W*H) to = W*H-1;
Color fg = cursor.inverse ? cursor.bg : cursor.fg;
Color bg = cursor.inverse ? cursor.fg : cursor.bg;
for (unsigned int i = from; i <= to; i++) {
diff --git a/user/screen.h b/user/screen.h
index a1d17fc..0e21fbf 100644
--- a/user/screen.h
+++ b/user/screen.h
@@ -56,18 +56,7 @@ typedef struct {
char title[TERM_TITLE_LEN];
char btn[5][TERM_BTN_LEN];
u8 theme;
-
- u8 _filler[
- TERMCONF_SIZE
- - 4
- - 4
- - 1
- - 1
- - 1
- - TERM_TITLE_LEN
- - TERM_BTN_LEN * 5
- ];
-
+ u32 parser_tout_ms;
} TerminalConfigBundle;
// Live config
diff --git a/user/syscfg.h b/user/syscfg.h
index 3fe65ed..6b9f607 100644
--- a/user/syscfg.h
+++ b/user/syscfg.h
@@ -15,13 +15,6 @@ typedef struct {
u32 uart_baudrate;
u8 uart_parity;
u8 uart_stopbits;
-
- u8 _filler[
- SYSCONF_SIZE
- - 4
- - 1
- - 1
- ];
} SystemConfigBundle;
extern SystemConfigBundle * const sysconf;
diff --git a/user/wifimgr.h b/user/wifimgr.h
index 165067d..060fb90 100644
--- a/user/wifimgr.h
+++ b/user/wifimgr.h
@@ -27,42 +27,21 @@ typedef struct {
WIFI_MODE opmode : 8;
u8 tpw;
- // --- AP config ---
+ // AP config
u8 ap_channel;
u8 ap_ssid[SSID_LEN];
u8 ap_password[PASSWORD_LEN];
bool ap_hidden;
+ //
u16 ap_dhcp_time; // in minutes
struct dhcps_lease ap_dhcp_range;
-
struct ip_info ap_addr;
- // --- Client config ---
+ // Client config
u8 sta_ssid[SSID_LEN];
u8 sta_password[PASSWORD_LEN];
bool sta_dhcp_enable;
struct ip_info sta_addr;
-
- u8 _filler[
- WIFICONF_SIZE
- - 1
- - 1
-
- - 1
- - SSID_LEN
- - PASSWORD_LEN
- - 1
- - 2
- - sizeof(struct dhcps_lease)
-
- - sizeof(struct ip_info)
-
- - SSID_LEN
- - PASSWORD_LEN
- - 1
- - sizeof(struct ip_info)
- - 8 // padding?
- ];
} WiFiConfigBundle;
typedef struct {