diff --git a/src/ESPEasy/net/Helpers/WiFi_AP_CandidatesList.h b/src/ESPEasy/net/Helpers/WiFi_AP_CandidatesList.h index 5dd3e9fa5..04d2d8ae8 100644 --- a/src/ESPEasy/net/Helpers/WiFi_AP_CandidatesList.h +++ b/src/ESPEasy/net/Helpers/WiFi_AP_CandidatesList.h @@ -105,13 +105,26 @@ public: private: - WiFi_AP_Candidate_List_t candidates; - + // Known credentials supplying the following: + // - Credentials index + // - Priority + // - SSID + // - Key WiFi_AP_Candidate_List_t known; - WiFi_AP_Candidate_List_t scanned; + // Unprocessed found from latest scan WiFi_AP_Candidate_List_t scanned_new; + // Processed found via one or more scans + // When processing scanned_new, matching elements from a previous scan (in 'scanned') + // will be updated with new information, like channel, RSSI, supported protocols, etc. + WiFi_AP_Candidate_List_t scanned; + + // Sorted list of possible APs to connect to. Matching known and scanned. + // First element in the candidates list is the best candidate to try first. + // Failed connect attempts will be removed from the candidates list. + WiFi_AP_Candidate_List_t candidates; + WiFi_AP_Candidate_const_iterator known_it; WiFi_AP_Candidate currentCandidate; diff --git a/src/ESPEasy/net/wifi/ESPEasyWiFi_STA_State.dotuml b/src/ESPEasy/net/wifi/ESPEasyWiFi_STA_State.dotuml index b18160df5..ed8e4ae61 100644 --- a/src/ESPEasy/net/wifi/ESPEasyWiFi_STA_State.dotuml +++ b/src/ESPEasy/net/wifi/ESPEasyWiFi_STA_State.dotuml @@ -10,6 +10,7 @@ StateDiagram [frame=true framecolor=steelblue label="State Diagram ESPEasy WiFi_ choice AlreadyConnected + choice HasScanned_NoCredentials choice AP_on_no_nw_found choice KnownAPfound @@ -23,7 +24,9 @@ StateDiagram [frame=true framecolor=steelblue label="State Diagram ESPEasy WiFi_ Disabled -> STA_Init "Init\nSTA" STA_Init -> AlreadyConnected "Already\nConnected?" AlreadyConnected -> STA_Connected "Connected" [color=green] - AlreadyConnected -> KnownAPfound "Known\nNetwork\nfound?" + AlreadyConnected -> HasScanned_NoCredentials "Has Credentials?" + Disabled <- HasScanned_NoCredentials "Scanned &\nNo Credentials" + HasScanned_NoCredentials -> KnownAPfound "Known\nNetwork\nfound?" KnownAPfound -> AP_on_no_nw_found "Scan\nNeeded" KnownAPfound -> STA_Connecting "No Scan\nNeeded" AP_on_no_nw_found -> STA_AP_Scanning "AP" @@ -32,9 +35,9 @@ StateDiagram [frame=true framecolor=steelblue label="State Diagram ESPEasy WiFi_ TimeOut <- ScanDone "Scan\nFail" [color=red] Disabled <- ScanDone "Scan\nSuccess" [color=green] + STA_Reconnecting <- STA_Connected "Disconnect" [color=red] STA_Reconnecting -> STA_Connected "Connected" [color=green] STA_Connecting -> STA_Connected "Connected" [color=green] - STA_Reconnecting <- STA_Connected "Disconnect" [color=red] STA_Connected -> STA_Connected "After 5 min:\nMark Stable" diff --git a/src/ESPEasy/net/wifi/ESPEasyWiFi_state_machine.cpp b/src/ESPEasy/net/wifi/ESPEasyWiFi_state_machine.cpp index 8e3acf446..f929349e3 100644 --- a/src/ESPEasy/net/wifi/ESPEasyWiFi_state_machine.cpp +++ b/src/ESPEasy/net/wifi/ESPEasyWiFi_state_machine.cpp @@ -48,11 +48,11 @@ void ESPEasyWiFi_t::setup() { void ESPEasyWiFi_t::enable() {} -void ESPEasyWiFi_t::disable() { setState(WiFi_STA_State_e::Disabled, 100); } +void ESPEasyWiFi_t::disable() { setState(WiFi_STA_State_e::Disabled, 0); } void ESPEasyWiFi_t::begin() { if (connected()) { - setState(WiFi_STA_State_e::STA_Connected, WIFI_STATE_MACHINE_STA_CONNECTED_STABLE); + setState(WiFi_STA_State_e::STA_Connected); } else { setState(WiFi_STA_State_e::STA_Init, 100); } @@ -60,13 +60,13 @@ void ESPEasyWiFi_t::begin() { void ESPEasyWiFi_t::loop() { - // TODO TD-er: Must inspect WiFiEventData to see if we need to update some state here. - auto wifi_STA_data = getWiFi_STA_NWPluginData_static_runtime(); - - if (!wifi_STA_data) { - // TODO TD-er: Must set to WiFi_STA_State_e::Disabled ??? - return; - } + /* + if ((_state != WiFi_STA_State_e::Disabled) && + (getWiFi_STA_NWPluginData_static_runtime() == nullptr)) { + setState(WiFi_STA_State_e::Disabled, 100); + return; + } + */ const bool stateTimeoutReached = _state_timeout.isSet() && _state_timeout.timeReached(); @@ -77,13 +77,18 @@ void ESPEasyWiFi_t::loop() _callbackError = false; // TODO TD-er: Must perhaps check what action was pending and act on it? - if ((_state == WiFi_STA_State_e::Disabled) && stateTimeoutReached) { - setState(WiFi_STA_State_e::STA_Init, 100); - } else if ((_state == WiFi_STA_State_e::STA_Connected) && stateTimeoutReached) { - setState(WiFi_STA_State_e::STA_Connected_Stable); - } else { - setState(WiFi_STA_State_e::TimeOut, 100); + if (stateTimeoutReached) { + if (_state == WiFi_STA_State_e::Disabled) { + setState(WiFi_STA_State_e::STA_Init, 100); + return; + } + + if (_state == WiFi_STA_State_e::STA_Connected) { + setState(WiFi_STA_State_e::STA_Connected_Stable); + return; + } } + setState(WiFi_STA_State_e::TimeOut, 100); return; } } @@ -93,22 +98,33 @@ void ESPEasyWiFi_t::loop() case WiFi_STA_State_e::Disabled: // Do nothing here, as the device is disabled. break; + case WiFi_STA_State_e::TimeOut: // We always go from TimeOut to Disabled. // Called this from the loop() to prevent recursive calls to setState setState(WiFi_STA_State_e::Disabled, 100); break; + case WiFi_STA_State_e::STA_Init: + WiFi_AP_Candidates.purge_expired(); + + if (connected()) { + setState(WiFi_STA_State_e::STA_Connected); + break; + } + + if (WiFi_AP_Candidates.hasScanned() && !WiFi_AP_Candidates.hasCandidateCredentials()) { + // We don't have any credentials and we do have some scanned, so we are prepared for setup. + // However we don't need to quickly switch between Disabled and STA_Init, thus set to 10 sec. + setState(WiFi_STA_State_e::Disabled, 10000); + break; + } + if (getWiFi_STA_NWPluginData_static_runtime() == nullptr) { Scheduler.setNetworkInitTimer(0, NETWORK_INDEX_WIFI_STA); } if (getWiFi_STA_NWPluginData_static_runtime() != nullptr) { - if (connected()) { - setState(WiFi_STA_State_e::STA_Connected, WIFI_STATE_MACHINE_STA_CONNECTED_STABLE); - break; - } - // This is where we decide what to do next: // - Reconnect // - Scan @@ -129,6 +145,7 @@ void ESPEasyWiFi_t::loop() setState(WiFi_STA_State_e::STA_Scanning, WIFI_STATE_MACHINE_STA_SCANNING_TIMEOUT); } break; + case WiFi_STA_State_e::STA_Scanning: case WiFi_STA_State_e::STA_AP_Scanning: { @@ -179,12 +196,13 @@ void ESPEasyWiFi_t::loop() } break; } + case WiFi_STA_State_e::STA_Connecting: case WiFi_STA_State_e::STA_Reconnecting: // Check if (re)connecting has finished if (getSTA_connected_state() == STA_connected_state::Connected) { - setState(WiFi_STA_State_e::STA_Connected, WIFI_STATE_MACHINE_STA_CONNECTED_STABLE); + setState(WiFi_STA_State_e::STA_Connected); } break; @@ -269,18 +287,16 @@ void ESPEasyWiFi_t::setState(WiFi_STA_State_e newState, uint32_t timeout) { // # endif // ifndef BUILD_NO_DEBUG - - if (oldState == WiFi_STA_State_e::STA_Connected) - {} - if ((oldState == WiFi_STA_State_e::STA_AP_Scanning) || (oldState == WiFi_STA_State_e::STA_Scanning)) { WiFi_AP_Candidates.load_knownCredentials(); WiFi_AP_Candidates.process_WiFiscan(); - } + // Make sure not to call setState from this function + // This may cause quite a lot of recursive calls. + switch (newState) { case WiFi_STA_State_e::Disabled: @@ -329,12 +345,12 @@ void ESPEasyWiFi_t::setState(WiFi_STA_State_e newState, uint32_t timeout) { break; } case WiFi_STA_State_e::STA_Init: -/* - if (getWiFi_STA_NWPluginData_static_runtime() == nullptr) { - Scheduler.setNetworkInitTimer(0, NETWORK_INDEX_WIFI_STA); - } - _state_timeout.setMillisFromNow(Settings.getNetworkInterfaceStartupDelay(NETWORK_INDEX_WIFI_STA) + 100); -*/ + /* + if (getWiFi_STA_NWPluginData_static_runtime() == nullptr) { + Scheduler.setNetworkInitTimer(0, NETWORK_INDEX_WIFI_STA); + } + _state_timeout.setMillisFromNow(Settings.getNetworkInterfaceStartupDelay(NETWORK_INDEX_WIFI_STA) + 100); + */ break; case WiFi_STA_State_e::STA_AP_Scanning: