diff --git a/README.md b/README.md index 7f00135..42df97b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,18 @@ The configuration portal is of the captive variety, so on various devices it wil First attempt at a library. Lots more changes and fixes to do. Contributions are welcome. -#### This works with the ESP8266 Arduino platform with a recent stable release(2.0.0 or newer) https://github.com/esp8266/Arduino +**This works with the ESP8266 Arduino platform with a recent stable release(2.0.0 or newer)** + +[https://github.com/esp8266/Arduino](https://github.com/esp8266/Arduino) + +**This works with the ESP32 Arduino platform with staging , with caveats below** + +[https://github.com/espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) + +### Known Issues +* :exclamation: ESP32 must be patched with webserver library, see [https://github.com/tzapu/WiFiManager/issues/513](https://github.com/tzapu/WiFiManager/issues/513) +* :exclamation: ESP32 espressif/dnsserver contains bugs that prevent captive portal from working, see [https://github.com/tzapu/WiFiManager/issues/513](https://github.com/tzapu/WiFiManager/issues/513) +* Documentation needs to be updated, see [https://github.com/tzapu/WiFiManager/issues/500](https://github.com/tzapu/WiFiManager/issues/500) ## Contents - [How it works](#how-it-works) @@ -348,6 +359,8 @@ __THANK YOU__ [Shawn A](https://github.com/tablatronix) +[bbx10](https://github.com/bbx10) + [kentaylor](https://github.com/kentaylor) [Maximiliano Duarte](https://github.com/domonetic) diff --git a/WiFiManager.cpp b/WiFiManager.cpp index bd5391d..9775874 100644 --- a/WiFiManager.cpp +++ b/WiFiManager.cpp @@ -136,7 +136,7 @@ WiFiManager::WiFiManager():_debugPort(Serial) { // destructor WiFiManager::~WiFiManager() { if(_userpersistent) WiFi.persistent(true); // reenable persistent, there is no getter we rely on _userpersistent - WiFi.mode(_usermode); + if(_usermode != WIFI_OFF) WiFi.mode(_usermode); // parameters // @todo belongs to wifimanagerparameter @@ -150,7 +150,7 @@ WiFiManager::~WiFiManager() { // AUTOCONNECT boolean WiFiManager::autoConnect() { - String ssid = (String)F("ESP") + String(WIFI_getChipId()); + String ssid = _wifissidprefix + "_" + String(WIFI_getChipId()); return autoConnect(ssid.c_str(), NULL); } @@ -159,6 +159,9 @@ boolean WiFiManager::autoConnect(char const *apName, char const *apPassword) { // attempt to connect using saved settings, on fail fallback to AP config portal WiFi_enableSTA(true); + _usermode = WIFI_STA; + + WiFi_autoReconnect(); // if already connected, or try stored connect if (WiFi.status() == WL_CONNECTED || connectWifi("", "") == WL_CONNECTED) { @@ -220,24 +223,28 @@ void WiFiManager::stopWebPortal() { boolean WiFiManager::configPortalHasTimeout(){ - if(_configPortalTimeout == 0 || (_cpClientCheck && (wifi_softap_get_station_num() > 0))){ + if(_configPortalTimeout == 0 || (_cpClientCheck && (WiFi_softap_num_stations() > 0))){ if(millis() - timer > 30000){ timer = millis(); - if(_debugLevel > 0) DEBUG_WM("NUM CLIENTS: " + (String)wifi_softap_get_station_num()); + if(_debugLevel > 0) DEBUG_WM("NUM CLIENTS: " + (String)WiFi_softap_num_stations()); } _configPortalStart = millis(); // kludge, bump configportal start time to skew timeouts return false; } - + // handle timeout if(_webClientCheck && _webPortalAccessed>_configPortalStart>0) _configPortalStart = _webPortalAccessed; if(millis() > _configPortalStart + _configPortalTimeout){ DEBUG_WM(F("config portal has timed out")); return true; } else if(_debugLevel > 0) { - if((millis() - timer) > 1000){ - timer = millis(); - DEBUG_WM(F("Portal Timeout In"),(String)((_configPortalStart + _configPortalTimeout-millis())/1000) + (String)F(" seconds")); + // log timeout + if(_debug){ + uint16_t logintvl = 30000; // how often to emit timeing out counter logging + if((millis() - timer) > logintvl){ + timer = millis(); + DEBUG_WM(F("Portal Timeout In"),(String)((_configPortalStart + _configPortalTimeout-millis())/1000) + (String)F(" seconds")); + } } } @@ -250,7 +257,11 @@ void WiFiManager::setupConfigPortal() { // setup dns and web servers dnsServer.reset(new DNSServer()); - server.reset(new ESP8266WebServer(80)); + #if defined(ESP32) && defined(WEBSERVERSHIM) + server.reset(new WebServer(80)); + #else + server.reset(new ESP8266WebServer(80)); + #endif /* Setup the DNS server redirecting all the domains to the apIP */ dnsServer->setErrorReplyCode(DNSReplyCode::NoError); @@ -274,7 +285,7 @@ void WiFiManager::setupConfigPortal() { } boolean WiFiManager::startConfigPortal() { - String ssid = (String)F("ESP") + String(WIFI_getChipId()); + String ssid = _wifissidprefix + "_" + String(WIFI_getChipId()); return startConfigPortal(ssid.c_str(), NULL); } @@ -364,19 +375,21 @@ uint8_t WiFiManager::handleConfigPortal(){ server->handleClient(); // Waiting for save... - if (connect) { + if(connect) { connect = false; - delay(2000); - DEBUG_WM(F("Connecting save WiFi")); + DEBUG_WM(F("Connecting to a new AP")); + if(_enableCaptivePortal) delay(2000); // configportal close delay // attempt sta connection to submitted _ssid, _pass if (connectWifi(_ssid, _pass) == WL_CONNECTED) { - DEBUG_WM(F("Connect to new AP SUCCESS")); + DEBUG_WM(F("Connect to new AP [SUCCESS]")); + DEBUG_WM(F("Got IP Address:")); + DEBUG_WM(WiFi.localIP()); stopConfigPortal(); return WL_CONNECTED; // success } - DEBUG_WM(F("Failed to connect.")); + DEBUG_WM(F("Connect to new AP [FAILED]")); if (_shouldBreakAfterConfig) { // this is more of an exiting callback than a save @@ -455,7 +468,7 @@ int WiFiManager::connectWifi(String ssid, String pass) { //@todo catch failures in set_config } else { // connect using saved ssid if there is one - if (WiFi.SSID() != "") { + if (WiFi_hasAutoConnect()) { DEBUG_WM(F("Connecting to saved AP")); WiFi_enableSTA(true,storeSTAmode); WiFi.begin(); @@ -509,7 +522,11 @@ uint8_t WiFiManager::waitForConnectResult() { void WiFiManager::startWPS() { DEBUG_WM(F("START WPS")); - WiFi.beginWPSConfig(); + #ifdef ESP8266 + WiFi.beginWPSConfig(); + #else + // @todo + #endif DEBUG_WM(F("END WPS")); } @@ -521,10 +538,8 @@ String WiFiManager::getConfigPortalSSID() { // SETTERS void WiFiManager::resetSettings() { DEBUG_WM(F("SETTINGS ERASED")); - WiFi.persistent(true); + WiFi_enableSTA(true,true); WiFi.disconnect(true); - WiFi.persistent(false); - //delay(200); } void WiFiManager::setTimeout(unsigned long seconds) { @@ -612,7 +627,7 @@ void WiFiManager::handleWifi(boolean scan) { page += getScanItemOut(); } String pitem = FPSTR(HTTP_FORM_START); - pitem.replace(FPSTR(T_v), WiFi.SSID()); + pitem.replace(FPSTR(T_v), WiFi_SSID()); page += pitem; page += getStaticOut(); @@ -908,42 +923,82 @@ void WiFiManager::handleInfo() { handleRequest(); String page = getHTTPHead(FPSTR(S_titleinfo)); // @token titleinfo reportStatus(page); - - String infoids[] = { - F("esphead"), - F("uptime"), - F("chipid"), - F("fchipid"), - F("idesize"), - F("flashsize"), - F("sdkver"), - F("corever"), - F("bootver"), - F("cpufreq"), - F("freeheap"), - F("memsketch"), - F("memsmeter"), - F("lastreset"), - F("wifihead"), - F("apip"), - F("apmac"), - F("apssid"), - F("apbssid"), - F("staip"), - F("stagw"), - F("stasub"), - F("dnss"), - F("host"), - F("stamac"), - F("conx"), - F("autoconx") - }; - for(int i=0; i<25;i++){ - page += getInfoData(infoids[i]); - } + //@todo convert to enum + #ifdef ESP8266 + String infoids[] = { + F("esphead"), + F("uptime"), + F("chipid"), + F("fchipid"), + F("idesize"), + F("flashsize"), + F("sdkver"), + F("corever"), + F("bootver"), + F("cpufreq"), + F("freeheap"), + F("memsketch"), + F("memsmeter"), + F("lastreset"), + F("wifihead"), + F("apip"), + F("apmac"), + F("apssid"), + F("apbssid"), + F("staip"), + F("stagw"), + F("stasub"), + F("dnss"), + F("host"), + F("stamac"), + F("conx"), + F("autoconx") + }; + + for(int i=0; i<25;i++){ + if(infoids[i] != NULL) page += getInfoData(infoids[i]); + } + page += F(""); + + #elif defined(ESP32) + String infoids[] = { + F("esphead"), + F("uptime"), + F("chipid"), + F("chiprev"), // esp32 + // "fchipid)", //esp8266 + F("idesize"), //esp8266 + // "flashsize)", //esp8266 + F("sdkver"), + // "corever)", //esp8266 + // "bootver)", //esp8266 + F("cpufreq"), + F("freeheap"), + // "memsketch)", //esp8266 + // "memsmeter)", //esp8266 + F("lastreset"), //esp8266 + F("wifihead"), + F("apip"), + F("apmac"), + F("apssid"), + F("apbssid"), + F("staip"), + F("stagw"), + F("stasub"), + F("dnss"), + F("host"), + F("stamac"), + F("conx"), + F("autoconx") + }; + + for(int i=0; i<19;i++){ + if(infoids[i] != NULL) page += getInfoData(infoids[i]); + } + page += F(""); + #endif - page += F(""); page += FPSTR(HTTP_ERASEBTN); page += FPSTR(HTTP_HELP); page += FPSTR(HTTP_END); @@ -970,29 +1025,47 @@ String WiFiManager::getInfoData(String id){ p = FPSTR(HTTP_INFO_chipid); p.replace(FPSTR(T_1),(String)WIFI_getChipId()); } + else if(id==F("chiprev")){ + #ifdef ESP32 + p = FPSTR(HTTP_INFO_chiprev); + p.replace(FPSTR(T_1),(String)ESP.getChipRevision()); + #endif + } else if(id==F("fchipid")){ - p = FPSTR(HTTP_INFO_fchipid); - p.replace(FPSTR(T_1),(String)ESP.getFlashChipId()); + #ifdef ESP8266 + p = FPSTR(HTTP_INFO_fchipid); + p.replace(FPSTR(T_1),(String)ESP.getFlashChipId()); + #endif } else if(id==F("idesize")){ p = FPSTR(HTTP_INFO_idesize); p.replace(FPSTR(T_1),(String)ESP.getFlashChipSize()); } else if(id==F("flashsize")){ - p = FPSTR(HTTP_INFO_flashsize); - p.replace(FPSTR(T_1),(String)ESP.getFlashChipRealSize()); + #ifdef ESP8266 + p = FPSTR(HTTP_INFO_flashsize); + p.replace(FPSTR(T_1),(String)ESP.getFlashChipRealSize()); + #endif } else if(id==F("sdkver")){ p = FPSTR(HTTP_INFO_sdkver); + #ifdef ESP32 + p.replace(FPSTR(T_1),(String)esp_get_idf_version()); + #else p.replace(FPSTR(T_1),(String)system_get_sdk_version()); + #endif } else if(id==F("corever")){ - p = FPSTR(HTTP_INFO_corever); - p.replace(FPSTR(T_1),(String)ESP.getCoreVersion()); + #ifdef ESP8266 + p = FPSTR(HTTP_INFO_corever); + p.replace(FPSTR(T_1),(String)ESP.getCoreVersion()); + #endif } else if(id==F("bootver")){ - p = FPSTR(HTTP_INFO_bootver); - p.replace(FPSTR(T_1),(String)system_get_boot_version()); + #ifdef ESP8266 + p = FPSTR(HTTP_INFO_bootver); + p.replace(FPSTR(T_1),(String)system_get_boot_version()); + #endif } else if(id==F("cpufreq")){ p = FPSTR(HTTP_INFO_cpufreq); @@ -1003,18 +1076,51 @@ String WiFiManager::getInfoData(String id){ p.replace(FPSTR(T_1),(String)ESP.getFreeHeap()); } else if(id==F("memsketch")){ + #ifdef ESP8266 p = FPSTR(HTTP_INFO_memsketch); p.replace(FPSTR(T_1),(String)(ESP.getSketchSize())); p.replace(FPSTR(T_2),(String)(ESP.getSketchSize()+ESP.getFreeSketchSpace())); + #endif } else if(id==F("memsmeter")){ + #ifdef ESP8266 p = FPSTR(HTTP_INFO_memsmeter); p.replace(FPSTR(T_1),(String)(ESP.getSketchSize())); p.replace(FPSTR(T_2),(String)(ESP.getSketchSize()+ESP.getFreeSketchSpace())); + #endif } else if(id==F("lastreset")){ - p = FPSTR(HTTP_INFO_lastreset); - p.replace(FPSTR(T_1),(String)ESP.getResetReason()); + #ifdef ESP8266 + p = FPSTR(HTTP_INFO_lastreset); + p.replace(FPSTR(T_1),(String)ESP.getResetReason()); + #elif defined(ESP32) && defined(_ROM_RTC_H_) + // requires #include + p = FPSTR(HTTP_INFO_lastreset); + for(int i=0;i<2;i++){ + int reason = rtc_get_reset_reason(i); + String tok = (String)T_ss+(String)(i+1)+(String)T_es; + switch (reason) + { + //@todo move to array + case 1 : p.replace(tok,F("Vbat power on reset"));break; + case 3 : p.replace(tok,F("Software reset digital core"));break; + case 4 : p.replace(tok,F("Legacy watch dog reset digital core"));break; + case 5 : p.replace(tok,F("Deep Sleep reset digital core"));break; + case 6 : p.replace(tok,F("Reset by SLC module, reset digital core"));break; + case 7 : p.replace(tok,F("Timer Group0 Watch dog reset digital core"));break; + case 8 : p.replace(tok,F("Timer Group1 Watch dog reset digital core"));break; + case 9 : p.replace(tok,F("RTC Watch dog Reset digital core"));break; + case 10 : p.replace(tok,F("Instrusion tested to reset CPU"));break; + case 11 : p.replace(tok,F("Time Group reset CPU"));break; + case 12 : p.replace(tok,F("Software reset CPU"));break; + case 13 : p.replace(tok,F("RTC Watch dog Reset CPU"));break; + case 14 : p.replace(tok,F("for APP CPU, reseted by PRO CPU"));break; + case 15 : p.replace(tok,F("Reset when the vdd voltage is not stable"));break; + case 16 : p.replace(tok,F("RTC Watch dog reset digital core and rtc module"));break; + default : p.replace(tok,F("NO_MEAN")); + } + } + #endif } else if(id==F("apip")){ p = FPSTR(HTTP_INFO_apip); @@ -1026,7 +1132,7 @@ String WiFiManager::getInfoData(String id){ } else if(id==F("apssid")){ p = FPSTR(HTTP_INFO_apssid); - p.replace(FPSTR(T_1),(String)WiFi.SSID()); + p.replace(FPSTR(T_1),(String)WiFi_SSID()); } else if(id==F("apbssid")){ p = FPSTR(HTTP_INFO_apbssid); @@ -1050,7 +1156,11 @@ String WiFiManager::getInfoData(String id){ } else if(id==F("host")){ p = FPSTR(HTTP_INFO_host); + #ifdef ESP32 + p.replace(FPSTR(T_1),WiFi.getHostname()); + #else p.replace(FPSTR(T_1),WiFi.hostname()); + #endif } else if(id==F("stamac")){ p = FPSTR(HTTP_INFO_stamac); @@ -1064,7 +1174,6 @@ String WiFiManager::getInfoData(String id){ p = FPSTR(HTTP_INFO_autoconx); p.replace(FPSTR(T_1),WiFi.getAutoConnect() ? FPSTR(S_enable) : FPSTR(S_disable)); } - return p; } @@ -1174,15 +1283,15 @@ boolean WiFiManager::captivePortal() { void WiFiManager::reportStatus(String &page){ String str; - if (WiFi.SSID() != ""){ + if (WiFi_SSID() != ""){ if (WiFi.status()==WL_CONNECTED){ str = FPSTR(HTTP_STATUS_ON); str.replace(FPSTR(T_i),WiFi.localIP().toString()); - str.replace(FPSTR(T_v),WiFi.SSID()); + str.replace(FPSTR(T_v),WiFi_SSID()); } else { str = FPSTR(HTTP_STATUS_OFF); - str.replace(FPSTR(T_v),WiFi.SSID()); + str.replace(FPSTR(T_v),WiFi_SSID()); } } else { @@ -1191,7 +1300,6 @@ void WiFiManager::reportStatus(String &page){ page += str; } - // MORE SETTERS //start up config portal callback @@ -1233,6 +1341,10 @@ void WiFiManager::setCaptivePortalEnable(boolean enabled){ _enableCaptivePortal = enabled; } +void WiFiManager::setWiFiAutoReconnect(boolean enabled){ + _wifiAutoReconnect = enabled; +} + void WiFiManager::setCaptivePortalClientCheck(boolean enabled){ _cpClientCheck = enabled; } @@ -1276,8 +1388,14 @@ void WiFiManager::DEBUG_WM(Generic text,Genericb textb) { } void WiFiManager::debugSoftAPConfig(){ - softap_config config; - wifi_softap_get_config(&config); + #ifdef ESP8266 + softap_config config; + wifi_softap_get_config(&config); + #elif defined(ESP32) + wifi_config_t conf_config; + esp_wifi_get_config(WIFI_IF_AP, &conf_config); // == ESP_OK + wifi_ap_config_t config = conf_config.ap; + #endif DEBUG_WM(F("SoftAP Configuration")); DEBUG_WM(FPSTR(D_HR)); @@ -1293,11 +1411,17 @@ void WiFiManager::debugSoftAPConfig(){ } void WiFiManager::debugPlatformInfo(){ + #ifdef ESP8266 system_print_meminfo(); DEBUG_WM(F("getCoreVersion(): "),ESP.getCoreVersion()); DEBUG_WM(F("system_get_sdk_version(): "),system_get_sdk_version()); DEBUG_WM(F("system_get_boot_version():"),system_get_boot_version()); DEBUG_WM(F("getFreeHeap(): "),(String)ESP.getFreeHeap()); + #elif defined(ESP32) + size_t freeHeap = heap_caps_get_free_size(MALLOC_CAP_8BIT); + DEBUG_WM("Free heap: ", freeHeap); + DEBUG_WM("ESP-IDF version: ", esp_get_idf_version()); + #endif } int WiFiManager::getRSSIasQuality(int RSSI) { @@ -1355,34 +1479,26 @@ String WiFiManager::getWLStatusString(uint8_t status){ } String WiFiManager::encryptionTypeStr(uint8_t authmode) { - switch(authmode) { - case ENC_TYPE_NONE: - return F("None"); - case ENC_TYPE_WEP: - return F("WEP"); - case ENC_TYPE_TKIP: - return F("WPA_PSK"); - case ENC_TYPE_CCMP: - return F("WPA2_PSK"); - case ENC_TYPE_AUTO: - return F("WPA_WPA2_PSK"); - default: - return FPSTR(S_NA); - } + // DEBUG_WM("enc_tye: ",authmode); + return AUTH_MODE_NAMES[authmode]; } // set mode ignores WiFi.persistent bool WiFiManager::WiFi_Mode(WiFiMode_t m,bool persistent) { - if((wifi_get_opmode() == (uint8) m ) && !persistent) { - return true; - } - bool ret; - ETS_UART_INTR_DISABLE(); - if(persistent) ret = wifi_set_opmode(m); - else ret = wifi_set_opmode_current(m); - ETS_UART_INTR_ENABLE(); + #ifdef ESP8266 + if((wifi_get_opmode() == (uint8) m ) && !persistent) { + return true; + } + bool ret; + ETS_UART_INTR_DISABLE(); + if(persistent) ret = wifi_set_opmode(m); + else ret = wifi_set_opmode_current(m); + ETS_UART_INTR_ENABLE(); - return ret; + return ret; + #elif defined(ESP32) + return WiFi.mode(m); // @todo persistent not implemented? + #endif } bool WiFiManager::WiFi_Mode(WiFiMode_t m) { return WiFi_Mode(m,false); @@ -1394,53 +1510,116 @@ bool WiFiManager::disconnect(){ // sta disconnect without persistent bool WiFiManager::WiFi_Disconnect() { - if((WiFi.getMode() & WIFI_STA) != 0) { - bool ret; - DEBUG_WM(F("wifi station disconnect")); - ETS_UART_INTR_DISABLE(); - ret = wifi_station_disconnect(); - ETS_UART_INTR_ENABLE(); - return ret; - } + #ifdef ESP8266 + if((WiFi.getMode() & WIFI_STA) != 0) { + bool ret; + DEBUG_WM(F("wifi station disconnect")); + ETS_UART_INTR_DISABLE(); + ret = wifi_station_disconnect(); + ETS_UART_INTR_ENABLE(); + return ret; + } + #elif defined(ESP32) + DEBUG_WM(F("wifi station disconnect")); + // @todo why does disconnect call these, might be needed + // WiFi.getMode(); // @todo wifiLowLevelInit(), probably not needed, for save config only + // esp_wifi_start(); // @todo can only disconnect if enabled perhaps, prevent failure, or correct for previous call ? + return esp_wifi_disconnect() == ESP_OK; + // return WiFi.disconnect(); + #endif } // toggle STA without persistent bool WiFiManager::WiFi_enableSTA(bool enable,bool persistent) { - + WiFiMode_t newMode; WiFiMode_t currentMode = WiFi.getMode(); - bool isEnabled = ((currentMode & WIFI_STA) != 0); + bool isEnabled = (currentMode & WIFI_STA) != 0; + if(enable) newMode = (WiFiMode_t)(currentMode | WIFI_STA); + else newMode = (WiFiMode_t)(currentMode & (~WIFI_STA)); - if((isEnabled != enable) || persistent) { - if(enable) { - if(persistent) DEBUG_WM(F("enableSTA PERSISTENT ON")); - return WiFi_Mode((WiFiMode_t)(currentMode | WIFI_STA),persistent); - } else { - return WiFi_Mode((WiFiMode_t)(currentMode & (~WIFI_STA)),persistent); - } - } else { - return true; - } + #ifdef ESP8266 + if((isEnabled != enable) || persistent) { + if(enable) { + if(persistent) DEBUG_WM(F("enableSTA PERSISTENT ON")); + return WiFi_Mode(newMode,persistent); + } else { + return WiFi_Mode(newMode,persistent); + } + } else { + return true; + } + #elif defined(ESP32) + return WiFi.mode(newMode); // @todo persistent not implemented? + #endif } bool WiFiManager::WiFi_enableSTA(bool enable) { return WiFi_enableSTA(enable,false); } -// erase config BUG polyfill -// https://github.com/esp8266/Arduino/pull/3635 bool WiFiManager::WiFi_eraseConfig(void) { - // return ESP.eraseConfig(); + #ifdef ESP8266 + return ESP.eraseConfig(); + // https://github.com/esp8266/Arduino/pull/3635 + // erase config BUG polyfill + // const size_t cfgSize = 0x4000; + // size_t cfgAddr = ESP.getFlashChipSize() - cfgSize; - const size_t cfgSize = 0x4000; - size_t cfgAddr = ESP.getFlashChipSize() - cfgSize; - - for (size_t offset = 0; offset < cfgSize; offset += SPI_FLASH_SEC_SIZE) { - if (!ESP.flashEraseSector((cfgAddr + offset) / SPI_FLASH_SEC_SIZE)) { - return false; - } - } - return true; + // for (size_t offset = 0; offset < cfgSize; offset += SPI_FLASH_SEC_SIZE) { + // if (!ESP.flashEraseSector((cfgAddr + offset) / SPI_FLASH_SEC_SIZE)) { + // return false; + // } + // } + // return true; + #elif defined(ESP32) + WiFi.mode(WIFI_AP_STA); // cannot erase if not in STA mode + return WiFi.disconnect(true); + #endif } void WiFiManager::reboot(){ ESP.restart(); +} + +uint8_t WiFiManager::WiFi_softap_num_stations(){ + #ifdef ESP8266 + return wifi_softap_get_station_num(); + #elif defined(ESP32) + return WiFi.softAPgetStationNum(); + #endif +} + +bool WiFiManager::WiFi_hasAutoConnect(){ + return WiFi_SSID() != ""; +} + +String WiFiManager::WiFi_SSID(){ + #ifdef ESP8266 + return WiFi.SSID(); + #elif defined(ESP32) + wifi_config_t conf; + esp_wifi_get_config(WIFI_IF_STA, &conf); + return String(reinterpret_cast(conf.sta.ssid)); + #endif +} + +void WiFiManager::WiFiEvent(WiFiEvent_t event){ + #ifdef ESP32 + WiFiManager _WiFiManager; + if(event == SYSTEM_EVENT_STA_DISCONNECTED){ + // Serial.println("Event: SYSTEM_EVENT_STA_DISCONNECTED, reconnecting"); + _WiFiManager.DEBUG_WM("ESP32 Event: SYSTEM_EVENT_STA_DISCONNECTED, reconnecting"); // @todo remove debugging from prod, or change static method + WiFi.reconnect(); + } + #endif +} + +void WiFiManager::WiFi_autoReconnect(){ + #ifdef ESP8266 + WiFi.setAutoReconnect(_wifiAutoReconnect); + #elif defined(ESP32) + if(_wifiAutoReconnect){ + DEBUG_WM("ESP32 autoreconnect handler enabled"); + WiFi.onEvent(WiFiEvent); + } + #endif } \ No newline at end of file diff --git a/WiFiManager.h b/WiFiManager.h index a8f8dc6..25f99b7 100644 --- a/WiFiManager.h +++ b/WiFiManager.h @@ -13,25 +13,45 @@ #ifndef WiFiManager_h #define WiFiManager_h -#if defined(ESP8266) - #include - #include +#define WEBSERVERSHIM // use webserver shim lib + +#ifdef ESP8266 + + extern "C" { + #include "user_interface.h" + } + #include + #include + + #define WIFI_getChipId() ESP.getChipId() + #define WIFI_AUTH_OPEN ENC_TYPE_NONE + +#elif defined(ESP32) + + #include + #include + + #define WIFI_getChipId() (uint32_t)ESP.getEfuseMac() + #define WIFI_AUTH_OPEN WIFI_AUTH_OPEN + + #ifndef WEBSERVER_H + #warning "WEBSERVER not implemented in espressif/esp32, see readme notes" + #ifdef WEBSERVERSHIM + #include + #else + #include + // Forthcoming official + // https://github.com/esp8266/ESPWebServer + #endif + #endif + +#else #endif #include #include - -#if defined(ESP8266) - extern "C" { - #include "user_interface.h" - } -#endif - #include "strings_en.h" -#define WIFI_getChipId() ESP.getChipId() -#define WIFI_AUTH_OPEN ENC_TYPE_NONE - #ifndef WIFI_MANAGER_MAX_PARAMS #define WIFI_MANAGER_MAX_PARAMS 5 // params will autoincrement and realloc by this amount when max is reached #endif @@ -137,6 +157,8 @@ class WiFiManager void setCaptivePortalClientCheck(boolean enabled); //if true, reset timeout when webclient connects (true), suggest disabling if captiveportal is open void setWebPortalClientCheck(boolean enabled); + // if true enable autoreconnecting + void setWiFiAutoReconnect(boolean enabled); // if true, wifiscan will show percentage instead of quality icons, until we have better templating void setScanDispPerc(boolean enabled); @@ -145,8 +167,15 @@ class WiFiManager private: std::unique_ptr dnsServer; - std::unique_ptr server; + #if defined(ESP32) && defined(WEBSERVERSHIM) + std::unique_ptr server; + #else + std::unique_ptr server; + #endif + + //const int WM_DONE = 0; + //const int WM_WAIT = 10; // ip configs IPAddress _ap_static_ip; IPAddress _ap_static_gw; @@ -168,6 +197,8 @@ class WiFiManager unsigned long _configPortalStart = 0; unsigned long _webPortalAccessed = 0; WiFiMode_t _usermode = WIFI_OFF; + + String _wifissidprefix = FPSTR(S_ssidpre); // option parameters int _minimumQuality = -1; @@ -178,6 +209,7 @@ class WiFiManager boolean _staShowStaticFields = false; boolean _enableCaptivePortal = true; boolean _userpersistent = true; + boolean _wifiAutoReconnect = true; // there is no getter for this, we must assume its true and make it so boolean _cpClientCheck = false; // keep cp alive if cp have station boolean _webClientCheck = true; // keep cp alive if web have client boolean _scanDispOptions = false; // show percentage in scans not icons @@ -217,7 +249,14 @@ class WiFiManager bool WiFi_enableSTA(bool enable); bool WiFi_enableSTA(bool enable,bool persistent); bool WiFi_eraseConfig(); + uint8_t WiFi_softap_num_stations(); + bool WiFi_hasAutoConnect(); + void WiFi_autoReconnect(); + String WiFi_SSID(); + static void WiFiEvent(WiFiEvent_t event); + + // output helpers String getParamOut(); String getIpForm(String id, String title, String value); diff --git a/examples/AutoConnect/AutoConnect.ino b/examples/AutoConnect/AutoConnect.ino index 0c44909..0f58900 100644 --- a/examples/AutoConnect/AutoConnect.ino +++ b/examples/AutoConnect/AutoConnect.ino @@ -1,10 +1,4 @@ -#include //https://github.com/esp8266/Arduino - -//needed for library -#include -#include -#include //https://github.com/tzapu/WiFiManager - +#include // https://github.com/tzapu/WiFiManager void setup() { // put your setup code here, to run once: diff --git a/examples/AutoConnectWithFSParameters/AutoConnectWithFSParameters.ino b/examples/AutoConnectWithFSParameters/AutoConnectWithFSParameters.ino index 1891808..d46729c 100644 --- a/examples/AutoConnectWithFSParameters/AutoConnectWithFSParameters.ino +++ b/examples/AutoConnectWithFSParameters/AutoConnectWithFSParameters.ino @@ -1,13 +1,6 @@ -#include //this needs to be first, or it all crashes and burns... - -#include //https://github.com/esp8266/Arduino - -//needed for library -#include -#include -#include //https://github.com/tzapu/WiFiManager - -#include //https://github.com/bblanchon/ArduinoJson +#include // this needs to be first, or it all crashes and burns... +#include // https://github.com/tzapu/WiFiManager +#include // https://github.com/bblanchon/ArduinoJson //define your default values here, if there are different values in config.json, they are overwritten. char mqtt_server[40]; @@ -112,7 +105,7 @@ void setup() { Serial.println("failed to connect and hit timeout"); delay(3000); //reset and try again, or maybe put it to deep sleep - ESP.reset(); + ESP.restart(); delay(5000); } diff --git a/examples/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino b/examples/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino index 135b99f..9392499 100644 --- a/examples/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino +++ b/examples/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino @@ -1,13 +1,6 @@ -#include //this needs to be first, or it all crashes and burns... - -#include //https://github.com/esp8266/Arduino - -//needed for library -#include -#include -#include //https://github.com/tzapu/WiFiManager - -#include //https://github.com/bblanchon/ArduinoJson +#include // this needs to be first, or it all crashes and burns... +#include // https://github.com/tzapu/WiFiManager +#include // https://github.com/bblanchon/ArduinoJson //define your default values here, if there are different values in config.json, they are overwritten. //length should be max size + 1 @@ -139,7 +132,7 @@ void setup() { Serial.println("failed to connect and hit timeout"); delay(3000); //reset and try again, or maybe put it to deep sleep - ESP.reset(); + ESP.restart(); delay(5000); } diff --git a/examples/AutoConnectWithFeedback/AutoConnectWithFeedback.ino b/examples/AutoConnectWithFeedback/AutoConnectWithFeedback.ino index 9491760..d3c4ed8 100644 --- a/examples/AutoConnectWithFeedback/AutoConnectWithFeedback.ino +++ b/examples/AutoConnectWithFeedback/AutoConnectWithFeedback.ino @@ -1,9 +1,4 @@ -#include //https://github.com/esp8266/Arduino - -//needed for library -#include -#include -#include "WiFiManager.h" //https://github.com/tzapu/WiFiManager +#include // https://github.com/tzapu/WiFiManager void configModeCallback (WiFiManager *myWiFiManager) { Serial.println("Entered config mode"); @@ -32,7 +27,7 @@ void setup() { if(!wifiManager.autoConnect()) { Serial.println("failed to connect and hit timeout"); //reset and try again, or maybe put it to deep sleep - ESP.reset(); + ESP.restart(); delay(1000); } diff --git a/examples/AutoConnectWithFeedbackLED/AutoConnectWithFeedbackLED.ino b/examples/AutoConnectWithFeedbackLED/AutoConnectWithFeedbackLED.ino index 77b264b..df74e42 100644 --- a/examples/AutoConnectWithFeedbackLED/AutoConnectWithFeedbackLED.ino +++ b/examples/AutoConnectWithFeedbackLED/AutoConnectWithFeedbackLED.ino @@ -1,9 +1,4 @@ -#include //https://github.com/esp8266/Arduino - -//needed for library -#include -#include -#include //https://github.com/tzapu/WiFiManager +#include // https://github.com/tzapu/WiFiManager //for LED status #include @@ -51,7 +46,7 @@ void setup() { if (!wifiManager.autoConnect()) { Serial.println("failed to connect and hit timeout"); //reset and try again, or maybe put it to deep sleep - ESP.reset(); + ESP.restart(); delay(1000); } diff --git a/examples/AutoConnectWithReset/AutoConnectWithReset.ino b/examples/AutoConnectWithReset/AutoConnectWithReset.ino index 5af3b1f..53a0d13 100644 --- a/examples/AutoConnectWithReset/AutoConnectWithReset.ino +++ b/examples/AutoConnectWithReset/AutoConnectWithReset.ino @@ -1,11 +1,5 @@ -#include //this needs to be first, or it all crashes and burns... - -#include //https://github.com/esp8266/Arduino - -//needed for library -#include -#include -#include //https://github.com/tzapu/WiFiManager +#include // this needs to be first, or it all crashes and burns... +#include // https://github.com/tzapu/WiFiManager void setup() { // put your setup code here, to run once: @@ -30,7 +24,7 @@ void setup() { if (!wifiManager.autoConnect("AutoConnectAP", "password")) { Serial.println("failed to connect, we should reset as see if it connects"); delay(3000); - ESP.reset(); + ESP.restart(); delay(5000); } diff --git a/examples/AutoConnectWithStaticIP/AutoConnectWithStaticIP.ino b/examples/AutoConnectWithStaticIP/AutoConnectWithStaticIP.ino index 86556d3..9f88e47 100644 --- a/examples/AutoConnectWithStaticIP/AutoConnectWithStaticIP.ino +++ b/examples/AutoConnectWithStaticIP/AutoConnectWithStaticIP.ino @@ -1,12 +1,5 @@ -#include //this needs to be first, or it all crashes and burns... - -#include //https://github.com/esp8266/Arduino - -//needed for library -#include -#include -#include //https://github.com/tzapu/WiFiManager - +#include // this needs to be first, or it all crashes and burns... +#include // https://github.com/tzapu/WiFiManager /************************************************************************************** * this example shows how to set a static IP configuration for the ESP @@ -15,9 +8,7 @@ * if you want the ability to configure and persist the new IP configuration * look at the FS examples, which save the config to file *************************************************************************************/ - - - + //default custom static IP //char static_ip[16] = "10.0.1.59"; //char static_gw[16] = "10.0.1.1"; @@ -61,7 +52,7 @@ void setup() { if (!wifiManager.autoConnect("AutoConnectAP", "password")) { Serial.println("failed to connect, we should reset as see if it connects"); delay(3000); - ESP.reset(); + ESP.restart(); delay(5000); } diff --git a/examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino b/examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino index da77cbe..9df428d 100644 --- a/examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino +++ b/examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino @@ -1,11 +1,4 @@ -#include //https://github.com/esp8266/Arduino - -//needed for library -#include -#include -#include //https://github.com/tzapu/WiFiManager - - +#include // https://github.com/tzapu/WiFiManager void setup() { // put your setup code here, to run once: @@ -30,7 +23,7 @@ void setup() { Serial.println("failed to connect and hit timeout"); delay(3000); //reset and try again, or maybe put it to deep sleep - ESP.reset(); + ESP.restart(); delay(5000); } diff --git a/examples/OnDemandConfigPortal/OnDemandConfigPortal.ino b/examples/OnDemandConfigPortal/OnDemandConfigPortal.ino index 435deac..0b80f51 100644 --- a/examples/OnDemandConfigPortal/OnDemandConfigPortal.ino +++ b/examples/OnDemandConfigPortal/OnDemandConfigPortal.ino @@ -1,14 +1,10 @@ -#include //https://github.com/esp8266/Arduino - -//needed for library -#include -#include -#include //https://github.com/tzapu/WiFiManager +#include // https://github.com/tzapu/WiFiManager // select which pin will trigger the configuration portal when set to LOW // ESP-01 users please note: the only pins available (0 and 2), are shared // with the bootloader, so always set them HIGH at power-up #define TRIGGER_PIN 0 +const char* modes[] = { "NULL", "STA", "AP", "STA+AP" }; void setup() { @@ -16,6 +12,28 @@ void setup() { Serial.begin(115200); Serial.println("\n Starting"); + Serial.setDebugOutput(true); + Serial.println(modes[WiFi.getMode()]); + WiFi.printDiag(Serial); + + //Local intialization. Once its business is done, there is no need to keep it around + WiFiManager wifiManager; + //reset settings - for testing + //wifiManager.resetSettings(); + + //sets timeout until configuration portal gets turned off + //useful to make it all retry or go to sleep + //in seconds + wifiManager.setConfigPortalTimeout(180); + + //fetches ssid and pass and tries to connect + //if it does not connect it starts an access point with the specified name + //here "AutoConnectAP" + //and goes into a blocking loop awaiting configuration + if(!wifiManager.autoConnect("AutoConnectAP","12345678")) { + Serial.println("failed to connect and hit timeout"); + } + pinMode(TRIGGER_PIN, INPUT); } diff --git a/examples/OnDemandWebPortal/OnDemandWebPortal.ino b/examples/OnDemandWebPortal/OnDemandWebPortal.ino index 50f5657..b45e4a0 100644 --- a/examples/OnDemandWebPortal/OnDemandWebPortal.ino +++ b/examples/OnDemandWebPortal/OnDemandWebPortal.ino @@ -4,23 +4,13 @@ * trigger pin will start a webportal for 120 seconds then turn it off. * */ - -#include //https://github.com/esp8266/Arduino - -//needed for library -#include -#include -#include //https://github.com/tzapu/WiFiManager +#include // https://github.com/tzapu/WiFiManager // select which pin will trigger the configuration portal when set to LOW // ESP-01 users please note: the only pins available (0 and 2), are shared // with the bootloader, so always set them HIGH at power-up #define TRIGGER_PIN 0 -// set your ap credentials -const char *ssid = "********"; -const char *password = "********"; - int timeout = 120; // seconds WiFiManager wifiManager; diff --git a/library.json b/library.json index 44400f6..99b43c3 100644 --- a/library.json +++ b/library.json @@ -8,6 +8,10 @@ "url": "https://github.com/tzapu/WiFiManager.git" }, "frameworks": "arduino", - "platforms": "espressif8266", + "platforms": + [ + "espressif8266", + "espressif32" + ], "version": "0.12" } diff --git a/library.properties b/library.properties index 2466f0d..382a56a 100644 --- a/library.properties +++ b/library.properties @@ -2,8 +2,8 @@ name=WiFiManager version=0.12 author=tzapu maintainer=tzapu -sentence=ESP8266 WiFi Connection manager with fallback web configuration portal +sentence=WiFi Connection manager with fallback web configuration portal for ESP boards paragraph=Library for configuring ESP8266 modules WiFi credentials at runtime. category=Communication url=https://github.com/tzapu/WiFiManager.git -architectures=esp8266 +architectures=esp8266,esp32 diff --git a/strings_en.h b/strings_en.h index 01ae48e..a6c058a 100644 --- a/strings_en.h +++ b/strings_en.h @@ -97,22 +97,28 @@ const char HTTP_JS[] PROGMEM = #endif // Info html -const char HTTP_INFO_esphead[] PROGMEM = "

