From 7125013511ba8fe5f8a938b326ef469833dd068e Mon Sep 17 00:00:00 2001 From: riwaghe <108741313+riwaghe@users.noreply.github.com> Date: Wed, 1 Feb 2023 19:47:36 +0530 Subject: [PATCH] [Silabs] Disconnection issue fix (#23795) * [Silabs] Disconnection issue fixed * Restyling the PR * addressing the comments - changed macro and variable names * addressing the comments - removed previous commented-out code * Restyling the PR * Added comments * Restyling the PR * Restyling the PR * Restyling the PR * Adressing the comments * Adressing the comments * Restyling the PR * Added comments * Create function for retry interval * Restyling the PR * Restyling the PR * Addressing the PR comments * Restyling the PR --- .../platform/silabs/efr32/rs911x/rsi_if.c | 44 +++++++++++-------- .../platform/silabs/efr32/wf200/host_if.cpp | 17 +++++-- .../silabs/ConnectivityManagerImpl_WIFI.cpp | 4 +- .../silabs/EFR32/wifi/wfx_host_events.h | 9 ++++ src/platform/silabs/EFR32/wifi/wfx_notify.cpp | 43 ++++++++++++++++++ 5 files changed, 94 insertions(+), 23 deletions(-) diff --git a/examples/platform/silabs/efr32/rs911x/rsi_if.c b/examples/platform/silabs/efr32/rs911x/rsi_if.c index ad72f6361c055c..fdeb534916aae2 100644 --- a/examples/platform/silabs/efr32/rs911x/rsi_if.c +++ b/examples/platform/silabs/efr32/rs911x/rsi_if.c @@ -67,6 +67,12 @@ bool hasNotifiedIPV4 = false; #endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */ bool hasNotifiedWifiConnectivity = false; +/* Declare a flag to differentiate between after boot-up first IP connection or reconnection */ +bool is_wifi_disconnection_event = false; + +/* Declare a variable to hold connection time intervals */ +uint32_t retryInterval = WLAN_MIN_RETRY_TIMER_MS; + /* * This file implements the interface to the RSI SAPIs */ @@ -195,12 +201,9 @@ static void wfx_rsi_join_cb(uint16_t status, const uint8_t * buf, const uint16_t * We should enable retry.. (Need config variable for this) */ WFX_RSI_LOG("%s: failed. retry: %d", __func__, wfx_rsi.join_retries); -#if (WFX_RSI_CONFIG_MAX_JOIN != 0) - if (++wfx_rsi.join_retries < WFX_RSI_CONFIG_MAX_JOIN) -#endif - { + wfx_retry_interval_handler(is_wifi_disconnection_event, wfx_rsi.join_retries++); + if (is_wifi_disconnection_event || wfx_rsi.join_retries <= WFX_RSI_CONFIG_MAX_JOIN) xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_START_JOIN); - } } else { @@ -213,6 +216,8 @@ static void wfx_rsi_join_cb(uint16_t status, const uint8_t * buf, const uint16_t #else xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_CONN); #endif + wfx_rsi.join_retries = 0; + retryInterval = WLAN_MIN_RETRY_TIMER_MS; } } @@ -228,9 +233,10 @@ static void wfx_rsi_join_cb(uint16_t status, const uint8_t * buf, const uint16_t *********************************************************************/ static void wfx_rsi_join_fail_cb(uint16_t status, uint8_t * buf, uint32_t len) { - WFX_RSI_LOG("%s: error: failed status: %02x on try %d", __func__, status, wfx_rsi.join_retries); + WFX_RSI_LOG("%s: error: failed status: %02x", __func__, status); wfx_rsi.join_retries += 1; - wfx_rsi.dev_state &= ~WFX_RSI_ST_STA_CONNECTING; + wfx_rsi.dev_state &= ~(WFX_RSI_ST_STA_CONNECTING | WFX_RSI_ST_STA_CONNECTED); + is_wifi_disconnection_event = true; xEventGroupSetBits(wfx_rsi.events, WFX_EVT_STA_START_JOIN); } #ifdef RS911X_SOCKETS @@ -461,6 +467,7 @@ static void wfx_rsi_do_join(void) { WFX_RSI_LOG("%s: WLAN: connecting to %s==%s, sec=%d", __func__, &wfx_rsi.sec.ssid[0], &wfx_rsi.sec.passkey[0], wfx_rsi.sec.security); + /* * Join the network */ @@ -469,12 +476,16 @@ static void wfx_rsi_do_join(void) */ wfx_rsi.dev_state |= WFX_RSI_ST_STA_CONNECTING; + if ((status = rsi_wlan_register_callbacks(RSI_JOIN_FAIL_CB, wfx_rsi_join_fail_cb)) != RSI_SUCCESS) + { + WFX_RSI_LOG("%s: RSI callback register join failed with status: %02x", __func__, status); + } + /* Try to connect Wifi with given Credentials * untill there is a success or maximum number of tries allowed */ - while (++wfx_rsi.join_retries < WFX_RSI_CONFIG_MAX_JOIN) + while (is_wifi_disconnection_event || wfx_rsi.join_retries <= WFX_RSI_CONFIG_MAX_JOIN) { - /* Call rsi connect call with given ssid and password * And check there is a success */ @@ -485,22 +496,17 @@ static void wfx_rsi_do_join(void) wfx_rsi.dev_state &= ~WFX_RSI_ST_STA_CONNECTING; WFX_RSI_LOG("%s: rsi_wlan_connect_async failed with status: %02x on try %d", __func__, status, wfx_rsi.join_retries); - vTaskDelay(4000); - /* TODO - Start a timer.. to retry */ + + wfx_retry_interval_handler(is_wifi_disconnection_event, wfx_rsi.join_retries); + wfx_rsi.join_retries++; } else { + WFX_RSI_LOG("%s: starting JOIN to %s after %d tries\n", __func__, (char *) &wfx_rsi.sec.ssid[0], + wfx_rsi.join_retries); break; // exit while loop } } - if (wfx_rsi.join_retries == MAX_JOIN_RETRIES_COUNT) - { - WFX_RSI_LOG("Connect failed after %d tries", wfx_rsi.join_retries); - } - else - { - WFX_RSI_LOG("%s: starting JOIN to %s after %d tries\n", __func__, (char *) &wfx_rsi.sec.ssid[0], wfx_rsi.join_retries); - } } } diff --git a/examples/platform/silabs/efr32/wf200/host_if.cpp b/examples/platform/silabs/efr32/wf200/host_if.cpp index a22735ae448529..faa2262bc7c090 100644 --- a/examples/platform/silabs/efr32/wf200/host_if.cpp +++ b/examples/platform/silabs/efr32/wf200/host_if.cpp @@ -99,6 +99,12 @@ bool hasNotifiedWifiConnectivity = false; static uint8_t retryJoin = 0; bool retryInProgress = false; +/* Declare a flag to differentiate between after boot-up first IP connection or reconnection */ +bool is_wifi_disconnection_event = false; + +/* Declare a variable to hold connection time intervals */ +uint32_t retryInterval = WLAN_MIN_RETRY_TIMER_MS; + #ifdef SL_WFX_CONFIG_SCAN static struct scan_result_holder { @@ -394,7 +400,7 @@ static void sl_wfx_connect_callback(sl_wfx_connect_ind_body_t connect_indication } } - if ((status != WFM_STATUS_SUCCESS) && retryJoin < MAX_JOIN_RETRIES_COUNT) + if ((status != WFM_STATUS_SUCCESS) && (!is_wifi_disconnection_event ? (retryJoin < MAX_JOIN_RETRIES_COUNT) : true)) { retryJoin += 1; retryInProgress = false; @@ -417,7 +423,9 @@ static void sl_wfx_disconnect_callback(uint8_t * mac, uint16_t reason) SILABS_LOG("WFX Disconnected %d\r\n", reason); sl_wfx_context->state = static_cast(static_cast(sl_wfx_context->state) & ~static_cast(SL_WFX_STA_INTERFACE_CONNECTED)); - xEventGroupSetBits(sl_wfx_event_group, SL_WFX_DISCONNECT); + retryInProgress = false; + is_wifi_disconnection_event = true; + xEventGroupSetBits(sl_wfx_event_group, SL_WFX_RETRY_CONNECT); } #ifdef SL_WFX_CONFIG_SOFTAP @@ -534,9 +542,10 @@ static void wfx_events_task(void * p_arg) { if (!retryInProgress) { + retryInProgress = true; + wfx_retry_interval_handler(is_wifi_disconnection_event, retryJoin); SILABS_LOG("WFX sending the connect command"); wfx_connect_to_ap(); - retryInProgress = true; } } @@ -589,6 +598,8 @@ static void wfx_events_task(void * p_arg) hasNotifiedWifiConnectivity = false; SILABS_LOG("WIFI: Connected to AP"); wifi_extra |= WE_ST_STA_CONN; + retryJoin = 0; + retryInterval = WLAN_MIN_RETRY_TIMER_MS; wfx_lwip_set_sta_link_up(); #ifdef SLEEP_ENABLED if (!(wfx_get_wifi_state() & SL_WFX_AP_INTERFACE_UP)) diff --git a/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp b/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp index effee8c67d71a5..deb2df49e1dbca 100644 --- a/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp +++ b/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp @@ -263,8 +263,10 @@ void ConnectivityManagerImpl::DriveStationState() // disconnect the station from the AP, unless the WiFi station mode is currently // under application control. #ifndef CHIP_ONNETWORK_PAIRING + // Incase of station interface disabled & provisioned, wifi_station should not be disconnected. + // Device will try to reconnect. if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled && - (mWiFiStationMode != kWiFiStationMode_Enabled || !IsWiFiStationProvisioned())) + (mWiFiStationMode != kWiFiStationMode_Enabled && !IsWiFiStationProvisioned())) { ChipLogProgress(DeviceLayer, "Disconnecting WiFi station interface"); serr = wfx_sta_discon(); diff --git a/src/platform/silabs/EFR32/wifi/wfx_host_events.h b/src/platform/silabs/EFR32/wifi/wfx_host_events.h index 40e4d8e7fca166..a787bdc5e08b84 100644 --- a/src/platform/silabs/EFR32/wifi/wfx_host_events.h +++ b/src/platform/silabs/EFR32/wifi/wfx_host_events.h @@ -141,6 +141,12 @@ typedef struct __attribute__((__packed__)) sl_wfx_mib_req_s #define MAX_JOIN_RETRIES_COUNT 5 #endif +// WLAN retry time intervals in milli seconds +#define WLAN_MAX_RETRY_TIMER_MS 30000 +#define WLAN_MIN_RETRY_TIMER_MS 1000 +#define WLAN_RETRY_TIMER_MS 5000 +#define CONVERT_MS_TO_SEC(TimeInMS) (TimeInMS / 1000) + // WLAN related Macros #define ETH_FRAME 0 #define CMP_SUCCESS 0 @@ -370,6 +376,9 @@ sl_status_t get_all_counters(void); void sl_wfx_host_gpio_init(void); sl_status_t sl_wfx_host_process_event(sl_wfx_generic_message_t * event_payload); #endif + +void wfx_retry_interval_handler(bool is_wifi_disconnection_event, uint16_t retryJoin); + #ifdef __cplusplus } #endif diff --git a/src/platform/silabs/EFR32/wifi/wfx_notify.cpp b/src/platform/silabs/EFR32/wifi/wfx_notify.cpp index 9f681e796c6d19..bbc7f91570de21 100644 --- a/src/platform/silabs/EFR32/wifi/wfx_notify.cpp +++ b/src/platform/silabs/EFR32/wifi/wfx_notify.cpp @@ -46,6 +46,8 @@ using namespace ::chip; using namespace ::chip::DeviceLayer; +extern uint32_t retryInterval; + /* * Notifications to the upper-layer * All done in the context of the RSI/WiFi task (rsi_if.c) @@ -187,3 +189,44 @@ void wfx_ip_changed_notify(int got_ip) chip::DeviceLayer::PlatformMgr().UnlockChipStack(); } } + +/************************************************************************************** + * @fn void wfx_retry_interval_handler(bool is_wifi_disconnection_event, uint16_t retryJoin) + * @brief + * Based on condition will delay for a certain period of time. + * @param[in] is_wifi_disconnection_event, retryJoin + * @return None + ********************************************************************************************/ +void wfx_retry_interval_handler(bool is_wifi_disconnection_event, uint16_t retryJoin) +{ + if (!is_wifi_disconnection_event) + { + /* After the reboot or a commissioning time device failed to connect with AP. + * Device will retry to connect with AP upto WFX_RSI_CONFIG_MAX_JOIN retries. + */ + if (retryJoin < MAX_JOIN_RETRIES_COUNT) + { + SILABS_LOG("%s: Next attempt after %d Seconds", __func__, CONVERT_MS_TO_SEC(WLAN_RETRY_TIMER_MS)); + vTaskDelay(pdMS_TO_TICKS(WLAN_RETRY_TIMER_MS)); + } + else + { + SILABS_LOG("Connect failed after max %d tries", retryJoin); + } + } + else + { + /* After disconnection + * At the telescopic time interval device try to reconnect with AP, upto WLAN_MAX_RETRY_TIMER_MS intervals + * are telescopic. If interval exceed WLAN_MAX_RETRY_TIMER_MS then it will try to reconnect at + * WLAN_MAX_RETRY_TIMER_MS intervals. + */ + if (retryInterval > WLAN_MAX_RETRY_TIMER_MS) + { + retryInterval = WLAN_MAX_RETRY_TIMER_MS; + } + SILABS_LOG("%s: Next attempt after %d Seconds", __func__, CONVERT_MS_TO_SEC(retryInterval)); + vTaskDelay(pdMS_TO_TICKS(retryInterval)); + retryInterval += retryInterval; + } +}