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