esp8266


"; -const char HTTP_INFO_wifihead[] PROGMEM = "

WiFi


"; +#ifdef ESP32 + const char HTTP_INFO_esphead[] PROGMEM = "

esp32


"; + const char HTTP_INFO_chiprev[] PROGMEM = "
Chip Rev
{1}
"; + const char HTTP_INFO_lastreset[] PROGMEM = "
Last reset reason
CPU0: {1}
CPU1: {2}
"; +#else + const char HTTP_INFO_esphead[] PROGMEM = "

esp8266


"; + const char HTTP_INFO_flashsize[] PROGMEM = "
Real Flash Size
{1} bytes
"; + const char HTTP_INFO_fchipid[] PROGMEM = "
Flash Chip ID
{1}
"; + const char HTTP_INFO_corever[] PROGMEM = "
Core Version
{1}
"; + const char HTTP_INFO_bootver[] PROGMEM = "
Boot Version
{1}
"; + const char HTTP_INFO_memsketch[] PROGMEM = "
Memory - Sketch Size
Used / Total bytes
{1} / {2}"; + const char HTTP_INFO_memsmeter[] PROGMEM = "
"; + const char HTTP_INFO_lastreset[] PROGMEM = "
Last reset reason
{1}
"; +#endif +const char HTTP_INFO_freeheap[] PROGMEM = "
Memory - Free Heap
{1} bytes available
"; +const char HTTP_INFO_wifihead[] PROGMEM = "

