moved funcs to flash to make it build again, reduced logging buffer, disabled some logging; add missing files

http-comm
Ondřej Hruška 7 years ago
parent 6e1173cfcf
commit 4c2421121f
  1. 2
      CMakeLists.txt
  2. 18
      Makefile
  3. 11
      esphttpdconfig.mk
  4. 58
      showmem.php
  5. 36
      user/apars_csi.c
  6. 4
      user/apars_dcs.c
  7. 2
      user/apars_osc.c
  8. 2
      user/apars_short.c
  9. 2
      user/apars_utf8.c
  10. 18
      user/cgi_logging.h
  11. 39
      user/cgi_network.c
  12. 5
      user/cgi_persist.c
  13. 7
      user/cgi_sockets.c
  14. 17
      user/cgi_system.c
  15. 71
      user/cgi_term_cfg.c
  16. 43
      user/cgi_wifi.c
  17. 10
      user/character_sets.h
  18. 54
      user/persist.c
  19. 10
      user/persist.h
  20. 257
      user/screen.c
  21. 8
      user/screen.h
  22. 5
      user/serial.c
  23. 3
      user/uart_buffer.c
  24. 6
      user/uart_handler.c
  25. 2
      user/user_main.c
  26. 58
      user/utf8.c
  27. 12
      user/utf8.h
  28. 38
      user/wifimgr.c
  29. 10
      user/wifimgr.h

@ -139,7 +139,7 @@ set(SOURCE_FILES
user/apars_osc.c user/apars_osc.c
user/apars_osc.h user/apars_osc.h
user/apars_dcs.c user/apars_dcs.c
user/apars_dcs.h user/uart_buffer.c user/uart_buffer.h user/jstring.c user/jstring.h user/character_sets.h) user/apars_dcs.h user/uart_buffer.c user/uart_buffer.h user/jstring.c user/jstring.h user/character_sets.h user/utf8.h user/utf8.c user/cgi_logging.h)
include_directories(include) include_directories(include)
include_directories(user) include_directories(user)

