parser timeout, better checksum checking and struct stuffing, shaved some bytes off RAM
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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');
|
||||
|
||||
|
||||
@@ -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' => '
|
||||
|
||||
@@ -104,6 +104,12 @@
|
||||
<input class="short" type="text" name="btn5" id="btn5" value="%h:btn5%">
|
||||
</div>
|
||||
|
||||
<div class="Row">
|
||||
<label for="parser_tout_ms"><?= tr('term.parser_tout_ms') ?><span class="mq-phone"> (ms)</span></label>
|
||||
<input type="number" step=1 min=0 name="parser_tout_ms" id="parser_tout_ms" value="%parser_tout_ms%" required>
|
||||
<span class="mq-no-phone"> ms</span>
|
||||
</div>
|
||||
|
||||
<div class="Row buttons">
|
||||
<a class="button icn-ok" href="#" onclick="qs('#form-1').submit()"><?= tr('apply') ?></a>
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
<nav id="botnav">
|
||||
<a href="#" onclick="toggleSoftKb(true); return false" class="icn-keyboard mq-tablet-max"></a><!--
|
||||
--><a href="<?= url('cfg_wifi') ?>"><?= tr('menu.settings') ?></a><!--
|
||||
--><a href="<?= url('cfg_term') ?>"><?= tr('menu.settings') ?></a><!--
|
||||
--><a href="<?= url('help') ?>">Help</a><!--
|
||||
--><a href="<?= url('about') ?>">About</a>
|
||||
</nav>
|
||||
|
||||
+44
-26
@@ -2,10 +2,11 @@
|
||||
/* #line 1 "user/ansi_parser.rl" */
|
||||
#include <esp8266.h>
|
||||
#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" */
|
||||
|
||||
}
|
||||
|
||||
+20
-2
@@ -1,5 +1,6 @@
|
||||
#include <esp8266.h>
|
||||
#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
|
||||
%%{
|
||||
#/*
|
||||
|
||||
+3
-3
@@ -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) {
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+28
-13
@@ -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);
|
||||
}
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
|
||||
+35
-12
@@ -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)
|
||||
{
|
||||
wifimgr_restore_defaults();
|
||||
terminal_restore_defaults();
|
||||
dbg("[Persist] Restore to hard defaults...");
|
||||
|
||||
dbg("[Persist] > system");
|
||||
sysconf_restore_defaults();
|
||||
|
||||
dbg("[Persist] > wifi");
|
||||
wifimgr_restore_defaults();
|
||||
|
||||
dbg("[Persist] > terminal");
|
||||
terminal_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;
|
||||
|
||||
|
||||
+11
-6
@@ -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.
|
||||
|
||||
+12
-3
@@ -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++) {
|
||||
|
||||
+1
-12
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
+3
-24
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user