Skip to content

Commit

Permalink
[Silabs] Disconnection issue fix (#23795)
Browse files Browse the repository at this point in the history
* [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
  • Loading branch information
riwaghe authored and pull[bot] committed Nov 14, 2023
1 parent f57b33b commit 7125013
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 23 deletions.
44 changes: 25 additions & 19 deletions examples/platform/silabs/efr32/rs911x/rsi_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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
{
Expand All @@ -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;
}
}

Expand All @@ -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
Expand Down Expand Up @@ -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
*/
Expand All @@ -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
*/
Expand All @@ -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);
}
}
}

Expand Down
17 changes: 14 additions & 3 deletions examples/platform/silabs/efr32/wf200/host_if.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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;
Expand All @@ -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<sl_wfx_state_t>(static_cast<int>(sl_wfx_context->state) & ~static_cast<int>(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
Expand Down Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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))
Expand Down
4 changes: 3 additions & 1 deletion src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
9 changes: 9 additions & 0 deletions src/platform/silabs/EFR32/wifi/wfx_host_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
43 changes: 43 additions & 0 deletions src/platform/silabs/EFR32/wifi/wfx_notify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
}

0 comments on commit 7125013

Please sign in to comment.