@ -62,8 +62,8 @@ LIBS = c gcc hal phy pp net80211 wpa main lwip crypto
#Add in esphttpd lib #Add in esphttpd lib
LIBS += esphttpd LIBS += esphttpd
# compiler flags using during compilation of source files # compiler flags using during compilation of source files -ggdb
CFLAGS = -Os -ggdb -std=gnu99 -Werror -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \ CFLAGS = -Os -std=gnu99 -Werror -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \
-nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH \ -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH \
-Wno-address -Wno-unused -Wno-address -Wno-unused
@ -171,7 +171,7 @@ MODULE_INCDIR := $(addsuffix /include,$(INCDIR))
ESP_FLASH_SIZE_IX=$(call maplookup,$(ESP_SPI_FLASH_SIZE_K),512:0 1024:2 2048:5 4096:6) ESP_FLASH_SIZE_IX=$(call maplookup,$(ESP_SPI_FLASH_SIZE_K),512:0 1024:2 2048:5 4096:6)
ESPTOOL_FREQ=$(call maplookup,$(ESP_FLASH_FREQ_DIV),0:40m 1:26m 2:20m 0xf:80m 15:80m) ESPTOOL_FREQ=$(call maplookup,$(ESP_FLASH_FREQ_DIV),0:40m 1:26m 2:20m 0xf:80m 15:80m)
ESPTOOL_MODE=$(call maplookup,$(ESP_FLASH_MODE),0:qio 1:qout 2:dio 3:dout) ESPTOOL_MODE=$(call maplookup,$(ESP_FLASH_MODE),0:qio 1:qout 2:dio 3:dout)
ESPTOOL_SIZE=$(call maplookup,$(ESP_SPI_FLASH_SIZE_K),512:4m 256:2m 1024:8m 2048:16m 4096:32m) ESPTOOL_SIZE=$(call maplookup,$(ESP_SPI_FLASH_SIZE_K),512:512KB 256:256KB 1024:1MB 2048:2MB 4096:4MB)
ESPTOOL_OPTS=--port $(ESPPORT) --baud $(ESPBAUD) ESPTOOL_OPTS=--port $(ESPPORT) --baud $(ESPBAUD)
ESPTOOL_FLASHDEF=--flash_freq $(ESPTOOL_FREQ) --flash_mode $(ESPTOOL_MODE) --flash_size $(ESPTOOL_SIZE) ESPTOOL_FLASHDEF=--flash_freq $(ESPTOOL_FREQ) --flash_mode $(ESPTOOL_MODE) --flash_size $(ESPTOOL_SIZE)
@ -189,7 +189,7 @@ $1/%.o: %.S
$(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@ $(Q) $(CC) $(INCDIR) $(MODULE_INCDIR) $(EXTRA_INCDIR) $(SDK_INCDIR) $(CFLAGS) -c $$< -o $$@
endef endef
.PHONY: all web parser checkdirs clean libesphttpd default-tgt .PHONY: all web parser checkdirs clean libesphttpd default-tgt espsize espmac
web: web:
$(Q) ./build_web.sh $(Q) ./build_web.sh
@ -197,7 +197,13 @@ web:
parser: parser:
$(Q) ./build_parser.sh $(Q) ./build_parser.sh
all: checkdirs web parser $(TARGET_OUT) $(FW_BASE) espsize:
$(Q) esptool --port /dev/ttyUSB0 flash_id
espmac:
$(Q) esptool --port /dev/ttyUSB0 read_mac
all: checkdirs parser $(TARGET_OUT) $(FW_BASE)
libesphttpd/Makefile: libesphttpd/Makefile:
$(Q) [[ -e "libesphttpd/Makefile" ]] || echo -e "\e[31mlibesphttpd submodule missing.\nIf build fails, run \"git submodule init\" and \"git submodule update\".\e[0m" $(Q) [[ -e "libesphttpd/Makefile" ]] || echo -e "\e[31mlibesphttpd submodule missing.\nIf build fails, run \"git submodule init\" and \"git submodule update\".\e[0m"
@ -209,7 +215,7 @@ $(APP_AR): libesphttpd $(OBJ)
$(vecho) "AR $@" $(vecho) "AR $@"
$(Q) $(AR) cru $@ $(OBJ) $(Q) $(AR) cru $@ $(OBJ)
checkdirs: $(BUILD_DIR) checkdirs: $(BUILD_DIR) html/favicon.ico
$(BUILD_DIR): $(BUILD_DIR):
$(Q) mkdir -p $@ $(Q) mkdir -p $@

@ -44,16 +44,19 @@ ADMIN_PASSWORD = "19738426"
GLOBAL_CFLAGS = \ GLOBAL_CFLAGS = \
-DDEBUG_ROUTER=0 \ -DDEBUG_ROUTER=0 \
-DDEBUG_CAPTDNS=0 \ -DDEBUG_CAPTDNS=0 \
-DDEBUG_HTTP=1 \ -DDEBUG_HTTP=0 \
-DDEBUG_ESPFS=0 \ -DDEBUG_ESPFS=0 \
-DDEBUG_PERSIST=0 \
-DDEBUG_CGI=0 \
-DDEBUG_WIFI=0 \
-DDEBUG_WS=0 \ -DDEBUG_WS=0 \
-DDEBUG_ANSI=1 \ -DDEBUG_ANSI=1 \
-DDEBUG_ANSI_NOIMPL=1 \ -DDEBUG_ANSI_NOIMPL=1 \
-DHTTPD_MAX_BACKLOG_SIZE=8192 \
-DHTTPD_MAX_HEAD_LEN=1024 \
-DHTTPD_MAX_POST_LEN=512 \
-DDEBUG_INPUT=0 \ -DDEBUG_INPUT=0 \
-DDEBUG_HEAP=1 \ -DDEBUG_HEAP=1 \
-DDEBUG_MALLOC=0 \ -DDEBUG_MALLOC=0 \
-DHTTPD_MAX_BACKLOG_SIZE=8192 \
-DHTTPD_MAX_HEAD_LEN=1024 \
-DHTTPD_MAX_POST_LEN=512 \
-mforce-l32 \ -mforce-l32 \
-DUSE_OPTIMIZE_PRINTF=1 -DUSE_OPTIMIZE_PRINTF=1

@ -0,0 +1,58 @@
#!/bin/env php
<?php
$dump = trim(shell_exec('xtensa-lx106-elf-size build/httpd_app.a -A'));
$pieces = explode("\n\n", $dump);
$all_sections = [];
$table = [];
foreach ($pieces as $piece) {
$rows = explode("\n", trim($piece));
if (!$rows) continue;
list($name,) = explode(' ', trim($rows[0]));
$entries = array_map(function($s) {
$pcs = preg_split('/\s+/', $s);
return [$pcs[0], $pcs[1]];
}, array_slice($rows, 3, count($rows)-4));
foreach($entries as $e) {
list($space, $bytes) = $e;
if (!in_array($space, $all_sections)) $all_sections[] = $space;
$table[$name][$space] = $bytes;
}
}
if ($argv[1]) {
$key = $argv[1];
uasort($table, function($a, $b) use ($key) {
$av = $a[$key] ?? 0;
$bv = $b[$key] ?? 0;
return -($av <=> $bv);
});
}
$all_sections = array_diff($all_sections, [
'.comment',
'.xtensa.info',
'.xt.lit',
'.xt.prop',
'.literal',
'.irom0.literal',
'.data',
]);
$widths = [];
foreach($all_sections as $k) {
$widths[$k] = max(8, strlen($k));
printf("%".($widths[$k])."s ", $k);
}
echo "\n";//.str_repeat('-',array_sum($widths))."\n";
foreach ($table as $file => $map) {
foreach ($all_sections as $space) {
$b = isset($map[$space]) ? $map[$space] : 0;
printf("%".$widths[$space]."d ", $b);
}
echo " $file\n";
}

@ -49,7 +49,8 @@ static inline void do_csi_set_private_option(CSI_Data *opts);
/** /**
* Show warning and dump context for invalid CSI * Show warning and dump context for invalid CSI
*/ */
static void warn_bad_csi(void) static void ICACHE_FLASH_ATTR
warn_bad_csi(void)
{ {
ansi_noimpl_r("Unknown CSI"); ansi_noimpl_r("Unknown CSI");
apars_show_context(); apars_show_context();
@ -487,27 +488,32 @@ switch_csi_LeadEquals(CSI_Data *opts)
static inline void ICACHE_FLASH_ATTR static inline void ICACHE_FLASH_ATTR
switch_csi_LeadQuest(CSI_Data *opts) switch_csi_LeadQuest(CSI_Data *opts)
{ {
int n = 0;
switch(opts->key) { switch(opts->key) {
case 's': case 's':
// Save private attributes // Save private attributes
ansi_noimpl("Save private attrs"); for (int i = 0; i < opts->count; i++) {
apars_show_context(); // TODO priv attr s/r n = opts->n[i];
screen_save_private_opt(n);
}
break; break;
case 'r': case 'r':
// Restore private attributes // Restore private attributes
ansi_noimpl("Restore private attrs"); for (int i = 0; i < opts->count; i++) {
apars_show_context(); // TODO priv attr s/r n = opts->n[i];
screen_restore_private_opt(n);
}
break; break;
case 'J': // Erase screen selectively case 'J': // Erase screen selectively
// TODO selective erase // TODO selective erase
ansi_noimpl("Selective screen erase"); switch_csi_Plain(opts); // ignore the ?, do normal erase
break; break;
case 'K': // Erase line selectively case 'K': // Erase line selectively
// TODO selective erase // TODO selective erase
ansi_noimpl("Selective line erase"); switch_csi_Plain(opts); // ignore the ?, do normal erase
break; break;
case 'l': case 'l':
@ -546,8 +552,8 @@ do_csi_sgr(CSI_Data *opts)
else if (n >= SGR_FG_BRT_START && n <= SGR_FG_BRT_END) screen_set_fg((Color) ((n - SGR_FG_BRT_START) + 8)); // AIX bright fg else if (n >= SGR_FG_BRT_START && n <= SGR_FG_BRT_END) screen_set_fg((Color) ((n - SGR_FG_BRT_START) + 8)); // AIX bright fg
else if (n >= SGR_BG_BRT_START && n <= SGR_BG_BRT_END) screen_set_bg((Color) ((n - SGR_BG_BRT_START) + 8)); // AIX bright bg else if (n >= SGR_BG_BRT_START && n <= SGR_BG_BRT_END) screen_set_bg((Color) ((n - SGR_BG_BRT_START) + 8)); // AIX bright bg
// reset color // reset color
else if (n == SGR_FG_DEFAULT) screen_set_fg(termconf_scratch.default_fg); // default fg else if (n == SGR_FG_DEFAULT) screen_set_fg(termconf_live.default_fg); // default fg
else if (n == SGR_BG_DEFAULT) screen_set_bg(termconf_scratch.default_bg); // default bg else if (n == SGR_BG_DEFAULT) screen_set_bg(termconf_live.default_bg); // default bg
// 256 colors // 256 colors
else if (n == SGR_FG_256 || n == SGR_BG_256) { else if (n == SGR_FG_256 || n == SGR_BG_256) {
if (i < count-2) { if (i < count-2) {
@ -617,7 +623,7 @@ do_csi_set_option(CSI_Data *opts)
} }
else if (n == 12) { else if (n == 12) {
// SRM is inverted, according to vt510 manual // SRM is inverted, according to vt510 manual
termconf_scratch.loopback = !yn; termconf_live.loopback = !yn;
} }
else if (n == 20) { else if (n == 20) {
screen_set_newline_mode(yn); screen_set_newline_mode(yn);
@ -754,11 +760,11 @@ do_csi_set_private_option(CSI_Data *opts)
ansi_noimpl("Bracketed paste"); ansi_noimpl("Bracketed paste");
} }
else if (n == 800) { // ESPTerm: Toggle display of buttons else if (n == 800) { // ESPTerm: Toggle display of buttons
termconf_scratch.show_buttons = yn; termconf_live.show_buttons = yn;
screen_notifyChange(CHANGE_CONTENT); // this info is included in the screen preamble screen_notifyChange(CHANGE_CONTENT); // this info is included in the screen preamble
} }
else if (n == 801) { // ESPTerm: Toggle display of config links else if (n == 801) { // ESPTerm: Toggle display of config links
termconf_scratch.show_config_links = yn; termconf_live.show_config_links = yn;
screen_notifyChange(CHANGE_CONTENT); // this info is included in the screen preamble screen_notifyChange(CHANGE_CONTENT); // this info is included in the screen preamble
} }
else { else {
@ -783,14 +789,14 @@ do_csi_xterm_screen_cmd(CSI_Data *opts)
case 18: // Report the size of the text area in characters. case 18: // Report the size of the text area in characters.
case 19: // Report the size of the screen in characters. case 19: // Report the size of the screen in characters.
sprintf(resp_buf, "\033[8;%d;%dt", termconf_scratch.height, termconf_scratch.width); sprintf(resp_buf, "\033[8;%d;%dt", termconf_live.height, termconf_live.width);
apars_respond(resp_buf); apars_respond(resp_buf);
break; break;
case 20: // Report icon case 20: // Report icon
case 21: // Report title case 21: // Report title
apars_respond("\033]l"); apars_respond("\033]l");
apars_respond(termconf_scratch.title); apars_respond(termconf_live.title);
apars_respond("\033\\"); apars_respond("\033\\");
break; break;
@ -802,7 +808,7 @@ do_csi_xterm_screen_cmd(CSI_Data *opts)
break; break;
case 24: // Set Height only case 24: // Set Height only
screen_resize(opts->n[1], termconf_scratch.width); screen_resize(opts->n[1], termconf_live.width);
break; break;
default: default:

@ -47,12 +47,12 @@ apars_handle_dcs(const char *buffer)
} }
else if (buffer[2] == 'r') { else if (buffer[2] == 'r') {
// DECSTBM - Query scrolling region // DECSTBM - Query scrolling region
sprintf(buf, "\033P1$r%d;%dr\033\\", 1, termconf_scratch.height); // 1-80 TODO real extent of scrolling region sprintf(buf, "\033P1$r%d;%dr\033\\", 1, termconf_live.height); // 1-80 TODO real extent of scrolling region
apars_respond(buf); apars_respond(buf);
} }
else if (buffer[2] == 's') { else if (buffer[2] == 's') {
// DECSLRM - Query horizontal margins // DECSLRM - Query horizontal margins
sprintf(buf, "\033P1$r%d;%ds\033\\", 1, termconf_scratch.width); // Can erase - TODO real extent of horiz margins if implemented sprintf(buf, "\033P1$r%d;%ds\033\\", 1, termconf_live.width); // Can erase - TODO real extent of horiz margins if implemented
apars_respond(buf); apars_respond(buf);
} }
else if (buffer[2] == 'm') { else if (buffer[2] == 'm') {

@ -52,7 +52,7 @@ apars_handle_osc(char *buffer)
} }
else if (n >= 91 && n <= 95) { else if (n >= 91 && n <= 95) {
// ESPTerm: action button message // ESPTerm: action button message
strncpy(termconf_scratch.btn_msg[n - 91], buffer, TERM_BTN_MSG_LEN); strncpy(termconf_live.btn_msg[n - 91], buffer, TERM_BTN_MSG_LEN);
} }
else { else {
ansi_noimpl("OSC %d ; %s ST", n, buffer); ansi_noimpl("OSC %d ; %s ST", n, buffer);

@ -139,7 +139,7 @@ void ICACHE_FLASH_ATTR apars_handle_short_cmd(char c)
break; break;
case 'F': // bottom left case 'F': // bottom left
screen_cursor_set(termconf_scratch.height-1, 0); screen_cursor_set(termconf_live.height-1, 0);
break; break;
case 'D': // move cursor down, scroll screen up if needed case 'D': // move cursor down, scroll screen up if needed

@ -37,7 +37,7 @@ apars_handle_plainchar(char c)
if (utf_i == 0) { if (utf_i == 0) {
// start // start
if (c == 192 || c == 193 || c >= 245) { if (c == 192 || c == 193 || c >= 245) {
// forbidden codes // forbidden codes (would be an overlong sequence)
goto fail; goto fail;
} }

@ -0,0 +1,18 @@
//
// Created by MightyPork on 2017/09/10.
//
#ifndef ESPTERM_CGI_LOGGING_H
#define ESPTERM_CGI_LOGGING_H
#if DEBUG_CGI
#define cgi_warn warn
#define cgi_dbg dbg
#define cgi_info info
#else
#define cgi_warn(fmt, ...)
#define cgi_dbg(fmt, ...)
#define cgi_info(fmt, ...)
#endif
#endif //ESPTERM_CGI_LOGGING_H

@ -8,6 +8,7 @@ configuring the network settings
#include "wifimgr.h" #include "wifimgr.h"
#include "persist.h" #include "persist.h"
#include "helpers.h" #include "helpers.h"
#include "cgi_logging.h"
#define SET_REDIR_SUC "/cfg/network" #define SET_REDIR_SUC "/cfg/network"
#define SET_REDIR_ERR SET_REDIR_SUC"?err=" #define SET_REDIR_ERR SET_REDIR_SUC"?err="
@ -43,7 +44,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
// ---- AP DHCP server lease time ---- // ---- AP DHCP server lease time ----
if (GET_ARG("ap_dhcp_time")) { if (GET_ARG("ap_dhcp_time")) {
dbg("Setting DHCP lease time to: %s min.", buff); cgi_dbg("Setting DHCP lease time to: %s min.", buff);
int min = atoi(buff); int min = atoi(buff);
if (min >= 1 && min <= 2880) { if (min >= 1 && min <= 2880) {
if (wificonf->ap_dhcp_time != min) { if (wificonf->ap_dhcp_time != min) {
@ -51,7 +52,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
wifi_change_flags.ap = true; wifi_change_flags.ap = true;
} }
} else { } else {
warn("Lease time %s out of allowed range 1-2880.", buff); cgi_warn("Lease time %s out of allowed range 1-2880.", buff);
redir_url += sprintf(redir_url, "ap_dhcp_time,"); redir_url += sprintf(redir_url, "ap_dhcp_time,");
} }
} }
@ -59,7 +60,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
// ---- AP DHCP start and end IP ---- // ---- AP DHCP start and end IP ----
if (GET_ARG("ap_dhcp_start")) { if (GET_ARG("ap_dhcp_start")) {
dbg("Setting DHCP range start IP to: \"%s\"", buff); cgi_dbg("Setting DHCP range start IP to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff); u32 ip = ipaddr_addr(buff);
if (ip != 0) { if (ip != 0) {
if (wificonf->ap_dhcp_range.start_ip.addr != ip) { if (wificonf->ap_dhcp_range.start_ip.addr != ip) {
@ -67,13 +68,13 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
wifi_change_flags.ap = true; wifi_change_flags.ap = true;
} }
} else { } else {
warn("Bad IP: %s", buff); cgi_warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "ap_dhcp_start,"); redir_url += sprintf(redir_url, "ap_dhcp_start,");
} }
} }
if (GET_ARG("ap_dhcp_end")) { if (GET_ARG("ap_dhcp_end")) {
dbg("Setting DHCP range end IP to: \"%s\"", buff); cgi_dbg("Setting DHCP range end IP to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff); u32 ip = ipaddr_addr(buff);
if (ip != 0) { if (ip != 0) {
if (wificonf->ap_dhcp_range.end_ip.addr != ip) { if (wificonf->ap_dhcp_range.end_ip.addr != ip) {
@ -81,7 +82,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
wifi_change_flags.ap = true; wifi_change_flags.ap = true;
} }
} else { } else {
warn("Bad IP: %s", buff); cgi_warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "ap_dhcp_end,"); redir_url += sprintf(redir_url, "ap_dhcp_end,");
} }
} }
@ -89,7 +90,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
// ---- AP local address & config ---- // ---- AP local address & config ----
if (GET_ARG("ap_addr_ip")) { if (GET_ARG("ap_addr_ip")) {
dbg("Setting AP local IP to: \"%s\"", buff); cgi_dbg("Setting AP local IP to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff); u32 ip = ipaddr_addr(buff);
if (ip != 0) { if (ip != 0) {
if (wificonf->ap_addr.ip.addr != ip) { if (wificonf->ap_addr.ip.addr != ip) {
@ -98,13 +99,13 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
wifi_change_flags.ap = true; wifi_change_flags.ap = true;
} }
} else { } else {
warn("Bad IP: %s", buff); cgi_warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "ap_addr_ip,"); redir_url += sprintf(redir_url, "ap_addr_ip,");
} }
} }
if (GET_ARG("ap_addr_mask")) { if (GET_ARG("ap_addr_mask")) {
dbg("Setting AP local IP netmask to: \"%s\"", buff); cgi_dbg("Setting AP local IP netmask to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff); u32 ip = ipaddr_addr(buff);
if (ip != 0) { if (ip != 0) {
if (wificonf->ap_addr.netmask.addr != ip) { if (wificonf->ap_addr.netmask.addr != ip) {
@ -114,7 +115,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
wifi_change_flags.ap = true; wifi_change_flags.ap = true;
} }
} else { } else {
warn("Bad IP mask: %s", buff); cgi_warn("Bad IP mask: %s", buff);
redir_url += sprintf(redir_url, "ap_addr_mask,"); redir_url += sprintf(redir_url, "ap_addr_mask,");
} }
} }
@ -123,7 +124,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
// DHCP enable / disable (disable means static IP is enabled) // DHCP enable / disable (disable means static IP is enabled)
if (GET_ARG("sta_dhcp_enable")) { if (GET_ARG("sta_dhcp_enable")) {
dbg("DHCP enable = %s", buff); cgi_dbg("DHCP enable = %s", buff);
int enable = atoi(buff); int enable = atoi(buff);
if (wificonf->sta_dhcp_enable != enable) { if (wificonf->sta_dhcp_enable != enable) {
wificonf->sta_dhcp_enable = (bool)enable; wificonf->sta_dhcp_enable = (bool)enable;
@ -134,7 +135,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
// ---- Station IP config (Static IP) ---- // ---- Station IP config (Static IP) ----
if (GET_ARG("sta_addr_ip")) { if (GET_ARG("sta_addr_ip")) {
dbg("Setting Station mode static IP to: \"%s\"", buff); cgi_dbg("Setting Station mode static IP to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff); u32 ip = ipaddr_addr(buff);
if (ip != 0) { if (ip != 0) {
if (wificonf->sta_addr.ip.addr != ip) { if (wificonf->sta_addr.ip.addr != ip) {
@ -142,13 +143,13 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
wifi_change_flags.sta = true; wifi_change_flags.sta = true;
} }
} else { } else {
warn("Bad IP: %s", buff); cgi_warn("Bad IP: %s", buff);
redir_url += sprintf(redir_url, "sta_addr_ip,"); redir_url += sprintf(redir_url, "sta_addr_ip,");
} }
} }
if (GET_ARG("sta_addr_mask")) { if (GET_ARG("sta_addr_mask")) {
dbg("Setting Station mode static IP netmask to: \"%s\"", buff); cgi_dbg("Setting Station mode static IP netmask to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff); u32 ip = ipaddr_addr(buff);
if (ip != 0 && ip != 0xFFFFFFFFUL) { if (ip != 0 && ip != 0xFFFFFFFFUL) {
if (wificonf->sta_addr.netmask.addr != ip) { if (wificonf->sta_addr.netmask.addr != ip) {
@ -156,13 +157,13 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
wifi_change_flags.sta = true; wifi_change_flags.sta = true;
} }
} else { } else {
warn("Bad IP mask: %s", buff); cgi_warn("Bad IP mask: %s", buff);
redir_url += sprintf(redir_url, "sta_addr_mask,"); redir_url += sprintf(redir_url, "sta_addr_mask,");
} }
} }
if (GET_ARG("sta_addr_gw")) { if (GET_ARG("sta_addr_gw")) {
dbg("Setting Station mode static IP default gateway to: \"%s\"", buff); cgi_dbg("Setting Station mode static IP default gateway to: \"%s\"", buff);
u32 ip = ipaddr_addr(buff); u32 ip = ipaddr_addr(buff);
if (ip != 0) { if (ip != 0) {
if (wificonf->sta_addr.gw.addr != ip) { if (wificonf->sta_addr.gw.addr != ip) {
@ -170,14 +171,14 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
wifi_change_flags.sta = true; wifi_change_flags.sta = true;
} }
} else { } else {
warn("Bad gw IP: %s", buff); cgi_warn("Bad gw IP: %s", buff);
redir_url += sprintf(redir_url, "sta_addr_gw,"); redir_url += sprintf(redir_url, "sta_addr_gw,");
} }
} }
if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) { if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) {
// All was OK // All was OK
info("Set network params - success, applying in 1000 ms"); cgi_info("Set network params - success, applying in 1000 ms");
// Settings are applied only if all was OK // Settings are applied only if all was OK
persist_store(); persist_store();
@ -190,7 +191,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiNetworkSetParams(HttpdConnData *connData)
httpdRedirect(connData, SET_REDIR_SUC); httpdRedirect(connData, SET_REDIR_SUC);
} else { } else {
warn("Some WiFi settings did not validate, asking for correction"); cgi_warn("Some WiFi settings did not validate, asking for correction");
// Some errors, appended to the URL as ?err= // Some errors, appended to the URL as ?err=
httpdRedirect(connData, redir_url_buf); httpdRedirect(connData, redir_url_buf);
} }

@ -6,6 +6,7 @@ Cgi/template routines for configuring non-wifi settings
#include "cgi_persist.h" #include "cgi_persist.h"
#include "persist.h" #include "persist.h"
#include "helpers.h" #include "helpers.h"
#include "cgi_logging.h"
#define SET_REDIR_SUC "/cfg/admin" #define SET_REDIR_SUC "/cfg/admin"
@ -29,9 +30,9 @@ cgiPersistWriteDefaults(HttpdConnData *connData)
// width and height must always go together so we can do max size validation // width and height must always go together so we can do max size validation
if (GET_ARG("pw")) { if (GET_ARG("pw")) {
dbg("Entered password for admin: %s", buff); cgi_dbg("Entered password for admin: %s", buff);
if (verify_admin_pw(buff)) { if (verify_admin_pw(buff)) {
dbg("pw is OK"); cgi_dbg("pw is OK");
persist_set_as_default(); persist_set_as_default();

@ -8,6 +8,7 @@
#include "ansi_parser.h" #include "ansi_parser.h"
#include "jstring.h" #include "jstring.h"
#include "uart_driver.h" #include "uart_driver.h"
#include "cgi_logging.h"
// Heartbeat interval in ms // Heartbeat interval in ms
#define HB_TIME 1000 #define HB_TIME 1000
@ -243,7 +244,7 @@ void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags)
switch (c) { switch (c) {
case 's': case 's':
// pass string verbatim // pass string verbatim
if (termconf_scratch.loopback) { if (termconf_live.loopback) {
for (int i = 1; i < len; i++) { for (int i = 1; i < len; i++) {
ansi_parser(data[i]); ansi_parser(data[i]);
} }
@ -264,13 +265,13 @@ void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags)
// action button press // action button press
btnNum = (u8) (data[1]); btnNum = (u8) (data[1]);
if (btnNum > 0 && btnNum < 10) { if (btnNum > 0 && btnNum < 10) {
UART_SendAsync(termconf_scratch.btn_msg[btnNum-1], -1); UART_SendAsync(termconf_live.btn_msg[btnNum-1], -1);
} }
break; break;
case 'i': case 'i':
// requests initial load // requests initial load
dbg("Client requests initial load"); ws_dbg("Client requests initial load");
notifyContentTimCb(ws); notifyContentTimCb(ws);
break; break;

@ -8,6 +8,7 @@
#include "syscfg.h" #include "syscfg.h"
#include "uart_driver.h" #include "uart_driver.h"
#include "ansi_parser.h" #include "ansi_parser.h"
#include "cgi_logging.h"
#define SET_REDIR_SUC "/cfg/system" #define SET_REDIR_SUC "/cfg/system"
#define SET_REDIR_ERR SET_REDIR_SUC"?err=" #define SET_REDIR_ERR SET_REDIR_SUC"?err="
@ -90,7 +91,7 @@ cgiSystemCfgSetParams(HttpdConnData *connData)
} }
if (GET_ARG("uart_baud")) { if (GET_ARG("uart_baud")) {
dbg("Baud rate: %s", buff); cgi_dbg("Baud rate: %s", buff);
int baud = atoi(buff); int baud = atoi(buff);
if (baud == BIT_RATE_300 || if (baud == BIT_RATE_300 ||
baud == BIT_RATE_600 || baud == BIT_RATE_600 ||
@ -110,43 +111,43 @@ cgiSystemCfgSetParams(HttpdConnData *connData)
baud == BIT_RATE_3686400) { baud == BIT_RATE_3686400) {
sysconf->uart_baudrate = (u32) baud; sysconf->uart_baudrate = (u32) baud;
} else { } else {
warn("Bad baud rate %s", buff); cgi_warn("Bad baud rate %s", buff);
redir_url += sprintf(redir_url, "uart_baud,"); redir_url += sprintf(redir_url, "uart_baud,");
} }
} }
if (GET_ARG("uart_parity")) { if (GET_ARG("uart_parity")) {
dbg("Parity: %s", buff); cgi_dbg("Parity: %s", buff);
int parity = atoi(buff); int parity = atoi(buff);
if (parity >= 0 && parity <= 2) { if (parity >= 0 && parity <= 2) {
sysconf->uart_parity = (UartParityMode) parity; sysconf->uart_parity = (UartParityMode) parity;
} else { } else {
warn("Bad parity %s", buff); cgi_warn("Bad parity %s", buff);
redir_url += sprintf(redir_url, "uart_parity,"); redir_url += sprintf(redir_url, "uart_parity,");
} }
} }
if (GET_ARG("uart_stopbits")) { if (GET_ARG("uart_stopbits")) {
dbg("Stop bits: %s", buff); cgi_dbg("Stop bits: %s", buff);
int stopbits = atoi(buff); int stopbits = atoi(buff);
if (stopbits >= 1 && stopbits <= 3) { if (stopbits >= 1 && stopbits <= 3) {
sysconf->uart_stopbits = (UartStopBitsNum) stopbits; sysconf->uart_stopbits = (UartStopBitsNum) stopbits;
} else { } else {
warn("Bad stopbits %s", buff); cgi_warn("Bad stopbits %s", buff);
redir_url += sprintf(redir_url, "uart_stopbits,"); redir_url += sprintf(redir_url, "uart_stopbits,");
} }
} }
if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) { if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) {
// All was OK // All was OK
info("Set system params - success, saving..."); cgi_info("Set system params - success, saving...");
sysconf_apply_settings(); sysconf_apply_settings();
persist_store(); persist_store();
httpdRedirect(connData, SET_REDIR_SUC); httpdRedirect(connData, SET_REDIR_SUC);
} else { } else {
warn("Some settings did not validate, asking for correction"); cgi_warn("Some settings did not validate, asking for correction");
// Some errors, appended to the URL as ?err= // Some errors, appended to the URL as ?err=
httpdRedirect(connData, redir_url_buf); httpdRedirect(connData, redir_url_buf);
} }

@ -8,6 +8,7 @@ Cgi/template routines for configuring non-wifi settings
#include "persist.h" #include "persist.h"
#include "screen.h" #include "screen.h"
#include "helpers.h" #include "helpers.h"
#include "cgi_logging.h"
#define SET_REDIR_SUC "/cfg/term" #define SET_REDIR_SUC "/cfg/term"
#define SET_REDIR_ERR SET_REDIR_SUC"?err=" #define SET_REDIR_ERR SET_REDIR_SUC"?err="
@ -36,11 +37,11 @@ cgiTermCfgSetParams(HttpdConnData *connData)
// width and height must always go together so we can do max size validation // width and height must always go together so we can do max size validation
if (GET_ARG("term_width")) { if (GET_ARG("term_width")) {
dbg("Default screen width: %s", buff); cgi_dbg("Default screen width: %s", buff);
w = atoi(buff); w = atoi(buff);
if (w > 1) { if (w > 1) {
if (GET_ARG("term_height")) { if (GET_ARG("term_height")) {
dbg("Default screen height: %s", buff); cgi_dbg("Default screen height: %s", buff);
h = atoi(buff); h = atoi(buff);
if (h > 1) { if (h > 1) {
if (w * h <= MAX_SCREEN_SIZE) { if (w * h <= MAX_SCREEN_SIZE) {
@ -50,26 +51,26 @@ cgiTermCfgSetParams(HttpdConnData *connData)
shall_clear_screen = true; // this causes a notify shall_clear_screen = true; // this causes a notify
} }
} else { } else {
warn("Bad dimensions: %d x %d (total %d)", w, h, w*h); cgi_warn("Bad dimensions: %d x %d (total %d)", w, h, w*h);
redir_url += sprintf(redir_url, "term_width,term_height,"); redir_url += sprintf(redir_url, "term_width,term_height,");
} }
} else { } else {
warn("Bad height: \"%s\"", buff); cgi_warn("Bad height: \"%s\"", buff);
redir_url += sprintf(redir_url, "term_width,"); redir_url += sprintf(redir_url, "term_width,");
} }
} else { } else {
warn("Missing height arg!"); cgi_warn("Missing height arg!");
// this wont happen normally when the form is used // this wont happen normally when the form is used
redir_url += sprintf(redir_url, "term_width,term_height,"); redir_url += sprintf(redir_url, "term_width,term_height,");
} }
} else { } else {
warn("Bad width: \"%s\"", buff); cgi_warn("Bad width: \"%s\"", buff);
redir_url += sprintf(redir_url, "term_width,"); redir_url += sprintf(redir_url, "term_width,");
} }
} }
if (GET_ARG("default_bg")) { if (GET_ARG("default_bg")) {
dbg("Screen default BG: %s", buff); cgi_dbg("Screen default BG: %s", buff);
n = atoi(buff); n = atoi(buff);
if (n >= 0 && n < 16) { if (n >= 0 && n < 16) {
if (termconf->default_bg != n) { if (termconf->default_bg != n) {
@ -77,13 +78,13 @@ cgiTermCfgSetParams(HttpdConnData *connData)
shall_clear_screen = true; shall_clear_screen = true;
} }
} else { } else {
warn("Bad color %s", buff); cgi_warn("Bad color %s", buff);
redir_url += sprintf(redir_url, "default_bg,"); redir_url += sprintf(redir_url, "default_bg,");
} }
} }
if (GET_ARG("default_fg")) { if (GET_ARG("default_fg")) {
dbg("Screen default FG: %s", buff); cgi_dbg("Screen default FG: %s", buff);
n = atoi(buff); n = atoi(buff);
if (n >= 0 && n < 16) { if (n >= 0 && n < 16) {
if (termconf->default_fg != n) { if (termconf->default_fg != n) {
@ -91,104 +92,104 @@ cgiTermCfgSetParams(HttpdConnData *connData)
shall_clear_screen = true; shall_clear_screen = true;
} }
} else { } else {
warn("Bad color %s", buff); cgi_warn("Bad color %s", buff);
redir_url += sprintf(redir_url, "default_fg,"); redir_url += sprintf(redir_url, "default_fg,");
} }
} }
if (GET_ARG("parser_tout_ms")) { if (GET_ARG("parser_tout_ms")) {
dbg("Parser timeout: %s ms", buff); cgi_dbg("Parser timeout: %s ms", buff);
n = atoi(buff); n = atoi(buff);
if (n >= 0) { if (n >= 0) {
termconf->parser_tout_ms = n; termconf->parser_tout_ms = n;
} else { } else {
warn("Bad parser timeout %s", buff); cgi_warn("Bad parser timeout %s", buff);
redir_url += sprintf(redir_url, "parser_tout_ms,"); redir_url += sprintf(redir_url, "parser_tout_ms,");
} }
} }
if (GET_ARG("display_tout_ms")) { if (GET_ARG("display_tout_ms")) {
dbg("Display update idle timeout: %s ms", buff); cgi_dbg("Display update idle timeout: %s ms", buff);
n = atoi(buff); n = atoi(buff);
if (n > 0) { if (n > 0) {
termconf->display_tout_ms = n; termconf->display_tout_ms = n;
} else { } else {
warn("Bad update timeout %s", buff); cgi_warn("Bad update timeout %s", buff);
redir_url += sprintf(redir_url, "display_tout_ms,"); redir_url += sprintf(redir_url, "display_tout_ms,");
} }
} }
if (GET_ARG("display_cooldown_ms")) { if (GET_ARG("display_cooldown_ms")) {
dbg("Display update cooldown: %s ms", buff); cgi_dbg("Display update cooldown: %s ms", buff);
n = atoi(buff); n = atoi(buff);
if (n > 0) { if (n > 0) {
termconf->display_cooldown_ms = n; termconf->display_cooldown_ms = n;
} else { } else {
warn("Bad cooldown %s", buff); cgi_warn("Bad cooldown %s", buff);
redir_url += sprintf(redir_url, "display_cooldown_ms,"); redir_url += sprintf(redir_url, "display_cooldown_ms,");
} }
} }
if (GET_ARG("fn_alt_mode")) { if (GET_ARG("fn_alt_mode")) {
dbg("FN alt mode: %s", buff); cgi_dbg("FN alt mode: %s", buff);
n = atoi(buff); n = atoi(buff);
termconf->fn_alt_mode = (bool)n; termconf->fn_alt_mode = (bool)n;
notify_screen_content = true; notify_screen_content = true;
} }
if (GET_ARG("crlf_mode")) { if (GET_ARG("crlf_mode")) {
dbg("CRLF mode: %s", buff); cgi_dbg("CRLF mode: %s", buff);
n = atoi(buff); n = atoi(buff);
termconf->crlf_mode = (bool)n; termconf->crlf_mode = (bool)n;
notify_screen_content = true; notify_screen_content = true;
} }
if (GET_ARG("show_buttons")) { if (GET_ARG("show_buttons")) {
dbg("Show buttons: %s", buff); cgi_dbg("Show buttons: %s", buff);
n = atoi(buff); n = atoi(buff);
termconf->show_buttons = (bool)n; termconf->show_buttons = (bool)n;
notify_screen_content = true; notify_screen_content = true;
} }
if (GET_ARG("show_config_links")) { if (GET_ARG("show_config_links")) {
dbg("Show config links: %s", buff); cgi_dbg("Show config links: %s", buff);
n = atoi(buff); n = atoi(buff);
termconf->show_config_links = (bool)n; termconf->show_config_links = (bool)n;
notify_screen_content = true; notify_screen_content = true;
} }
if (GET_ARG("loopback")) { if (GET_ARG("loopback")) {
dbg("Loopback: %s", buff); cgi_dbg("Loopback: %s", buff);
n = atoi(buff); n = atoi(buff);
termconf->loopback = (bool)n; termconf->loopback = (bool)n;
} }
if (GET_ARG("theme")) { if (GET_ARG("theme")) {
dbg("Screen color theme: %s", buff); cgi_dbg("Screen color theme: %s", buff);
n = atoi(buff); n = atoi(buff);
if (n >= 0 && n <= 5) { // ALWAYS ADJUST WHEN ADDING NEW THEME! if (n >= 0 && n <= 5) { // ALWAYS ADJUST WHEN ADDING NEW THEME!
termconf->theme = (u8) n; termconf->theme = (u8) n;
// this can't be notified, page must reload. // this can't be notified, page must reload.
} else { } else {
warn("Bad theme num: %s", buff); cgi_warn("Bad theme num: %s", buff);
redir_url += sprintf(redir_url, "theme,"); redir_url += sprintf(redir_url, "theme,");
} }
} }
if (GET_ARG("cursor_shape")) { if (GET_ARG("cursor_shape")) {
dbg("Cursor shape: %s", buff); cgi_dbg("Cursor shape: %s", buff);
n = atoi(buff); n = atoi(buff);
if (n >= 0 && n <= 6 && n != 1) { if (n >= 0 && n <= 6 && n != 1) {
termconf->cursor_shape = (enum CursorShape) n; termconf->cursor_shape = (enum CursorShape) n;
notify_screen_content = true; notify_screen_content = true;
} else { } else {
warn("Bad cursor_shape num: %s", buff); cgi_warn("Bad cursor_shape num: %s", buff);
redir_url += sprintf(redir_url, "cursor_shape,"); redir_url += sprintf(redir_url, "cursor_shape,");
} }
} }
if (GET_ARG("term_title")) { if (GET_ARG("term_title")) {
dbg("Terminal title default text: \"%s\"", buff); cgi_dbg("Terminal title default text: \"%s\"", buff);
strncpy_safe(termconf->title, buff, 64); // ATTN those must match the values in strncpy_safe(termconf->title, buff, 64); // ATTN those must match the values in
notify_screen_labels = true; notify_screen_labels = true;
} }
@ -196,14 +197,14 @@ cgiTermCfgSetParams(HttpdConnData *connData)
for (int btn_i = 1; btn_i <= TERM_BTN_COUNT; btn_i++) { for (int btn_i = 1; btn_i <= TERM_BTN_COUNT; btn_i++) {
sprintf(buff, "btn%d", btn_i); sprintf(buff, "btn%d", btn_i);
if (GET_ARG(buff)) { if (GET_ARG(buff)) {
dbg("Button%d default text: \"%s\"", btn_i, buff); cgi_dbg("Button%d default text: \"%s\"", btn_i, buff);
strncpy_safe(termconf->btn[btn_i-1], buff, TERM_BTN_LEN); strncpy_safe(termconf->btn[btn_i-1], buff, TERM_BTN_LEN);
notify_screen_labels = true; notify_screen_labels = true;
} }
sprintf(buff, "bm%d", btn_i); sprintf(buff, "bm%d", btn_i);
if (GET_ARG(buff)) { if (GET_ARG(buff)) {
dbg("Button%d message (ASCII): \"%s\"", btn_i, buff); cgi_dbg("Button%d message (ASCII): \"%s\"", btn_i, buff);
// parse: comma,space or semicolon separated decimal values of ASCII codes // parse: comma,space or semicolon separated decimal values of ASCII codes
char c; char c;
@ -217,18 +218,18 @@ cgiTermCfgSetParams(HttpdConnData *connData)
if(lastsp) continue; if(lastsp) continue;
if (acu==0 || acu>255) { if (acu==0 || acu>255) {
warn("Bad value! %d", acu); cgi_warn("Bad value! %d", acu);
redir_url += sprintf(redir_url, "bm%d,", btn_i); redir_url += sprintf(redir_url, "bm%d,", btn_i);
break; break;
} }
if (char_i >= TERM_BTN_MSG_LEN-1) { if (char_i >= TERM_BTN_MSG_LEN-1) {
warn("Too long! %d", acu); cgi_warn("Too long! %d", acu);
redir_url += sprintf(redir_url, "bm%d,", btn_i); redir_url += sprintf(redir_url, "bm%d,", btn_i);
break; break;
} }
dbg("acu %d", acu); cgi_dbg("acu %d", acu);
buff_bm[char_i++] = (char)acu; buff_bm[char_i++] = (char)acu;
// prepare for next char // prepare for next char
@ -239,20 +240,20 @@ cgiTermCfgSetParams(HttpdConnData *connData)
acu *= 10; acu *= 10;
acu += c - '0'; acu += c - '0';
} else { } else {
warn("Bad syntax!"); cgi_warn("Bad syntax!");
redir_url += sprintf(redir_url, "bm%d,", btn_i); redir_url += sprintf(redir_url, "bm%d,", btn_i);
break; break;
} }
} }
if (lastsp && char_i == 0) { if (lastsp && char_i == 0) {
warn("Required!"); cgi_warn("Required!");
redir_url += sprintf(redir_url, "bm%d,", btn_i); redir_url += sprintf(redir_url, "bm%d,", btn_i);
} }
if (!lastsp) { if (!lastsp) {
buff_bm[char_i++] = (char)acu; buff_bm[char_i++] = (char)acu;
} }
buff_bm[char_i] = 0; buff_bm[char_i] = 0;
dbg("%s, chari = %d", buff_bm, char_i); cgi_dbg("%s, chari = %d", buff_bm, char_i);
strncpy(termconf->btn_msg[btn_i-1], buff_bm, TERM_BTN_MSG_LEN); strncpy(termconf->btn_msg[btn_i-1], buff_bm, TERM_BTN_MSG_LEN);
} }
@ -280,7 +281,7 @@ cgiTermCfgSetParams(HttpdConnData *connData)
httpdRedirect(connData, SET_REDIR_SUC); httpdRedirect(connData, SET_REDIR_SUC);
} else { } else {
warn("Some settings did not validate, asking for correction"); cgi_warn("Some settings did not validate, asking for correction");
// Some errors, appended to the URL as ?err= // Some errors, appended to the URL as ?err=
httpdRedirect(connData, redir_url_buf); httpdRedirect(connData, redir_url_buf);
} }

@ -19,6 +19,7 @@ Cgi/template routines for the /wifi url.
#include "wifimgr.h" #include "wifimgr.h"
#include "persist.h" #include "persist.h"
#include "helpers.h" #include "helpers.h"
#include "cgi_logging.h"
#define SET_REDIR_SUC "/cfg/wifi" #define SET_REDIR_SUC "/cfg/wifi"
#define SET_REDIR_ERR SET_REDIR_SUC"?err=" #define SET_REDIR_ERR SET_REDIR_SUC"?err="
@ -116,7 +117,7 @@ void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status)
{ {
int n; int n;
struct bss_info *bss_link = (struct bss_info *) arg; struct bss_info *bss_link = (struct bss_info *) arg;
dbg("wifiScanDoneCb %d", status); cgi_dbg("wifiScanDoneCb %d", status);
if (status != OK) { if (status != OK) {
cgiWifiAps.scanInProgress = 0; cgiWifiAps.scanInProgress = 0;
return; return;
@ -141,7 +142,7 @@ void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status)
return; return;
} }
cgiWifiAps.noAps = n; cgiWifiAps.noAps = n;
info("Scan done: found %d APs", n); cgi_info("Scan done: found %d APs", n);
// Copy access point data to the static struct // Copy access point data to the static struct
n = 0; n = 0;
@ -288,7 +289,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiConnStatus(HttpdConnData *connData)
} }
STATION_STATUS st = wifi_station_get_connect_status(); STATION_STATUS st = wifi_station_get_connect_status();
dbg("CONN STATE = %d", st); cgi_dbg("CONN STATE = %d", st);
switch(st) { switch(st) {
case STATION_IDLE: case STATION_IDLE:
sprintf(buff, "{\"status\": \"idle\"}"); // unclear when this is used sprintf(buff, "{\"status\": \"idle\"}"); // unclear when this is used
@ -360,18 +361,18 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
// ---- WiFi opmode ---- // ---- WiFi opmode ----
if (GET_ARG("opmode")) { if (GET_ARG("opmode")) {
dbg("Setting WiFi opmode to: %s", buff); cgi_dbg("Setting WiFi opmode to: %s", buff);
int mode = atoi(buff); int mode = atoi(buff);
if (mode > NULL_MODE && mode < MAX_MODE) { if (mode > NULL_MODE && mode < MAX_MODE) {
wificonf->opmode = (WIFI_MODE) mode; wificonf->opmode = (WIFI_MODE) mode;
} else { } else {
warn("Bad opmode value \"%s\"", buff); cgi_warn("Bad opmode value \"%s\"", buff);
redir_url += sprintf(redir_url, "opmode,"); redir_url += sprintf(redir_url, "opmode,");
} }
} }
if (GET_ARG("ap_enable")) { if (GET_ARG("ap_enable")) {
dbg("Enable AP: %s", buff); cgi_dbg("Enable AP: %s", buff);
int enable = atoi(buff); int enable = atoi(buff);
if (enable) { if (enable) {
@ -382,7 +383,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
} }
if (GET_ARG("sta_enable")) { if (GET_ARG("sta_enable")) {
dbg("Enable STA: %s", buff); cgi_dbg("Enable STA: %s", buff);
int enable = atoi(buff); int enable = atoi(buff);
if (enable) { if (enable) {
@ -396,7 +397,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
// ---- AP transmit power ---- // ---- AP transmit power ----
if (GET_ARG("tpw")) { if (GET_ARG("tpw")) {
dbg("Setting AP power to: %s", buff); cgi_dbg("Setting AP power to: %s", buff);
int tpw = atoi(buff); int tpw = atoi(buff);
if (tpw >= 0 && tpw <= 82) { // 0 actually isn't 0 but quite low. 82 is very strong if (tpw >= 0 && tpw <= 82) { // 0 actually isn't 0 but quite low. 82 is very strong
if (wificonf->tpw != tpw) { if (wificonf->tpw != tpw) {
@ -404,7 +405,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
wifi_change_flags.ap = true; wifi_change_flags.ap = true;
} }
} else { } else {
warn("tpw %s out of allowed range 0-82.", buff); cgi_warn("tpw %s out of allowed range 0-82.", buff);
redir_url += sprintf(redir_url, "tpw,"); redir_url += sprintf(redir_url, "tpw,");
} }
} }
@ -412,7 +413,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
// ---- AP channel (applies in AP-only mode) ---- // ---- AP channel (applies in AP-only mode) ----
if (GET_ARG("ap_channel")) { if (GET_ARG("ap_channel")) {
info("ap_channel = %s", buff); cgi_info("ap_channel = %s", buff);
int channel = atoi(buff); int channel = atoi(buff);
if (channel > 0 && channel < 15) { if (channel > 0 && channel < 15) {
if (wificonf->ap_channel != channel) { if (wificonf->ap_channel != channel) {
@ -420,7 +421,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
wifi_change_flags.ap = true; wifi_change_flags.ap = true;
} }
} else { } else {
warn("Bad channel value \"%s\", allowed 1-14", buff); cgi_warn("Bad channel value \"%s\", allowed 1-14", buff);
redir_url += sprintf(redir_url, "ap_channel,"); redir_url += sprintf(redir_url, "ap_channel,");
} }
} }
@ -439,12 +440,12 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
if (strlen(buff) > 0) { if (strlen(buff) > 0) {
if (!streq(wificonf->ap_ssid, buff)) { if (!streq(wificonf->ap_ssid, buff)) {
info("Setting SSID to \"%s\"", buff); cgi_info("Setting SSID to \"%s\"", buff);
strncpy_safe(wificonf->ap_ssid, buff, SSID_LEN); strncpy_safe(wificonf->ap_ssid, buff, SSID_LEN);
wifi_change_flags.ap = true; wifi_change_flags.ap = true;
} }
} else { } else {
warn("Bad SSID len."); cgi_warn("Bad SSID len.");
redir_url += sprintf(redir_url, "ap_ssid,"); redir_url += sprintf(redir_url, "ap_ssid,");
} }
} }
@ -456,12 +457,12 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
// but it may lock them out. // but it may lock them out.
if (strlen(buff) == 0 || (strlen(buff) >= 8 && strlen(buff) < PASSWORD_LEN-1)) { if (strlen(buff) == 0 || (strlen(buff) >= 8 && strlen(buff) < PASSWORD_LEN-1)) {
if (!streq(wificonf->ap_password, buff)) { if (!streq(wificonf->ap_password, buff)) {
info("Setting AP password to \"%s\"", buff); cgi_info("Setting AP password to \"%s\"", buff);
strncpy_safe(wificonf->ap_password, buff, PASSWORD_LEN); strncpy_safe(wificonf->ap_password, buff, PASSWORD_LEN);
wifi_change_flags.ap = true; wifi_change_flags.ap = true;
} }
} else { } else {
warn("Bad password len."); cgi_warn("Bad password len.");
redir_url += sprintf(redir_url, "ap_password,"); redir_url += sprintf(redir_url, "ap_password,");
} }
} }
@ -469,7 +470,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
// ---- Hide AP network (do not announce) ---- // ---- Hide AP network (do not announce) ----
if (GET_ARG("ap_hidden")) { if (GET_ARG("ap_hidden")) {
dbg("AP hidden = %s", buff); cgi_dbg("AP hidden = %s", buff);
int hidden = atoi(buff); int hidden = atoi(buff);
if (hidden != wificonf->ap_hidden) { if (hidden != wificonf->ap_hidden) {
wificonf->ap_hidden = (hidden != 0); wificonf->ap_hidden = (hidden != 0);
@ -482,7 +483,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
if (GET_ARG("sta_ssid")) { if (GET_ARG("sta_ssid")) {
if (!streq(wificonf->sta_ssid, buff)) { if (!streq(wificonf->sta_ssid, buff)) {
// No verification needed, at worst it fails to connect // No verification needed, at worst it fails to connect
info("Setting station SSID to: \"%s\"", buff); cgi_info("Setting station SSID to: \"%s\"", buff);
strncpy_safe(wificonf->sta_ssid, buff, SSID_LEN); strncpy_safe(wificonf->sta_ssid, buff, SSID_LEN);
wifi_change_flags.sta = true; wifi_change_flags.sta = true;
sta_ssid_pw_changed = true; sta_ssid_pw_changed = true;
@ -494,7 +495,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
if (GET_ARG("sta_password")) { if (GET_ARG("sta_password")) {
if (!streq(wificonf->sta_password, buff)) { if (!streq(wificonf->sta_password, buff)) {
// No verification needed, at worst it fails to connect // No verification needed, at worst it fails to connect
info("Setting station password to: \"%s\"", buff); cgi_info("Setting station password to: \"%s\"", buff);
strncpy_safe(wificonf->sta_password, buff, PASSWORD_LEN); strncpy_safe(wificonf->sta_password, buff, PASSWORD_LEN);
wifi_change_flags.sta = true; wifi_change_flags.sta = true;
sta_ssid_pw_changed = true; sta_ssid_pw_changed = true;
@ -503,7 +504,7 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) { if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) {
// All was OK // All was OK
info("Set WiFi params - success, applying in 2000 ms"); cgi_info("Set WiFi params - success, applying in 2000 ms");
// Settings are applied only if all was OK // Settings are applied only if all was OK
// //
@ -523,14 +524,14 @@ httpd_cgi_state ICACHE_FLASH_ATTR cgiWiFiSetParams(HttpdConnData *connData)
&& wificonf->sta_ssid[0] != 0) { && wificonf->sta_ssid[0] != 0) {
// User wants to connect // User wants to connect
info("User wants to connect to SSID, redirecting to ConnStatus page."); cgi_info("User wants to connect to SSID, redirecting to ConnStatus page.");
httpdRedirect(connData, "/cfg/wifi/connecting"); httpdRedirect(connData, "/cfg/wifi/connecting");
} }
else { else {
httpdRedirect(connData, SET_REDIR_SUC); httpdRedirect(connData, SET_REDIR_SUC);
} }
} else { } else {
warn("Some WiFi settings did not validate, asking for correction"); cgi_warn("Some WiFi settings did not validate, asking for correction");
// Some errors, appended to the URL as ?err= // Some errors, appended to the URL as ?err=
httpdRedirect(connData, redir_url_buf); httpdRedirect(connData, redir_url_buf);
} }

@ -9,15 +9,7 @@
// Tables must be contiguous! // Tables must be contiguous!
#define CODEPAGE_A_BEGIN 35 // Full range of UTF-8 is now supported, if needed, but the table must be changed to uint32_t
#define CODEPAGE_A_END 35
static const u16 codepage_A[] ESP_CONST_DATA =
{// Unicode ASCII SYM
// %%BEGIN:A%%
0x20a4, // 35 # £
// %%END:A%%
};
#define CODEPAGE_0_BEGIN 96 #define CODEPAGE_0_BEGIN 96
#define CODEPAGE_0_END 126 #define CODEPAGE_0_END 126

@ -16,36 +16,36 @@ PersistBlock persist;
static void ICACHE_FLASH_ATTR static void ICACHE_FLASH_ATTR
apply_live_settings(void) apply_live_settings(void)
{ {
dbg("[Persist] Applying live settings..."); persist_dbg("[Persist] Applying live settings...");
dbg("[Persist] > system"); persist_dbg("[Persist] > system");
sysconf_apply_settings(); sysconf_apply_settings();
dbg("[Persist] > wifi"); persist_dbg("[Persist] > wifi");
wifimgr_apply_settings(); wifimgr_apply_settings();
dbg("[Persist] > terminal"); persist_dbg("[Persist] > terminal");
terminal_apply_settings(); terminal_apply_settings();
dbg("[Persist] Live settings applied."); persist_dbg("[Persist] Live settings applied.");
// ... // ...
} }
static void ICACHE_FLASH_ATTR static void ICACHE_FLASH_ATTR
restore_live_settings_to_hard_defaults(void) restore_live_settings_to_hard_defaults(void)
{ {
dbg("[Persist] Restore to hard defaults..."); persist_dbg("[Persist] Restore to hard defaults...");
dbg("[Persist] > system"); persist_dbg("[Persist] > system");
sysconf_restore_defaults(); sysconf_restore_defaults();
dbg("[Persist] > wifi"); persist_dbg("[Persist] > wifi");
wifimgr_restore_defaults(); wifimgr_restore_defaults();
dbg("[Persist] > terminal"); persist_dbg("[Persist] > terminal");
terminal_restore_defaults(); terminal_restore_defaults();
dbg("[Persist] Restored to hard defaults."); persist_dbg("[Persist] Restored to hard defaults.");
// ... // ...
} }
@ -103,14 +103,14 @@ compute_checksum(AppConfigBundle *bundle)
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
persist_load(void) persist_load(void)
{ {
info("[Persist] Loading stored settings from FLASH..."); persist_info("[Persist] Loading stored settings from FLASH...");
dbg("AppConfigBundle memory map:"); persist_dbg("AppConfigBundle memory map:");
dbg("> WiFiConfigBundle at %4d (error %2d)", wconf_at, wconf_at - 0); persist_dbg("> WiFiConfigBundle at %4d (error %2d)", wconf_at, wconf_at - 0);
dbg("> SystemConfigBundle at %4d (error %2d)", sconf_at, sconf_at - WIFICONF_SIZE); persist_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); persist_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)); persist_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)); persist_dbg("> Total size = %d bytes (error %d)", sizeof(AppConfigBundle), APPCONF_SIZE - sizeof(AppConfigBundle));
bool hard_reset = false; bool hard_reset = false;
@ -124,7 +124,7 @@ persist_load(void)
error("[Persist] Checksum verification: FAILED"); error("[Persist] Checksum verification: FAILED");
hard_reset = true; hard_reset = true;
} else { } else {
info("[Persist] Checksum verification: PASSED"); persist_info("[Persist] Checksum verification: PASSED");
} }
if (hard_reset) { if (hard_reset) {
@ -142,13 +142,13 @@ persist_load(void)
apply_live_settings(); apply_live_settings();
} }
info("[Persist] All settings loaded and applied."); persist_info("[Persist] All settings loaded and applied.");
} }
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
persist_store(void) persist_store(void)
{ {
info("[Persist] Storing all settings to FLASH..."); persist_info("[Persist] Storing all settings to FLASH...");
// Update checksums before write // Update checksums before write
persist.current.checksum = compute_checksum(&persist.current); persist.current.checksum = compute_checksum(&persist.current);
@ -157,7 +157,7 @@ persist_store(void)
if (!system_param_save_with_protect(PERSIST_SECTOR_ID, &persist, sizeof(PersistBlock))) { if (!system_param_save_with_protect(PERSIST_SECTOR_ID, &persist, sizeof(PersistBlock))) {
error("[Persist] Store to flash failed!"); error("[Persist] Store to flash failed!");
} }
info("[Persist] All settings persisted."); persist_info("[Persist] All settings persisted.");
} }
/** /**
@ -166,13 +166,13 @@ persist_store(void)
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
persist_load_hard_default(void) persist_load_hard_default(void)
{ {
info("[Persist] Restoring live settings to hard defaults..."); persist_info("[Persist] Restoring live settings to hard defaults...");
// Set live config to default values // Set live config to default values
restore_live_settings_to_hard_defaults(); restore_live_settings_to_hard_defaults();
persist_store(); persist_store();
info("[Persist] Settings restored to hard defaults."); persist_info("[Persist] Settings restored to hard defaults.");
apply_live_settings(); // apply apply_live_settings(); // apply
} }
@ -183,13 +183,13 @@ persist_load_hard_default(void)
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
persist_restore_default(void) persist_restore_default(void)
{ {
info("[Persist] Restoring live settings to stored defaults..."); persist_info("[Persist] Restoring live settings to stored defaults...");
memcpy(&persist.current, &persist.defaults, sizeof(AppConfigBundle)); memcpy(&persist.current, &persist.defaults, sizeof(AppConfigBundle));
apply_live_settings(); apply_live_settings();
persist_store(); persist_store();
info("[Persist] Settings restored to stored defaults."); persist_info("[Persist] Settings restored to stored defaults.");
} }
/** /**
@ -198,11 +198,11 @@ persist_restore_default(void)
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
persist_set_as_default(void) persist_set_as_default(void)
{ {
info("[Persist] Storing live settings as defaults.."); persist_info("[Persist] Storing live settings as defaults..");
// current -> defaults // current -> defaults
memcpy(&persist.defaults, &persist.current, sizeof(AppConfigBundle)); memcpy(&persist.defaults, &persist.current, sizeof(AppConfigBundle));
persist_store(); persist_store();
info("[Persist] Default settings updated."); persist_info("[Persist] Default settings updated.");
} }

@ -65,4 +65,14 @@ void persist_restore_default(void);
void persist_set_as_default(void); void persist_set_as_default(void);
void persist_store(void); void persist_store(void);
#if DEBUG_PERSIST
#define persist_warn warn
#define persist_dbg dbg
#define persist_info info
#else
#define persist_warn(fmt, ...)
#define persist_dbg(fmt, ...)
#define persist_info(fmt, ...)
#endif
#endif //ESP_VT100_FIRMWARE_PERSIST_H #endif //ESP_VT100_FIRMWARE_PERSIST_H

@ -7,17 +7,18 @@
#include "apars_logging.h" #include "apars_logging.h"
#include "jstring.h" #include "jstring.h"
#include "character_sets.h" #include "character_sets.h"
#include "utf8.h"
TerminalConfigBundle * const termconf = &persist.current.termconf; TerminalConfigBundle * const termconf = &persist.current.termconf;
TerminalConfigBundle termconf_scratch; TerminalConfigBundle termconf_live;
MouseTrackingConfig mouse_tracking; MouseTrackingConfig mouse_tracking;
// forward declare // forward declare
static void utf8_remap(char* out, char g, char charset); static void utf8_remap(char* out, char g, char charset);
#define W termconf_scratch.width #define W termconf_live.width
#define H termconf_scratch.height #define H termconf_live.height
/** /**
* Highest permissible value of the color attribute * Highest permissible value of the color attribute
@ -48,8 +49,9 @@ static Cell screen[MAX_SCREEN_SIZE];
static struct { static struct {
bool numpad_alt_mode; //!< DECNKM - Numpad Application Mode bool numpad_alt_mode; //!< DECNKM - Numpad Application Mode
bool cursors_alt_mode; //!< DECCKM - Cursors Application mode bool cursors_alt_mode; //!< DECCKM - Cursors Application mode
bool bracketed_paste;
bool reverse; //!< DECSCNM - Reverse video bool reverse_video; //!< DECSCNM - Reverse video
bool insert_mode; //!< IRM - Insert mode (move rest of the line to the right) bool insert_mode; //!< IRM - Insert mode (move rest of the line to the right)
bool cursor_visible; //!< DECTCEM - Cursor visible bool cursor_visible; //!< DECTCEM - Cursor visible
@ -90,7 +92,7 @@ typedef struct {
/** Options saved with cursor */ /** Options saved with cursor */
bool auto_wrap; //!< DECAWM - Wrapping when EOL bool auto_wrap; //!< DECAWM - Wrapping when EOL
bool reverse_wraparound; //!< Reverse-wraparound Mode. DECSET 45 bool reverse_wrap; //!< Reverse-wraparound Mode. DECSET 45
bool origin_mode; //!< DECOM - absolute positioning is relative to vertical margins bool origin_mode; //!< DECOM - absolute positioning is relative to vertical margins
} CursorTypeDef; } CursorTypeDef;
@ -118,6 +120,23 @@ static struct {
u32 tab_stops[TABSTOP_WORDS]; u32 tab_stops[TABSTOP_WORDS];
} state_backup; } state_backup;
/** options backup (save/restore) */
static struct {
bool cursors_alt_mode;
bool reverse_video;
bool origin_mode;
bool auto_wrap;
enum MTM mouse_tracking;
enum MTE mouse_encoding;
bool focus_tracking;
bool cursor_blink;
bool cursor_visible;
bool reverse_wrap;
bool bracketed_paste;
bool show_buttons;
bool show_config_links;
} opt_backup;
/** /**
* This is used to prevent premature change notifications * This is used to prevent premature change notifications
* (from nested calls) * (from nested calls)
@ -188,14 +207,14 @@ terminal_apply_settings_noclear(void)
// Migrate to v1 // Migrate to v1
if (termconf->config_version < 1) { if (termconf->config_version < 1) {
dbg("termconf: Updating to version 1"); persist_dbg("termconf: Updating to version 1");
termconf->display_cooldown_ms = SCR_DEF_DISPLAY_COOLDOWN_MS; termconf->display_cooldown_ms = SCR_DEF_DISPLAY_COOLDOWN_MS;
changed = 1; changed = 1;
} }
// Migrate to v2 // Migrate to v2
if (termconf->config_version < 2) { if (termconf->config_version < 2) {
dbg("termconf: Updating to version 2"); persist_dbg("termconf: Updating to version 2");
termconf->loopback = 0; termconf->loopback = 0;
termconf->show_config_links = 1; termconf->show_config_links = 1;
termconf->show_buttons = 1; termconf->show_buttons = 1;
@ -204,7 +223,7 @@ terminal_apply_settings_noclear(void)
// Migrate to v3 // Migrate to v3
if (termconf->config_version < 3) { if (termconf->config_version < 3) {
dbg("termconf: Updating to version 3"); persist_dbg("termconf: Updating to version 3");
for(int i=1; i <= TERM_BTN_COUNT; i++) { for(int i=1; i <= TERM_BTN_COUNT; i++) {
sprintf(termconf->btn_msg[i-1], "%c", i); sprintf(termconf->btn_msg[i-1], "%c", i);
} }
@ -213,7 +232,7 @@ terminal_apply_settings_noclear(void)
// Migrate to v3 // Migrate to v3
if (termconf->config_version < 4) { if (termconf->config_version < 4) {
dbg("termconf: Updating to version 4"); persist_dbg("termconf: Updating to version 4");
termconf->cursor_shape = CURSOR_BLOCK_BL; termconf->cursor_shape = CURSOR_BLOCK_BL;
termconf->crlf_mode = false; termconf->crlf_mode = false;
changed = 1; changed = 1;
@ -231,13 +250,13 @@ terminal_apply_settings_noclear(void)
changed = 1; changed = 1;
} }
memcpy(&termconf_scratch, termconf, sizeof(TerminalConfigBundle)); memcpy(&termconf_live, termconf, sizeof(TerminalConfigBundle));
if (W*H > MAX_SCREEN_SIZE) { if (W*H > MAX_SCREEN_SIZE) {
error("BAD SCREEN SIZE: %d rows x %d cols", H, W); error("BAD SCREEN SIZE: %d rows x %d cols", H, W);
error("reverting terminal settings to default"); error("reverting terminal settings to default");
terminal_restore_defaults(); terminal_restore_defaults();
changed = true; changed = true;
memcpy(&termconf_scratch, termconf, sizeof(TerminalConfigBundle)); memcpy(&termconf_live, termconf, sizeof(TerminalConfigBundle));
screen_init(); screen_init();
} }
@ -255,7 +274,7 @@ terminal_apply_settings_noclear(void)
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_init(void) screen_init(void)
{ {
dbg("Screen buffer size = %d bytes", sizeof(screen)); if(DEBUG_HEAP) dbg("Screen buffer size = %d bytes", sizeof(screen));
NOTIFY_LOCK(); NOTIFY_LOCK();
screen_reset(); screen_reset();
@ -285,7 +304,7 @@ cursor_reset(void)
static void ICACHE_FLASH_ATTR static void ICACHE_FLASH_ATTR
screen_reset_on_resize(void) screen_reset_on_resize(void)
{ {
dbg("Screen partial reset due to resize"); ansi_dbg("Screen partial reset due to resize");
NOTIFY_LOCK(); NOTIFY_LOCK();
cursor.x = 0; cursor.x = 0;
@ -320,7 +339,7 @@ screen_reset_sgr(void)
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_reset(void) screen_reset(void)
{ {
dbg("Screen reset."); ansi_dbg("Screen reset.");
NOTIFY_LOCK(); NOTIFY_LOCK();
cursor_reset(); cursor_reset();
@ -330,13 +349,13 @@ screen_reset(void)
scr.insert_mode = false; scr.insert_mode = false;
cursor.origin_mode = false; cursor.origin_mode = false;
cursor.auto_wrap = true; cursor.auto_wrap = true;
cursor.reverse_wraparound = false; cursor.reverse_wrap = false;
termconf_scratch.cursor_shape = termconf->cursor_shape; termconf_live.cursor_shape = termconf->cursor_shape;
scr.numpad_alt_mode = false; scr.numpad_alt_mode = false;
scr.cursors_alt_mode = false; scr.cursors_alt_mode = false;
termconf_scratch.crlf_mode = termconf->crlf_mode; termconf_live.crlf_mode = termconf->crlf_mode;
scr.reverse = false; scr.reverse_video = false;
scr.vm0 = 0; scr.vm0 = 0;
scr.vm1 = H-1; scr.vm1 = H-1;
@ -350,13 +369,26 @@ screen_reset(void)
// size is left unchanged // size is left unchanged
screen_clear(CLEAR_ALL); screen_clear(CLEAR_ALL);
screen_clear_all_tabs();
// Set initial tabstops // Set initial tabstops
for (int i = 0; i < TABSTOP_WORDS; i++) { for (int i = 0; i < TABSTOP_WORDS; i++) {
scr.tab_stops[i] = 0x80808080; scr.tab_stops[i] = 0x80808080;
} }
// initial values in the save buffer in case of receiving restore without storing first
opt_backup.cursors_alt_mode = scr.cursors_alt_mode;
opt_backup.reverse_video = scr.reverse_video;
opt_backup.origin_mode = cursor.origin_mode;
opt_backup.auto_wrap = cursor.auto_wrap;
opt_backup.mouse_tracking = mouse_tracking.mode;
opt_backup.mouse_encoding = mouse_tracking.encoding;
opt_backup.focus_tracking = mouse_tracking.focus_tracking;
opt_backup.cursor_blink = CURSOR_BLINKS(termconf_live.cursor_shape);
opt_backup.cursor_visible = scr.cursor_visible;
opt_backup.reverse_wrap = cursor.reverse_wrap;
opt_backup.bracketed_paste = scr.bracketed_paste;
opt_backup.show_buttons = termconf_live.show_buttons;
opt_backup.show_config_links = termconf_live.show_config_links;
NOTIFY_DONE(); NOTIFY_DONE();
} }
@ -369,16 +401,16 @@ void ICACHE_FLASH_ATTR
screen_swap_state(bool alternate) screen_swap_state(bool alternate)
{ {
if (alternate == state_backup.alternate_active) { if (alternate == state_backup.alternate_active) {
warn("No swap, already alternate = %d", alternate); ansi_warn("No swap, already alternate = %d", alternate);
return; // nothing to do return; // nothing to do
} }
if (alternate) { if (alternate) {
dbg("Swap to alternate"); ansi_dbg("Swap to alternate");
// store old state // store old state
memcpy(state_backup.title, termconf_scratch.title, TERM_TITLE_LEN); memcpy(state_backup.title, termconf_live.title, TERM_TITLE_LEN);
memcpy(state_backup.btn, termconf_scratch.btn, sizeof(termconf_scratch.btn)); memcpy(state_backup.btn, termconf_live.btn, sizeof(termconf_live.btn));
memcpy(state_backup.btn_msg, termconf_scratch.btn_msg, sizeof(termconf_scratch.btn_msg)); memcpy(state_backup.btn_msg, termconf_live.btn_msg, sizeof(termconf_live.btn_msg));
memcpy(state_backup.tab_stops, scr.tab_stops, sizeof(scr.tab_stops)); memcpy(state_backup.tab_stops, scr.tab_stops, sizeof(scr.tab_stops));
state_backup.vm0 = scr.vm0; state_backup.vm0 = scr.vm0;
state_backup.vm1 = scr.vm1; state_backup.vm1 = scr.vm1;
@ -388,11 +420,11 @@ screen_swap_state(bool alternate)
// TODO backup screen content (if this is ever possible) // TODO backup screen content (if this is ever possible)
} }
else { else {
dbg("Unswap from alternate"); ansi_dbg("Unswap from alternate");
NOTIFY_LOCK(); NOTIFY_LOCK();
memcpy(termconf_scratch.title, state_backup.title, TERM_TITLE_LEN); memcpy(termconf_live.title, state_backup.title, TERM_TITLE_LEN);
memcpy(termconf_scratch.btn, state_backup.btn, sizeof(termconf_scratch.btn)); memcpy(termconf_live.btn, state_backup.btn, sizeof(termconf_live.btn));
memcpy(termconf_scratch.btn_msg, state_backup.btn_msg, sizeof(termconf_scratch.btn_msg)); memcpy(termconf_live.btn_msg, state_backup.btn_msg, sizeof(termconf_live.btn_msg));
memcpy(scr.tab_stops, state_backup.tab_stops, sizeof(scr.tab_stops)); memcpy(scr.tab_stops, state_backup.tab_stops, sizeof(scr.tab_stops));
scr.vm0 = state_backup.vm0; scr.vm0 = state_backup.vm0;
scr.vm1 = state_backup.vm1; scr.vm1 = state_backup.vm1;
@ -613,7 +645,8 @@ screen_clear_in_line(unsigned int count)
} }
} }
void screen_insert_lines(unsigned int lines) void ICACHE_FLASH_ATTR
screen_insert_lines(unsigned int lines)
{ {
if (!cursor_inside_region()) return; // can't insert if not inside region if (!cursor_inside_region()) return; // can't insert if not inside region
NOTIFY_LOCK(); NOTIFY_LOCK();
@ -637,7 +670,8 @@ void screen_insert_lines(unsigned int lines)
NOTIFY_DONE(); NOTIFY_DONE();
} }
void screen_delete_lines(unsigned int lines) void ICACHE_FLASH_ATTR
screen_delete_lines(unsigned int lines)
{ {
if (!cursor_inside_region()) return; // can't delete if not inside region if (!cursor_inside_region()) return; // can't delete if not inside region
NOTIFY_LOCK(); NOTIFY_LOCK();
@ -658,7 +692,8 @@ void screen_delete_lines(unsigned int lines)
NOTIFY_DONE(); NOTIFY_DONE();
} }
void screen_insert_characters(unsigned int count) void ICACHE_FLASH_ATTR
screen_insert_characters(unsigned int count)
{ {
NOTIFY_LOCK(); NOTIFY_LOCK();
int targetStart = cursor.x + count; int targetStart = cursor.x + count;
@ -675,7 +710,8 @@ void screen_insert_characters(unsigned int count)
NOTIFY_DONE(); NOTIFY_DONE();
} }
void screen_delete_characters(unsigned int count) void ICACHE_FLASH_ATTR
screen_delete_characters(unsigned int count)
{ {
NOTIFY_LOCK(); NOTIFY_LOCK();
int targetEnd = W - count; int targetEnd = W - count;
@ -730,12 +766,12 @@ screen_resize(int rows, int cols)
{ {
// sanitize // sanitize
if (cols < 1 || rows < 1) { if (cols < 1 || rows < 1) {
error("Screen size must be positive, ignoring command: %d x %d", cols, rows); error("Bad size: %d x %d", cols, rows);
return; return;
} }
if (cols * rows > MAX_SCREEN_SIZE) { if (cols * rows > MAX_SCREEN_SIZE) {
error("Max screen size exceeded, ignoring command: %d x %d", cols, rows); error("Too big size: %d x %d", cols, rows);
return; return;
} }
@ -751,7 +787,7 @@ screen_resize(int rows, int cols)
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_set_title(const char *title) screen_set_title(const char *title)
{ {
strncpy(termconf_scratch.title, title, TERM_TITLE_LEN); strncpy(termconf_live.title, title, TERM_TITLE_LEN);
screen_notifyChange(CHANGE_LABELS); screen_notifyChange(CHANGE_LABELS);
} }
@ -763,7 +799,7 @@ screen_set_title(const char *title)
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_set_button_text(int num, const char *text) screen_set_button_text(int num, const char *text)
{ {
strncpy(termconf_scratch.btn[num-1], text, TERM_BTN_LEN); strncpy(termconf_live.btn[num-1], text, TERM_BTN_LEN);
screen_notifyChange(CHANGE_LABELS); screen_notifyChange(CHANGE_LABELS);
} }
@ -851,7 +887,7 @@ screen_cursor_shape(enum CursorShape shape)
{ {
NOTIFY_LOCK(); NOTIFY_LOCK();
if (shape == CURSOR_DEFAULT) shape = termconf->cursor_shape; if (shape == CURSOR_DEFAULT) shape = termconf->cursor_shape;
termconf_scratch.cursor_shape = shape; termconf_live.cursor_shape = shape;
NOTIFY_DONE(); NOTIFY_DONE();
} }
@ -861,13 +897,13 @@ screen_cursor_blink(bool blink)
{ {
NOTIFY_LOCK(); NOTIFY_LOCK();
if (blink) { if (blink) {
if (termconf_scratch.cursor_shape == CURSOR_BLOCK) termconf_scratch.cursor_shape = CURSOR_BLOCK_BL; if (termconf_live.cursor_shape == CURSOR_BLOCK) termconf_live.cursor_shape = CURSOR_BLOCK_BL;
if (termconf_scratch.cursor_shape == CURSOR_BAR) termconf_scratch.cursor_shape = CURSOR_BAR_BL; if (termconf_live.cursor_shape == CURSOR_BAR) termconf_live.cursor_shape = CURSOR_BAR_BL;
if (termconf_scratch.cursor_shape == CURSOR_UNDERLINE) termconf_scratch.cursor_shape = CURSOR_UNDERLINE_BL; if (termconf_live.cursor_shape == CURSOR_UNDERLINE) termconf_live.cursor_shape = CURSOR_UNDERLINE_BL;
} else { } else {
if (termconf_scratch.cursor_shape == CURSOR_BLOCK_BL) termconf_scratch.cursor_shape = CURSOR_BLOCK; if (termconf_live.cursor_shape == CURSOR_BLOCK_BL) termconf_live.cursor_shape = CURSOR_BLOCK;
if (termconf_scratch.cursor_shape == CURSOR_BAR_BL) termconf_scratch.cursor_shape = CURSOR_BAR; if (termconf_live.cursor_shape == CURSOR_BAR_BL) termconf_live.cursor_shape = CURSOR_BAR;
if (termconf_scratch.cursor_shape == CURSOR_UNDERLINE_BL) termconf_scratch.cursor_shape = CURSOR_UNDERLINE; if (termconf_live.cursor_shape == CURSOR_UNDERLINE_BL) termconf_live.cursor_shape = CURSOR_UNDERLINE;
} }
NOTIFY_DONE(); NOTIFY_DONE();
} }
@ -956,7 +992,7 @@ screen_cursor_move(int dy, int dx, bool scroll)
cursor.y += dy; cursor.y += dy;
if (cursor.x >= (int)W) cursor.x = W - 1; if (cursor.x >= (int)W) cursor.x = W - 1;
if (cursor.x < (int)0) { if (cursor.x < (int)0) {
if (cursor.auto_wrap && cursor.reverse_wraparound) { if (cursor.auto_wrap && cursor.reverse_wrap) {
// this is mimicking a behavior from xterm that allows any number of steps backwards with reverse wraparound enabled // this is mimicking a behavior from xterm that allows any number of steps backwards with reverse wraparound enabled
int steps = -cursor.x; int steps = -cursor.x;
if(steps > 1000) steps = 1; // avoid something stupid causing infinite loop here if(steps > 1000) steps = 1; // avoid something stupid causing infinite loop here
@ -1097,7 +1133,7 @@ screen_wrap_enable(bool enable)
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_reverse_wrap_enable(bool enable) screen_reverse_wrap_enable(bool enable)
{ {
cursor.reverse_wraparound = enable; cursor.reverse_wrap = enable;
} }
/** /**
@ -1201,7 +1237,7 @@ void ICACHE_FLASH_ATTR
screen_set_reverse_video(bool reverse) screen_set_reverse_video(bool reverse)
{ {
NOTIFY_LOCK(); NOTIFY_LOCK();
scr.reverse = reverse; scr.reverse_video = reverse;
NOTIFY_DONE(); NOTIFY_DONE();
} }
@ -1209,7 +1245,7 @@ void ICACHE_FLASH_ATTR
screen_set_newline_mode(bool nlm) screen_set_newline_mode(bool nlm)
{ {
NOTIFY_LOCK(); NOTIFY_LOCK();
termconf_scratch.crlf_mode = nlm; termconf_live.crlf_mode = nlm;
NOTIFY_DONE(); NOTIFY_DONE();
} }
@ -1220,6 +1256,79 @@ screen_set_origin_mode(bool region_origin)
screen_cursor_set(0, 0); screen_cursor_set(0, 0);
} }
static void ICACHE_FLASH_ATTR
do_save_private_opt(int n, bool save)
{
#define SAVE_RESTORE(sf, of) do { if (save) sf=(of); else of=(sf); } while(0)
switch (n) {
case 1:
SAVE_RESTORE(opt_backup.cursors_alt_mode, scr.cursors_alt_mode);
break;
case 5:
SAVE_RESTORE(opt_backup.reverse_video, scr.reverse_video);
break;
case 6:
SAVE_RESTORE(opt_backup.origin_mode, cursor.origin_mode);
break;
case 7:
SAVE_RESTORE(opt_backup.auto_wrap, cursor.auto_wrap);
break;
case 9:
case 1000:
case 1001: // hilite, not implemented
case 1002:
case 1003:
SAVE_RESTORE(opt_backup.mouse_tracking, mouse_tracking.mode);
break;
case 1004:
SAVE_RESTORE(opt_backup.focus_tracking, mouse_tracking.focus_tracking);
break;
case 1005:
case 1006:
case 1015:
SAVE_RESTORE(opt_backup.mouse_encoding, mouse_tracking.encoding);
break;
case 12: // cursor blink
if (save) {
opt_backup.cursor_blink = CURSOR_BLINKS(termconf_live.cursor_shape);
} else {
screen_cursor_blink(opt_backup.cursor_blink);
}
break;
case 25:
SAVE_RESTORE(opt_backup.cursor_visible, scr.cursor_visible);
break;
case 45:
SAVE_RESTORE(opt_backup.reverse_wrap, cursor.reverse_wrap);
break;
case 2004:
SAVE_RESTORE(opt_backup.bracketed_paste, scr.bracketed_paste);
break;
case 800:
SAVE_RESTORE(opt_backup.show_buttons, termconf_live.show_buttons);
break;
case 801:
SAVE_RESTORE(opt_backup.show_config_links, termconf_live.show_config_links);
break;
default:
ansi_warn("Cannot store ?%d", n);
}
}
void ICACHE_FLASH_ATTR
screen_save_private_opt(int n)
{
do_save_private_opt(n, true);
}
void ICACHE_FLASH_ATTR
screen_restore_private_opt(int n)
{
NOTIFY_LOCK();
do_save_private_opt(n, false);
NOTIFY_DONE();
}
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_report_sgr(char *buffer) screen_report_sgr(char *buffer)
{ {
@ -1357,10 +1466,7 @@ utf8_remap(char *out, char g, char charset)
break; break;
case CS_A_UKASCII: /* UK, replaces # with GBP */ case CS_A_UKASCII: /* UK, replaces # with GBP */
if ((g >= CODEPAGE_A_BEGIN) && (g <= CODEPAGE_A_END)) { if (g == '#') utf = 0x20a4; // £
n = codepage_A[g - CODEPAGE_A_BEGIN];
if (n) utf = n;
}
break; break;
default: default:
@ -1369,28 +1475,7 @@ utf8_remap(char *out, char g, char charset)
break; break;
} }
// Encode to UTF-8 utf8_encode(out, utf);
if (utf > 0x7F) {
// formulas taken from: https://gist.github.com/yamamushi/5823402
if ((utf >= 0x80) && (utf <= 0x07FF)) {
// 2-byte unicode
out[0] = (char) ((utf >> 0x06) ^ 0xC0);
out[1] = (char) (((utf ^ 0xFFC0) | 0x80) & ~0x40);
out[2]=0;
}
else {
// 3-byte unicode
out[0] = (char) (((utf ^ 0xFC0FFF) >> 0x0C) | 0xE0);
out[1] = (char) ((((utf ^ 0xFFF03F) >> 0x06) | 0x80) & ~0x40);
out[2] = (char) (((utf ^ 0xFFFC0) | 0x80) & ~0x40);
out[3]=0;
}
// Missing 4-byte formulas :(
} else {
// low ASCII
out[0] = (char) utf;
out[1] = 0;
}
} }
//endregion //endregion
@ -1415,12 +1500,12 @@ screenSerializeLabelsToBuffer(char *buffer, size_t buf_len)
{ {
// let's just assume it's long enough - called with the huge websocket buffer // let's just assume it's long enough - called with the huge websocket buffer
sprintf(buffer, "T%s\x01%s\x01%s\x01%s\x01%s\x01%s", // use 0x01 as separator sprintf(buffer, "T%s\x01%s\x01%s\x01%s\x01%s\x01%s", // use 0x01 as separator
termconf_scratch.title, termconf_live.title,
termconf_scratch.btn[0], termconf_live.btn[0],
termconf_scratch.btn[1], termconf_live.btn[1],
termconf_scratch.btn[2], termconf_live.btn[2],
termconf_scratch.btn[3], termconf_live.btn[3],
termconf_scratch.btn[4] termconf_live.btn[4]
); );
} }
@ -1502,13 +1587,13 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data)
(cursor.hanging << 1) | (cursor.hanging << 1) |
(scr.cursors_alt_mode << 2) | (scr.cursors_alt_mode << 2) |
(scr.numpad_alt_mode << 3) | (scr.numpad_alt_mode << 3) |
(termconf_scratch.fn_alt_mode << 4) | (termconf_live.fn_alt_mode << 4) |
((mouse_tracking.mode>MTM_NONE) << 5) | // disables context menu ((mouse_tracking.mode>MTM_NONE) << 5) | // disables context menu
((mouse_tracking.mode>=MTM_NORMAL) << 6) | // disables selecting ((mouse_tracking.mode>=MTM_NORMAL) << 6) | // disables selecting
(termconf_scratch.show_buttons << 7) | (termconf_live.show_buttons << 7) |
(termconf_scratch.show_config_links << 8) | (termconf_live.show_config_links << 8) |
((termconf_scratch.cursor_shape&0x07) << 9) | // 9,10,11 - cursor shape based on DECSCUSR ((termconf_live.cursor_shape&0x07) << 9) | // 9,10,11 - cursor shape based on DECSCUSR
(termconf_scratch.crlf_mode << 12) (termconf_live.crlf_mode << 12)
); );
} }
@ -1535,7 +1620,7 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data)
Color fg, bg; Color fg, bg;
// Reverse fg and bg if we're in global reverse mode // Reverse fg and bg if we're in global reverse mode
if (! scr.reverse) { if (! scr.reverse_video) {
fg = cell0->fg; fg = cell0->fg;
bg = cell0->bg; bg = cell0->bg;
} }

