diff --git a/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp b/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp index 33a594f923..d9c53375e3 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/SiWx/ble/BLEManagerImpl.cpp b/src/platform/silabs/SiWx/ble/BLEManagerImpl.cpp index 458620117d..dfe62643d8 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 7ef4e91dc1..03ea0b2746 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 @@ -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; } @@ -645,7 +650,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 + TriggerPlatformWifiDisconnection(); wfx_rsi.dev_state.Clear(WifiInterface::WifiState::kStationReady) .Clear(WifiInterface::WifiState::kStationConnecting) @@ -664,15 +669,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; @@ -748,7 +756,16 @@ 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) + { + mUseQuickJoin = false; // Scan and join + ScheduleConnectionAttempt(); + } + else + { + mUseQuickJoin = true; // Quick join + ScheduleConnectionAttempt(); + } return status; } @@ -776,7 +793,16 @@ 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.mUseQuickJoin = false; // Scan and join + mInstance.ScheduleConnectionAttempt(); + } + else + { + mInstance.mUseQuickJoin = true; // Quick join + mInstance.ScheduleConnectionAttempt(); + } } return status; @@ -873,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 @@ -1048,9 +1077,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 +1137,22 @@ 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); + ChipLogProgress(DeviceLayer, "%s to access point: %s", mUseQuickJoin ? "quick join" : "connect", wfx_rsi.credentials.ssid); + 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 922b0a60bf..5867b88a09 100644 --- a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.h +++ b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.h @@ -19,144 +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, - kStationStartJoin = 5, - kConnectionComplete = 6, /* This combines the DHCP and Notify */ - kStationDhcpDone = 7, - kStationDhcpPoll = 8, - }; - - 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; - void 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; + 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 4c4c2246b5..3d29c6a1a2 100644 --- a/src/platform/silabs/wifi/WifiInterface.cpp +++ b/src/platform/silabs/wifi/WifiInterface.cpp @@ -42,17 +42,15 @@ 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. */ void RetryConnectionTimerHandler(void * arg) { - if (chip::DeviceLayer::Silabs::WifiInterface::GetInstance().ConnectToAccessPoint() != CHIP_NO_ERROR) + chip::DeviceLayer::Silabs::WifiInterface & wifi = chip::DeviceLayer::Silabs::WifiInterface::GetInstance(); + CHIP_ERROR err = wifi.ConnectToAccessPoint(); + if (err != CHIP_NO_ERROR) { - ChipLogError(DeviceLayer, "ConnectToAccessPoint() failed."); + ChipLogError(DeviceLayer, "Connection attempt failed."); } } @@ -126,7 +124,7 @@ 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 + // Creating a timer which will be used to retry connection with AP. mRetryTimer = osTimerNew(RetryConnectionTimerHandler, osTimerOnce, NULL, NULL); VerifyOrReturn(mRetryTimer != NULL); @@ -158,7 +156,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 94458e55b2..71cf65d235 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 @@ -315,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