diff --git a/user/persist.c b/user/persist.c index 381b266..7fc2c9e 100644 --- a/user/persist.c +++ b/user/persist.c @@ -7,7 +7,7 @@ #include "wifimgr.h" #include "screen.h" -FullPersistBlock persist; +PersistBlock persist; #define PERSIST_SECTOR_ID 0x3D @@ -20,17 +20,17 @@ static void ICACHE_FLASH_ATTR load_settings_to_live(void) { dbg("[Persist] Loading current settings to modules..."); - memcpy(&wificonf, &persist.current.wificonf, sizeof(WiFiConfigBlock)); - memcpy(&termconf, &persist.current.termconf, sizeof(TerminalConfigBlock)); + memcpy(wificonf, &persist.current.wificonf, sizeof(WiFiConfigBundle)); + memcpy(termconf, &persist.current.termconf, sizeof(TerminalConfigBundle)); // ... } static void ICACHE_FLASH_ATTR -store_settings_from_live(void) +store_all_settings_from_live(void) { dbg("[Persist] Collecting live settings to persist block..."); - memcpy(&persist.current.wificonf, &wificonf, sizeof(wificonf)); - memcpy(&persist.current.termconf, &termconf, sizeof(termconf)); + memcpy(&persist.current.wificonf, wificonf, sizeof(WiFiConfigBundle)); + memcpy(&persist.current.termconf, termconf, sizeof(TerminalConfigBundle)); // ... } @@ -86,9 +86,9 @@ calculateCRC32(const uint8_t *data, size_t length) * @return */ static uint32_t ICACHE_FLASH_ATTR -compute_checksum(PersistBundle *bundle) +compute_checksum(AppConfigBundle *bundle) { - return calculateCRC32((uint8_t *) bundle, sizeof(PersistBundle) - 4); + return calculateCRC32((uint8_t *) bundle, sizeof(AppConfigBundle) - 4); } /** @@ -102,7 +102,7 @@ persist_load(void) bool hard_reset = false; // Try to load - hard_reset |= !system_param_load(PERSIST_SECTOR_ID, 0, &persist, sizeof(persist)); + hard_reset |= !system_param_load(PERSIST_SECTOR_ID, 0, &persist, sizeof(PersistBlock)); // Verify checksums if (hard_reset || @@ -127,13 +127,13 @@ void ICACHE_FLASH_ATTR persist_store(void) { info("[Persist] Storing all settings to FLASH..."); - store_settings_from_live(); + store_all_settings_from_live(); // Update checksums before write persist.current.checksum = compute_checksum(&persist.current); persist.defaults.checksum = compute_checksum(&persist.defaults); - if (!system_param_save_with_protect(PERSIST_SECTOR_ID, &persist, sizeof(persist))) { + if (!system_param_save_with_protect(PERSIST_SECTOR_ID, &persist, sizeof(PersistBlock))) { error("[Persist] Store to flash failed!"); } info("[Persist] All settings persisted."); @@ -151,10 +151,10 @@ persist_restore_hard_default(void) restore_live_settings_to_hard_defaults(); // Store live -> current - store_settings_from_live(); + store_all_settings_from_live(); // Store current -> default - memcpy(&persist.defaults, &persist.current, sizeof(persist.current)); + memcpy(&persist.defaults, &persist.current, sizeof(AppConfigBundle)); persist_store(); info("[Persist] All settings restored to hard defaults."); @@ -169,7 +169,7 @@ void ICACHE_FLASH_ATTR persist_restore_default(void) { info("[Persist] Restoring live settings to stored defaults..."); - memcpy(&persist.current, &persist.defaults, sizeof(persist.defaults)); + memcpy(&persist.current, &persist.defaults, sizeof(AppConfigBundle)); load_settings_to_live(); apply_live_settings(); info("[Persist] Settings restored to stored defaults."); @@ -183,8 +183,8 @@ persist_set_as_default(void) { info("[Persist] Storing live settings as defaults.."); - store_settings_from_live(); - memcpy(&persist.defaults, &persist.current, sizeof(persist.current)); + store_all_settings_from_live(); + memcpy(&persist.defaults, &persist.current, sizeof(AppConfigBundle)); persist_store(); diff --git a/user/persist.h b/user/persist.h index 197eaa6..676c1e6 100644 --- a/user/persist.h +++ b/user/persist.h @@ -14,21 +14,21 @@ #include "screen.h" typedef struct { - WiFiConfigBlock wificonf; - TerminalConfigBlock termconf; + WiFiConfigBundle wificonf; + TerminalConfigBundle termconf; // ... // other settings here // ... uint32_t checksum; // computed before write and tested on load. If it doesn't match, values are reset to hard defaults. -} PersistBundle; +} AppConfigBundle; typedef struct { - PersistBundle defaults; // defaults are stored here - PersistBundle current; // settings persisted by user -} FullPersistBlock; + AppConfigBundle defaults; // defaults are stored here + AppConfigBundle current; // settings persisted by user +} PersistBlock; // Persist holds the data currently loaded from the flash -extern FullPersistBlock persist; +extern PersistBlock persist; void persist_load(void); void persist_restore_hard_default(void); diff --git a/user/screen.c b/user/screen.c index 90f3fbc..e2e07f1 100644 --- a/user/screen.c +++ b/user/screen.c @@ -1,26 +1,28 @@ #include #include #include "screen.h" +#include "persist.h" //region Data structures -TerminalConfigBlock termconf; +TerminalConfigBundle * const termconf = &persist.current.termconf; +TerminalConfigBundle termconf_scratch; /** * Restore hard defaults */ void terminal_restore_defaults(void) { - termconf.default_bg = 0; - termconf.default_fg = 7; - termconf.width = 26; - termconf.height = 10; - sprintf(termconf.title, "ESP8266 Wireless Terminal"); - sprintf(termconf.btn1, "1"); - sprintf(termconf.btn2, "2"); - sprintf(termconf.btn3, "3"); - sprintf(termconf.btn4, "4"); - sprintf(termconf.btn5, "5"); + termconf->default_bg = 0; + termconf->default_fg = 7; + termconf->width = 26; + termconf->height = 10; + sprintf(termconf->title, "ESP8266 Wireless Terminal"); + sprintf(termconf->btn1, "1"); + sprintf(termconf->btn2, "2"); + sprintf(termconf->btn3, "3"); + sprintf(termconf->btn4, "4"); + sprintf(termconf->btn5, "5"); } /** @@ -28,11 +30,12 @@ void terminal_restore_defaults(void) */ void terminal_apply_settings(void) { + memcpy(&termconf_scratch, termconf, sizeof(TerminalConfigBundle)); screen_init(); } -#define W termconf.width -#define H termconf.height +#define W termconf_scratch.width +#define H termconf_scratch.height /** * Highest permissible value of the color attribute @@ -119,8 +122,8 @@ cursor_reset(void) { cursor.x = 0; cursor.y = 0; - cursor.fg = termconf.default_fg; - cursor.bg = termconf.default_bg; + cursor.fg = termconf_scratch.default_fg; + cursor.bg = termconf_scratch.default_bg; cursor.visible = 1; cursor.inverse = 0; cursor.autowrap = 1; @@ -383,8 +386,8 @@ screen_cursor_save(bool withAttrs) cursor_sav.bg = cursor.bg; cursor_sav.inverse = cursor.inverse; } else { - cursor_sav.fg = termconf.default_fg; - cursor_sav.bg = termconf.default_bg; + cursor_sav.fg = termconf_scratch.default_fg; + cursor_sav.bg = termconf_scratch.default_bg; cursor_sav.inverse = 0; } } diff --git a/user/screen.h b/user/screen.h index 36ab637..5ab2bc6 100644 --- a/user/screen.h +++ b/user/screen.h @@ -45,10 +45,16 @@ typedef struct { char btn3[10]; char btn4[10]; char btn5[10]; -} TerminalConfigBlock; +} TerminalConfigBundle; // Live config -extern TerminalConfigBlock termconf; +extern TerminalConfigBundle * const termconf; + +/** + * Transient live config with no persist, can be modified via esc sequences. + * terminal_apply_settings() copies termconf to this struct, erasing old scratch changes + */ +extern TerminalConfigBundle termconf_scratch; void terminal_restore_defaults(void); void terminal_apply_settings(void); diff --git a/user/wifimgr.c b/user/wifimgr.c index 04ec363..5d120e4 100644 --- a/user/wifimgr.c +++ b/user/wifimgr.c @@ -3,8 +3,9 @@ // #include "wifimgr.h" +#include "persist.h" -WiFiConfigBlock wificonf; +WiFiConfigBundle * const wificonf = &persist.current.wificonf; /** * Restore defaults in the WiFi config block. @@ -17,31 +18,31 @@ wifimgr_restore_defaults(void) u8 mac[6]; wifi_get_macaddr(SOFTAP_IF, mac); - wificonf.opmode = SOFTAP_MODE; - wificonf.tpw = 20; - wificonf.ap_channel = 1; - sprintf((char *) wificonf.ap_ssid, "TERM-%02X%02X%02X", mac[3], mac[4], mac[5]); - wificonf.ap_password[0] = 0; // PSK2 always if password is not null. - wificonf.ap_hidden = false; + wificonf->opmode = SOFTAP_MODE; + wificonf->tpw = 20; + wificonf->ap_channel = 1; + sprintf((char *) wificonf->ap_ssid, "TERM-%02X%02X%02X", mac[3], mac[4], mac[5]); + wificonf->ap_password[0] = 0; // PSK2 always if password is not null. + wificonf->ap_hidden = false; - IP4_ADDR(&wificonf.ap_ip.ip, 192, 168, 4, 60); - IP4_ADDR(&wificonf.ap_ip.netmask, 255, 255, 255, 0); - wificonf.ap_ip.gw.addr = wificonf.ap_ip.gw.addr; + IP4_ADDR(&wificonf->ap_ip.ip, 192, 168, 4, 60); + IP4_ADDR(&wificonf->ap_ip.netmask, 255, 255, 255, 0); + wificonf->ap_ip.gw.addr = wificonf->ap_ip.gw.addr; - IP4_ADDR(&wificonf.ap_dhcp_range.start_ip, 192, 168, 4, 100); - IP4_ADDR(&wificonf.ap_dhcp_range.end_ip, 192, 168, 4, 200); - wificonf.ap_dhcp_range.enable = 1; - wificonf.ap_dhcp_lease_time = 120; + IP4_ADDR(&wificonf->ap_dhcp_range.start_ip, 192, 168, 4, 100); + IP4_ADDR(&wificonf->ap_dhcp_range.end_ip, 192, 168, 4, 200); + wificonf->ap_dhcp_range.enable = 1; + wificonf->ap_dhcp_lease_time = 120; // --- Client config --- - wificonf.sta_ssid[0] = 0; - wificonf.sta_password[0] = 0; - strcpy((char *) wificonf.sta_hostname, (char *) wificonf.ap_ssid); // use the same value for sta_hostname as AP name - wificonf.sta_dhcp_enable = true; - - IP4_ADDR(&wificonf.sta_ip.ip, 192, 168, 0, (mac[5]==1?2:mac[5]));// avoid being the same as "default gw" - IP4_ADDR(&wificonf.sta_ip.netmask, 255, 255, 255, 0); - IP4_ADDR(&wificonf.sta_ip.gw, 192, 168, 0, 1); + wificonf->sta_ssid[0] = 0; + wificonf->sta_password[0] = 0; + strcpy((char *) wificonf->sta_hostname, (char *) wificonf->ap_ssid); // use the same value for sta_hostname as AP name + wificonf->sta_dhcp_enable = true; + + IP4_ADDR(&wificonf->sta_ip.ip, 192, 168, 0, (mac[5]==1?2:mac[5]));// avoid being the same as "default gw" + IP4_ADDR(&wificonf->sta_ip.netmask, 255, 255, 255, 0); + IP4_ADDR(&wificonf->sta_ip.gw, 192, 168, 0, 1); } static void ICACHE_FLASH_ATTR @@ -49,17 +50,17 @@ configure_station(void) { info("[WiFi] Configuring Station mode..."); struct station_config conf; - strcpy((char *) conf.ssid, (char *) wificonf.sta_ssid); - strcpy((char *) conf.password, (char *) wificonf.sta_password); + strcpy((char *) conf.ssid, (char *) wificonf->sta_ssid); + strcpy((char *) conf.password, (char *) wificonf->sta_password); dbg("[WiFi] Connecting to \"%s\", password \"%s\"", conf.ssid, conf.password); conf.bssid_set = 0; conf.bssid[0] = 0; wifi_station_disconnect(); wifi_station_set_config_current(&conf); - dbg("[WiFi] Hostname = %s", wificonf.sta_hostname); - wifi_station_set_hostname((char*)wificonf.sta_hostname); + dbg("[WiFi] Hostname = %s", wificonf->sta_hostname); + wifi_station_set_hostname((char*)wificonf->sta_hostname); - if (wificonf.sta_dhcp_enable) { + if (wificonf->sta_dhcp_enable) { dbg("[WiFi] Starting DHCP..."); if (!wifi_station_dhcpc_start()) { error("[WiFi] DHCp failed to start!"); @@ -68,13 +69,13 @@ configure_station(void) } else { info("[WiFi] Setting up static IP..."); - dbg("[WiFi] Client.ip = "IPSTR, GOOD_IP2STR(wificonf.sta_ip.ip.addr)); - dbg("[WiFi] Client.mask = "IPSTR, GOOD_IP2STR(wificonf.sta_ip.netmask.addr)); - dbg("[WiFi] Client.gw = "IPSTR, GOOD_IP2STR(wificonf.sta_ip.gw.addr)); + dbg("[WiFi] Client.ip = "IPSTR, GOOD_IP2STR(wificonf->sta_ip.ip.addr)); + dbg("[WiFi] Client.mask = "IPSTR, GOOD_IP2STR(wificonf->sta_ip.netmask.addr)); + dbg("[WiFi] Client.gw = "IPSTR, GOOD_IP2STR(wificonf->sta_ip.gw.addr)); wifi_station_dhcpc_stop(); // Load static IP config - if (!wifi_set_ip_info(STATION_IF, &wificonf.sta_ip)) { + if (!wifi_set_ip_info(STATION_IF, &wificonf->sta_ip)) { error("[WiFi] Error setting static IP!"); return; } @@ -92,12 +93,12 @@ configure_ap(void) info("[WiFi] Configuring SoftAP mode..."); // AP is enabled struct softap_config conf; - conf.channel = wificonf.ap_channel; - strcpy((char *) conf.ssid, (char *) wificonf.ap_ssid); - strcpy((char *) conf.password, (char *) wificonf.ap_password); - conf.authmode = (wificonf.ap_password[0] == 0 ? AUTH_OPEN : AUTH_WPA2_PSK); + conf.channel = wificonf->ap_channel; + strcpy((char *) conf.ssid, (char *) wificonf->ap_ssid); + strcpy((char *) conf.password, (char *) wificonf->ap_password); + conf.authmode = (wificonf->ap_password[0] == 0 ? AUTH_OPEN : AUTH_WPA2_PSK); conf.ssid_len = (uint8_t) strlen((char *) conf.ssid); - conf.ssid_hidden = wificonf.ap_hidden; + conf.ssid_hidden = wificonf->ap_hidden; conf.max_connection = 4; // default 4 (max possible) conf.beacon_interval = 100; // default 100 ms @@ -112,29 +113,29 @@ configure_ap(void) // Set IP info("[WiFi] Configuring SoftAP local IP..."); - dbg("[WiFi] SoftAP.ip = "IPSTR, GOOD_IP2STR(wificonf.ap_ip.ip.addr)); - dbg("[WiFi] SoftAP.mask = "IPSTR, GOOD_IP2STR(wificonf.ap_ip.netmask.addr)); - dbg("[WiFi] SoftAP.gw = "IPSTR, GOOD_IP2STR(wificonf.ap_ip.gw.addr)); + dbg("[WiFi] SoftAP.ip = "IPSTR, GOOD_IP2STR(wificonf->ap_ip.ip.addr)); + dbg("[WiFi] SoftAP.mask = "IPSTR, GOOD_IP2STR(wificonf->ap_ip.netmask.addr)); + dbg("[WiFi] SoftAP.gw = "IPSTR, GOOD_IP2STR(wificonf->ap_ip.gw.addr)); wifi_softap_dhcps_stop(); // Configure DHCP - if (!wifi_set_ip_info(SOFTAP_IF, &wificonf.ap_ip)) { + if (!wifi_set_ip_info(SOFTAP_IF, &wificonf->ap_ip)) { error("[WiFi] IP set fail!"); return; } info("[WiFi] Configuring SoftAP DHCP server..."); - 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)); - dbg("[WiFi] DHCP.lease = %d minutes", wificonf.ap_dhcp_lease_time); + 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)); + dbg("[WiFi] DHCP.lease = %d minutes", wificonf->ap_dhcp_lease_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!"); return; } - if (!wifi_softap_set_dhcps_lease_time(wificonf.ap_dhcp_lease_time)) { + if (!wifi_softap_set_dhcps_lease_time(wificonf->ap_dhcp_lease_time)) { error("[WiFi] DHCP lease time set fail!"); return; } @@ -159,15 +160,15 @@ wifimgr_apply_settings(void) // Force wifi cycle wifi_set_opmode(NULL_MODE); - wifi_set_opmode(wificonf.opmode); + wifi_set_opmode(wificonf->opmode); // Configure the client - if (wificonf.opmode == STATIONAP_MODE || wificonf.opmode == STATION_MODE) { + if (wificonf->opmode == STATIONAP_MODE || wificonf->opmode == STATION_MODE) { configure_station(); } // Configure the AP - if (wificonf.opmode == STATIONAP_MODE || wificonf.opmode == SOFTAP_MODE) { + if (wificonf->opmode == STATIONAP_MODE || wificonf->opmode == SOFTAP_MODE) { configure_ap(); } diff --git a/user/wifimgr.h b/user/wifimgr.h index 2bb7f11..fa616d7 100644 --- a/user/wifimgr.h +++ b/user/wifimgr.h @@ -37,9 +37,9 @@ typedef struct { bool sta_dhcp_enable; struct ip_info sta_ip; -} WiFiConfigBlock; +} WiFiConfigBundle; -extern WiFiConfigBlock wificonf; +extern WiFiConfigBundle * const wificonf; void wifimgr_restore_defaults(void);