@ -68,6 +68,8 @@ enum CursorShape {
CURSOR_BAR = 6, CURSOR_BAR = 6,
}; };
#define CURSOR_BLINKS(shape) ((shape)==CURSOR_BLOCK_BL||(shape)==CURSOR_UNDERLINE_BL||(shape)==CURSOR_BAR_BL)
typedef struct { typedef struct {
u32 width; u32 width;
u32 height; u32 height;
@ -96,7 +98,7 @@ extern TerminalConfigBundle * const termconf;
* Transient live config with no persist, can be modified via esc sequences. * Transient live config with no persist, can be modified via esc sequences.
* terminal_apply_settings() copies termconf to this struct, erasing old scratch changes * terminal_apply_settings() copies termconf to this struct, erasing old scratch changes
*/ */
extern TerminalConfigBundle termconf_scratch; extern TerminalConfigBundle termconf_live;
enum MTM { enum MTM {
MTM_NONE = 0, MTM_NONE = 0,
@ -259,6 +261,10 @@ void screen_set_numpad_alt_mode(bool app_mode);
void screen_set_cursors_alt_mode(bool app_mode); void screen_set_cursors_alt_mode(bool app_mode);
/** Set reverse video mode */ /** Set reverse video mode */
void screen_set_reverse_video(bool reverse); void screen_set_reverse_video(bool reverse);
/** Save DECOPT */
void screen_save_private_opt(int n);
/** Restore DECOPT */
void screen_restore_private_opt(int n);
// --- Charset --- // --- Charset ---

@ -4,7 +4,7 @@
#include "ansi_parser.h" #include "ansi_parser.h"
#include "syscfg.h" #include "syscfg.h"
#define LOGBUF_SIZE 2048 #define LOGBUF_SIZE 512
static char logbuf[LOGBUF_SIZE]; static char logbuf[LOGBUF_SIZE];
static u32 lb_nw = 1; static u32 lb_nw = 1;
static u32 lb_ls = 0; static u32 lb_ls = 0;
@ -18,7 +18,8 @@ static void buf_putc(char c)
} }
} }
static void buf_pop(void *unused) static void ICACHE_FLASH_ATTR
buf_pop(void *unused)
{ {
u32 quantity = 32; u32 quantity = 32;
u32 old_ls; u32 old_ls;

@ -62,7 +62,8 @@ UART_AsyncBufferInit(uint32 buf_size)
* @param pdata - data src * @param pdata - data src
* @param data_len - data len * @param data_len - data len
*/ */
static void UART_WriteToAsyncBuffer(struct UartBuffer *pCur, const char *pdata, uint16 data_len) static void ICACHE_FLASH_ATTR
UART_WriteToAsyncBuffer(struct UartBuffer *pCur, const char *pdata, uint16 data_len)
{ {
if (data_len == 0) return; if (data_len == 0) return;

@ -118,7 +118,8 @@ void ICACHE_FLASH_ATTR UART_SetupAsyncReceiver(void)
* *
* @param events * @param events
*/ */
static void uart_recvTask(os_event_t *events) static void ICACHE_FLASH_ATTR
uart_recvTask(os_event_t *events)
{ {
//#define PROCESS_CHUNK_LEN 64 //#define PROCESS_CHUNK_LEN 64
// static char buf[PROCESS_CHUNK_LEN]; // static char buf[PROCESS_CHUNK_LEN];
@ -158,7 +159,8 @@ static void uart_recvTask(os_event_t *events)
* *
* @param events * @param events
*/ */
static void uart_processTask(os_event_t *events) static void ICACHE_FLASH_ATTR
uart_processTask(os_event_t *events)
{ {
static char buf[PROCESS_CHUNK_LEN]; static char buf[PROCESS_CHUNK_LEN];

@ -124,7 +124,7 @@ void ICACHE_FLASH_ATTR user_init(void)
os_timer_arm(&userStartTimer, 10, 0); os_timer_arm(&userStartTimer, 10, 0);
} }
static void user_start(void *unused) static void ICACHE_FLASH_ATTR user_start(void *unused)
{ {
// Load and apply stored settings, or defaults if stored settings are invalid // Load and apply stored settings, or defaults if stored settings are invalid
persist_load(); persist_load();

@ -0,0 +1,58 @@
//
// Created by MightyPork on 2017/09/10.
//
#include "utf8.h"
/**
* Encode a code point using UTF-8
*
* @author Ondřej Hruška <ondra@ondrovo.com>
* @license MIT
*
* @param out - output buffer (min 4 characters), will be 0-terminated if shorten than 4
* @param utf - code point 0-0x10FFFF
* @return number of bytes on success, 0 on failure (also produces U+FFFD, which uses 3 bytes)
*/
int ICACHE_FLASH_ATTR
utf8_encode(char *out, uint32_t utf)
{
if (utf <= 0x7F) {
// Plain ASCII
out[0] = (char) utf;
out[1] = 0;
return 1;
}
else if (utf <= 0x07FF) {
// 2-byte unicode
out[0] = (char) (((utf >> 6) & 0x1F) | 0xC0);
out[1] = (char) (((utf >> 0) & 0x3F) | 0x80);
out[2] = 0;
return 2;
}
else if (utf <= 0xFFFF) {
// 3-byte unicode
out[0] = (char) (((utf >> 12) & 0x0F) | 0xE0);
out[1] = (char) (((utf >> 6) & 0x3F) | 0x80);
out[2] = (char) (((utf >> 0) & 0x3F) | 0x80);
out[3] = 0;
return 3;
}
else if (utf <= 0x10FFFF) {
// 4-byte unicode
out[0] = (char) (((utf >> 18) & 0x07) | 0xF0);
out[1] = (char) (((utf >> 12) & 0x3F) | 0x80);
out[2] = (char) (((utf >> 6) & 0x3F) | 0x80);
out[3] = (char) (((utf >> 0) & 0x3F) | 0x80);
// out[4] = 0;
return 4;
}
else {
// error - use replacement character
out[0] = (char) 0xEF;
out[1] = (char) 0xBF;
out[2] = (char) 0xBD;
out[3] = 0;
return 0;
}
}

@ -0,0 +1,12 @@
//
// Created by MightyPork on 2017/09/10.
//
#ifndef ESPTERM_UTF8_H
#define ESPTERM_UTF8_H
#include <c_types.h>
int utf8_encode(char *out, uint32_t utf);
#endif //ESPTERM_UTF8_H

@ -48,28 +48,28 @@ wifimgr_restore_defaults(void)
static void ICACHE_FLASH_ATTR static void ICACHE_FLASH_ATTR
configure_station(void) configure_station(void)
{ {
info("[WiFi] Configuring Station mode..."); wifi_info("[WiFi] Configuring Station mode...");
struct station_config conf; struct station_config conf;
strcpy((char *) conf.ssid, (char *) wificonf->sta_ssid); strcpy((char *) conf.ssid, (char *) wificonf->sta_ssid);
strcpy((char *) conf.password, (char *) wificonf->sta_password); strcpy((char *) conf.password, (char *) wificonf->sta_password);
dbg("[WiFi] Connecting to \"%s\"%s password", conf.ssid, conf.password[0]!=0?" using saved":", no"); wifi_dbg("[WiFi] Connecting to \"%s\"%s password", conf.ssid, conf.password[0]!=0?" using saved":", no");
conf.bssid_set = 0; conf.bssid_set = 0;
conf.bssid[0] = 0; conf.bssid[0] = 0;
wifi_station_disconnect(); wifi_station_disconnect();
wifi_station_set_config_current(&conf); wifi_station_set_config_current(&conf);
if (wificonf->sta_dhcp_enable) { if (wificonf->sta_dhcp_enable) {
dbg("[WiFi] Starting DHCP..."); wifi_dbg("[WiFi] Starting DHCP...");
if (!wifi_station_dhcpc_start()) { if (!wifi_station_dhcpc_start()) {
error("[WiFi] DHCP failed to start!"); error("[WiFi] DHCP failed to start!");
return; return;
} }
} }
else { else {
info("[WiFi] Setting up static IP..."); wifi_info("[WiFi] Setting up static IP...");
dbg("[WiFi] Client.ip = "IPSTR, GOOD_IP2STR(wificonf->sta_addr.ip.addr)); wifi_dbg("[WiFi] Client.ip = "IPSTR, GOOD_IP2STR(wificonf->sta_addr.ip.addr));
dbg("[WiFi] Client.mask = "IPSTR, GOOD_IP2STR(wificonf->sta_addr.netmask.addr)); wifi_dbg("[WiFi] Client.mask = "IPSTR, GOOD_IP2STR(wificonf->sta_addr.netmask.addr));
dbg("[WiFi] Client.gw = "IPSTR, GOOD_IP2STR(wificonf->sta_addr.gw.addr)); wifi_dbg("[WiFi] Client.gw = "IPSTR, GOOD_IP2STR(wificonf->sta_addr.gw.addr));
wifi_station_dhcpc_stop(); wifi_station_dhcpc_stop();
// Load static IP config // Load static IP config
@ -79,7 +79,7 @@ configure_station(void)
} }
} }
info("[WiFi] Trying to connect to AP..."); wifi_info("[WiFi] Trying to connect to AP...");
wifi_station_connect(); wifi_station_connect();
} }
@ -88,7 +88,7 @@ configure_ap(void)
{ {
bool suc; bool suc;
info("[WiFi] Configuring SoftAP mode..."); wifi_info("[WiFi] Configuring SoftAP mode...");
// AP is enabled // AP is enabled
struct softap_config conf; struct softap_config conf;
conf.channel = wificonf->ap_channel; conf.channel = wificonf->ap_channel;
@ -110,10 +110,10 @@ configure_ap(void)
} }
// Set IP // Set IP
info("[WiFi] Configuring SoftAP local IP..."); wifi_info("[WiFi] Configuring SoftAP local IP...");
dbg("[WiFi] SoftAP.ip = "IPSTR, GOOD_IP2STR(wificonf->ap_addr.ip.addr)); wifi_dbg("[WiFi] SoftAP.ip = "IPSTR, GOOD_IP2STR(wificonf->ap_addr.ip.addr));
dbg("[WiFi] SoftAP.mask = "IPSTR, GOOD_IP2STR(wificonf->ap_addr.netmask.addr)); wifi_dbg("[WiFi] SoftAP.mask = "IPSTR, GOOD_IP2STR(wificonf->ap_addr.netmask.addr));
dbg("[WiFi] SoftAP.gw = "IPSTR, GOOD_IP2STR(wificonf->ap_addr.gw.addr)); wifi_dbg("[WiFi] SoftAP.gw = "IPSTR, GOOD_IP2STR(wificonf->ap_addr.gw.addr));
wifi_softap_dhcps_stop(); wifi_softap_dhcps_stop();
@ -123,10 +123,10 @@ configure_ap(void)
return; return;
} }
info("[WiFi] Configuring SoftAP DHCP server..."); wifi_info("[WiFi] Configuring SoftAP DHCP server...");
dbg("[WiFi] DHCP.start = "IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_range.start_ip.addr)); wifi_dbg("[WiFi] DHCP.start = "IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_range.start_ip.addr));
dbg("[WiFi] DHCP.end = "IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_range.end_ip.addr)); wifi_dbg("[WiFi] DHCP.end = "IPSTR, GOOD_IP2STR(wificonf->ap_dhcp_range.end_ip.addr));
dbg("[WiFi] DHCP.lease = %d minutes", wificonf->ap_dhcp_time); wifi_dbg("[WiFi] DHCP.lease = %d minutes", wificonf->ap_dhcp_time);
if (!wifi_softap_set_dhcps_lease(&wificonf->ap_dhcp_range)) { if (!wifi_softap_set_dhcps_lease(&wificonf->ap_dhcp_range)) {
error("[WiFi] DHCP address range set fail!"); error("[WiFi] DHCP address range set fail!");
@ -154,7 +154,7 @@ configure_ap(void)
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
wifimgr_apply_settings(void) wifimgr_apply_settings(void)
{ {
info("[WiFi] Initializing..."); wifi_info("[WiFi] Initializing...");
// !!! Update to current version !!! // !!! Update to current version !!!
@ -190,5 +190,5 @@ wifimgr_apply_settings(void)
wifi_change_flags.ap = false; wifi_change_flags.ap = false;
wifi_change_flags.sta = false; wifi_change_flags.sta = false;
info("[WiFi] WiFi settings applied."); wifi_info("[WiFi] WiFi settings applied.");
} }

@ -60,4 +60,14 @@ void wifimgr_restore_defaults(void);
void wifimgr_apply_settings(void); void wifimgr_apply_settings(void);
#if DEBUG_WIFI
#define wifi_warn warn
#define wifi_dbg dbg
#define wifi_info info
#else
#define wifi_warn(fmt, ...)
#define wifi_dbg(fmt, ...)
#define wifi_info(fmt, ...)
#endif
#endif //ESP_VT100_FIRMWARE_WIFI_MANAGER_H #endif //ESP_VT100_FIRMWARE_WIFI_MANAGER_H

Loading…
Cancel
Save