From c05e42f56371e79faf2a76c5961854d7ebf2e337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20R=2E=20Weimar?= Date: Tue, 12 Feb 2019 11:22:46 +0100 Subject: [PATCH 01/18] Changed ws2812 clock to local time instead of UTC --- sonoff/xplg_ws2812.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sonoff/xplg_ws2812.ino b/sonoff/xplg_ws2812.ino index ab4ba1c35..e7eb16dd8 100644 --- a/sonoff/xplg_ws2812.ino +++ b/sonoff/xplg_ws2812.ino @@ -170,7 +170,8 @@ void Ws2812Clock(void) Ws2812UpdateHand((RtcTime.second * 1000) / clksize, WS_SECOND); Ws2812UpdateHand((RtcTime.minute * 1000) / clksize, WS_MINUTE); - Ws2812UpdateHand(((RtcTime.hour % 12) * (5000 / clksize)) + ((RtcTime.minute * 1000) / (12 * clksize)), WS_HOUR); + uint32_t local_hour = (LocalTime()/3600)%12; // RtcTime.hour is UTC timezone, not local. + Ws2812UpdateHand(((local_hour % 12) * (5000 / clksize)) + ((RtcTime.minute * 1000) / (12 * clksize)), WS_HOUR); if (Settings.ws_color[WS_MARKER][WS_RED] + Settings.ws_color[WS_MARKER][WS_GREEN] + Settings.ws_color[WS_MARKER][WS_BLUE]) { for (uint8_t i = 0; i < 12; i++) { Ws2812UpdateHand((i * 5000) / clksize, WS_MARKER); From e8df8c4fa6c1e74156746bdb05c64eda7fbbca5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20R=2E=20Weimar?= Date: Tue, 12 Feb 2019 15:28:45 +0100 Subject: [PATCH 02/18] corrected sliding hour rounding for pixels < 60 --- sonoff/xplg_ws2812.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sonoff/xplg_ws2812.ino b/sonoff/xplg_ws2812.ino index e7eb16dd8..5fdc68f82 100644 --- a/sonoff/xplg_ws2812.ino +++ b/sonoff/xplg_ws2812.ino @@ -170,8 +170,7 @@ void Ws2812Clock(void) Ws2812UpdateHand((RtcTime.second * 1000) / clksize, WS_SECOND); Ws2812UpdateHand((RtcTime.minute * 1000) / clksize, WS_MINUTE); - uint32_t local_hour = (LocalTime()/3600)%12; // RtcTime.hour is UTC timezone, not local. - Ws2812UpdateHand(((local_hour % 12) * (5000 / clksize)) + ((RtcTime.minute * 1000) / (12 * clksize)), WS_HOUR); + Ws2812UpdateHand((((RtcTime.hour % 12) * 5000) + ((RtcTime.minute * 1000) / 12 )) / clksize, WS_HOUR); if (Settings.ws_color[WS_MARKER][WS_RED] + Settings.ws_color[WS_MARKER][WS_GREEN] + Settings.ws_color[WS_MARKER][WS_BLUE]) { for (uint8_t i = 0; i < 12; i++) { Ws2812UpdateHand((i * 5000) / clksize, WS_MARKER); From 51227b1d951476effa4458e3566e31563f6f1312 Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Wed, 20 Feb 2019 21:07:01 +0100 Subject: [PATCH 03/18] Update platformio.ini --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index f5d958ebf..21816c3ab 100644 --- a/platformio.ini +++ b/platformio.ini @@ -65,8 +65,8 @@ build_flags = ${esp82xx_defaults.build_flags} -DVTABLES_IN_FLASH [core_2_5_0] -; *** Esp8266 core for Arduino version 2.5.0 release (still not available via platformio) -platform = https://github.com/Jason2866/platform-espressif8266.git#Tasmota +; *** Esp8266 core for Arduino version 2.5.0 +platform = espressif8266@2.0.0 build_flags = ${esp82xx_defaults.build_flags} -Wl,-Teagle.flash.1m.ld ; lwIP 1.4 (Default) From cfd3f3f4f5dd095e9cc1c294c905b48be2a5e7cc Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 21 Feb 2019 09:48:58 +0100 Subject: [PATCH 04/18] Fix WebSend compile warning Fix WebSend compile warning --- sonoff/xdrv_01_webserver.ino | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index 46b6ca6eb..2bdf55248 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -2179,7 +2179,7 @@ int WebSend(char *buffer) user = Trim(user); // user = |admin| if (password) { password = Trim(password); } // password = |joker| } - + command = Trim(command); // command = |POWER1 ON| or |/any/link/starting/with/a/slash.php?log=123| if (command[0] != '/') { url += F("/cm?"); // url = |http://192.168.178.86/cm?| @@ -2197,8 +2197,14 @@ int WebSend(char *buffer) //snprintf_P(log_data, sizeof(log_data), PSTR("DBG: Uri |%s|"), url.c_str()); //AddLog(LOG_LEVEL_DEBUG); +#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) HTTPClient http; if (http.begin(UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON| +#else + WiFiClient http_client; + HTTPClient http; + if (http.begin(client, UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON| +#endif int http_code = http.GET(); // Start connection and send HTTP header if (http_code > 0) { // http_code will be negative on error if (http_code == HTTP_CODE_OK || http_code == HTTP_CODE_MOVED_PERMANENTLY) { @@ -2209,8 +2215,7 @@ int WebSend(char *buffer) for (uint16_t i = 0; i < result.length(); i++) { char text = result.charAt(i); if (text > 31) { // Remove control characters like linefeed - mqtt_data[j] = result.charAt(i); - j++; + mqtt_data[j++] = text; if (j == sizeof(mqtt_data) -2) { break; } } } @@ -2222,7 +2227,7 @@ int WebSend(char *buffer) } else { status = 2; // Connection failed } - http.end(); + http.end(); // Clean up connection data } else { status = 3; // Host not found or connection error } From 05b02800198a1ef592c0bc6099a6c8cefc239e83 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 21 Feb 2019 14:31:31 +0100 Subject: [PATCH 05/18] 6.4.1.18 - Fix some exceptions and watchdogs 6.4.1.18 20191221 * Fix some exceptions and watchdogs due to lack of stack space - part 1 (#5215) --- sonoff/_changelog.ino | 5 ++++- sonoff/sonoff.ino | 40 ++++++------------------------------ sonoff/sonoff_version.h | 2 +- sonoff/support.ino | 36 ++++++++++++++++++++++++++++++++ sonoff/xdrv_01_webserver.ino | 2 ++ 5 files changed, 49 insertions(+), 36 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 0549b2576..0d4fef299 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,7 @@ -/* 6.4.1.17 20190214 +/* 6.4.1.18 20191221 + * Fix some exceptions and watchdogs due to lack of stack space - part 1 (#5215) + * + * 6.4.1.17 20190214 * Change template update by removing possibility to add user module config keeping template as defined (#5222) * Fix regression from 6.4.1.16 where GPIO9 and GPIO10 connected devices did not work (#5197) * Fix GUI wifi password acception starting with asteriks (*) (#5231, #5242) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 55d218456..39f0d7e0b 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -963,41 +963,12 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len) } } } - else if (data_len > 9) { // Workaround exception if empty JSON like {} - Needs checks - StaticJsonBuffer<350> jb; // 331 from https://arduinojson.org/v5/assistant/ - JsonObject& obj = jb.parseObject(dataBuf); - if (!obj.success()) { + else if (data_len > 9) { // Workaround exception if empty JSON like {} - Needs checks + if (JsonTemplate(dataBuf)) { // Free 336 bytes StaticJsonBuffer stack space by moving code to function + if (USER_MODULE == Settings.module) { restart_flag = 2; } + } else { snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, D_JSON_INVALID_JSON); error = true; - } else { - // All parameters are optional allowing for partial changes - const char* name = obj[D_JSON_NAME]; - if (name != nullptr) { - strlcpy(Settings.user_template.name, name, sizeof(Settings.user_template.name)); - } - if (obj[D_JSON_GPIO].success()) { - for (uint8_t i = 0; i < sizeof(mycfgio); i++) { - Settings.user_template.gp.io[i] = obj[D_JSON_GPIO][i] | 0; - } - } - if (obj[D_JSON_FLAG].success()) { - uint8_t flag = obj[D_JSON_FLAG] | 0; - memcpy(&Settings.user_template.flag, &flag, sizeof(gpio_flag)); - } - if (obj[D_JSON_BASE].success()) { - uint8_t base = obj[D_JSON_BASE]; - if ((0 == base) || (base >= MAXMODULE)) { base = 17; } else { base--; } - Settings.user_template_base = base; // Default WEMOS - } - - // Validate GPIO -// for (uint8_t i = 0; i < sizeof(mycfgio); i++) { - // For now do not allow non-user configurable GPIO -// if ((Settings.user_template.gp.io[i] > GPIO_FIX_START) && (Settings.user_template.gp.io[i] < GPIO_USER)) { -// Settings.user_template.gp.io[i] = GPIO_NONE; -// }; -// } - if (USER_MODULE == Settings.module) { restart_flag = 2; } } } if (!error) { TemplateJson(); } @@ -2223,7 +2194,8 @@ void ArduinoOTAInit(void) void SerialInput(void) { while (Serial.available()) { - yield(); +// yield(); + delay(0); serial_in_byte = Serial.read(); /*-------------------------------------------------------------------------------------------*\ diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index 3816029fd..bba08f9de 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x06040111 +#define VERSION 0x06040112 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/support.ino b/sonoff/support.ino index d37185e3f..113968974 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -845,6 +845,42 @@ bool GetUsedInModule(uint8_t val, uint8_t *arr) return false; } +bool JsonTemplate(const char* dataBuf) +{ + StaticJsonBuffer<350> jb; // 331 from https://arduinojson.org/v5/assistant/ + JsonObject& obj = jb.parseObject(dataBuf); + if (!obj.success()) { return false; } + + // All parameters are optional allowing for partial changes + const char* name = obj[D_JSON_NAME]; + if (name != nullptr) { + strlcpy(Settings.user_template.name, name, sizeof(Settings.user_template.name)); + } + if (obj[D_JSON_GPIO].success()) { + for (uint8_t i = 0; i < sizeof(mycfgio); i++) { + Settings.user_template.gp.io[i] = obj[D_JSON_GPIO][i] | 0; + } + } + if (obj[D_JSON_FLAG].success()) { + uint8_t flag = obj[D_JSON_FLAG] | 0; + memcpy(&Settings.user_template.flag, &flag, sizeof(gpio_flag)); + } + if (obj[D_JSON_BASE].success()) { + uint8_t base = obj[D_JSON_BASE]; + if ((0 == base) || (base >= MAXMODULE)) { base = 17; } else { base--; } + Settings.user_template_base = base; // Default WEMOS + } + + // Validate GPIO +// for (uint8_t i = 0; i < sizeof(mycfgio); i++) { + // For now do not allow non-user configurable GPIO +// if ((Settings.user_template.gp.io[i] > GPIO_FIX_START) && (Settings.user_template.gp.io[i] < GPIO_USER)) { +// Settings.user_template.gp.io[i] = GPIO_NONE; +// }; +// } + return true; +} + void TemplateJson() { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), Settings.user_template.name); diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index 2bdf55248..e8aab33db 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -1968,6 +1968,7 @@ void HandleHttpCommand(void) if (JSON) { // Is it a JSON message (and not only [15:26:08 MQT: stat/wemos5/POWER = O]) if (message.length() > 1) { message += F(","); } size_t JSONlen = len - (JSON - tmp); + if (JSONlen > sizeof(mqtt_data)) { JSONlen = sizeof(mqtt_data); } strlcpy(mqtt_data, JSON +1, JSONlen -2); message += mqtt_data; } @@ -2047,6 +2048,7 @@ void HandleAjaxConsoleRefresh(void) } else { cflg = true; } + if (len > sizeof(mqtt_data) -2) { len = sizeof(mqtt_data); } strlcpy(mqtt_data, tmp, len); message += mqtt_data; // mqtt_data used as scratch space } From 95da493325fbad0be9e88f950f6bc0c3a51c90e6 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 21 Feb 2019 14:56:39 +0100 Subject: [PATCH 06/18] Update xdrv_01_webserver.ino Fix compile error --- sonoff/xdrv_01_webserver.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index e8aab33db..a056c48ef 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -2205,7 +2205,7 @@ int WebSend(char *buffer) #else WiFiClient http_client; HTTPClient http; - if (http.begin(client, UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON| + if (http.begin(http_client, UrlEncode(url))) { // UrlEncode(url) = |http://192.168.178.86/cm?cmnd=POWER1%20ON| #endif int http_code = http.GET(); // Start connection and send HTTP header if (http_code > 0) { // http_code will be negative on error From eb08bb07ee2c37aaa1a73b70746655cc0ec9ecef Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Thu, 21 Feb 2019 15:37:46 +0100 Subject: [PATCH 07/18] decode-config.py: adapt settings - remove SetOption62 (no_pullup) - remove obsolete Tasmota command converter --- tools/decode-config.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/decode-config.py b/tools/decode-config.py index 642c31954..0b76ece85 100755 --- a/tools/decode-config.py +++ b/tools/decode-config.py @@ -866,11 +866,15 @@ Setting_6_4_1_16.update({ 'pullup': ('B', (0x73C,1,1), (None, None, ('Management', None)) ), }, 0x73C, (None, None, ('Management', None)) ), - }, 0x720, (None, None, ('Management', '"Template GPIO:{}".format(@["user_template"]["gp"][0])')) + }, 0x720, (None, None, ('Management', None)) ), }) # ====================================================================== +Setting_6_4_1_17 = copy.deepcopy(Setting_6_4_1_16) +Setting_6_4_1_17['flag3'][0].pop('no_pullup',None) +# ====================================================================== Settings = [ + (0x6040111, 0xe00, Setting_6_4_1_17), (0x6040110, 0xe00, Setting_6_4_1_16), (0x604010D, 0xe00, Setting_6_4_1_13), (0x604010B, 0xe00, Setting_6_4_1_11), From 3c58f5b7b9a3fe937f6365f4a2d461b1a267693e Mon Sep 17 00:00:00 2001 From: netpok Date: Thu, 21 Feb 2019 15:53:29 +0100 Subject: [PATCH 08/18] Add password validation to password command --- sonoff/sonoff.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 39f0d7e0b..24a3d5723 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1144,7 +1144,7 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len) snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.sta_ssid[index -1]); } else if ((CMND_PASSWORD == command_code) && (index > 0) && (index <= 2)) { - if ((data_len > 0) && (data_len < sizeof(Settings.sta_pwd[0]))) { + if ((data_len > 4 || SC_CLEAR == Shortcut(dataBuf) || SC_DEFAULT == Shortcut(dataBuf)) && (data_len < sizeof(Settings.sta_pwd[0]))) { strlcpy(Settings.sta_pwd[index -1], (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? (1 == index) ? STA_PASS1 : STA_PASS2 : dataBuf, sizeof(Settings.sta_pwd[0])); Settings.sta_active = index -1; restart_flag = 2; From e035a3253a0b23fb69dd3466ce633c79da1517a9 Mon Sep 17 00:00:00 2001 From: netpok Date: Thu, 21 Feb 2019 15:58:37 +0100 Subject: [PATCH 09/18] Add password validation to WebUI --- sonoff/xdrv_01_webserver.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index a056c48ef..8c9f373a8 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -1236,9 +1236,9 @@ void WifiSaveSettings(void) WebGetArg("s2", tmp, sizeof(tmp)); strlcpy(Settings.sta_ssid[1], (!strlen(tmp)) ? STA_SSID2 : tmp, sizeof(Settings.sta_ssid[1])); WebGetArg("p1", tmp, sizeof(tmp)); - strlcpy(Settings.sta_pwd[0], (!strlen(tmp)) ? "" : (!strcmp(tmp,D_ASTERISK_PWD)) ? Settings.sta_pwd[0] : tmp, sizeof(Settings.sta_pwd[0])); + strlcpy(Settings.sta_pwd[0], (!strlen(tmp)) ? "" : (strlen(tmp) < 5) ? Settings.sta_pwd[0] : tmp, sizeof(Settings.sta_pwd[0])); WebGetArg("p2", tmp, sizeof(tmp)); - strlcpy(Settings.sta_pwd[1], (!strlen(tmp)) ? "" : (!strcmp(tmp,D_ASTERISK_PWD)) ? Settings.sta_pwd[1] : tmp, sizeof(Settings.sta_pwd[1])); + strlcpy(Settings.sta_pwd[1], (!strlen(tmp)) ? "" : (strlen(tmp) < 5) ? Settings.sta_pwd[1] : tmp, sizeof(Settings.sta_pwd[1])); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_CMND_HOSTNAME " %s, " D_CMND_SSID "1 %s, " D_CMND_SSID "2 %s"), Settings.hostname, Settings.sta_ssid[0], Settings.sta_ssid[1]); AddLog(LOG_LEVEL_INFO); @@ -2181,7 +2181,7 @@ int WebSend(char *buffer) user = Trim(user); // user = |admin| if (password) { password = Trim(password); } // password = |joker| } - + command = Trim(command); // command = |POWER1 ON| or |/any/link/starting/with/a/slash.php?log=123| if (command[0] != '/') { url += F("/cm?"); // url = |http://192.168.178.86/cm?| From 4993d16ecb1c19a2c182b6405297c51efc2a5335 Mon Sep 17 00:00:00 2001 From: netpok Date: Thu, 21 Feb 2019 17:49:11 +0100 Subject: [PATCH 10/18] Implement WifiConfig 7 --- sonoff/sonoff.h | 2 +- sonoff/support_wifi.ino | 4 +- sonoff/xdrv_01_webserver.ino | 223 +++++++++++++++++++---------------- 3 files changed, 124 insertions(+), 105 deletions(-) diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 790059450..c86733621 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -212,7 +212,7 @@ enum GetDateAndTimeOptions { DT_LOCAL, DT_UTC, DT_RESTART, DT_ENERGY }; enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL}; -enum WifiConfigOptions {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, WIFI_SERIAL, MAX_WIFI_OPTION}; +enum WifiConfigOptions {WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, WIFI_SERIAL, WIFI_MANAGER_RESET_ONLY, MAX_WIFI_OPTION}; enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, MAX_SWITCH_OPTION}; diff --git a/sonoff/support_wifi.ino b/sonoff/support_wifi.ino index c394005a1..23f4b20c1 100644 --- a/sonoff/support_wifi.ino +++ b/sonoff/support_wifi.ino @@ -174,9 +174,9 @@ void WifiConfig(uint8_t type) } #endif // USE_WPS #ifdef USE_WEBSERVER - else if (WIFI_MANAGER == wifi_config_type) { + else if (WIFI_MANAGER == wifi_config_type || WIFI_MANAGER_RESET_ONLY == wifi_config_type) { AddLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_2_WIFIMANAGER " " D_ACTIVE_FOR_3_MINUTES)); - WifiManagerBegin(); + WifiManagerBegin(WIFI_MANAGER_RESET_ONLY == wifi_config_type); } #endif // USE_WEBSERVER } diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index a056c48ef..5d975ac1b 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -294,12 +294,14 @@ const char HTTP_BTN_RSTRT[] PROGMEM = const char HTTP_BTN_MENU_MODULE[] PROGMEM = "