WiFi


"; const char HTTP_INFO_uptime[] PROGMEM = "
Uptime
{1} Mins {2} Secs
"; const char HTTP_INFO_chipid[] PROGMEM = "
Chip ID
{1}
"; -const char HTTP_INFO_fchipid[] PROGMEM = "
Flash Chip ID
{1}
"; -const char HTTP_INFO_idesize[] PROGMEM = "
IDE Flash Size
{1} bytes
"; -const char HTTP_INFO_flashsize[] PROGMEM = "
Actual Flash Size
{1} bytes
"; +const char HTTP_INFO_idesize[] PROGMEM = "
Flash Size
{1} bytes
"; const char HTTP_INFO_sdkver[] PROGMEM = "
SDK Version
{1}
"; -const char HTTP_INFO_corever[] PROGMEM = "
Core Version
{1}
"; -const char HTTP_INFO_bootver[] PROGMEM = "
Boot Version
{1}
"; const char HTTP_INFO_cpufreq[] PROGMEM = "
CPU Frequency
{1}MHz
"; -const char HTTP_INFO_freeheap[] PROGMEM = "
Memory - Free Heap
{1} bytes available
"; -const char HTTP_INFO_memsketch[] PROGMEM = "
Memory - Sketch Size
Used / Total bytes
{1} / {2}"; -const char HTTP_INFO_memsmeter[] PROGMEM = "
"; -const char HTTP_INFO_lastreset[] PROGMEM = "
Last reset reason
{1}
"; const char HTTP_INFO_apip[] PROGMEM = "
Access Point IP
{1}
"; const char HTTP_INFO_apmac[] PROGMEM = "
Access Point MAC
{1}
"; const char HTTP_INFO_apssid[] PROGMEM = "
SSID
{1}
"; @@ -168,8 +174,19 @@ const char S_ip[] PROGMEM = "ip"; const char S_gw[] PROGMEM = "gw"; const char S_sn[] PROGMEM = "sn"; +// softap ssid default prefix +#ifdef ESP8266 + const char S_ssidpre[] PROGMEM = "ESP"; +#elif defined(ESP32) + const char S_ssidpre[] PROGMEM = "ESP32"; +#else + const char S_ssidpre[] PROGMEM = "WM"; +#endif + //Tokens //@todo consolidate and reduce +const char T_ss[] PROGMEM = "{"; // token start sentinel +const char T_es[] PROGMEM = "}"; // token end sentinel const char T_1[] PROGMEM = "{1}"; // @token 1 const char T_2[] PROGMEM = "{2}"; // @token 2 const char T_v[] PROGMEM = "{v}"; // @token v @@ -200,3 +217,29 @@ const char * const WIFI_STA_STATUS[] PROGMEM "WL_CONNECTION_LOST", "WL_DISCONNECTED" }; + +#ifdef ESP32 +const char * const AUTH_MODE_NAMES[] PROGMEM +{ + "OPEN", + "WEP", + "WPA_PSK", + "WPA2_PSK", + "WPA_WPA2_PSK", + "WPA2_ENTERPRISE", + "MAX" +}; +#elif defined(ESP8266) +const char * const AUTH_MODE_NAMES[] PROGMEM +{ + "", + "", + "WPA_PSK", // 2 ENC_TYPE_TKIP + "", + "WPA2_PSK", // 4 ENC_TYPE_CCMP + "WEP", // 5 ENC_TYPE_WEP + "", + "OPEN", //7 ENC_TYPE_NONE + "WPA_WPA2_PSK", // 8 ENC_TYPE_AUTO +}; +#endif \ No newline at end of file