From 0088643497fefba1c9bee65f1e77893f8c148f34 Mon Sep 17 00:00:00 2001 From: chirag-silabs Date: Thu, 12 Mar 2026 10:11:35 +0530 Subject: [PATCH 1/7] Spliting the join, scan and disconnect --- .../silabs/NetworkCommissioningWiFiDriver.cpp | 3 +- .../silabs/wifi/SiWx/WifiInterfaceImpl.cpp | 40 +++++++++++-------- .../silabs/wifi/SiWx/WifiInterfaceImpl.h | 12 +++--- src/platform/silabs/wifi/WifiInterface.h | 13 +++++- 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp b/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp index 33a594f923e..d9c53375e32 100644 --- a/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp +++ b/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp @@ -167,8 +167,7 @@ CHIP_ERROR SlWiFiDriver::ConnectWiFiNetwork(const char * ssid, uint8_t ssidLen, ChipLogProgress(NetworkProvisioning, "Setting up connection for WiFi SSID: %s", NullTerminated(ssid, ssidLen).c_str()); // Resetting the retry connection state machine for a new access point connection WifiInterface::GetInstance().ResetConnectionRetryInterval(); - // Configure the WFX WiFi interface. - WifiInterface::GetInstance().SetWifiCredentials(wifiConfig); + ReturnErrorOnFailure(WifiInterface::GetInstance().SetWifiCredentials(wifiConfig)); ReturnErrorOnFailure(ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Disabled)); ReturnErrorOnFailure(ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Enabled)); return CHIP_NO_ERROR; diff --git a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp index 7ef4e91dc1b..2e95cccfa61 100644 --- a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp +++ b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp @@ -645,7 +645,7 @@ void WifiInterfaceImpl::ProcessEvent(WifiPlatformEvent event) case WifiPlatformEvent::kStationDisconnect: { ChipLogDetail(DeviceLayer, "WifiPlatformEvent::kStationDisconnect"); - // TODO: This event is not being posted anywhere, seems to be a dead code or we are missing something + TEMPORARY_RETURN_IGNORED TriggerPlatformWifiDisconnection(); wfx_rsi.dev_state.Clear(WifiInterface::WifiState::kStationReady) .Clear(WifiInterface::WifiState::kStationConnecting) @@ -664,15 +664,18 @@ void WifiInterfaceImpl::ProcessEvent(WifiPlatformEvent event) // TODO: Currently unimplemented break; - case WifiPlatformEvent::kStationStartJoin: - ChipLogDetail(DeviceLayer, "WifiPlatformEvent::kStationStartJoin"); - -// To avoid IOP issues, it is recommended to enable high-performance mode before joining the network. -// TODO: Remove this once the IOP issue related to power save mode switching is fixed in the Wi-Fi SDK. + case WifiPlatformEvent::kStationStartScan: + ChipLogDetail(DeviceLayer, "WifiPlatformEvent::kStationStartScan"); + // To avoid IOP issues, enable high-performance mode before scan/join. TODO: Remove once IOP fix is in Wi-Fi SDK. #if CHIP_CONFIG_ENABLE_ICD_SERVER TEMPORARY_RETURN_IGNORED chip::DeviceLayer::Silabs::WifiSleepManager::GetInstance().RequestHighPerformanceWithTransition(); #endif // CHIP_CONFIG_ENABLE_ICD_SERVER InitiateScan(); + PostWifiPlatformEvent(WifiPlatformEvent::kStationStartJoin); + break; + + case WifiPlatformEvent::kStationStartJoin: + ChipLogDetail(DeviceLayer, "WifiPlatformEvent::kStationStartJoin"); JoinWifiNetwork(); break; @@ -1048,9 +1051,7 @@ bool WifiInterfaceImpl::IsStationReady() CHIP_ERROR WifiInterfaceImpl::TriggerDisconnection() { - VerifyOrReturnError(TriggerPlatformWifiDisconnection() == SL_STATUS_OK, CHIP_ERROR_INTERNAL); - wfx_rsi.dev_state.Clear(WifiState::kStationConnected); - + PostWifiPlatformEvent(WifiPlatformEvent::kStationDisconnect); return CHIP_NO_ERROR; } @@ -1110,25 +1111,32 @@ bool WifiInterfaceImpl::IsWifiProvisioned() return wfx_rsi.dev_state.Has(WifiState::kStationProvisioned); } -void WifiInterfaceImpl::SetWifiCredentials(const WifiCredentials & credentials) +CHIP_ERROR WifiInterfaceImpl::SetWifiCredentials(const WifiCredentials & credentials) { + VerifyOrReturnError(credentials.ssidLength, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(credentials.ssidLength <= WFX_MAX_SSID_LENGTH, CHIP_ERROR_INVALID_ARGUMENT); wfx_rsi.credentials = credentials; wfx_rsi.dev_state.Set(WifiState::kStationProvisioned); + return CHIP_NO_ERROR; } CHIP_ERROR WifiInterfaceImpl::ConnectToAccessPoint() { VerifyOrReturnError(IsWifiProvisioned(), CHIP_ERROR_INCORRECT_STATE); - VerifyOrReturnError(wfx_rsi.credentials.ssidLength, CHIP_ERROR_INCORRECT_STATE); - - // TODO: We should move this validation to where we set the credentials. It is too late here. - VerifyOrReturnError(wfx_rsi.credentials.ssidLength <= WFX_MAX_SSID_LENGTH, CHIP_ERROR_INVALID_ARGUMENT); ChipLogProgress(DeviceLayer, "connect to access point: %s", wfx_rsi.credentials.ssid); - WifiPlatformEvent event = WifiPlatformEvent::kStationStartJoin; - PostWifiPlatformEvent(event); + PostWifiPlatformEvent(WifiPlatformEvent::kStationStartScan); + return CHIP_NO_ERROR; +} + +CHIP_ERROR WifiInterfaceImpl::QuickJoinToAccessPoint() +{ + VerifyOrReturnError(IsWifiProvisioned(), CHIP_ERROR_INCORRECT_STATE); + + ChipLogProgress(DeviceLayer, "quick join to access point: %s", wfx_rsi.credentials.ssid); + PostWifiPlatformEvent(WifiPlatformEvent::kStationStartJoin); return CHIP_NO_ERROR; } diff --git a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.h b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.h index 922b0a60bf9..8b6c8920239 100644 --- a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.h +++ b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.h @@ -34,10 +34,11 @@ class WifiInterfaceImpl final : public WifiInterface kStationDisconnect = 1, kAPStart = 2, kAPStop = 3, - kStationStartJoin = 5, - kConnectionComplete = 6, /* This combines the DHCP and Notify */ - kStationDhcpDone = 7, - kStationDhcpPoll = 8, + kStationStartScan = 5, + kStationStartJoin = 6, + kConnectionComplete = 7, /* This combines the DHCP and Notify */ + kStationDhcpDone = 8, + kStationDhcpPoll = 9, }; static WifiInterfaceImpl & GetInstance() { return mInstance; } @@ -58,9 +59,10 @@ class WifiInterfaceImpl final : public WifiInterface bool IsStationReady() override; CHIP_ERROR TriggerDisconnection() override; void ClearWifiCredentials() override; - void SetWifiCredentials(const WifiCredentials & credentials) override; + CHIP_ERROR SetWifiCredentials(const WifiCredentials & credentials) override; CHIP_ERROR GetWifiCredentials(WifiCredentials & credentials) override; CHIP_ERROR ConnectToAccessPoint(void) override; + CHIP_ERROR QuickJoinToAccessPoint(void) override; bool HasAnIPv4Address() override; bool HasAnIPv6Address() override; void CancelScanNetworks() override; diff --git a/src/platform/silabs/wifi/WifiInterface.h b/src/platform/silabs/wifi/WifiInterface.h index 94458e55b23..1d6e672c95a 100644 --- a/src/platform/silabs/wifi/WifiInterface.h +++ b/src/platform/silabs/wifi/WifiInterface.h @@ -296,8 +296,9 @@ class WifiInterface : public WifiStateProvider, public PowerSaveInterface * The function will overwrite any existing Wi-Fi credentials. * * @param[in] credentials + * @return CHIP_ERROR CHIP_NO_ERROR on success, CHIP_ERROR_INVALID_ARGUMENT if ssidLength is 0 or exceeds WFX_MAX_SSID_LENGTH */ - virtual void SetWifiCredentials(const WifiCredentials & credentials) = 0; + virtual CHIP_ERROR SetWifiCredentials(const WifiCredentials & credentials) = 0; /** * @brief Returns the configured Wi-Fi credentials @@ -323,6 +324,16 @@ class WifiInterface : public WifiStateProvider, public PowerSaveInterface */ virtual CHIP_ERROR ConnectToAccessPoint(void) = 0; + /** + * @brief Triggers join to the provisioned access point without scanning. + * Use when scan info (e.g. channel, BSSID) is already known to avoid a prior scan. + * + * @return CHIP_ERROR CHIP_NO_ERROR, the join was successfully triggered + * CHIP_ERROR_INCORRECT_STATE, not provisioned or no credentials + * CHIP_ERROR_INVALID_ARGUMENT, credentials invalid + */ + virtual CHIP_ERROR QuickJoinToAccessPoint(void) = 0; + /** * @brief Cancels the on-going network scan operation. * If one isn't in-progress, function doesn't do anything From 55900613eadc15b00df61d7db3bad82d075c148c Mon Sep 17 00:00:00 2001 From: chirag-silabs Date: Thu, 12 Mar 2026 12:12:03 +0530 Subject: [PATCH 2/7] Updating the retry connect --- .../silabs/SiWx/ble/BLEManagerImpl.cpp | 2 +- .../silabs/wifi/CODE_REVIEW_WIFI_CHANGES.md | 94 +++++++++++++++++++ .../silabs/wifi/SiWx/WifiInterfaceImpl.cpp | 20 +++- src/platform/silabs/wifi/WifiInterface.cpp | 23 ++--- src/platform/silabs/wifi/WifiInterface.h | 5 +- 5 files changed, 128 insertions(+), 16 deletions(-) create mode 100644 src/platform/silabs/wifi/CODE_REVIEW_WIFI_CHANGES.md diff --git a/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp b/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp index 458620117d2..dfe62643d86 100644 --- a/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp +++ b/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp @@ -102,7 +102,7 @@ constexpr osThreadAttr_t kBleTaskAttr = { .name = "rsi_ble", .cb_size = osThreadCbSize, .stack_mem = bleStack, .stack_size = kBleTaskSize, - .priority = osPriorityHigh }; + .priority = osPriorityHigh2 }; void rsi_ble_add_matter_service(void) { diff --git a/src/platform/silabs/wifi/CODE_REVIEW_WIFI_CHANGES.md b/src/platform/silabs/wifi/CODE_REVIEW_WIFI_CHANGES.md new file mode 100644 index 00000000000..d99f01459fe --- /dev/null +++ b/src/platform/silabs/wifi/CODE_REVIEW_WIFI_CHANGES.md @@ -0,0 +1,94 @@ +# Code Review: Wi-Fi Platform Changes + +## Summary of Changes + +### 1. Scan and join split (WifiInterfaceImpl) +- **Events**: Added `kStationStartScan` (5); renumbered `kStationStartJoin` (6), `kConnectionComplete` (7), etc. +- **Flow**: `ConnectToAccessPoint()` posts `kStationStartScan` -> ProcessEvent runs high-perf (ICD), `InitiateScan()`, then posts `kStationStartJoin` -> ProcessEvent runs `JoinWifiNetwork()` only. +- **Effect**: Scan and join are separate events; join runs only after scan completes. + +### 2. Trigger disconnection via event (WifiInterfaceImpl) +- **TriggerDisconnection()**: Now only posts `kStationDisconnect` and returns `CHIP_NO_ERROR` (no direct platform call). +- **kStationDisconnect handler**: Calls `TriggerPlatformWifiDisconnection()` at the start, then clears state and notifies IP/connectivity. +- **Effect**: Disconnect is asynchronous and runs on the Wi-Fi task. + +### 3. QuickJoinToAccessPoint API (WifiInterface + WifiInterfaceImpl) +- **New API**: `QuickJoinToAccessPoint()` validates provisioned state, then posts `kStationStartJoin` only (no scan). +- **Use case**: When channel/BSSID is already known to avoid a prior scan. + +### 4. Credential validation in SetWifiCredentials (WifiInterfaceImpl + interface) +- **SetWifiCredentials**: Now returns `CHIP_ERROR`; validates `ssidLength > 0` and `ssidLength <= WFX_MAX_SSID_LENGTH` before storing. +- **ConnectToAccessPoint / QuickJoinToAccessPoint**: Removed redundant ssidLength checks (rely on validation at set time). +- **Call site**: NetworkCommissioningWiFiDriver uses `ReturnErrorOnFailure(SetWifiCredentials(wifiConfig))`. + +### 5. Retry with scan+join on specific join failure (WifiInterfaceImpl) +- **JoinWifiNetwork** (sync failure): On failure, if `status == SL_STATUS_SI91X_NO_AP_FOUND` schedules retry with scan+join; otherwise schedules default retry. +- **JoinCallback**: Calls `ScheduleConnectionAttempt()` with no argument (default). +- **Note**: Earlier design used 0x10003 and `mJoinAttemptIsQuickJoin` so only quick-join attempts would fall back to scan+join; current code uses `SL_STATUS_SI91X_NO_AP_FOUND` for all join paths. + +### 6. ScheduleConnectionAttempt(quickJoin) and timer (WifiInterface) +- **ScheduleConnectionAttempt(bool quickJoin = false)**: `quickJoin == true` -> next retry uses quick join; `quickJoin == false` -> next retry uses scan then join (ConnectToAccessPoint). +- **Timer**: Intended to pass the quickJoin value via the timer argument (e.g. timer created with `&mRetryTimerQuickJoin`, callback reads `*static_cast(arg)`). + +--- + +## Issues and Inconsistencies + +### 1. NO_AP_FOUND retry mode (likely bug) +**File**: `WifiInterfaceImpl.cpp` (JoinWifiNetwork failure path) + +```cpp +if (status == SL_STATUS_SI91X_NO_AP_FOUND) +{ + ScheduleConnectionAttempt(true); // -> next retry = quick join +} +else +{ + ScheduleConnectionAttempt(false); // -> next retry = scan + join +} +``` + +When the AP is not found, the next retry should use **scan then join**, not quick join. So for `SL_STATUS_SI91X_NO_AP_FOUND` it should be `ScheduleConnectionAttempt(false)`. + +**Suggested fix**: Use `ScheduleConnectionAttempt(false)` when `status == SL_STATUS_SI91X_NO_AP_FOUND`, and `ScheduleConnectionAttempt(true)` (or no arg) in the `else` branch. + +### 2. Timer callback still using global (WifiInterface.cpp) +**Current**: A file-scope `bool mWiFiQuickJoin` is set in `ScheduleConnectionAttempt(quickJoin)` and read in `RetryConnectionTimerHandler`. The timer is created with `this`, but the callback does not use `arg`. + +**Intended design**: Pass `&mRetryTimerQuickJoin` when creating the timer; in `ScheduleConnectionAttempt(quickJoin)` set `mRetryTimerQuickJoin = quickJoin`; in the callback read `*static_cast(arg)`. No global. + +**Suggested fix**: Remove the global; add private member `bool mRetryTimerQuickJoin` in `WifiInterface`; create timer with `&mRetryTimerQuickJoin`; in the callback use `bool quickJoin = *static_cast(arg);` and `GetInstance()` for the interface. + +### 3. Timer failed-to-start fallback (WifiInterface.cpp) +**Current**: When `osTimerStart` fails, the code always calls `ConnectToAccessPoint()`. + +**Consideration**: For consistency with the scheduled retry, the fallback could use the same `quickJoin` value just set (e.g. if `mRetryTimerQuickJoin` then `QuickJoinToAccessPoint()`, else `ConnectToAccessPoint()`). Optional improvement. + +### 4. JoinCallback and quick-join vs scan+join retry +**Current**: `JoinCallback` on failure always calls `ScheduleConnectionAttempt()` with no argument (default quick join). + +If the intent is “only when the attempt was quick-join and failed with AP-not-found, retry with scan+join”, then you need to track whether the current join was from quick join (e.g. `mJoinAttemptIsQuickJoin` set in `QuickJoinToAccessPoint`, cleared in scan path and on success/failure), and in JoinCallback when `status == SL_STATUS_SI91X_NO_AP_FOUND` (or 0x10003) and `mJoinAttemptIsQuickJoin` call `ScheduleConnectionAttempt(false)`. Otherwise JoinCallback’s behavior is consistent with “always default retry (quick join).” + +### 5. ScheduleConnectionAttempt default parameter +**Header**: `void ScheduleConnectionAttempt(bool quickJoin = false);` + +Default `false` means “next retry = scan and join.” If the preferred default is “next retry = quick join” (to match previous behavior), the default should be `true`. + +--- + +## What Looks Good + +- Clear split between scan and join events and use of `kStationStartScan` / `kStationStartJoin`. +- TriggerDisconnection fully event-driven; platform disconnect in one place (kStationDisconnect). +- SetWifiCredentials validation and return value; callers simplified. +- QuickJoinToAccessPoint and ConnectToAccessPoint have clear, separate roles. +- Event enum renumbering is consistent. + +--- + +## Suggested Next Steps + +1. Fix NO_AP_FOUND retry: use `ScheduleConnectionAttempt(false)` when `status == SL_STATUS_SI91X_NO_AP_FOUND`. +2. Remove the global in WifiInterface.cpp and pass quickJoin via the timer argument as designed. +3. Decide default for `ScheduleConnectionAttempt(bool quickJoin)` and document it. +4. Optionally: add quick-join tracking and use it in JoinCallback so only quick-join failures with AP-not-found trigger scan+join retry. diff --git a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp index 2e95cccfa61..5813534e3f1 100644 --- a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp +++ b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp @@ -98,7 +98,7 @@ constexpr osThreadAttr_t kWlanTaskAttr = { .name = "wlan_rsi", .cb_size = osThreadCbSize, .stack_mem = wlanStack, .stack_size = kWlanTaskSize, - .priority = osPriorityAboveNormal7 }; + .priority = osPriorityHigh }; #if CHIP_CONFIG_ENABLE_ICD_SERVER constexpr uint32_t kTimeToFullBeaconReception = 5000; // 5 seconds @@ -751,7 +751,14 @@ sl_status_t WifiInterfaceImpl::JoinWifiNetwork(void) ChipLogError(DeviceLayer, "sl_net_up failed: 0x%lx", static_cast(status)); wfx_rsi.dev_state.Clear(WifiInterface::WifiState::kStationConnecting).Clear(WifiInterface::WifiState::kStationConnected); - ScheduleConnectionAttempt(); + if (status == SL_STATUS_SI91X_NO_AP_FOUND) + { + ScheduleConnectionAttempt(false); // Scan and join + } + else + { + ScheduleConnectionAttempt(true); // Quick join + } return status; } @@ -779,7 +786,14 @@ sl_status_t WifiInterfaceImpl::JoinCallback(sl_wifi_event_t event, char * result ChipLogError(DeviceLayer, "JoinCallback: failed: 0x%lx", status); wfx_rsi.dev_state.Clear(WifiInterface::WifiState::kStationConnected); - mInstance.ScheduleConnectionAttempt(); + if (status == SL_STATUS_SI91X_NO_AP_FOUND) + { + mInstance.ScheduleConnectionAttempt(false); // Scan and join + } + else + { + mInstance.ScheduleConnectionAttempt(true); // Quick join + } } return status; diff --git a/src/platform/silabs/wifi/WifiInterface.cpp b/src/platform/silabs/wifi/WifiInterface.cpp index 4c4c2246b58..ea756802a4c 100644 --- a/src/platform/silabs/wifi/WifiInterface.cpp +++ b/src/platform/silabs/wifi/WifiInterface.cpp @@ -42,17 +42,17 @@ constexpr uint8_t kWlanMaxRetryIntervalsInSec = 60; uint8_t retryInterval = kWlanMinRetryIntervalsInSec; /** - * @brief Retry timer callback that triggers a reconnection attempt - * - * TODO: The structure of the retry needs to be redone - * - * @param arg + * @brief Retry timer callback that triggers a reconnection attempt. + * @param arg Pointer to bool (quickJoin) written by ScheduleConnectionAttempt when the timer was started. */ void RetryConnectionTimerHandler(void * arg) { - if (chip::DeviceLayer::Silabs::WifiInterface::GetInstance().ConnectToAccessPoint() != CHIP_NO_ERROR) + bool quickJoin = *static_cast(arg); + chip::DeviceLayer::Silabs::WifiInterface & wifi = chip::DeviceLayer::Silabs::WifiInterface::GetInstance(); + CHIP_ERROR err = quickJoin ? wifi.QuickJoinToAccessPoint() : wifi.ConnectToAccessPoint(); + if (err != CHIP_NO_ERROR) { - ChipLogError(DeviceLayer, "ConnectToAccessPoint() failed."); + ChipLogError(DeviceLayer, "Connection attempt failed."); } } @@ -126,8 +126,8 @@ void WifiInterface::NotifyWifiTaskInitialized(void) sl_wfx_startup_ind_t evt = { 0 }; // TODO: We should move this to the init function and not the notification function - // Creating a timer which will be used to retry connection with AP - mRetryTimer = osTimerNew(RetryConnectionTimerHandler, osTimerOnce, NULL, NULL); + // Creating a timer which will be used to retry connection with AP (arg points to mRetryTimerQuickJoin, set in ScheduleConnectionAttempt). + mRetryTimer = osTimerNew(RetryConnectionTimerHandler, osTimerOnce, &mRetryTimerQuickJoin, NULL); VerifyOrReturn(mRetryTimer != NULL); evt.header.id = to_underlying(WifiEvent::kStartUp); @@ -148,8 +148,10 @@ void WifiInterface::NotifyWifiTaskInitialized(void) } // TODO: The retry stategy needs to be re-worked -void WifiInterface::ScheduleConnectionAttempt() +void WifiInterface::ScheduleConnectionAttempt(bool quickJoin) { + mRetryTimerQuickJoin = quickJoin; + if (retryInterval > kWlanMaxRetryIntervalsInSec) { retryInterval = kWlanMaxRetryIntervalsInSec; @@ -158,7 +160,6 @@ void WifiInterface::ScheduleConnectionAttempt() if (osTimerStart(mRetryTimer, pdMS_TO_TICKS(retryInterval * 1000)) != osOK) { ChipLogProgress(DeviceLayer, "Failed to start retry timer"); - // Sending the join command if retry timer failed to start if (ConnectToAccessPoint() != CHIP_NO_ERROR) { ChipLogError(DeviceLayer, "ConnectToAccessPoint() failed."); diff --git a/src/platform/silabs/wifi/WifiInterface.h b/src/platform/silabs/wifi/WifiInterface.h index 1d6e672c95a..0e9c4364060 100644 --- a/src/platform/silabs/wifi/WifiInterface.h +++ b/src/platform/silabs/wifi/WifiInterface.h @@ -414,8 +414,10 @@ class WifiInterface : public WifiStateProvider, public PowerSaveInterface * @note The retry interval increases exponentially with each attempt, starting from a minimum value and doubling each time, * up to a maximum value. For example, if the initial retry interval is 1 second, the subsequent intervals will be 2 * seconds, 4 seconds, 8 seconds, and so on, until the maximum retry interval is reached. + * + * @param quickJoin If true, the next retry will use quick join; if false, scan then join (ConnectToAccessPoint). */ - void ScheduleConnectionAttempt(); + void ScheduleConnectionAttempt(bool quickJoin = false); bool mHasNotifiedIPv6 = false; #if CHIP_DEVICE_CONFIG_ENABLE_IPV4 @@ -424,6 +426,7 @@ class WifiInterface : public WifiStateProvider, public PowerSaveInterface private: osTimerId_t mRetryTimer; + bool mRetryTimerQuickJoin = false; }; } // namespace Silabs From bc2c2381a6fe6cdcdc9ecdfbc350ceb938548889 Mon Sep 17 00:00:00 2001 From: chirag-silabs Date: Thu, 12 Mar 2026 20:47:54 +0530 Subject: [PATCH 3/7] Removing the doc file --- .../silabs/wifi/CODE_REVIEW_WIFI_CHANGES.md | 94 ------------------- 1 file changed, 94 deletions(-) delete mode 100644 src/platform/silabs/wifi/CODE_REVIEW_WIFI_CHANGES.md diff --git a/src/platform/silabs/wifi/CODE_REVIEW_WIFI_CHANGES.md b/src/platform/silabs/wifi/CODE_REVIEW_WIFI_CHANGES.md deleted file mode 100644 index d99f01459fe..00000000000 --- a/src/platform/silabs/wifi/CODE_REVIEW_WIFI_CHANGES.md +++ /dev/null @@ -1,94 +0,0 @@ -# Code Review: Wi-Fi Platform Changes - -## Summary of Changes - -### 1. Scan and join split (WifiInterfaceImpl) -- **Events**: Added `kStationStartScan` (5); renumbered `kStationStartJoin` (6), `kConnectionComplete` (7), etc. -- **Flow**: `ConnectToAccessPoint()` posts `kStationStartScan` -> ProcessEvent runs high-perf (ICD), `InitiateScan()`, then posts `kStationStartJoin` -> ProcessEvent runs `JoinWifiNetwork()` only. -- **Effect**: Scan and join are separate events; join runs only after scan completes. - -### 2. Trigger disconnection via event (WifiInterfaceImpl) -- **TriggerDisconnection()**: Now only posts `kStationDisconnect` and returns `CHIP_NO_ERROR` (no direct platform call). -- **kStationDisconnect handler**: Calls `TriggerPlatformWifiDisconnection()` at the start, then clears state and notifies IP/connectivity. -- **Effect**: Disconnect is asynchronous and runs on the Wi-Fi task. - -### 3. QuickJoinToAccessPoint API (WifiInterface + WifiInterfaceImpl) -- **New API**: `QuickJoinToAccessPoint()` validates provisioned state, then posts `kStationStartJoin` only (no scan). -- **Use case**: When channel/BSSID is already known to avoid a prior scan. - -### 4. Credential validation in SetWifiCredentials (WifiInterfaceImpl + interface) -- **SetWifiCredentials**: Now returns `CHIP_ERROR`; validates `ssidLength > 0` and `ssidLength <= WFX_MAX_SSID_LENGTH` before storing. -- **ConnectToAccessPoint / QuickJoinToAccessPoint**: Removed redundant ssidLength checks (rely on validation at set time). -- **Call site**: NetworkCommissioningWiFiDriver uses `ReturnErrorOnFailure(SetWifiCredentials(wifiConfig))`. - -### 5. Retry with scan+join on specific join failure (WifiInterfaceImpl) -- **JoinWifiNetwork** (sync failure): On failure, if `status == SL_STATUS_SI91X_NO_AP_FOUND` schedules retry with scan+join; otherwise schedules default retry. -- **JoinCallback**: Calls `ScheduleConnectionAttempt()` with no argument (default). -- **Note**: Earlier design used 0x10003 and `mJoinAttemptIsQuickJoin` so only quick-join attempts would fall back to scan+join; current code uses `SL_STATUS_SI91X_NO_AP_FOUND` for all join paths. - -### 6. ScheduleConnectionAttempt(quickJoin) and timer (WifiInterface) -- **ScheduleConnectionAttempt(bool quickJoin = false)**: `quickJoin == true` -> next retry uses quick join; `quickJoin == false` -> next retry uses scan then join (ConnectToAccessPoint). -- **Timer**: Intended to pass the quickJoin value via the timer argument (e.g. timer created with `&mRetryTimerQuickJoin`, callback reads `*static_cast(arg)`). - ---- - -## Issues and Inconsistencies - -### 1. NO_AP_FOUND retry mode (likely bug) -**File**: `WifiInterfaceImpl.cpp` (JoinWifiNetwork failure path) - -```cpp -if (status == SL_STATUS_SI91X_NO_AP_FOUND) -{ - ScheduleConnectionAttempt(true); // -> next retry = quick join -} -else -{ - ScheduleConnectionAttempt(false); // -> next retry = scan + join -} -``` - -When the AP is not found, the next retry should use **scan then join**, not quick join. So for `SL_STATUS_SI91X_NO_AP_FOUND` it should be `ScheduleConnectionAttempt(false)`. - -**Suggested fix**: Use `ScheduleConnectionAttempt(false)` when `status == SL_STATUS_SI91X_NO_AP_FOUND`, and `ScheduleConnectionAttempt(true)` (or no arg) in the `else` branch. - -### 2. Timer callback still using global (WifiInterface.cpp) -**Current**: A file-scope `bool mWiFiQuickJoin` is set in `ScheduleConnectionAttempt(quickJoin)` and read in `RetryConnectionTimerHandler`. The timer is created with `this`, but the callback does not use `arg`. - -**Intended design**: Pass `&mRetryTimerQuickJoin` when creating the timer; in `ScheduleConnectionAttempt(quickJoin)` set `mRetryTimerQuickJoin = quickJoin`; in the callback read `*static_cast(arg)`. No global. - -**Suggested fix**: Remove the global; add private member `bool mRetryTimerQuickJoin` in `WifiInterface`; create timer with `&mRetryTimerQuickJoin`; in the callback use `bool quickJoin = *static_cast(arg);` and `GetInstance()` for the interface. - -### 3. Timer failed-to-start fallback (WifiInterface.cpp) -**Current**: When `osTimerStart` fails, the code always calls `ConnectToAccessPoint()`. - -**Consideration**: For consistency with the scheduled retry, the fallback could use the same `quickJoin` value just set (e.g. if `mRetryTimerQuickJoin` then `QuickJoinToAccessPoint()`, else `ConnectToAccessPoint()`). Optional improvement. - -### 4. JoinCallback and quick-join vs scan+join retry -**Current**: `JoinCallback` on failure always calls `ScheduleConnectionAttempt()` with no argument (default quick join). - -If the intent is “only when the attempt was quick-join and failed with AP-not-found, retry with scan+join”, then you need to track whether the current join was from quick join (e.g. `mJoinAttemptIsQuickJoin` set in `QuickJoinToAccessPoint`, cleared in scan path and on success/failure), and in JoinCallback when `status == SL_STATUS_SI91X_NO_AP_FOUND` (or 0x10003) and `mJoinAttemptIsQuickJoin` call `ScheduleConnectionAttempt(false)`. Otherwise JoinCallback’s behavior is consistent with “always default retry (quick join).” - -### 5. ScheduleConnectionAttempt default parameter -**Header**: `void ScheduleConnectionAttempt(bool quickJoin = false);` - -Default `false` means “next retry = scan and join.” If the preferred default is “next retry = quick join” (to match previous behavior), the default should be `true`. - ---- - -## What Looks Good - -- Clear split between scan and join events and use of `kStationStartScan` / `kStationStartJoin`. -- TriggerDisconnection fully event-driven; platform disconnect in one place (kStationDisconnect). -- SetWifiCredentials validation and return value; callers simplified. -- QuickJoinToAccessPoint and ConnectToAccessPoint have clear, separate roles. -- Event enum renumbering is consistent. - ---- - -## Suggested Next Steps - -1. Fix NO_AP_FOUND retry: use `ScheduleConnectionAttempt(false)` when `status == SL_STATUS_SI91X_NO_AP_FOUND`. -2. Remove the global in WifiInterface.cpp and pass quickJoin via the timer argument as designed. -3. Decide default for `ScheduleConnectionAttempt(bool quickJoin)` and document it. -4. Optionally: add quick-join tracking and use it in JoinCallback so only quick-join failures with AP-not-found trigger scan+join retry. From 9f884d59cdd4e5733ff82f12c1c628d587f32694 Mon Sep 17 00:00:00 2001 From: chirag-silabs Date: Fri, 13 Mar 2026 11:15:46 +0530 Subject: [PATCH 4/7] Addressing and modifying the code --- .../silabs/wifi/SiWx/WifiInterfaceImpl.cpp | 33 ++- .../silabs/wifi/SiWx/WifiInterfaceImpl.h | 272 +++++++++--------- src/platform/silabs/wifi/WifiInterface.cpp | 12 +- src/platform/silabs/wifi/WifiInterface.h | 16 +- 4 files changed, 157 insertions(+), 176 deletions(-) diff --git a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp index 5813534e3f1..94cf5638315 100644 --- a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp +++ b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp @@ -486,6 +486,9 @@ sl_status_t SetWifiConfigurations() .encryption = SL_WIFI_DEFAULT_ENCRYPTION, .client_options = SL_WIFI_JOIN_WITH_SCAN, .credential_id = SL_NET_DEFAULT_WIFI_CLIENT_CREDENTIAL_ID, + .channel_bitmap = { + .channel_bitmap_2_4 = SL_WIFI_DEFAULT_CHANNEL_BITMAP + }, }, .ip = { .mode = SL_IP_MANAGEMENT_DHCP, @@ -503,7 +506,8 @@ sl_status_t SetWifiConfigurations() { // AP channel is known - This indicates that the network scan was done for a specific SSID. // Providing the channel and BSSID in the profile avoids scanning all channels again. - profile.config.channel.channel = wfx_rsi.ap_chan; + profile.config.channel.channel = wfx_rsi.ap_chan; + profile.config.channel_bitmap.channel_bitmap_2_4 = BIT((wfx_rsi.ap_chan - 1)); chip::MutableByteSpan bssidSpan(profile.config.bssid.octet, kWifiMacAddressLength); chip::ByteSpan inBssid(wfx_rsi.ap_bssid.data(), kWifiMacAddressLength); @@ -519,6 +523,7 @@ sl_status_t SetWifiConfigurations() status = sl_net_set_profile(SL_NET_WIFI_CLIENT_INTERFACE, SL_NET_DEFAULT_WIFI_CLIENT_PROFILE_ID, &profile); VerifyOrReturnError(status == SL_STATUS_OK, status, ChipLogError(DeviceLayer, "sl_net_set_profile failed: 0x%lx", status)); + osDelay(1000); return status; } @@ -753,11 +758,13 @@ sl_status_t WifiInterfaceImpl::JoinWifiNetwork(void) wfx_rsi.dev_state.Clear(WifiInterface::WifiState::kStationConnecting).Clear(WifiInterface::WifiState::kStationConnected); if (status == SL_STATUS_SI91X_NO_AP_FOUND) { - ScheduleConnectionAttempt(false); // Scan and join + mUseQuickJoin = false; // Scan and join + ScheduleConnectionAttempt(); } else { - ScheduleConnectionAttempt(true); // Quick join + mUseQuickJoin = true; // Quick join + ScheduleConnectionAttempt(); } return status; @@ -788,11 +795,13 @@ sl_status_t WifiInterfaceImpl::JoinCallback(sl_wifi_event_t event, char * result if (status == SL_STATUS_SI91X_NO_AP_FOUND) { - mInstance.ScheduleConnectionAttempt(false); // Scan and join + mInstance.mUseQuickJoin = false; // Scan and join + mInstance.ScheduleConnectionAttempt(); } else { - mInstance.ScheduleConnectionAttempt(true); // Quick join + mInstance.mUseQuickJoin = true; // Quick join + mInstance.ScheduleConnectionAttempt(); } } @@ -1138,19 +1147,9 @@ CHIP_ERROR WifiInterfaceImpl::ConnectToAccessPoint() { VerifyOrReturnError(IsWifiProvisioned(), CHIP_ERROR_INCORRECT_STATE); - ChipLogProgress(DeviceLayer, "connect to access point: %s", wfx_rsi.credentials.ssid); - - PostWifiPlatformEvent(WifiPlatformEvent::kStationStartScan); - return CHIP_NO_ERROR; -} - -CHIP_ERROR WifiInterfaceImpl::QuickJoinToAccessPoint() -{ - VerifyOrReturnError(IsWifiProvisioned(), CHIP_ERROR_INCORRECT_STATE); - - ChipLogProgress(DeviceLayer, "quick join to access point: %s", wfx_rsi.credentials.ssid); + ChipLogProgress(DeviceLayer, "%s to access point: %s", mUseQuickJoin ? "quick join" : "connect", wfx_rsi.credentials.ssid); - PostWifiPlatformEvent(WifiPlatformEvent::kStationStartJoin); + PostWifiPlatformEvent(mUseQuickJoin ? WifiPlatformEvent::kStationStartJoin : WifiPlatformEvent::kStationStartScan); return CHIP_NO_ERROR; } diff --git a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.h b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.h index 8b6c8920239..5867b88a098 100644 --- a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.h +++ b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.h @@ -19,146 +19,144 @@ namespace chip { namespace DeviceLayer { -namespace Silabs { - -/** - * @brief WifiInterface implementation for the SiWx platform - * - */ -class WifiInterfaceImpl final : public WifiInterface -{ -public: - enum class WifiPlatformEvent : uint8_t - { - kStationConnect = 0, - kStationDisconnect = 1, - kAPStart = 2, - kAPStop = 3, - kStationStartScan = 5, - kStationStartJoin = 6, - kConnectionComplete = 7, /* This combines the DHCP and Notify */ - kStationDhcpDone = 8, - kStationDhcpPoll = 9, - }; - - static WifiInterfaceImpl & GetInstance() { return mInstance; } - - WifiInterfaceImpl(const WifiInterfaceImpl &) = delete; - WifiInterfaceImpl & operator=(const WifiInterfaceImpl &) = delete; - - /* - * WifiInterface impl - */ - - CHIP_ERROR GetMacAddress(sl_wfx_interface_t interface, chip::MutableByteSpan & addr) override; - CHIP_ERROR StartNetworkScan(chip::ByteSpan ssid, ScanCallback callback) override; - CHIP_ERROR StartWifiTask() override; - void ConfigureStationMode() override; - bool IsStationConnected() override; - bool IsStationModeEnabled() override; - bool IsStationReady() override; - CHIP_ERROR TriggerDisconnection() override; - void ClearWifiCredentials() override; - CHIP_ERROR SetWifiCredentials(const WifiCredentials & credentials) override; - CHIP_ERROR GetWifiCredentials(WifiCredentials & credentials) override; - CHIP_ERROR ConnectToAccessPoint(void) override; - CHIP_ERROR QuickJoinToAccessPoint(void) override; - bool HasAnIPv4Address() override; - bool HasAnIPv6Address() override; - void CancelScanNetworks() override; - bool IsWifiProvisioned() override; - CHIP_ERROR InitWiFiStack(void) override; - CHIP_ERROR GetAccessPointInfo(wfx_wifi_scan_result_t & info) override; - CHIP_ERROR GetAccessPointExtendedInfo(wfx_wifi_scan_ext_t & info) override; - CHIP_ERROR ResetCounters() override; + namespace Silabs { + + /** + * @brief WifiInterface implementation for the SiWx platform + * + */ + class WifiInterfaceImpl final : public WifiInterface { + public: + enum class WifiPlatformEvent : uint8_t { + kStationConnect = 0, + kStationDisconnect = 1, + kAPStart = 2, + kAPStop = 3, + kStationStartScan = 5, + kStationStartJoin = 6, + kConnectionComplete = 7, /* This combines the DHCP and Notify */ + kStationDhcpDone = 8, + kStationDhcpPoll = 9, + }; + + static WifiInterfaceImpl & GetInstance() { return mInstance; } + + WifiInterfaceImpl(const WifiInterfaceImpl &) = delete; + WifiInterfaceImpl & operator=(const WifiInterfaceImpl &) = delete; + + /* + * WifiInterface impl + */ + + CHIP_ERROR GetMacAddress(sl_wfx_interface_t interface, chip::MutableByteSpan & addr) override; + CHIP_ERROR StartNetworkScan(chip::ByteSpan ssid, ScanCallback callback) override; + CHIP_ERROR StartWifiTask() override; + void ConfigureStationMode() override; + bool IsStationConnected() override; + bool IsStationModeEnabled() override; + bool IsStationReady() override; + CHIP_ERROR TriggerDisconnection() override; + void ClearWifiCredentials() override; + CHIP_ERROR SetWifiCredentials(const WifiCredentials & credentials) override; + CHIP_ERROR GetWifiCredentials(WifiCredentials & credentials) override; + CHIP_ERROR ConnectToAccessPoint(void) override; + bool HasAnIPv4Address() override; + bool HasAnIPv6Address() override; + void CancelScanNetworks() override; + bool IsWifiProvisioned() override; + CHIP_ERROR InitWiFiStack(void) override; + CHIP_ERROR GetAccessPointInfo(wfx_wifi_scan_result_t & info) override; + CHIP_ERROR GetAccessPointExtendedInfo(wfx_wifi_scan_ext_t & info) override; + CHIP_ERROR ResetCounters() override; #if CHIP_CONFIG_ENABLE_ICD_SERVER - CHIP_ERROR ConfigureBroadcastFilter(bool enableBroadcastFilter) override; - CHIP_ERROR ConfigurePowerSave(PowerSaveInterface::PowerSaveConfiguration configuration, uint32_t listenInterval) override; + CHIP_ERROR ConfigureBroadcastFilter(bool enableBroadcastFilter) override; + CHIP_ERROR ConfigurePowerSave(PowerSaveInterface::PowerSaveConfiguration configuration, uint32_t listenInterval) override; #endif // CHIP_CONFIG_ENABLE_ICD_SERVER - /** - * @brief Processes the wifi platform events for the SiWx platform - * - * @param event - */ - void ProcessEvent(WifiPlatformEvent event); - -protected: - /** - * @brief Function calls the underlying platforms disconnection API. - * - * @return sl_status_t SL_STATUS_OK, the Wi-Fi disconnection was succesfully triggered - * SL_STATUS_FAILURE, otherwise - */ - sl_status_t TriggerPlatformWifiDisconnection(); - /** - * @brief Posts an event to the Wi-Fi task - * - * @param[in] event Event to process. - */ - void PostWifiPlatformEvent(WifiPlatformEvent event); - /** - * @brief Main worker function for the Matter Wi-Fi task responsible of processing Wi-Fi platform events. - * Function is used in the StartWifiTask. - * - * @param[in] arg context pointer - */ - static void MatterWifiTask(void * arg); - - /** - * @brief Notify the application about the connectivity status if it has not been notified yet. - */ - void NotifyConnectivity(void); - - /** - * @brief Function resets the IP and connectiity flags and triggers the DHCP operation - * - */ - void ResetConnectivityNotificationFlags(); - -private: - WifiInterfaceImpl() = default; - ~WifiInterfaceImpl() = default; - - /** - * @brief Callback function for the SL_WIFI_JOIN_EVENTS group - * - * This callback handler will be invoked when any event within join event group occurs, providing the event details and any - * associated data The callback doesn't get called when we join a network using the sl net APIs - * - * @note In case of failure, the 'result' parameter will be of type sl_status_t, and the 'resultLenght' parameter should be - * ignored - * - * @param[in] event sl_wifi_event_t that triggered the callback - * @param[in] result Pointer to the response data received - * @param[in] result_length Length of the data received in bytes - * @param[in] arg Optional user provided argument - * - * @return sl_status_t Returns the status of the operation - */ - static sl_status_t JoinCallback(sl_wifi_event_t event, char * result, uint32_t resultLenght, void * arg); - - /** - * @brief Triggers a synchronous connection attempt to the stored Wifi crendetials - * - * @return sl_status_t SL_STATUS_IN_PROGRESS, if the device is already connected or connecting. - * SL_STATUS_OK, on connection success. - * other error on failure, otherwise - */ - sl_status_t JoinWifiNetwork(); - - /** - * @brief Processing function responsible for notifying the upper layers of a succesful connection attempt. - * - */ - void NotifySuccessfulConnection(); - - bool mHasNotifiedWifiConnectivity = false; - - static WifiInterfaceImpl mInstance; -}; - -} // namespace Silabs + /** + * @brief Processes the wifi platform events for the SiWx platform + * + * @param event + */ + void ProcessEvent(WifiPlatformEvent event); + + protected: + /** + * @brief Function calls the underlying platforms disconnection API. + * + * @return sl_status_t SL_STATUS_OK, the Wi-Fi disconnection was succesfully triggered + * SL_STATUS_FAILURE, otherwise + */ + sl_status_t TriggerPlatformWifiDisconnection(); + /** + * @brief Posts an event to the Wi-Fi task + * + * @param[in] event Event to process. + */ + void PostWifiPlatformEvent(WifiPlatformEvent event); + /** + * @brief Main worker function for the Matter Wi-Fi task responsible of processing Wi-Fi platform events. + * Function is used in the StartWifiTask. + * + * @param[in] arg context pointer + */ + static void MatterWifiTask(void * arg); + + /** + * @brief Notify the application about the connectivity status if it has not been notified yet. + */ + void NotifyConnectivity(void); + + /** + * @brief Function resets the IP and connectiity flags and triggers the DHCP operation + * + */ + void ResetConnectivityNotificationFlags(); + + private: + WifiInterfaceImpl() = default; + ~WifiInterfaceImpl() = default; + + /** + * @brief Callback function for the SL_WIFI_JOIN_EVENTS group + * + * This callback handler will be invoked when any event within join event group occurs, providing the event details and any + * associated data The callback doesn't get called when we join a network using the sl net APIs + * + * @note In case of failure, the 'result' parameter will be of type sl_status_t, and the 'resultLenght' parameter should be + * ignored + * + * @param[in] event sl_wifi_event_t that triggered the callback + * @param[in] result Pointer to the response data received + * @param[in] result_length Length of the data received in bytes + * @param[in] arg Optional user provided argument + * + * @return sl_status_t Returns the status of the operation + */ + static sl_status_t JoinCallback(sl_wifi_event_t event, char * result, uint32_t resultLenght, void * arg); + + /** + * @brief Triggers a synchronous connection attempt to the stored Wifi crendetials + * + * @return sl_status_t SL_STATUS_IN_PROGRESS, if the device is already connected or connecting. + * SL_STATUS_OK, on connection success. + * other error on failure, otherwise + */ + sl_status_t JoinWifiNetwork(); + + /** + * @brief Processing function responsible for notifying the upper layers of a succesful connection attempt. + * + */ + void NotifySuccessfulConnection(); + + bool mHasNotifiedWifiConnectivity = false; + bool mUseQuickJoin = false; + + static WifiInterfaceImpl mInstance; + }; + + } // namespace Silabs } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/silabs/wifi/WifiInterface.cpp b/src/platform/silabs/wifi/WifiInterface.cpp index ea756802a4c..3d29c6a1a21 100644 --- a/src/platform/silabs/wifi/WifiInterface.cpp +++ b/src/platform/silabs/wifi/WifiInterface.cpp @@ -43,13 +43,11 @@ uint8_t retryInterval = kWlanMinRetryIntervalsInSec; /** * @brief Retry timer callback that triggers a reconnection attempt. - * @param arg Pointer to bool (quickJoin) written by ScheduleConnectionAttempt when the timer was started. */ void RetryConnectionTimerHandler(void * arg) { - bool quickJoin = *static_cast(arg); chip::DeviceLayer::Silabs::WifiInterface & wifi = chip::DeviceLayer::Silabs::WifiInterface::GetInstance(); - CHIP_ERROR err = quickJoin ? wifi.QuickJoinToAccessPoint() : wifi.ConnectToAccessPoint(); + CHIP_ERROR err = wifi.ConnectToAccessPoint(); if (err != CHIP_NO_ERROR) { ChipLogError(DeviceLayer, "Connection attempt failed."); @@ -126,8 +124,8 @@ void WifiInterface::NotifyWifiTaskInitialized(void) sl_wfx_startup_ind_t evt = { 0 }; // TODO: We should move this to the init function and not the notification function - // Creating a timer which will be used to retry connection with AP (arg points to mRetryTimerQuickJoin, set in ScheduleConnectionAttempt). - mRetryTimer = osTimerNew(RetryConnectionTimerHandler, osTimerOnce, &mRetryTimerQuickJoin, NULL); + // Creating a timer which will be used to retry connection with AP. + mRetryTimer = osTimerNew(RetryConnectionTimerHandler, osTimerOnce, NULL, NULL); VerifyOrReturn(mRetryTimer != NULL); evt.header.id = to_underlying(WifiEvent::kStartUp); @@ -148,10 +146,8 @@ void WifiInterface::NotifyWifiTaskInitialized(void) } // TODO: The retry stategy needs to be re-worked -void WifiInterface::ScheduleConnectionAttempt(bool quickJoin) +void WifiInterface::ScheduleConnectionAttempt() { - mRetryTimerQuickJoin = quickJoin; - if (retryInterval > kWlanMaxRetryIntervalsInSec) { retryInterval = kWlanMaxRetryIntervalsInSec; diff --git a/src/platform/silabs/wifi/WifiInterface.h b/src/platform/silabs/wifi/WifiInterface.h index 0e9c4364060..71cf65d2351 100644 --- a/src/platform/silabs/wifi/WifiInterface.h +++ b/src/platform/silabs/wifi/WifiInterface.h @@ -316,6 +316,7 @@ class WifiInterface : public WifiStateProvider, public PowerSaveInterface * connection attempt was successful or not. * * The returned error code only indicates if the connection attempt was triggered or not. + * On retry after failure, the implementation may use quick join (no scan) when channel/BSSID are known. * * @return CHIP_ERROR CHIP_NO_ERROR, the connection attempt was succesfully triggered * CHIP_ERROR_INCORRECT_STATE, the Wi-Fi station does not have any Wi-Fi credentials @@ -324,16 +325,6 @@ class WifiInterface : public WifiStateProvider, public PowerSaveInterface */ virtual CHIP_ERROR ConnectToAccessPoint(void) = 0; - /** - * @brief Triggers join to the provisioned access point without scanning. - * Use when scan info (e.g. channel, BSSID) is already known to avoid a prior scan. - * - * @return CHIP_ERROR CHIP_NO_ERROR, the join was successfully triggered - * CHIP_ERROR_INCORRECT_STATE, not provisioned or no credentials - * CHIP_ERROR_INVALID_ARGUMENT, credentials invalid - */ - virtual CHIP_ERROR QuickJoinToAccessPoint(void) = 0; - /** * @brief Cancels the on-going network scan operation. * If one isn't in-progress, function doesn't do anything @@ -414,10 +405,8 @@ class WifiInterface : public WifiStateProvider, public PowerSaveInterface * @note The retry interval increases exponentially with each attempt, starting from a minimum value and doubling each time, * up to a maximum value. For example, if the initial retry interval is 1 second, the subsequent intervals will be 2 * seconds, 4 seconds, 8 seconds, and so on, until the maximum retry interval is reached. - * - * @param quickJoin If true, the next retry will use quick join; if false, scan then join (ConnectToAccessPoint). */ - void ScheduleConnectionAttempt(bool quickJoin = false); + void ScheduleConnectionAttempt(); bool mHasNotifiedIPv6 = false; #if CHIP_DEVICE_CONFIG_ENABLE_IPV4 @@ -426,7 +415,6 @@ class WifiInterface : public WifiStateProvider, public PowerSaveInterface private: osTimerId_t mRetryTimer; - bool mRetryTimerQuickJoin = false; }; } // namespace Silabs From 15ec311b7e1c1196a1a0522ca53ebc0f30a9491b Mon Sep 17 00:00:00 2001 From: chirag-silabs Date: Fri, 13 Mar 2026 11:23:44 +0530 Subject: [PATCH 5/7] Printing the disconnection --- src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp index 94cf5638315..3a6b1243bea 100644 --- a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp +++ b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp @@ -650,7 +650,7 @@ void WifiInterfaceImpl::ProcessEvent(WifiPlatformEvent event) case WifiPlatformEvent::kStationDisconnect: { ChipLogDetail(DeviceLayer, "WifiPlatformEvent::kStationDisconnect"); - TEMPORARY_RETURN_IGNORED TriggerPlatformWifiDisconnection(); + TriggerPlatformWifiDisconnection(); wfx_rsi.dev_state.Clear(WifiInterface::WifiState::kStationReady) .Clear(WifiInterface::WifiState::kStationConnecting) @@ -899,7 +899,10 @@ void WifiInterfaceImpl::PostWifiPlatformEvent(WifiPlatformEvent event) sl_status_t WifiInterfaceImpl::TriggerPlatformWifiDisconnection() { - return sl_net_down(SL_NET_WIFI_CLIENT_INTERFACE); + sl_status_t status = sl_net_down(SL_NET_WIFI_CLIENT_INTERFACE); + VerifyOrReturnError(status == SL_STATUS_OK, status, ChipLogError(DeviceLayer, "sl_net_down failed: 0x%lx", status)); + + return SL_STATUS_OK; } #if CHIP_CONFIG_ENABLE_ICD_SERVER From 83828cf47ebcebc9dce975166707a4934c07b0e2 Mon Sep 17 00:00:00 2001 From: chirag-silabs Date: Fri, 13 Mar 2026 11:24:46 +0530 Subject: [PATCH 6/7] Reverting the priority for ble and wlan task --- src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp | 2 +- src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp b/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp index dfe62643d86..458620117d2 100644 --- a/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp +++ b/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp @@ -102,7 +102,7 @@ constexpr osThreadAttr_t kBleTaskAttr = { .name = "rsi_ble", .cb_size = osThreadCbSize, .stack_mem = bleStack, .stack_size = kBleTaskSize, - .priority = osPriorityHigh2 }; + .priority = osPriorityHigh }; void rsi_ble_add_matter_service(void) { diff --git a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp index 3a6b1243bea..6293e259251 100644 --- a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp +++ b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp @@ -98,7 +98,7 @@ constexpr osThreadAttr_t kWlanTaskAttr = { .name = "wlan_rsi", .cb_size = osThreadCbSize, .stack_mem = wlanStack, .stack_size = kWlanTaskSize, - .priority = osPriorityHigh }; + .priority = osPriorityAboveNormal7 }; #if CHIP_CONFIG_ENABLE_ICD_SERVER constexpr uint32_t kTimeToFullBeaconReception = 5000; // 5 seconds From db0acc016ca655b1b4ab60e75221c9b25b8c2b65 Mon Sep 17 00:00:00 2001 From: chirag-silabs Date: Fri, 13 Mar 2026 11:29:53 +0530 Subject: [PATCH 7/7] Correcting the ble and wlan tasks priority --- src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp | 2 +- src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp b/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp index 458620117d2..dfe62643d86 100644 --- a/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp +++ b/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp @@ -102,7 +102,7 @@ constexpr osThreadAttr_t kBleTaskAttr = { .name = "rsi_ble", .cb_size = osThreadCbSize, .stack_mem = bleStack, .stack_size = kBleTaskSize, - .priority = osPriorityHigh }; + .priority = osPriorityHigh2 }; void rsi_ble_add_matter_service(void) { diff --git a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp index 6293e259251..03ea0b27463 100644 --- a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp +++ b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp @@ -98,7 +98,7 @@ constexpr osThreadAttr_t kWlanTaskAttr = { .name = "wlan_rsi", .cb_size = osThreadCbSize, .stack_mem = wlanStack, .stack_size = kWlanTaskSize, - .priority = osPriorityAboveNormal7 }; + .priority = osPriorityHigh1 }; #if CHIP_CONFIG_ENABLE_ICD_SERVER constexpr uint32_t kTimeToFullBeaconReception = 5000; // 5 seconds