/**************************************************************************************************************************** ESP_WiFiManager-Impl.h For ESP8266 / ESP32 boards ESP_WiFiManager is a library for the ESP8266/Arduino platform (https://github.com/esp8266/Arduino) to enable easy configuration and reconfiguration of WiFi credentials using a Captive Portal inspired by: http://www.esp8266.com/viewtopic.php?f=29&t=2520 https://github.com/chriscook8/esp-arduino-apboot https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/ Modified from Tzapu https://github.com/tzapu/WiFiManager and from Ken Taylor https://github.com/kentaylor Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager Licensed under MIT license Version: 1.11.0 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 07/10/2019 Initial coding ... 1.8.0 K Hoang 29/12/2021 Fix `multiple-definitions` linker error and weird bug related to src_cpp 1.9.0 K Hoang 17/01/2022 Enable compatibility with old code to include only ESP_WiFiManager.h 1.10.0 K Hoang 10/02/2022 Add support to new ESP32-S3 1.10.1 K Hoang 11/02/2022 Add LittleFS support to ESP32-C3. Use core LittleFS instead of Lorol's LITTLEFS for v2.0.0+ 1.10.2 K Hoang 13/03/2022 Send CORS header in handleWifiSave() function 1.11.0 K Hoang 09/09/2022 Fix ESP32 chipID and add ESP_getChipOUI() *****************************************************************************************************************************/ #pragma once #ifndef ESP_WiFiManager_Impl_h #define ESP_WiFiManager_Impl_h ////////////////////////////////////////// ESP_WMParameter::ESP_WMParameter(const char *custom) { _WMParam_data._id = NULL; _WMParam_data._placeholder = NULL; _WMParam_data._length = 0; _WMParam_data._value = NULL; _WMParam_data._labelPlacement = WFM_LABEL_BEFORE; _customHTML = custom; } ////////////////////////////////////////// ESP_WMParameter::ESP_WMParameter(const char *id, const char *placeholder, const char *defaultValue, const int& length, const char *custom, const int& labelPlacement) { init(id, placeholder, defaultValue, length, custom, labelPlacement); } ////////////////////////////////////////// // New in v1.4.0 ESP_WMParameter::ESP_WMParameter(const WMParam_Data& WMParam_data) { init(WMParam_data._id, WMParam_data._placeholder, WMParam_data._value, WMParam_data._length, "", WMParam_data._labelPlacement); } ////// ////////////////////////////////////////// void ESP_WMParameter::init(const char *id, const char *placeholder, const char *defaultValue, const int& length, const char *custom, const int& labelPlacement) { _WMParam_data._id = id; _WMParam_data._placeholder = placeholder; _WMParam_data._length = length; _WMParam_data._labelPlacement = labelPlacement; _WMParam_data._value = new char[_WMParam_data._length + 1]; if (_WMParam_data._value != NULL) { memset(_WMParam_data._value, 0, _WMParam_data._length + 1); if (defaultValue != NULL) { strncpy(_WMParam_data._value, defaultValue, _WMParam_data._length); } } _customHTML = custom; } ////////////////////////////////////////// ESP_WMParameter::~ESP_WMParameter() { if (_WMParam_data._value != NULL) { delete[] _WMParam_data._value; } } ////////////////////////////////////////// // New in v1.4.0 // Using Struct to get/set whole data at once void ESP_WMParameter::setWMParam_Data(const WMParam_Data& WMParam_data) { LOGINFO(F("setWMParam_Data")); memcpy(&_WMParam_data, &WMParam_data, sizeof(_WMParam_data)); } ////////////////////////////////////////// void ESP_WMParameter::getWMParam_Data(WMParam_Data &WMParam_data) { LOGINFO(F("getWMParam_Data")); memcpy(&WMParam_data, &_WMParam_data, sizeof(WMParam_data)); } ////// ////////////////////////////////////////// const char* ESP_WMParameter::getValue() { return _WMParam_data._value; } ////////////////////////////////////////// const char* ESP_WMParameter::getID() { return _WMParam_data._id; } ////////////////////////////////////////// const char* ESP_WMParameter::getPlaceholder() { return _WMParam_data._placeholder; } ////////////////////////////////////////// int ESP_WMParameter::getValueLength() { return _WMParam_data._length; } ////////////////////////////////////////// int ESP_WMParameter::getLabelPlacement() { return _WMParam_data._labelPlacement; } ////////////////////////////////////////// const char* ESP_WMParameter::getCustomHTML() { return _customHTML; } ////////////////////////////////////////// /** [getParameters description] @access public */ ESP_WMParameter** ESP_WiFiManager::getParameters() { return _params; } /** [getParametersCount description] @access public */ int ESP_WiFiManager::getParametersCount() { return _paramsCount; } ////////////////////////////////////////// char* ESP_WiFiManager::getRFC952_hostname(const char* iHostname) { memset(RFC952_hostname, 0, sizeof(RFC952_hostname)); size_t len = (RFC952_HOSTNAME_MAXLEN < strlen(iHostname)) ? RFC952_HOSTNAME_MAXLEN : strlen(iHostname); size_t j = 0; for (size_t i = 0; i < len - 1; i++) { if (isalnum(iHostname[i]) || iHostname[i] == '-') { RFC952_hostname[j] = iHostname[i]; j++; } } // no '-' as last char if (isalnum(iHostname[len - 1]) || (iHostname[len - 1] != '-')) RFC952_hostname[j] = iHostname[len - 1]; return RFC952_hostname; } ////////////////////////////////////////// ESP_WiFiManager::ESP_WiFiManager(const char *iHostname) { #if USE_DYNAMIC_PARAMS _max_params = WIFI_MANAGER_MAX_PARAMS; _params = (ESP_WMParameter**)malloc(_max_params * sizeof(ESP_WMParameter*)); #endif //WiFi not yet started here, must call WiFi.mode(WIFI_STA) and modify function WiFiGenericClass::mode(wifi_mode_t m) !!! WiFi.mode(WIFI_STA); if (iHostname[0] == 0) { #ifdef ESP8266 String _hostname = "ESP8266-" + String(ESP.getChipId(), HEX); #else //ESP32 String _hostname = "ESP32-" + String(ESP_getChipId(), HEX); #endif _hostname.toUpperCase(); getRFC952_hostname(_hostname.c_str()); } else { // Prepare and store the hostname only not NULL getRFC952_hostname(iHostname); } LOGWARN1(F("RFC925 Hostname ="), RFC952_hostname); setHostname(); networkIndices = NULL; } ////////////////////////////////////////// ESP_WiFiManager::~ESP_WiFiManager() { #if USE_DYNAMIC_PARAMS if (_params != NULL) { LOGINFO(F("freeing allocated params!")); free(_params); } #endif if (networkIndices) { free(networkIndices); //indices array no longer required so free memory } } ////////////////////////////////////////// #if USE_DYNAMIC_PARAMS bool ESP_WiFiManager::addParameter(ESP_WMParameter *p) #else void ESP_WiFiManager::addParameter(ESP_WMParameter *p) #endif { #if USE_DYNAMIC_PARAMS if (_paramsCount == _max_params) { // rezise the params array _max_params += WIFI_MANAGER_MAX_PARAMS; LOGINFO1(F("Increasing _max_params to:"), _max_params); ESP_WMParameter** new_params = (ESP_WMParameter**)realloc(_params, _max_params * sizeof(ESP_WMParameter*)); if (new_params != NULL) { _params = new_params; } else { LOGINFO(F("ERROR: failed to realloc params, size not increased!")); return false; } } _params[_paramsCount] = p; _paramsCount++; LOGINFO1(F("Adding parameter"), p->getID()); return true; #else // Danger here. Better to use Tzapu way here if (_paramsCount < (WIFI_MANAGER_MAX_PARAMS)) { _params[_paramsCount] = p; _paramsCount++; LOGINFO1(F("Adding parameter"), p->getID()); } else { LOGINFO("Can't add parameter. Full"); } #endif } ////////////////////////////////////////// void ESP_WiFiManager::setupConfigPortal() { stopConfigPortal = false; //Signal not to close config portal /*This library assumes autoconnect is set to 1. It usually is but just in case check the setting and turn on autoconnect if it is off. Some useful discussion at https://github.com/esp8266/Arduino/issues/1615*/ if (WiFi.getAutoConnect() == 0) WiFi.setAutoConnect(1); dnsServer.reset(new DNSServer()); #ifdef ESP8266 server.reset(new ESP8266WebServer(HTTP_PORT_TO_USE)); #else //ESP32 server.reset(new WebServer(HTTP_PORT_TO_USE)); #endif // optional soft ip config // Must be put here before dns server start to take care of the non-default ConfigPortal AP IP. // Check (https://github.com/khoih-prog/ESP_WiFiManager/issues/58) if (_WiFi_AP_IPconfig._ap_static_ip) { LOGWARN3(F("Custom AP IP/GW/Subnet = "), _WiFi_AP_IPconfig._ap_static_ip, _WiFi_AP_IPconfig._ap_static_gw, _WiFi_AP_IPconfig._ap_static_sn); WiFi.softAPConfig(_WiFi_AP_IPconfig._ap_static_ip, _WiFi_AP_IPconfig._ap_static_gw, _WiFi_AP_IPconfig._ap_static_sn); } /* Setup the DNS server redirecting all the domains to the apIP */ if (dnsServer) { dnsServer->setErrorReplyCode(DNSReplyCode::NoError); // DNSServer started with "*" domain name, all DNS requests will be passsed to WiFi.softAPIP() if (! dnsServer->start(DNS_PORT, "*", WiFi.softAPIP())) { // No socket available LOGERROR(F("Can't start DNS Server. No available socket")); } } else { // No space available LOGERROR(F("Can't initiate DNS Server. No enough space")); } _configPortalStart = millis(); LOGWARN1(F("Configuring AP SSID ="), _apName); if (_apPassword != NULL) { if (strlen(_apPassword) < 8 || strlen(_apPassword) > 63) { // fail passphrase to short or long! LOGERROR(F("Invalid AccessPoint password. Ignoring")); _apPassword = NULL; } LOGWARN1(F("AP PWD ="), _apPassword); } // KH, new from v1.0.10 to enable dynamic/random channel static int channel; // Use random channel if _WiFiAPChannel == 0 if (_WiFiAPChannel == 0) channel = (_configPortalStart % MAX_WIFI_CHANNEL) + 1; else channel = _WiFiAPChannel; if (_apPassword != NULL) { LOGWARN1(F("AP Channel ="), channel); //WiFi.softAP(_apName, _apPassword);//password option WiFi.softAP(_apName, _apPassword, channel); } else { // Can't use channel here WiFi.softAP(_apName); } ////// delay(500); // Without delay I've seen the IP address blank LOGWARN1(F("AP IP address ="), WiFi.softAPIP()); /* Setup web pages: root, wifi config pages, SO captive portal detectors and not found. */ server->on("/", std::bind(&ESP_WiFiManager::handleRoot, this)); server->on("/wifi", std::bind(&ESP_WiFiManager::handleWifi, this)); server->on("/wifisave", std::bind(&ESP_WiFiManager::handleWifiSave, this)); server->on("/close", std::bind(&ESP_WiFiManager::handleServerClose, this)); server->on("/i", std::bind(&ESP_WiFiManager::handleInfo, this)); server->on("/r", std::bind(&ESP_WiFiManager::handleReset, this)); server->on("/state", std::bind(&ESP_WiFiManager::handleState, this)); server->on("/scan", std::bind(&ESP_WiFiManager::handleScan, this)); server->onNotFound(std::bind(&ESP_WiFiManager::handleNotFound, this)); server->begin(); // Web server start LOGWARN(F("HTTP server started")); } ////////////////////////////////////////// bool ESP_WiFiManager::autoConnect() { #ifdef ESP8266 String ssid = "ESP_" + String(ESP.getChipId()); #else //ESP32 String ssid = "ESP_" + String(ESP_getChipId()); #endif return autoConnect(ssid.c_str(), NULL); } /* This is not very useful as there has been an assumption that device has to be told to connect but Wifi already does it's best to connect in background. Calling this method will block until WiFi connects. Sketch can avoid blocking call then use (WiFi.status()==WL_CONNECTED) test to see if connected yet. See some discussion at https://github.com/tzapu/WiFiManager/issues/68 */ // New in v1.0.11 // To permit autoConnect() to use STA static IP or DHCP IP. #ifndef AUTOCONNECT_NO_INVALIDATE #define AUTOCONNECT_NO_INVALIDATE true #endif ////////////////////////////////////////// bool ESP_WiFiManager::autoConnect(char const *apName, char const *apPassword) { #if AUTOCONNECT_NO_INVALIDATE LOGINFO(F("\nAutoConnect using previously saved SSID/PW, but keep previous settings")); // Connect to previously saved SSID/PW, but keep previous settings connectWifi(); #else LOGINFO(F("\nAutoConnect using previously saved SSID/PW, but invalidate previous settings")); // Connect to previously saved SSID/PW, but invalidate previous settings connectWifi(WiFi_SSID(), WiFi_Pass()); #endif unsigned long startedAt = millis(); while (millis() - startedAt < 10000) { //delay(100); delay(200); if (WiFi.status() == WL_CONNECTED) { float waited = (millis() - startedAt); LOGWARN1(F("Connected after waiting (s) :"), waited / 1000); LOGWARN1(F("Local ip ="), WiFi.localIP()); return true; } } return startConfigPortal(apName, apPassword); } ////////////////////////////////////////// bool ESP_WiFiManager::startConfigPortal() { #ifdef ESP8266 String ssid = "ESP_" + String(ESP.getChipId()); #else //ESP32 String ssid = "ESP_" + String(ESP_getChipId()); #endif ssid.toUpperCase(); return startConfigPortal(ssid.c_str(), NULL); } ////////////////////////////////////////// bool ESP_WiFiManager::startConfigPortal(char const *apName, char const *apPassword) { //setup AP int connRes = WiFi.waitForConnectResult(); LOGINFO("WiFi.waitForConnectResult Done"); if (connRes == WL_CONNECTED) { LOGINFO("SET AP_STA"); WiFi.mode(WIFI_AP_STA); //Dual mode works fine if it is connected to WiFi } else { LOGINFO("SET AP"); WiFi.mode(WIFI_AP); // Dual mode becomes flaky if not connected to a WiFi network. // When ESP8266 station is trying to find a target AP, it will scan on every channel, // that means ESP8266 station is changing its channel to scan. This makes the channel of ESP8266 softAP keep changing too.. // So the connection may break. From http://bbs.espressif.com/viewtopic.php?t=671#p2531 } _apName = apName; _apPassword = apPassword; //notify we entered AP mode if (_apcallback != NULL) { LOGINFO("_apcallback"); _apcallback(this); } connect = false; setupConfigPortal(); bool TimedOut = true; LOGINFO("startConfigPortal : Enter loop"); while (_configPortalTimeout == 0 || millis() < _configPortalStart + _configPortalTimeout) { //DNS dnsServer->processNextRequest(); //HTTP server->handleClient(); #if ( USING_ESP32_S2 || USING_ESP32_C3 ) // Fix ESP32-S2 issue with WebServer (https://github.com/espressif/arduino-esp32/issues/4348) delay(1); #endif if (connect) { TimedOut = false; delay(2000); LOGERROR(F("Connecting to new AP")); // using user-provided _ssid, _pass in place of system-stored ssid and pass if (connectWifi(_ssid, _pass) != WL_CONNECTED) { LOGERROR(F("Failed to connect")); WiFi.mode(WIFI_AP); // Dual mode becomes flaky if not connected to a WiFi network. } else { //notify that configuration has changed and any optional parameters should be saved if (_savecallback != NULL) { //todo: check if any custom parameters actually exist, and check if they really changed maybe _savecallback(); } break; } if (_shouldBreakAfterConfig) { //flag set to exit after config after trying to connect //notify that configuration has changed and any optional parameters should be saved if (_savecallback != NULL) { //todo: check if any custom parameters actually exist, and check if they really changed maybe _savecallback(); } break; } } if (stopConfigPortal) { LOGERROR("Stop ConfigPortal"); //KH stopConfigPortal = false; break; } yield(); } WiFi.mode(WIFI_STA); if (TimedOut) { setHostname(); // New v1.0.8 to fix static IP when CP not entered or timed-out setWifiStaticIP(); WiFi.begin(); int connRes = waitForConnectResult(); LOGERROR1("Timed out connection result:", getStatus(connRes)); } server->stop(); server.reset(); dnsServer->stop(); dnsServer.reset(); return WiFi.status() == WL_CONNECTED; } ////////////////////////////////////////// void ESP_WiFiManager::setWifiStaticIP() { #if USE_CONFIGURABLE_DNS if (_WiFi_STA_IPconfig._sta_static_ip) { LOGWARN(F("Custom STA IP/GW/Subnet")); //***** Added section for DNS config option ***** if (_WiFi_STA_IPconfig._sta_static_dns1 && _WiFi_STA_IPconfig._sta_static_dns2) { LOGWARN(F("DNS1 and DNS2 set")); WiFi.config(_WiFi_STA_IPconfig._sta_static_ip, _WiFi_STA_IPconfig._sta_static_gw, _WiFi_STA_IPconfig._sta_static_sn, _WiFi_STA_IPconfig._sta_static_dns1, _WiFi_STA_IPconfig._sta_static_dns2); } else if (_WiFi_STA_IPconfig._sta_static_dns1) { LOGWARN(F("Only DNS1 set")); WiFi.config(_WiFi_STA_IPconfig._sta_static_ip, _WiFi_STA_IPconfig._sta_static_gw, _WiFi_STA_IPconfig._sta_static_sn, _WiFi_STA_IPconfig._sta_static_dns1); } else { LOGWARN(F("No DNS server set")); WiFi.config(_WiFi_STA_IPconfig._sta_static_ip, _WiFi_STA_IPconfig._sta_static_gw, _WiFi_STA_IPconfig._sta_static_sn); } //***** End added section for DNS config option ***** LOGINFO1(F("setWifiStaticIP IP ="), WiFi.localIP()); } else { LOGWARN(F("Can't use Custom STA IP/GW/Subnet")); } #else // check if we've got static_ip settings, if we do, use those. if (_WiFi_STA_IPconfig._sta_static_ip) { WiFi.config(_WiFi_STA_IPconfig._sta_static_ip, _WiFi_STA_IPconfig._sta_static_gw, _WiFi_STA_IPconfig._sta_static_sn); LOGWARN1(F("Custom STA IP/GW/Subnet : "), WiFi.localIP()); } #endif } ////////////////////////////////////////// // New from v1.1.0 int ESP_WiFiManager::reconnectWifi() { int connectResult; // using user-provided _ssid, _pass in place of system-stored ssid and pass if ( ( connectResult = connectWifi(_ssid, _pass) ) != WL_CONNECTED) { LOGERROR1(F("Failed to connect to"), _ssid); if ( ( connectResult = connectWifi(_ssid1, _pass1) ) != WL_CONNECTED) { LOGERROR1(F("Failed to connect to"), _ssid1); } else LOGERROR1(F("Connected to"), _ssid1); } else LOGERROR1(F("Connected to"), _ssid); return connectResult; } ////////////////////////////////////////// int ESP_WiFiManager::connectWifi(const String& ssid, const String& pass) { //KH, from v1.0.10. // Add option if didn't input/update SSID/PW => Use the previous saved Credentials. // But update the Static/DHCP options if changed. if ( (ssid != "") || ( (ssid == "") && (WiFi_SSID() != "") ) ) { //fix for auto connect racing issue. Move up from v1.1.0 to avoid resetSettings() if (WiFi.status() == WL_CONNECTED) { LOGWARN(F("Already connected. Bailing out.")); return WL_CONNECTED; } if (ssid != "") resetSettings(); #ifdef ESP8266 setWifiStaticIP(); #endif WiFi.mode(WIFI_AP_STA); //It will start in station mode if it was previously in AP mode. setHostname(); // KH, Fix ESP32 staticIP after exiting CP, from v1.0.9 #ifdef ESP32 setWifiStaticIP(); #endif if (ssid != "") { // Start Wifi with new values. LOGWARN(F("Connect to new WiFi using new IP parameters")); WiFi.begin(ssid.c_str(), pass.c_str()); } else { // Start Wifi with old values. LOGWARN(F("Connect to previous WiFi using new IP parameters")); WiFi.begin(); } } else if (WiFi_SSID() == "") { LOGWARN(F("No saved credentials")); } int connRes = waitForConnectResult(); LOGWARN1("Connection result: ", getStatus(connRes)); //not connected, WPS enabled, no pass - first attempt if (_tryWPS && connRes != WL_CONNECTED && pass == "") { startWPS(); //should be connected at the end of WPS connRes = waitForConnectResult(); } return connRes; } ////////////////////////////////////////// uint8_t ESP_WiFiManager::waitForConnectResult() { if (_connectTimeout == 0) { unsigned long startedAt = millis(); // In ESP8266, WiFi.waitForConnectResult() @return wl_status_t (0-255) or -1 on timeout !!! // In ESP32, WiFi.waitForConnectResult() @return wl_status_t (0-255) // So, using int for connRes to be safe //int connRes = WiFi.waitForConnectResult(); WiFi.waitForConnectResult(); float waited = (millis() - startedAt); LOGWARN1(F("Connected after waiting (s) :"), waited / 1000); LOGWARN1(F("Local ip ="), WiFi.localIP()); // Fix bug from v1.1.0+, connRes is sometimes not correct. //return connRes; return WiFi.status(); } else { LOGERROR(F("Waiting WiFi connection with time out")); unsigned long start = millis(); bool keepConnecting = true; uint8_t status; while (keepConnecting) { status = WiFi.status(); if (millis() > start + _connectTimeout) { keepConnecting = false; LOGERROR(F("Connection timed out")); } if (status == WL_CONNECTED || status == WL_CONNECT_FAILED) { keepConnecting = false; } delay(100); } return status; } } ////////////////////////////////////////// void ESP_WiFiManager::startWPS() { #ifdef ESP8266 LOGINFO("START WPS"); WiFi.beginWPSConfig(); LOGINFO("END WPS"); #else //ESP32 // TODO LOGINFO("ESP32 WPS TODO"); #endif } ////////////////////////////////////////// //Convenient for debugging but wasteful of program space. //Remove if short of space const char* ESP_WiFiManager::getStatus(const int& status) { switch (status) { case WL_IDLE_STATUS: return "WL_IDLE_STATUS"; case WL_NO_SSID_AVAIL: return "WL_NO_SSID_AVAIL"; case WL_CONNECTED: return "WL_CONNECTED"; case WL_CONNECT_FAILED: return "WL_CONNECT_FAILED"; case WL_DISCONNECTED: return "WL_DISCONNECTED"; default: return "UNKNOWN"; } } ////////////////////////////////////////// String ESP_WiFiManager::getConfigPortalSSID() { return _apName; } ////////////////////////////////////////// String ESP_WiFiManager::getConfigPortalPW() { return _apPassword; } ////////////////////////////////////////// void ESP_WiFiManager::resetSettings() { LOGINFO(F("Previous settings invalidated")); #ifdef ESP8266 WiFi.disconnect(true); #else WiFi.disconnect(true, true); // New in v1.0.11 // Temporary fix for issue of not clearing WiFi SSID/PW from flash of ESP32 // See https://github.com/khoih-prog/ESP_WiFiManager/issues/25 and https://github.com/espressif/arduino-esp32/issues/400 WiFi.begin("0","0"); ////// #endif delay(200); return; } ////////////////////////////////////////// void ESP_WiFiManager::setTimeout(const unsigned long& seconds) { setConfigPortalTimeout(seconds); } ////////////////////////////////////////// void ESP_WiFiManager::setConfigPortalTimeout(const unsigned long& seconds) { _configPortalTimeout = seconds * 1000; } ////////////////////////////////////////// void ESP_WiFiManager::setConnectTimeout(const unsigned long& seconds) { _connectTimeout = seconds * 1000; } ////////////////////////////////////////// void ESP_WiFiManager::setDebugOutput(bool debug) { _debug = debug; } ////////////////////////////////////////// // KH, new from v1.0.10 to enable dynamic/random channel int ESP_WiFiManager::setConfigPortalChannel(const int& channel) { // If channel < MIN_WIFI_CHANNEL - 1 or channel > MAX_WIFI_CHANNEL => channel = 1 // If channel == 0 => will use random channel from MIN_WIFI_CHANNEL to MAX_WIFI_CHANNEL // If (MIN_WIFI_CHANNEL <= channel <= MAX_WIFI_CHANNEL) => use it if ( (channel < MIN_WIFI_CHANNEL - 1) || (channel > MAX_WIFI_CHANNEL) ) _WiFiAPChannel = 1; else if ( (channel >= MIN_WIFI_CHANNEL - 1) && (channel <= MAX_WIFI_CHANNEL) ) _WiFiAPChannel = channel; return _WiFiAPChannel; } ////////////////////////////////////////// void ESP_WiFiManager::setAPStaticIPConfig(const IPAddress& ip, const IPAddress& gw, const IPAddress& sn) { LOGINFO(F("setAPStaticIPConfig")); _WiFi_AP_IPconfig._ap_static_ip = ip; _WiFi_AP_IPconfig._ap_static_gw = gw; _WiFi_AP_IPconfig._ap_static_sn = sn; } ////////////////////////////////////////// // New in v1.4.0 void ESP_WiFiManager::setAPStaticIPConfig(const WiFi_AP_IPConfig& WM_AP_IPconfig) { LOGINFO(F("setAPStaticIPConfig")); memcpy((void*) &_WiFi_AP_IPconfig, &WM_AP_IPconfig, sizeof(_WiFi_AP_IPconfig)); } ////////////////////////////////////////// void ESP_WiFiManager::getAPStaticIPConfig(WiFi_AP_IPConfig &WM_AP_IPconfig) { LOGINFO(F("getAPStaticIPConfig")); memcpy((void*) &WM_AP_IPconfig, &_WiFi_AP_IPconfig, sizeof(WM_AP_IPconfig)); } ////// ////////////////////////////////////////// void ESP_WiFiManager::setSTAStaticIPConfig(const IPAddress& ip, const IPAddress& gw, const IPAddress& sn) { LOGINFO(F("setSTAStaticIPConfig")); _WiFi_STA_IPconfig._sta_static_ip = ip; _WiFi_STA_IPconfig._sta_static_gw = gw; _WiFi_STA_IPconfig._sta_static_sn = sn; } ////////////////////////////////////////// // New in v1.4.0 void ESP_WiFiManager::setSTAStaticIPConfig(const WiFi_STA_IPConfig& WM_STA_IPconfig) { LOGINFO(F("setSTAStaticIPConfig")); memcpy((void*) &_WiFi_STA_IPconfig, &WM_STA_IPconfig, sizeof(_WiFi_STA_IPconfig)); } ////////////////////////////////////////// void ESP_WiFiManager::getSTAStaticIPConfig(WiFi_STA_IPConfig &WM_STA_IPconfig) { LOGINFO(F("getSTAStaticIPConfig")); memcpy((void*) &WM_STA_IPconfig, &_WiFi_STA_IPconfig, sizeof(WM_STA_IPconfig)); } ////// ////////////////////////////////////////// #if USE_CONFIGURABLE_DNS void ESP_WiFiManager::setSTAStaticIPConfig(const IPAddress& ip, const IPAddress& gw, const IPAddress& sn, const IPAddress& dns_address_1, const IPAddress& dns_address_2) { LOGINFO(F("setSTAStaticIPConfig for USE_CONFIGURABLE_DNS")); _WiFi_STA_IPconfig._sta_static_ip = ip; _WiFi_STA_IPconfig._sta_static_gw = gw; _WiFi_STA_IPconfig._sta_static_sn = sn; _WiFi_STA_IPconfig._sta_static_dns1 = dns_address_1; //***** Added argument ***** _WiFi_STA_IPconfig._sta_static_dns2 = dns_address_2; //***** Added argument ***** } #endif ////////////////////////////////////////// void ESP_WiFiManager::setMinimumSignalQuality(const int& quality) { _minimumQuality = quality; } ////////////////////////////////////////// void ESP_WiFiManager::setBreakAfterConfig(bool shouldBreak) { _shouldBreakAfterConfig = shouldBreak; } ////////////////////////////////////////// void ESP_WiFiManager::reportStatus(String &page) { page += FPSTR(WM_HTTP_SCRIPT_NTP_MSG); if (WiFi_SSID() != "") { page += F("Configured to connect to access point "); page += WiFi_SSID(); if (WiFi.status() == WL_CONNECTED) { page += F(" and currently connected on IP "); page += WiFi.localIP().toString(); page += F(""); } else { page += F(" but not currently connected to network."); } } else { page += F("No network currently configured."); } } ////////////////////////////////////////// /** Handle root or redirect to captive portal */ void ESP_WiFiManager::handleRoot() { LOGDEBUG(F("Handle root")); // Disable _configPortalTimeout when someone accessing Portal to give some time to config _configPortalTimeout = 0; //KH if (captivePortal()) { // If caprive portal redirect instead of displaying the error page. return; } server->sendHeader(FPSTR(WM_HTTP_CACHE_CONTROL), FPSTR(WM_HTTP_NO_STORE)); #if USING_CORS_FEATURE // New from v1.1.1, for configure CORS Header, default to WM_HTTP_CORS_ALLOW_ALL = "*" server->sendHeader(FPSTR(WM_HTTP_CORS), _CORS_Header); #endif server->sendHeader(FPSTR(WM_HTTP_PRAGMA), FPSTR(WM_HTTP_NO_CACHE)); server->sendHeader(FPSTR(WM_HTTP_EXPIRES), "-1"); String page = FPSTR(WM_HTTP_HEAD_START); page.replace("{v}", "Options"); page += FPSTR(WM_HTTP_SCRIPT); page += FPSTR(WM_HTTP_SCRIPT_NTP); page += FPSTR(WM_HTTP_STYLE); page += _customHeadElement; page += FPSTR(WM_HTTP_HEAD_END); page += "
Name | Value |
---|---|
Chip ID | "); page += F("0x"); #ifdef ESP8266 page += String(ESP.getChipId(), HEX); //ESP.getChipId(); #else //ESP32 page += String(ESP_getChipId(), HEX); //ESP.getChipId(); page += F(" |
Chip OUI | "); page += F("0x"); page += String(getChipOUI(), HEX); //ESP.getChipId(); page += F(" |
Chip Model | "); page += ESP.getChipModel(); page += F(" Rev"); page += ESP.getChipRevision(); #endif page += F(" |
Flash Chip ID | "); #ifdef ESP8266 page += String(ESP.getFlashChipId(), HEX); //ESP.getFlashChipId(); #else //ESP32 // TODO page += F("TODO"); #endif page += F(" |
IDE Flash Size | "); page += ESP.getFlashChipSize(); page += F(" bytes |
Real Flash Size | "); #ifdef ESP8266 page += ESP.getFlashChipRealSize(); #else //ESP32 // TODO page += F("TODO"); #endif page += F(" bytes |
Access Point IP | "); page += WiFi.softAPIP().toString(); page += F(" |
Access Point MAC | "); page += WiFi.softAPmacAddress(); page += F(" |
SSID | "); page += WiFi_SSID(); page += F(" |
Station IP | "); page += WiFi.localIP().toString(); page += F(" |
Station MAC | "); page += WiFi.macAddress(); page += F(" |