diff --git a/libraries/WiFi/src/WiFi.cpp b/libraries/WiFi/src/WiFi.cpp index 858fa56aa..da6102a33 100644 --- a/libraries/WiFi/src/WiFi.cpp +++ b/libraries/WiFi/src/WiFi.cpp @@ -17,6 +17,8 @@ int arduino::WiFiClass::begin(const char* ssid, const char* passphrase) { return 0; } + wifi_if->attach(&arduino::WiFiClass::statusCallback); + scanNetworks(); // use scan result to populate security field if (!isVisible(ssid)) { @@ -26,7 +28,11 @@ int arduino::WiFiClass::begin(const char* ssid, const char* passphrase) { nsapi_error_t result = wifi_if->connect(ssid, passphrase, ap_list[connected_ap].get_security()); + if(result == NSAPI_ERROR_IS_CONNECTED) { + wifi_if->disconnect(); + } _currentNetworkStatus = (result == NSAPI_ERROR_OK && setSSID(ssid)) ? WL_CONNECTED : WL_CONNECT_FAILED; + return _currentNetworkStatus; } @@ -160,9 +166,10 @@ static uint8_t sec2enum(nsapi_security_t sec) { int8_t arduino::WiFiClass::scanNetworks() { uint8_t count = 10; - if (ap_list == nullptr) { - ap_list = new WiFiAccessPoint[count]; + if (ap_list != nullptr) { + free(ap_list); } + ap_list = new WiFiAccessPoint[count]; return wifi_if->scan(ap_list, count); } @@ -210,6 +217,15 @@ unsigned long arduino::WiFiClass::getTime() { return 0; } +void arduino::WiFiClass::statusCallback(nsapi_event_t status, intptr_t param) +{ + if (((param == NSAPI_STATUS_DISCONNECTED) || + (param == NSAPI_STATUS_CONNECTING)) && + (WiFi.status() == WL_CONNECTED)) { + WiFi._currentNetworkStatus = WL_CONNECTION_LOST; + } +} + #if defined(COMPONENT_4343W_FS) #define WIFI_FIRMWARE_PATH "/wlan/4343WA1.BIN" diff --git a/libraries/WiFi/src/WiFi.h b/libraries/WiFi/src/WiFi.h index 96e66c19b..d6fd69765 100644 --- a/libraries/WiFi/src/WiFi.h +++ b/libraries/WiFi/src/WiFi.h @@ -209,6 +209,7 @@ class WiFiClass : public MbedSocketClass { void ensureDefaultAPNetworkConfiguration(); static void* handleAPEvents(whd_interface_t ifp, const whd_event_header_t* event_header, const uint8_t* event_data, void* handler_user_data); bool isVisible(const char* ssid); + static void statusCallback(nsapi_event_t status, intptr_t param); }; } diff --git a/patches/0174-WHD-force-disconnect-on-roamed-due-to-low-RSSI.patch b/patches/0174-WHD-force-disconnect-on-roamed-due-to-low-RSSI.patch new file mode 100644 index 000000000..059350e93 --- /dev/null +++ b/patches/0174-WHD-force-disconnect-on-roamed-due-to-low-RSSI.patch @@ -0,0 +1,28 @@ +From 7d59d1e04f2cc6872d07c30cb6f66457dbd383f2 Mon Sep 17 00:00:00 2001 +From: pennam +Date: Thu, 11 Aug 2022 10:29:34 +0200 +Subject: [PATCH] WHD: force disconnect on roamed due to low RSSI + +--- + .../drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp +index 6fec15adb0..509a2c0981 100644 +--- a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp ++++ b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp +@@ -178,7 +178,10 @@ static void *whd_wifi_link_state_change_handler(whd_interface_t ifp, + (event_header->event_type == WLC_E_DISASSOC_IND) || + ((event_header->event_type == WLC_E_PSK_SUP) && + (event_header->status == WLC_SUP_KEYED) && +- (event_header->reason == WLC_E_SUP_DEAUTH))) { ++ (event_header->reason == WLC_E_SUP_DEAUTH)) || ++ ((event_header->event_type == WLC_E_LINK) && ++ (event_header->status == WLC_E_STATUS_SUCCESS) && ++ (event_header->reason == WLC_E_REASON_LOW_RSSI))) { + whd_emac_wifi_link_state_changed(ifp, WHD_FALSE); + return handler_user_data; + } +-- +2.37.1 +