parser timeout, better checksum checking and struct stuffing, shaved some bytes off RAM

pull/111/merge
Ondřej Hruška 7 years ago
parent 4eaee9389d
commit f8c60b0668
  1. 2
      Makefile
  2. 6
      html_orig/_pages.php
  3. 10
      html_orig/lang/en.php
  4. 6
      html_orig/pages/cfg_term.php
  5. 2
      html_orig/pages/term.php
  6. 70
      user/ansi_parser.c
  7. 22
      user/ansi_parser.rl
  8. 6
      user/cgi_network.c
  9. 2
      user/cgi_persist.c
  10. 2
      user/cgi_sockets.c
  11. 2
      user/cgi_system.c
  12. 41
      user/cgi_term_cfg.c
  13. 4
      user/cgi_wifi.c
  14. 45
      user/persist.c
  15. 17
      user/persist.h
  16. 15
      user/screen.c
  17. 13
      user/screen.h
  18. 7
      user/syscfg.h
  19. 27
      user/wifimgr.h

@ -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">&nbsp;(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">&nbsp;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>

@ -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" */
}

@ -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
%%{
#/*

@ -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) {

@ -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.

@ -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;

@ -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

@ -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);
}

@ -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;

@ -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;

@ -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.

@ -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++) {

@ -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;

@ -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 {

Loading…
Cancel
Save