" "

"; +const char HTTP_BTN_RESET[] PROGMEM = + "
" + "
"; const char HTTP_BTN_MENU4[] PROGMEM = "

" "

" - "

" - "
" - "
" + "

"; +const char HTTP_BTN_MENU5[] PROGMEM = "

" "

"; const char HTTP_BTN_MAIN[] PROGMEM = @@ -437,7 +439,7 @@ const char HDR_CTYPE_JSON[] PROGMEM = "application/json"; const char HDR_CTYPE_STREAM[] PROGMEM = "application/octet-stream"; #define DNS_PORT 53 -enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER}; +enum HttpOptions {HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER, HTTP_MANAGER_RESET_ONLY}; DNSServer *DnsServer; ESP8266WebServer *WebServer; @@ -460,6 +462,10 @@ static void WebGetArg(const char* arg, char* out, size_t max) // out[max-1] = '\0'; // Ensure terminating NUL } +static bool WifiIsInManagerMode(){ + return (HTTP_MANAGER == webserver_state || HTTP_MANAGER_RESET_ONLY == webserver_state); +} + void ShowWebSource(int source) { if ((source > 0) && (source < SRC_MAX)) { @@ -480,34 +486,39 @@ void StartWebserver(int type, IPAddress ipweb) if (!Settings.web_refresh) { Settings.web_refresh = HTTP_REFRESH_TIME; } if (!webserver_state) { if (!WebServer) { - WebServer = new ESP8266WebServer((HTTP_MANAGER==type) ? 80 : WEB_PORT); + WebServer = new ESP8266WebServer((HTTP_MANAGER==type || HTTP_MANAGER_RESET_ONLY == type) ? 80 : WEB_PORT); WebServer->on("/", HandleRoot); - WebServer->on("/up", HandleUpgradeFirmware); - WebServer->on("/u1", HandleUpgradeFirmwareStart); // OTA - WebServer->on("/u2", HTTP_POST, HandleUploadDone, HandleUploadLoop); - WebServer->on("/u2", HTTP_OPTIONS, HandlePreflightRequest); - WebServer->on("/cs", HandleConsole); - WebServer->on("/ax", HandleAjaxConsoleRefresh); - WebServer->on("/ay", HandleAjaxStatusRefresh); - WebServer->on("/cm", HandleHttpCommand); WebServer->onNotFound(HandleNotFound); #ifndef FIRMWARE_MINIMAL - WebServer->on("/cn", HandleConfiguration); - WebServer->on("/md", HandleModuleConfiguration); - WebServer->on("/wi", HandleWifiConfiguration); - WebServer->on("/lg", HandleLoggingConfiguration); - WebServer->on("/tp", HandleTemplateConfiguration); - WebServer->on("/co", HandleOtherConfiguration); - WebServer->on("/dl", HandleBackupConfiguration); - WebServer->on("/rs", HandleRestoreConfiguration); WebServer->on("/rt", HandleResetConfiguration); - WebServer->on("/in", HandleInformation); +#endif // FIRMWARE_MINIMAL + if(HTTP_MANAGER_RESET_ONLY != type){ + WebServer->on("/up", HandleUpgradeFirmware); + WebServer->on("/u1", HandleUpgradeFirmwareStart); // OTA + WebServer->on("/u2", HTTP_POST, HandleUploadDone, HandleUploadLoop); + WebServer->on("/u2", HTTP_OPTIONS, HandlePreflightRequest); + WebServer->on("/cs", HandleConsole); + WebServer->on("/ax", HandleAjaxConsoleRefresh); + WebServer->on("/ay", HandleAjaxStatusRefresh); + WebServer->on("/cm", HandleHttpCommand); +#ifndef FIRMWARE_MINIMAL + WebServer->on("/cn", HandleConfiguration); + WebServer->on("/md", HandleModuleConfiguration); + WebServer->on("/wi", HandleWifiConfiguration); + WebServer->on("/lg", HandleLoggingConfiguration); + WebServer->on("/tp", HandleTemplateConfiguration); + WebServer->on("/co", HandleOtherConfiguration); + WebServer->on("/dl", HandleBackupConfiguration); + WebServer->on("/rs", HandleRestoreConfiguration); + WebServer->on("/rt", HandleResetConfiguration); + WebServer->on("/in", HandleInformation); #ifdef USE_EMULATION - HueWemoAddHandlers(); + HueWemoAddHandlers(); #endif // USE_EMULATION - XdrvCall(FUNC_WEB_ADD_HANDLER); - XsnsCall(FUNC_WEB_ADD_HANDLER); + XdrvCall(FUNC_WEB_ADD_HANDLER); + XsnsCall(FUNC_WEB_ADD_HANDLER); #endif // Not FIRMWARE_MINIMAL + } } reset_web_log_flag = false; WebServer->begin(); // Web server start @@ -529,7 +540,7 @@ void StopWebserver(void) } } -void WifiManagerBegin(void) +void WifiManagerBegin(bool reset_only) { // setup AP if (!global_state.wifi_down) { @@ -553,7 +564,7 @@ void WifiManagerBegin(void) DnsServer->setErrorReplyCode(DNSReplyCode::NoError); DnsServer->start(DNS_PORT, "*", WiFi.softAPIP()); - StartWebserver(HTTP_MANAGER, WiFi.softAPIP()); + StartWebserver((reset_only ? HTTP_MANAGER_RESET_ONLY : HTTP_MANAGER), WiFi.softAPIP()); } void PollDnsWebserver(void) @@ -576,7 +587,7 @@ void SetHeader(void) bool WebAuthenticate(void) { - if (Settings.web_password[0] != 0) { + if (Settings.web_password[0] != 0 && HTTP_MANAGER_RESET_ONLY != webserver_state) { return WebServer->authenticate(WEB_USERNAME, Settings.web_password); } else { return true; @@ -611,7 +622,7 @@ void ShowPage(String &page, bool auth) } page.replace(F("{j}"), info); - if (HTTP_MANAGER == webserver_state) { + if (WifiIsInManagerMode()) { if (WifiConfigCounter()) { page.replace(F(""), FPSTR(HTTP_SCRIPT_COUNTER)); page += FPSTR(HTTP_COUNTER); @@ -690,12 +701,12 @@ void HandleRoot(void) return; } - if (HTTP_MANAGER == webserver_state) { + if (WifiIsInManagerMode()) { #ifndef FIRMWARE_MINIMAL - if ((Settings.web_password[0] != 0) && !(WebServer->hasArg("USER1")) && !(WebServer->hasArg("PASS1"))) { + if ((Settings.web_password[0] != 0) && !(WebServer->hasArg("USER1")) && !(WebServer->hasArg("PASS1")) && HTTP_MANAGER_RESET_ONLY != webserver_state) { HandleWifiLogin(); } else { - if (!(Settings.web_password[0] != 0) || ((WebServer->arg("USER1") == WEB_USERNAME ) && (WebServer->arg("PASS1") == Settings.web_password ))) { + if (!(Settings.web_password[0] != 0) || ((WebServer->arg("USER1") == WEB_USERNAME ) && (WebServer->arg("PASS1") == Settings.web_password ) || HTTP_MANAGER_RESET_ONLY == webserver_state)) { HandleWifiConfiguration(); } else { // wrong user and pass @@ -874,6 +885,8 @@ void HandleConfiguration(void) page += String(mqtt_data); page += FPSTR(HTTP_BTN_MENU4); + page += FPSTR(HTTP_BTN_RESET); + page += FPSTR(HTTP_BTN_MENU5); page += FPSTR(HTTP_BTN_MAIN); ShowPage(page); } @@ -1125,7 +1138,7 @@ void HandleWifiConfiguration(void) AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_WIFI); - if (WebServer->hasArg("save")) { + if (WebServer->hasArg("save") && HTTP_MANAGER_RESET_ONLY != webserver_state) { WifiSaveSettings(); WebRestart(2); return; @@ -1136,90 +1149,96 @@ void HandleWifiConfiguration(void) page += FPSTR(HTTP_SCRIPT_WIFI); page += FPSTR(HTTP_HEAD_STYLE); - if (WebServer->hasArg("scan")) { -#ifdef USE_EMULATION - UdpDisconnect(); -#endif // USE_EMULATION - int n = WiFi.scanNetworks(); - AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_SCAN_DONE)); - if (0 == n) { - AddLog_P(LOG_LEVEL_DEBUG, S_LOG_WIFI, S_NO_NETWORKS_FOUND); - page += FPSTR(S_NO_NETWORKS_FOUND); - page += F(". " D_REFRESH_TO_SCAN_AGAIN "."); - } else { - //sort networks - int indices[n]; - for (int i = 0; i < n; i++) { - indices[i] = i; - } + if(HTTP_MANAGER_RESET_ONLY != webserver_state){ + if (WebServer->hasArg("scan")) { + #ifdef USE_EMULATION + UdpDisconnect(); + #endif // USE_EMULATION + int n = WiFi.scanNetworks(); + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_SCAN_DONE)); - // RSSI SORT - for (int i = 0; i < n; i++) { - for (int j = i + 1; j < n; j++) { - if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i])) { - std::swap(indices[i], indices[j]); - } - } - } - - // remove duplicates ( must be RSSI sorted ) - if (remove_duplicate_access_points) { - String cssid; + if (0 == n) { + AddLog_P(LOG_LEVEL_DEBUG, S_LOG_WIFI, S_NO_NETWORKS_FOUND); + page += FPSTR(S_NO_NETWORKS_FOUND); + page += F(". " D_REFRESH_TO_SCAN_AGAIN "."); + } else { + //sort networks + int indices[n]; + for (int i = 0; i < n; i++) { + indices[i] = i; + } + + // RSSI SORT for (int i = 0; i < n; i++) { - if (-1 == indices[i]) { continue; } - cssid = WiFi.SSID(indices[i]); for (int j = i + 1; j < n; j++) { - if (cssid == WiFi.SSID(indices[j])) { - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_DUPLICATE_ACCESSPOINT " %s"), WiFi.SSID(indices[j]).c_str()); - AddLog(LOG_LEVEL_DEBUG); - indices[j] = -1; // set dup aps to index -1 + if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i])) { + std::swap(indices[i], indices[j]); } } } - } - //display networks in page - for (int i = 0; i < n; i++) { - if (-1 == indices[i]) { continue; } // skip dups - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_SSID " %s, " D_BSSID " %s, " D_CHANNEL " %d, " D_RSSI " %d"), WiFi.SSID(indices[i]).c_str(), WiFi.BSSIDstr(indices[i]).c_str(), WiFi.channel(indices[i]), WiFi.RSSI(indices[i])); - AddLog(LOG_LEVEL_DEBUG); - int quality = WifiGetRssiAsQuality(WiFi.RSSI(indices[i])); - - if (minimum_signal_quality == -1 || minimum_signal_quality < quality) { - String item = FPSTR(HTTP_LNK_ITEM); - String rssiQ; - rssiQ += quality; - item.replace(F("{v}"), htmlEscape(WiFi.SSID(indices[i]))); - item.replace(F("{w}"), String(WiFi.channel(indices[i]))); - item.replace(F("{r}"), rssiQ); - uint8_t auth = WiFi.encryptionType(indices[i]); - item.replace(F("{i}"), (ENC_TYPE_WEP == auth) ? F(D_WEP) : (ENC_TYPE_TKIP == auth) ? F(D_WPA_PSK) : (ENC_TYPE_CCMP == auth) ? F(D_WPA2_PSK) : (ENC_TYPE_AUTO == auth) ? F(D_AUTO) : F("")); - page += item; - delay(0); - } else { - AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_SKIPPING_LOW_QUALITY)); + // remove duplicates ( must be RSSI sorted ) + if (remove_duplicate_access_points) { + String cssid; + for (int i = 0; i < n; i++) { + if (-1 == indices[i]) { continue; } + cssid = WiFi.SSID(indices[i]); + for (int j = i + 1; j < n; j++) { + if (cssid == WiFi.SSID(indices[j])) { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_DUPLICATE_ACCESSPOINT " %s"), WiFi.SSID(indices[j]).c_str()); + AddLog(LOG_LEVEL_DEBUG); + indices[j] = -1; // set dup aps to index -1 + } + } + } } - } - page += "
"; - } - } else { - page += FPSTR(HTTP_LNK_SCAN); - } + //display networks in page + for (int i = 0; i < n; i++) { + if (-1 == indices[i]) { continue; } // skip dups + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_WIFI D_SSID " %s, " D_BSSID " %s, " D_CHANNEL " %d, " D_RSSI " %d"), WiFi.SSID(indices[i]).c_str(), WiFi.BSSIDstr(indices[i]).c_str(), WiFi.channel(indices[i]), WiFi.RSSI(indices[i])); + AddLog(LOG_LEVEL_DEBUG); + int quality = WifiGetRssiAsQuality(WiFi.RSSI(indices[i])); - page += FPSTR(HTTP_FORM_WIFI); - page.replace(F("{h1"), Settings.hostname); - page.replace(F("{s1"), Settings.sta_ssid[0]); - page.replace(F("{s2"), Settings.sta_ssid[1]); - page += FPSTR(HTTP_FORM_END); - if (HTTP_MANAGER == webserver_state) { + if (minimum_signal_quality == -1 || minimum_signal_quality < quality) { + String item = FPSTR(HTTP_LNK_ITEM); + String rssiQ; + rssiQ += quality; + item.replace(F("{v}"), htmlEscape(WiFi.SSID(indices[i]))); + item.replace(F("{w}"), String(WiFi.channel(indices[i]))); + item.replace(F("{r}"), rssiQ); + uint8_t auth = WiFi.encryptionType(indices[i]); + item.replace(F("{i}"), (ENC_TYPE_WEP == auth) ? F(D_WEP) : (ENC_TYPE_TKIP == auth) ? F(D_WPA_PSK) : (ENC_TYPE_CCMP == auth) ? F(D_WPA2_PSK) : (ENC_TYPE_AUTO == auth) ? F(D_AUTO) : F("")); + page += item; + delay(0); + } else { + AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_SKIPPING_LOW_QUALITY)); + } + + } + page += "
"; + } + } else { + page += FPSTR(HTTP_LNK_SCAN); + } + + page += FPSTR(HTTP_FORM_WIFI); + page.replace(F("{h1"), Settings.hostname); + page.replace(F("{s1"), Settings.sta_ssid[0]); + page.replace(F("{s2"), Settings.sta_ssid[1]); + page += FPSTR(HTTP_FORM_END); + } + if (WifiIsInManagerMode()) { page += FPSTR(HTTP_BTN_RSTRT); + #ifndef FIRMWARE_MINIMAL + page += FPSTR(HTTP_BTN_RESET); + #endif // FIRMWARE_MINIMAL } else { page += FPSTR(HTTP_BTN_CONF); } // ShowPage(page); - ShowPage(page, !(HTTP_MANAGER == webserver_state)); + ShowPage(page, !(WifiIsInManagerMode())); } void WifiSaveSettings(void) @@ -2089,7 +2108,7 @@ void HandleNotFound(void) /* Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */ bool CaptivePortal(void) { - if ((HTTP_MANAGER == webserver_state) && !ValidIpAddress(WebServer->hostHeader())) { + if ((WifiIsInManagerMode()) && !ValidIpAddress(WebServer->hostHeader())) { AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED)); WebServer->sendHeader(F("Location"), String("http://") + WebServer->client().localIP().toString(), true); From 731154cc9bc3c3f1434b329b21b074994e011a12 Mon Sep 17 00:00:00 2001 From: netpok Date: Thu, 21 Feb 2019 19:45:03 +0100 Subject: [PATCH 11/18] Handle authentication on reset/restart --- sonoff/xdrv_01_webserver.ino | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index 5d975ac1b..05f095010 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -666,14 +666,16 @@ void WebRestart(uint8_t type) page.replace(F("{v}"), FPSTR(S_RESTART)); } + bool reset_only = (HTTP_MANAGER_RESET_ONLY == webserver_state); + page += FPSTR(HTTP_MSG_RSTRT); - if (HTTP_MANAGER == webserver_state) { + if (HTTP_MANAGER == webserver_state || reset_only) { webserver_state = HTTP_ADMIN; } else { page += FPSTR(HTTP_BTN_MAIN); } page.replace(F(""), FPSTR(HTTP_SCRIPT_RELOAD)); - ShowPage(page); + ShowPage(page, !reset_only); ShowWebSource(SRC_WEBGUI); restart_flag = 2; @@ -1494,7 +1496,7 @@ void HandleResetConfiguration(void) page += F("
" D_CONFIGURATION_RESET "
"); page += FPSTR(HTTP_MSG_RSTRT); page += FPSTR(HTTP_BTN_MAIN); - ShowPage(page); + ShowPage(page, HTTP_MANAGER_RESET_ONLY != webserver_state); snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RESET " 1")); ExecuteWebCommand(svalue, SRC_WEBGUI); From e9396d0ed42864835fef78e61a142cb87809e953 Mon Sep 17 00:00:00 2001 From: netpok Date: Thu, 21 Feb 2019 19:45:21 +0100 Subject: [PATCH 12/18] Add missing localization strings --- sonoff/i18n.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index 7340a3484..e0b3af57b 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -248,6 +248,7 @@ #define D_WCFG_4_RETRY "Retry" #define D_WCFG_5_WAIT "Wait" #define D_WCFG_6_SERIAL "Serial" + #define D_WCFG_7_WIFIMANAGER_RESET_ONLY "ManagerRst" #define D_CMND_FRIENDLYNAME "FriendlyName" #define D_CMND_SWITCHMODE "SwitchMode" #define D_CMND_INTERLOCK "Interlock" @@ -540,7 +541,8 @@ const char kWifiConfig[MAX_WIFI_OPTION][WCFG_MAX_STRING_LENGTH] PROGMEM = { D_WCFG_3_WPSCONFIG, D_WCFG_4_RETRY, D_WCFG_5_WAIT, - D_WCFG_6_SERIAL }; + D_WCFG_6_SERIAL, + D_WCFG_7_WIFIMANAGER_RESET_ONLY }; const char kPrefixes[3][PRFX_MAX_STRING_LENGTH] PROGMEM = { D_CMND, D_STAT, From b3adab40979b6882bab6f8a8277e84f23f112805 Mon Sep 17 00:00:00 2001 From: netpok Date: Thu, 21 Feb 2019 21:27:52 +0100 Subject: [PATCH 13/18] Add flag for no hold retain --- sonoff/settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/settings.h b/sonoff/settings.h index bc39d7d8a..447db10c0 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -75,7 +75,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t hass_tele_on_power : 1; // bit 9 (v6.3.0.13) uint32_t sleep_normal : 1; // bit 10 (v6.3.0.15) - SetOption60 - Enable normal sleep instead of dynamic sleep uint32_t button_switch_force_local : 1;// bit 11 (v6.3.0.16) - SetOption61 - Force local operation when button/switch topic is set - uint32_t spare12 : 1; + uint32_t no_hold_retain : 1; // bit 12 (v6.4.1.19) - SetOption62 - Don't use retain flag on HOLD messages uint32_t spare13 : 1; uint32_t spare14 : 1; uint32_t spare15 : 1; From 6cbfb0308aede1b6d2161b51c36f377151e077ba Mon Sep 17 00:00:00 2001 From: netpok Date: Thu, 21 Feb 2019 21:28:35 +0100 Subject: [PATCH 14/18] Check no hold retain flag on hold action sending --- sonoff/sonoff.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 24a3d5723..5cb6379f9 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1434,10 +1434,10 @@ bool SendKey(uint8_t key, uint8_t device, uint8_t state) } #ifdef USE_DOMOTICZ if (!(DomoticzSendKey(key, device, state, strlen(mqtt_data)))) { - MqttPublishDirect(stopic, (key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain); + MqttPublishDirect(stopic, ((key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain) && (state != 3 || !Settings.flag3.no_hold_retain)); } #else - MqttPublishDirect(stopic, (key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain); + MqttPublishDirect(stopic, ((key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain) && (state != 3 || !Settings.flag3.no_hold_retain)); #endif // USE_DOMOTICZ result = !Settings.flag3.button_switch_force_local; } else { From 49f0b514ebae8f9f17a48eada91361258ee92585 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 22 Feb 2019 12:04:05 +0100 Subject: [PATCH 15/18] Fix some exceptions and watchdogs * Fix some exceptions and watchdogs due to lack of stack space - part 2 * Add command SetOption62 0/1 to disable retain on Button or Swith hold messages (#5299) * Add option WifiConfig 7 to allow reset of device in AP mode without admin password (#5297) --- sonoff/_changelog.ino | 3 +++ sonoff/sonoff.ino | 14 +++++++------- sonoff/xdrv_01_webserver.ino | 24 +++++++++++------------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 0d4fef299..0ca38587b 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,5 +1,8 @@ /* 6.4.1.18 20191221 * Fix some exceptions and watchdogs due to lack of stack space - part 1 (#5215) + * Fix some exceptions and watchdogs due to lack of stack space - part 2 + * Add command SetOption62 0/1 to disable retain on Button or Swith hold messages (#5299) + * Add option WifiConfig 7 to allow reset of device in AP mode without admin password (#5297) * * 6.4.1.17 20190214 * Change template update by removing possibility to add user module config keeping template as defined (#5222) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 5cb6379f9..161c26ed8 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -866,9 +866,7 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len) } restart_flag = 2; } - uint8_t module = Settings.module; - if (USER_MODULE == Settings.module) { module = 0; } else { module++; } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_SVALUE, command, module, ModuleName().c_str()); + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE_SVALUE, command, ModuleNr(), ModuleName().c_str()); } else if (CMND_MODULES == command_code) { for (uint8_t i = 0; i <= MAXMODULE; i++) { @@ -1566,8 +1564,6 @@ void StopAllPowerBlink(void) void ExecuteCommand(char *cmnd, int source) { - char stopic[CMDSZ]; - char svalue[INPUT_BUFFER_SIZE]; char *start; char *token; @@ -1579,9 +1575,13 @@ void ExecuteCommand(char *cmnd, int source) start = strrchr(token, '/'); // Skip possible cmnd/sonoff/ preamble if (start) { token = start +1; } } + uint16_t size = (token != NULL) ? strlen(token) : 0; + char stopic[size +2]; // / + \0 snprintf_P(stopic, sizeof(stopic), PSTR("/%s"), (token == NULL) ? "" : token); + token = strtok(NULL, ""); -// snprintf_P(svalue, sizeof(svalue), (token == NULL) ? "" : token); // Fails with command FullTopic home/%prefix%/%topic% as it processes %p of %prefix% + size = (token != NULL) ? strlen(token) : 0; + char svalue[size +1]; strlcpy(svalue, (token == NULL) ? "" : token, sizeof(svalue)); // Fixed 5.8.0b MqttDataHandler(stopic, (uint8_t*)svalue, strlen(svalue)); } @@ -1610,7 +1610,7 @@ void PublishStatus(uint8_t payload) snprintf_P(stemp2, sizeof(stemp2), PSTR("%s%s%d" ), stemp2, (i > 0 ? "," : ""), Settings.switchmode[i]); } snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d,\"" D_CMND_FRIENDLYNAME "\":[%s],\"" D_CMND_TOPIC "\":\"%s\",\"" D_CMND_BUTTONTOPIC "\":\"%s\",\"" D_CMND_POWER "\":%d,\"" D_CMND_POWERONSTATE "\":%d,\"" D_CMND_LEDSTATE "\":%d,\"" D_CMND_SAVEDATA "\":%d,\"" D_JSON_SAVESTATE "\":%d,\"" D_CMND_SWITCHTOPIC "\":\"%s\",\"" D_CMND_SWITCHMODE "\":[%s],\"" D_CMND_BUTTONRETAIN "\":%d,\"" D_CMND_SWITCHRETAIN "\":%d,\"" D_CMND_SENSORRETAIN "\":%d,\"" D_CMND_POWERRETAIN "\":%d}}"), - (USER_MODULE == Settings.module)?0:Settings.module +1, stemp, mqtt_topic, Settings.button_topic, power, Settings.poweronstate, Settings.ledstate, Settings.save_data, Settings.flag.save_state, Settings.switch_topic, stemp2, Settings.flag.mqtt_button_retain, Settings.flag.mqtt_switch_retain, Settings.flag.mqtt_sensor_retain, Settings.flag.mqtt_power_retain); + ModuleNr(), stemp, mqtt_topic, Settings.button_topic, power, Settings.poweronstate, Settings.ledstate, Settings.save_data, Settings.flag.save_state, Settings.switch_topic, stemp2, Settings.flag.mqtt_button_retain, Settings.flag.mqtt_switch_retain, Settings.flag.mqtt_sensor_retain, Settings.flag.mqtt_power_retain); MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS)); } diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index 0258484b9..779872bb9 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -1956,8 +1956,6 @@ void HandleHttpCommand(void) { if (!HttpCheckPriviledgedAccess(false)) { return; } - char svalue[INPUT_BUFFER_SIZE]; // Large to serve Backlog - AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_COMMAND)); uint8_t valid = 1; @@ -1972,9 +1970,9 @@ void HandleHttpCommand(void) String message = F("{\"" D_RSLT_WARNING "\":\""); if (valid) { uint8_t curridx = web_log_index; - WebGetArg("cmnd", svalue, sizeof(svalue)); - if (strlen(svalue)) { - ExecuteWebCommand(svalue, SRC_WEBCOMMAND); + String svalue = WebServer->arg("cmnd"); + if (svalue.length() && (svalue.length() < INPUT_BUFFER_SIZE)) { + ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCONSOLE); if (web_log_index != curridx) { uint8_t counter = curridx; @@ -2032,19 +2030,19 @@ void HandleAjaxConsoleRefresh(void) { if (!HttpCheckPriviledgedAccess()) { return; } - char svalue[INPUT_BUFFER_SIZE]; // Large to serve Backlog bool cflg = true; uint8_t counter = 0; // Initial start, should never be 0 again - WebGetArg("c1", svalue, sizeof(svalue)); - if (strlen(svalue)) { - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), svalue); + String svalue = WebServer->arg("c1"); + if (svalue.length() && (svalue.length() < INPUT_BUFFER_SIZE)) { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_COMMAND "%s"), svalue.c_str()); AddLog(LOG_LEVEL_INFO); - ExecuteWebCommand(svalue, SRC_WEBCONSOLE); + ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCONSOLE); } - WebGetArg("c2", svalue, sizeof(svalue)); - if (strlen(svalue)) { counter = atoi(svalue); } + char stmp[10]; + WebGetArg("c2", stmp, sizeof(stmp)); + if (strlen(stmp)) { counter = atoi(stmp); } bool last_reset_web_log_flag = reset_web_log_flag; // mqtt_data used as scratch space @@ -2202,7 +2200,7 @@ int WebSend(char *buffer) user = Trim(user); // user = |admin| if (password) { password = Trim(password); } // password = |joker| } - + command = Trim(command); // command = |POWER1 ON| or |/any/link/starting/with/a/slash.php?log=123| if (command[0] != '/') { url += F("/cm?"); // url = |http://192.168.178.86/cm?| From d219d1c9b5d482f5233e37caa63071a194c7240b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 22 Feb 2019 12:11:15 +0100 Subject: [PATCH 16/18] Update support.ino Houskeeping --- sonoff/support.ino | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/sonoff/support.ino b/sonoff/support.ino index 113968974..ff488d008 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -699,6 +699,13 @@ void ShowSource(int source) * GPIO Module and Template management \*********************************************************************************************/ +uint8_t ModuleNr() +{ + // 0 = User module (255) + // 1 up = Template module 0 up + return (USER_MODULE == Settings.module) ? 0 : Settings.module +1; +} + String AnyModuleName(uint8_t index) { if (USER_MODULE == index) { @@ -720,7 +727,6 @@ void ModuleGpios(myio *gp) uint8_t src[sizeof(mycfgio)]; if (USER_MODULE == Settings.module) { -// src = Settings.user_template.gp; memcpy(&src, &Settings.user_template.gp, sizeof(mycfgio)); } else { memcpy_P(&src, &kModules[Settings.module].gp, sizeof(mycfgio)); @@ -870,14 +876,6 @@ bool JsonTemplate(const char* dataBuf) if ((0 == base) || (base >= MAXMODULE)) { base = 17; } else { base--; } Settings.user_template_base = base; // Default WEMOS } - - // Validate GPIO -// for (uint8_t i = 0; i < sizeof(mycfgio); i++) { - // For now do not allow non-user configurable GPIO -// if ((Settings.user_template.gp.io[i] > GPIO_FIX_START) && (Settings.user_template.gp.io[i] < GPIO_USER)) { -// Settings.user_template.gp.io[i] = GPIO_NONE; -// }; -// } return true; } @@ -887,8 +885,6 @@ void TemplateJson() for (uint8_t i = 0; i < sizeof(Settings.user_template.gp); i++) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s%d"), mqtt_data, (i>0)?",":"", Settings.user_template.gp.io[i]); } -// snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":\"%d (%s)\"}"), -// mqtt_data, Settings.user_template.flag, Settings.user_template_base +1, AnyModuleName(Settings.user_template_base).c_str()); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), mqtt_data, Settings.user_template.flag, Settings.user_template_base +1); } From e315be06198ae481b102967359c886ed1e9bd6da Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 22 Feb 2019 15:19:59 +0100 Subject: [PATCH 17/18] Fix command WebSend Fix command WebSend when using a port number as regression from 6.4.1.17 (#5304) --- sonoff/_changelog.ino | 1 + sonoff/xdrv_01_webserver.ino | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 0ca38587b..d9762ec24 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -3,6 +3,7 @@ * Fix some exceptions and watchdogs due to lack of stack space - part 2 * Add command SetOption62 0/1 to disable retain on Button or Swith hold messages (#5299) * Add option WifiConfig 7 to allow reset of device in AP mode without admin password (#5297) + * Fix command WebSend when using a port number as regression from 6.4.1.17 (#5304) * * 6.4.1.17 20190214 * Change template update by removing possibility to add user module config keeping template as defined (#5222) diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index 779872bb9..cb2717db3 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -2182,18 +2182,19 @@ int WebSend(char *buffer) // buffer = | [ 192.168.178.86 : 80 , admin : joker ] POWER1 ON | host = strtok_r(buffer, "]", &command); // host = | [ 192.168.178.86 : 80 , admin : joker |, command = | POWER1 ON | if (host && command) { - String url = F("http:"); // url = |http:| + String url = F("http://"); // url = |http://| host = Trim(host); // host = |[ 192.168.178.86 : 80 , admin : joker| host++; // host = | 192.168.178.86 : 80 , admin : joker| - Skip [ host = strtok_r(host, ",", &user); // host = | 192.168.178.86 : 80 |, user = | admin : joker| host = strtok_r(host, ":", &port); // host = | 192.168.178.86 |, port = | 80 | host = Trim(host); // host = |192.168.178.86| + url += host; // url = |http://192.168.178.86| + if (port) { port = Trim(port); // port = |80| - url += port; // url = |http:80| + url += F(":"); // url = |http://192.168.178.86:| + url += port; // url = |http://192.168.178.86:80| } - url += F("//"); // url = |http://| or |http:80//| - url += host; // url = |http://192.168.178.86| if (user) { user = strtok_r(user, ":", &password); // user = | admin |, password = | joker| From 2a8e785a8bd1c1b5e2633fa40b46e5981612195b Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Fri, 22 Feb 2019 15:23:37 +0100 Subject: [PATCH 18/18] Revert to modular build 2.5.0 release --- platformio.ini | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 21816c3ab..af1adb697 100644 --- a/platformio.ini +++ b/platformio.ini @@ -65,8 +65,9 @@ build_flags = ${esp82xx_defaults.build_flags} -DVTABLES_IN_FLASH [core_2_5_0] -; *** Esp8266 core for Arduino version 2.5.0 -platform = espressif8266@2.0.0 +; *** Esp8266 core for Arduino version 2.5.0 (since version from platformio is faulty) +platform = https://github.com/Jason2866/platform-espressif8266.git#Tasmota +;platform = espressif8266@2.0.0 build_flags = ${esp82xx_defaults.build_flags} -Wl,-Teagle.flash.1m.ld ; lwIP 1.4 (Default)