Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Silabs] Disconnection issue fix #23795

Merged
Merged
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++;
riwaghe marked this conversation as resolved.
Show resolved Hide resolved
}
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;
riwaghe marked this conversation as resolved.
Show resolved Hide resolved

#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;
}
}