diff --git a/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp b/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp index ba80a94be6a96c..88373b85d2e12c 100644 --- a/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp +++ b/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp @@ -265,26 +265,24 @@ chip::BitFlags SlWiFiDriver::ConvertSecuritytype(wfx_sec_t securit bool SlWiFiDriver::StartScanWiFiNetworks(ByteSpan ssid) { - bool scanStarted = false; ChipLogProgress(DeviceLayer, "Start Scan WiFi Networks"); - if (!ssid.empty()) // ssid is given, only scan this network - { - char cSsid[DeviceLayer::Internal::kMaxWiFiSSIDLength] = {}; - memcpy(cSsid, ssid.data(), ssid.size()); - scanStarted = wfx_start_scan(cSsid, OnScanWiFiNetworkDone); - } - else // scan all networks + CHIP_ERROR err = StartNetworkScan(ssid, OnScanWiFiNetworkDone); + + if (err != CHIP_NO_ERROR) { - scanStarted = wfx_start_scan(nullptr, OnScanWiFiNetworkDone); + ChipLogError(DeviceLayer, "StartNetworkScan failed: %s", chip::ErrorStr(err)); + return false; } - return scanStarted; + + return true; } void SlWiFiDriver::OnScanWiFiNetworkDone(wfx_wifi_scan_result_t * aScanResult) { - ChipLogProgress(DeviceLayer, "OnScanWiFiNetworkDone"); if (!aScanResult) { + ChipLogProgress(DeviceLayer, "OnScanWiFiNetworkDone: Receive all scanned networks information."); + if (GetInstance().mpScanCallback != nullptr) { if (mScanResponseIter.Count() == 0) @@ -309,7 +307,7 @@ void SlWiFiDriver::OnScanWiFiNetworkDone(wfx_wifi_scan_result_t * aScanResult) scanResponse.security.Set(GetInstance().ConvertSecuritytype(aScanResult->security)); scanResponse.channel = aScanResult->chan; scanResponse.rssi = aScanResult->rssi; - scanResponse.ssidLen = strnlen(aScanResult->ssid, DeviceLayer::Internal::kMaxWiFiSSIDLength); + scanResponse.ssidLen = aScanResult->ssid_length; memcpy(scanResponse.ssid, aScanResult->ssid, scanResponse.ssidLen); memcpy(scanResponse.bssid, aScanResult->bssid, sizeof(scanResponse.bssid)); diff --git a/src/platform/silabs/wifi/BUILD.gn b/src/platform/silabs/wifi/BUILD.gn index 304fa89cd2e9c3..fa4ef8057fe373 100644 --- a/src/platform/silabs/wifi/BUILD.gn +++ b/src/platform/silabs/wifi/BUILD.gn @@ -21,7 +21,6 @@ import("${chip_root}/third_party/silabs/silabs_board.gni") declare_args() { # Wifi related stuff - they are overridden by gn -args="use_wf200=true" sl_wfx_config_softap = false - sl_wfx_config_scan = true # Argument to force enable WPA3 security on rs91x rs91x_wpa3_transition = true @@ -85,10 +84,6 @@ config("wifi-platform-config") { defines += [ "SL_WFX_CONFIG_SOFTAP" ] } - if (sl_wfx_config_scan) { - defines += [ "SL_WFX_CONFIG_SCAN" ] - } - if (chip_enable_wifi_ipv4) { defines += [ "CHIP_DEVICE_CONFIG_ENABLE_IPV4" ] } diff --git a/src/platform/silabs/wifi/SiWx/WifiInterface.cpp b/src/platform/silabs/wifi/SiWx/WifiInterface.cpp index 7ff167fc718813..f864e0379d9a1e 100644 --- a/src/platform/silabs/wifi/SiWx/WifiInterface.cpp +++ b/src/platform/silabs/wifi/SiWx/WifiInterface.cpp @@ -187,6 +187,7 @@ constexpr uint8_t kAdvActiveScanDuration = 15; constexpr uint8_t kAdvPassiveScanDuration = 20; constexpr uint8_t kAdvMultiProbe = 1; constexpr uint8_t kAdvScanPeriodicity = 10; +constexpr uint8_t kAdvEnableInstantbgScan = 1; // TODO: Confirm that this value works for size and timing constexpr uint8_t kWfxQueueSize = 10; @@ -194,6 +195,72 @@ constexpr uint8_t kWfxQueueSize = 10; // TODO: Figure out why we actually need this, we are already handling failure and retries somewhere else. constexpr uint16_t kWifiScanTimeoutTicks = 10000; +/** + * @brief Network Scan callback when the device receive a scan operation from the controller. + * This callback is used whe the Network Commission Driver send a ScanNetworks command. + * + * If the scan network was requested for a specific SSID - wfx_rsi.scan_ssid had a valid value, + * the callback will only forward that specific networks information. + * If no ssid is provided, wfx_rsi.scan_ssid is a nullptr, we return the information of all scanned networks. + */ +sl_status_t BackgroundScanCallback(sl_wifi_event_t event, sl_wifi_scan_result_t * result, uint32_t result_length, void * arg) +{ + VerifyOrReturnError(result != nullptr, SL_STATUS_NULL_POINTER); + VerifyOrReturnError(wfx_rsi.scan_cb != nullptr, SL_STATUS_INVALID_HANDLE); + + uint32_t nbreResults = result->scan_count; + chip::ByteSpan requestedSsidSpan(wfx_rsi.scan_ssid, wfx_rsi.scan_ssid_length); + + for (uint32_t i = 0; i < nbreResults; i++) + { + wfx_wifi_scan_result_t currentScanResult = { 0 }; + + // Lenght excludes null-character + size_t scannedSsidLenght = strnlen(reinterpret_cast(result->scan_info[i].ssid), WFX_MAX_SSID_LENGTH); + chip::ByteSpan scannedSsidSpan(result->scan_info[i].ssid, scannedSsidLenght); + + // Copy the scanned SSID to the current scan ssid buffer that will be forwarded to the callback + chip::MutableByteSpan currentScanSsid(currentScanResult.ssid, WFX_MAX_SSID_LENGTH); + chip::CopySpanToMutableSpan(scannedSsidSpan, currentScanSsid); + currentScanResult.ssid_length = currentScanSsid.size(); + + chip::ByteSpan inBssid(result->scan_info[i].bssid, kWifiMacAddressLength); + chip::MutableByteSpan outBssid(currentScanResult.bssid, kWifiMacAddressLength); + chip::CopySpanToMutableSpan(inBssid, outBssid); + + // TODO: We should revisit this to make sure we are setting the correct values + currentScanResult.security = static_cast(result->scan_info[i].security_mode); + currentScanResult.rssi = (-1) * result->scan_info[i].rssi_val; // The returned value is positive - we need to flip it + currentScanResult.chan = result->scan_info[i].rf_channel; + + // if user has provided ssid, check if the current scan result ssid matches the user provided ssid + if (!requestedSsidSpan.empty()) + { + if (requestedSsidSpan.data_equal(currentScanSsid)) + { + wfx_rsi.scan_cb(¤tScanResult); + } + } + else // No ssid was provide - forward all results + { + wfx_rsi.scan_cb(¤tScanResult); + } + } + + // cleanup and return + wfx_rsi.dev_state.Clear(WifiState::kScanStarted); + wfx_rsi.scan_cb(nullptr); + wfx_rsi.scan_cb = nullptr; + if (wfx_rsi.scan_ssid) + { + chip::Platform::MemoryFree(wfx_rsi.scan_ssid); + wfx_rsi.scan_ssid = nullptr; + } + osSemaphoreRelease(sScanCompleteSemaphore); + + return SL_STATUS_OK; +} + void DHCPTimerEventHandler(void * arg) { WifiPlatformEvent event = WifiPlatformEvent::kStationDhcpPoll; @@ -474,16 +541,26 @@ sl_status_t sl_matter_wifi_platform_init(void) *********************************************************************/ int32_t wfx_rsi_get_ap_info(wfx_wifi_scan_result_t * ap) { - sl_status_t status = SL_STATUS_OK; - int32_t rssi = 0; - ap->ssid_length = wfx_rsi.sec.ssid_length; - ap->security = wfx_rsi.sec.security; - ap->chan = wfx_rsi.ap_chan; - chip::Platform::CopyString(ap->ssid, ap->ssid_length, wfx_rsi.sec.ssid); - memcpy(&ap->bssid[0], wfx_rsi.ap_mac.data(), kWifiMacAddressLength); - sl_wifi_get_signal_strength(SL_WIFI_CLIENT_INTERFACE, &rssi); + // TODO: Convert this to a int8 + int32_t rssi = 0; + ap->security = wfx_rsi.sec.security; + ap->chan = wfx_rsi.ap_chan; + + chip::MutableByteSpan output(ap->ssid, WFX_MAX_SSID_LENGTH); + // Cast is a workaround until the wfx_rsi structure is refactored + chip::ByteSpan ssid(reinterpret_cast(wfx_rsi.sec.ssid), wfx_rsi.sec.ssid_length); + chip::CopySpanToMutableSpan(ssid, output); + ap->ssid_length = output.size(); + + chip::ByteSpan apMacSpan(wfx_rsi.ap_mac.data(), wfx_rsi.ap_mac.size()); + chip::MutableByteSpan bssidSpan(ap->bssid, kWifiMacAddressLength); + chip::CopySpanToMutableSpan(apMacSpan, bssidSpan); + + // TODO: add error processing + sl_wifi_get_signal_strength(SL_WIFI_CLIENT_INTERFACE, &(rssi)); ap->rssi = rssi; - return status; + + return SL_STATUS_OK; } /****************************************************************** @@ -547,59 +624,6 @@ int32_t sl_wifi_platform_disconnect(void) return sl_net_down((sl_net_interface_t) SL_NET_WIFI_CLIENT_INTERFACE); } -sl_status_t show_scan_results(sl_wifi_scan_result_t * scan_result) -{ - SL_WIFI_ARGS_CHECK_NULL_POINTER(scan_result); - VerifyOrReturnError(wfx_rsi.scan_cb != nullptr, SL_STATUS_INVALID_HANDLE); - - wfx_wifi_scan_result_t cur_scan_result; - for (int idx = 0; idx < (int) scan_result->scan_count; idx++) - { - memset(&cur_scan_result, 0, sizeof(cur_scan_result)); - - cur_scan_result.ssid_length = strnlen((char *) scan_result->scan_info[idx].ssid, - std::min(sizeof(scan_result->scan_info[idx].ssid), WFX_MAX_SSID_LENGTH)); - chip::Platform::CopyString(cur_scan_result.ssid, cur_scan_result.ssid_length, (char *) scan_result->scan_info[idx].ssid); - - // if user has provided ssid, then check if the current scan result ssid matches the user provided ssid - if (wfx_rsi.scan_ssid != nullptr && - (strncmp(wfx_rsi.scan_ssid, cur_scan_result.ssid, std::min(strlen(wfx_rsi.scan_ssid), strlen(cur_scan_result.ssid))) == - 0)) - { - continue; - } - cur_scan_result.security = static_cast(scan_result->scan_info[idx].security_mode); - cur_scan_result.rssi = (-1) * scan_result->scan_info[idx].rssi_val; - memcpy(cur_scan_result.bssid, scan_result->scan_info[idx].bssid, kWifiMacAddressLength); - wfx_rsi.scan_cb(&cur_scan_result); - - // if user has not provided the ssid, then call the callback for each scan result - if (wfx_rsi.scan_ssid == nullptr) - { - continue; - } - break; - } - - // cleanup and return - wfx_rsi.dev_state.Clear(WifiState::kScanStarted); - wfx_rsi.scan_cb((wfx_wifi_scan_result_t *) 0); - wfx_rsi.scan_cb = nullptr; - if (wfx_rsi.scan_ssid) - { - chip::Platform::MemoryFree(wfx_rsi.scan_ssid); - wfx_rsi.scan_ssid = nullptr; - } - return SL_STATUS_OK; -} - -sl_status_t bg_scan_callback_handler(sl_wifi_event_t event, sl_wifi_scan_result_t * result, uint32_t result_length, void * arg) -{ - show_scan_results(result); // To do Check error - osSemaphoreRelease(sScanCompleteSemaphore); - return SL_STATUS_OK; -} - /// NotifyConnectivity /// @brief Notify the application about the connectivity status if it has not been notified yet. /// Helper function for HandleDHCPPolling. @@ -711,45 +735,54 @@ void ProcessEvent(WifiPlatformEvent event) case WifiPlatformEvent::kScan: ChipLogDetail(DeviceLayer, "WifiPlatformEvent::kScan"); - -#ifdef SL_WFX_CONFIG_SCAN if (!(wfx_rsi.dev_state.Has(WifiState::kScanStarted))) { ChipLogDetail(DeviceLayer, "WifiPlatformEvent::kScan"); - sl_wifi_scan_configuration_t wifi_scan_configuration; - memset(&wifi_scan_configuration, 0, sizeof(wifi_scan_configuration)); - - // TODO: Add scan logic - sl_wifi_advanced_scan_configuration_t advanced_scan_configuration = { 0 }; - int32_t status; - advanced_scan_configuration.active_channel_time = kAdvActiveScanDuration; - advanced_scan_configuration.passive_channel_time = kAdvPassiveScanDuration; - advanced_scan_configuration.trigger_level = kAdvScanThreshold; - advanced_scan_configuration.trigger_level_change = kAdvRssiToleranceThreshold; - advanced_scan_configuration.enable_multi_probe = kAdvMultiProbe; - status = sl_wifi_set_advanced_scan_configuration(&advanced_scan_configuration); - if (SL_STATUS_OK != status) - { - // TODO: Seems like Chipdie should be called here, the device should be initialized here - ChipLogError(DeviceLayer, "sl_wifi_set_advanced_scan_configuration failed: 0x%lx", static_cast(status)); - return; - } + sl_status_t status = SL_STATUS_OK; + sl_wifi_scan_configuration_t wifi_scan_configuration = default_wifi_scan_configuration; if (wfx_rsi.dev_state.Has(WifiState::kStationConnected)) { /* Terminate with end of scan which is no ap sent back */ wifi_scan_configuration.type = SL_WIFI_SCAN_TYPE_ADV_SCAN; wifi_scan_configuration.periodic_scan_interval = kAdvScanPeriodicity; } - else + + sl_wifi_advanced_scan_configuration_t advanced_scan_configuration = { + .trigger_level = kAdvScanThreshold, + .trigger_level_change = kAdvRssiToleranceThreshold, + .active_channel_time = kAdvActiveScanDuration, + .passive_channel_time = kAdvPassiveScanDuration, + .enable_instant_scan = kAdvEnableInstantbgScan, + .enable_multi_probe = kAdvMultiProbe, + }; + + status = sl_wifi_set_advanced_scan_configuration(&advanced_scan_configuration); + + // TODO: Seems like Chipdie should be called here, the device should be initialized here + VerifyOrReturn( + status == SL_STATUS_OK, + ChipLogError(DeviceLayer, "sl_wifi_set_advanced_scan_configuration failed: 0x%lx", static_cast(status))); + + sl_wifi_set_scan_callback(BackgroundScanCallback, nullptr); + wfx_rsi.dev_state.Set(WifiState::kScanStarted); + + // If an ssid was not provided, we need to call the scan API with nullptr to scan all Wi-Fi networks + sl_wifi_ssid_t ssid = { 0 }; + sl_wifi_ssid_t * ssidPtr = nullptr; + + if (wfx_rsi.scan_ssid != nullptr) { - wifi_scan_configuration = default_wifi_scan_configuration; + chip::ByteSpan requestedSsid(wfx_rsi.scan_ssid, wfx_rsi.scan_ssid_length); + chip::MutableByteSpan ouputSsid(ssid.value, sizeof(ssid.value)); + chip::CopySpanToMutableSpan(requestedSsid, ouputSsid); + + ssid.length = ouputSsid.size(); + ssidPtr = &ssid; } - sl_wifi_set_scan_callback(bg_scan_callback_handler, nullptr); - wfx_rsi.dev_state.Set(WifiState::kScanStarted); osSemaphoreAcquire(sScanInProgressSemaphore, osWaitForever); - status = sl_wifi_start_scan(SL_WIFI_CLIENT_2_4GHZ_INTERFACE, nullptr, &wifi_scan_configuration); + status = sl_wifi_start_scan(SL_WIFI_CLIENT_2_4GHZ_INTERFACE, ssidPtr, &wifi_scan_configuration); if (SL_STATUS_IN_PROGRESS == status) { osSemaphoreAcquire(sScanCompleteSemaphore, kWifiScanTimeoutTicks); @@ -757,7 +790,6 @@ void ProcessEvent(WifiPlatformEvent event) osSemaphoreRelease(sScanInProgressSemaphore); } -#endif /* SL_WFX_CONFIG_SCAN */ break; case WifiPlatformEvent::kStationStartJoin: diff --git a/src/platform/silabs/wifi/WifiInterfaceAbstraction.h b/src/platform/silabs/wifi/WifiInterfaceAbstraction.h index f89f3fefed532d..6f42c76f97f014 100644 --- a/src/platform/silabs/wifi/WifiInterfaceAbstraction.h +++ b/src/platform/silabs/wifi/WifiInterfaceAbstraction.h @@ -131,13 +131,14 @@ typedef enum typedef struct wfx_wifi_scan_result { - char ssid[WFX_MAX_SSID_LENGTH + 1]; + uint8_t ssid[WFX_MAX_SSID_LENGTH]; // excludes null-character size_t ssid_length; wfx_sec_t security; uint8_t bssid[kWifiMacAddressLength]; uint8_t chan; int16_t rssi; /* I suspect this is in dBm - so signed */ } wfx_wifi_scan_result_t; +using ScanCallback = void (*)(wfx_wifi_scan_result_t *); typedef struct wfx_wifi_scan_ext { @@ -167,11 +168,9 @@ typedef struct wfx_rsi_s chip::BitFlags dev_state; uint16_t ap_chan; /* The chan our STA is using */ wfx_wifi_provision_t sec; -#ifdef SL_WFX_CONFIG_SCAN - void (*scan_cb)(wfx_wifi_scan_result_t *); - char * scan_ssid; /* Which one are we scanning for */ + ScanCallback scan_cb; + uint8_t * scan_ssid; /* Which one are we scanning for */ size_t scan_ssid_length; -#endif #ifdef SL_WFX_CONFIG_SOFTAP MacAddress softap_mac; #endif @@ -234,6 +233,22 @@ void NotifyConnection(const MacAddress & ap); */ CHIP_ERROR GetMacAddress(sl_wfx_interface_t interface, chip::MutableByteSpan & addr); +/** + * @brief Triggers a network scan + * The function is asynchronous and the result is provided via the callback. + * + * @param ssid The SSID to scan for. If empty, all networks are scanned + * @param callback The callback to be called when the scan is complete. Cannot be nullptr. + * The callback is called asynchrounously. + * + * @return CHIP_ERROR CHIP_NO_ERROR if the network scan was successfully started + * CHIP_INVALID_ARGUMENT if the callback is nullptr + * CHIP_ERROR_IN_PROGRESS, if there is already a network scan in progress + * CHIP_ERROR_INVALID_STRING_LENGTH, if there SSID length exceeds handled limit + * other, if there is a platform error when starting the scan + */ +CHIP_ERROR StartNetworkScan(chip::ByteSpan ssid, ScanCallback callback); + /* Function to update */ sl_status_t wfx_wifi_start(void); @@ -256,7 +271,6 @@ bool wfx_have_ipv4_addr(sl_wfx_interface_t); bool wfx_have_ipv6_addr(sl_wfx_interface_t); wifi_mode_t wfx_get_wifi_mode(void); -bool wfx_start_scan(char * ssid, void (*scan_cb)(wfx_wifi_scan_result_t *)); /* true returned if successfully started */ void wfx_cancel_scan(void); /* diff --git a/src/platform/silabs/wifi/rs911x/WifiInterface.cpp b/src/platform/silabs/wifi/rs911x/WifiInterface.cpp index fa0fac5482a505..8b4b401630ba0d 100644 --- a/src/platform/silabs/wifi/rs911x/WifiInterface.cpp +++ b/src/platform/silabs/wifi/rs911x/WifiInterface.cpp @@ -677,68 +677,61 @@ void ProcessEvent(WifiPlatformEvent event) // TODO: Currently unimplemented break; case WifiPlatformEvent::kScan: { -#ifdef SL_WFX_CONFIG_SCAN rsi_rsp_scan_t scan_rsp = { 0 }; - memset(&scan_rsp, 0, sizeof(scan_rsp)); - int32_t status = rsi_wlan_bgscan_profile(1, &scan_rsp, sizeof(scan_rsp)); + int32_t status = rsi_wlan_bgscan_profile(1, &scan_rsp, sizeof(scan_rsp)); - if (status != RSI_SUCCESS) - { - ChipLogError(DeviceLayer, "rsi_wlan_bgscan failed: %ld ", status); - return; - } + VerifyOrReturn(status == RSI_SUCCESS, ChipLogError(DeviceLayer, "rsi_wlan_bgscan_profile failed: %ld", status)); + VerifyOrReturn(wfx_rsi.scan_cb != nullptr, ChipLogError(DeviceLayer, "wfx_rsi.scan_cb is nullptr")); - if (wfx_rsi.scan_cb == NULL) + uint8_t nbreOfScannedNetworks = scan_rsp.scan_count[0]; + for (int i = 0; i < nbreOfScannedNetworks; i++) { - ChipLogError(DeviceLayer, "wfx_rsi.scan_cb is NULL"); - return; - } + rsi_scan_info_t scan = scan_rsp.scan_info[i]; + wfx_wifi_scan_result_t ap = { 0 }; - rsi_scan_info_t * scan; - wfx_wifi_scan_result_t ap; + ap.ssid_length = strnlen(reinterpret_cast(scan.ssid), WFX_MAX_SSID_LENGTH); - for (int x = 0; x < scan_rsp.scan_count[0]; x++) - { - scan = &scan_rsp.scan_info[x]; - // clear structure and calculate size of SSID - memset(&ap, 0, sizeof(ap)); - ap.ssid_length = - strnlen(reinterpret_cast(scan->ssid), std::min(sizeof(scan->ssid), WFX_MAX_SSID_LENGTH)); - chip::Platform::CopyString(ap.ssid, ap.ssid_length, reinterpret_cast(scan->ssid)); - - // check if the scanned ssid is the one we are looking for - if (wfx_rsi.scan_ssid_length != 0 && strncmp(wfx_rsi.scan_ssid, ap.ssid, WFX_MAX_SSID_LENGTH) != 0) + chip::ByteSpan scannedSsid(scan.ssid, ap.ssid_length); + chip::MutableByteSpan outputSsid(ap.ssid, WFX_MAX_SSID_LENGTH); + chip::CopySpanToMutableSpan(scannedSsid, outputSsid); + + // Check if the scanned ssid is the requested Ssid + chip::ByteSpan requestedSsid(wfx_rsi.scan_ssid, wfx_rsi.scan_ssid_length); + if (!requestedSsid.empty() && !requestedSsid.data_equal(scannedSsid)) { - continue; // we found the targeted ssid. + // Scanned SSID entry does not match the requested SSID. Continue to the next. + continue; } + // TODO: convert security mode from RSI to WFX - ap.security = static_cast(scan->security_mode); - ap.rssi = (-1) * scan->rssi_val; + ap.security = static_cast(scan.security_mode); + ap.rssi = (-1) * scan.rssi_val; configASSERT(sizeof(ap.bssid) == kWifiMacAddressLength); - configASSERT(sizeof(scan->bssid) == kWifiMacAddressLength); - memcpy(ap.bssid, scan->bssid, kWifiMacAddressLength); - (*wfx_rsi.scan_cb)(&ap); + configASSERT(sizeof(scan.bssid) == kWifiMacAddressLength); + + chip::MutableByteSpan bssidSpan(ap.bssid, kWifiMacAddressLength); + chip::ByteSpan scanBssidSpan(scan.bssid, kWifiMacAddressLength); + chip::CopySpanToMutableSpan(scanBssidSpan, bssidSpan); + + wfx_rsi.scan_cb(&ap); - // no ssid filter set, return all results - if (wfx_rsi.scan_ssid_length == 0) + // If we reach this and the requestedSsid is not empty, it means we found the requested SSID and we can exit + if (!requestedSsid.empty()) { - continue; + break; } - - break; } + // Notify the stack that we have finishes scanning for Networks + wfx_rsi.scan_cb(nullptr); - /* Terminate with end of scan which is no ap sent back */ - (*wfx_rsi.scan_cb)((wfx_wifi_scan_result_t *) NULL); + // Clean up wfx_rsi.scan_cb = nullptr; - if (wfx_rsi.scan_ssid) { chip::Platform::MemoryFree(wfx_rsi.scan_ssid); wfx_rsi.scan_ssid = NULL; } -#endif /* SL_WFX_CONFIG_SCAN */ } break; case WifiPlatformEvent::kStationStartJoin: { diff --git a/src/platform/silabs/wifi/wf200/WifiInterface.cpp b/src/platform/silabs/wifi/wf200/WifiInterface.cpp index d93bb170111081..8b3ff043132ced 100644 --- a/src/platform/silabs/wifi/wf200/WifiInterface.cpp +++ b/src/platform/silabs/wifi/wf200/WifiInterface.cpp @@ -115,19 +115,17 @@ bool hasNotifiedWifiConnectivity = false; static uint8_t retryJoin = 0; bool retryInProgress = false; -#ifdef SL_WFX_CONFIG_SCAN static struct scan_result_holder { struct scan_result_holder * next; wfx_wifi_scan_result scan; } * scan_save; static uint8_t scan_count = 0; -static void (*scan_cb)(wfx_wifi_scan_result_t *); /* user-callback - when scan is done */ -static char * scan_ssid; /* Which one are we scanning for */ -size_t scan_ssid_length = 0; +static ScanCallback scan_cb; /* user-callback - when scan is done */ +static uint8_t * scan_ssid = nullptr; /* Which one are we scanning for */ +static size_t scan_ssid_length = 0; static void sl_wfx_scan_result_callback(sl_wfx_scan_result_ind_body_t * scan_result); static void sl_wfx_scan_complete_callback(uint32_t status); -#endif /* SL_WFX_CONFIG_SCAN */ static void wfx_events_task(void * p_arg); @@ -305,6 +303,40 @@ CHIP_ERROR GetMacAddress(sl_wfx_interface_t interface, MutableByteSpan & address return CopySpanToMutableSpan(byteSpan, address); } +CHIP_ERROR StartNetworkScan(chip::ByteSpan ssid, ScanCallback callback) +{ + VerifyOrReturnError(callback != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + // SSID Max Length that is supported by the Wi-Fi SDK is 32 + VerifyOrReturnError(ssid.size() <= WFX_MAX_SSID_LENGTH, CHIP_ERROR_INVALID_STRING_LENGTH); + + // Make sure memory is cleared before starting a new scan + if (scan_ssid) + { + chip::Platform::MemoryFree(scan_ssid); + scan_ssid = nullptr; + } + + if (ssid.empty()) + { + scan_ssid_length = 0; + scan_ssid = nullptr; + } + else + { + scan_ssid_length = ssid.size(); + scan_ssid = reinterpret_cast(chip::Platform::MemoryAlloc(scan_ssid_length)); + VerifyOrReturnError(scan_ssid != nullptr, CHIP_ERROR_NO_MEMORY); + + chip::MutableByteSpan scannedSsidSpan(scan_ssid, WFX_MAX_SSID_LENGTH); + chip::CopySpanToMutableSpan(ssid, scannedSsidSpan); + } + scan_cb = callback; + + xEventGroupSetBits(sl_wfx_event_group, SL_WFX_SCAN_START); + return CHIP_NO_ERROR; +} + /*************************************************************************** * @brief * Creates WFX events processing task. @@ -357,7 +389,6 @@ extern "C" sl_status_t sl_wfx_host_process_event(sl_wfx_generic_message_t * even } break; } -#ifdef SL_WFX_CONFIG_SCAN case SL_WFX_SCAN_RESULT_IND_ID: { sl_wfx_scan_result_ind_t * scan_result = (sl_wfx_scan_result_ind_t *) event_payload; sl_wfx_scan_result_callback(&scan_result->body); @@ -368,7 +399,6 @@ extern "C" sl_status_t sl_wfx_host_process_event(sl_wfx_generic_message_t * even sl_wfx_scan_complete_callback(scan_complete->body.status); break; } -#endif /* SL_WFX_CONFIG_SCAN */ #ifdef SL_WFX_CONFIG_SOFTAP case SL_WFX_START_AP_IND_ID: { sl_wfx_start_ap_ind_t * start_ap_indication = (sl_wfx_start_ap_ind_t *) event_payload; @@ -435,7 +465,6 @@ extern "C" sl_status_t sl_wfx_host_process_event(sl_wfx_generic_message_t * even return SL_STATUS_OK; } -#ifdef SL_WFX_CONFIG_SCAN /**************************************************************************** * @brief * Callback for individual scan result @@ -443,56 +472,60 @@ extern "C" sl_status_t sl_wfx_host_process_event(sl_wfx_generic_message_t * even *****************************************************************************/ static void sl_wfx_scan_result_callback(sl_wfx_scan_result_ind_body_t * scan_result) { - struct scan_result_holder * ap; ChipLogDetail(DeviceLayer, "# %2d %2d %03d %02X:%02X:%02X:%02X:%02X:%02X %s", scan_count, scan_result->channel, ((int16_t) (scan_result->rcpi - 220) / 2), scan_result->mac[0], scan_result->mac[1], scan_result->mac[2], scan_result->mac[3], scan_result->mac[4], scan_result->mac[5], scan_result->ssid_def.ssid); - /* Report one AP information */ - /* don't save if filter only wants specific ssid */ - if (scan_ssid != nullptr) + + chip::ByteSpan requestedSsid(scan_ssid, scan_ssid_length); + chip::ByteSpan scannedSsid(scan_result->ssid_def.ssid, scan_result->ssid_def.ssid_length); + + // Verify that there was no requested SSID or that the SSID matches the requested SSID + VerifyOrReturn(requestedSsid.empty() || requestedSsid.data_equal(scannedSsid)); + + struct scan_result_holder * ap = reinterpret_cast(chip::Platform::MemoryAlloc(sizeof(*ap))); + VerifyOrReturn(ap != nullptr, ChipLogError(DeviceLayer, "Scan Callback: No Memory for scanned network.")); + + // Add Scan to the linked list + ap->next = scan_save; + scan_save = ap; + + // Copy scanned SSID to the output buffer + chip::MutableByteSpan outputSsid(ap->scan.ssid, WFX_MAX_SSID_LENGTH); + chip::CopySpanToMutableSpan(scannedSsid, outputSsid); + ap->scan.ssid_length = outputSsid.size(); + + // Set Network Security - We start by WPA3 to set the most secure type + ap->scan.security = WFX_SEC_UNSPECIFIED; + if (scan_result->security_mode.wpa3) + { + ap->scan.security = WFX_SEC_WPA3; + } + else if (scan_result->security_mode.wpa2) + { + ap->scan.security = WFX_SEC_WPA2; + } + else if (scan_result->security_mode.wpa) { - if (strcmp(scan_ssid, (char *) &scan_result->ssid_def.ssid[0]) != 0) - return; + ap->scan.security = WFX_SEC_WPA; } - if ((ap = (struct scan_result_holder *) (chip::Platform::MemoryAlloc(sizeof(*ap)))) == (struct scan_result_holder *) 0) + else if (scan_result->security_mode.wep) { - ChipLogError(DeviceLayer, "Scan: No Mem"); + ap->scan.security = WFX_SEC_WEP; } else { - ap->next = scan_save; - scan_save = ap; - /* Not checking if scan_result->ssid_length is < 33 */ - chip::Platform::CopyString(ap->scan.ssid, sizeof(ap->scan.ssid), (char *) &scan_result->ssid_def.ssid[0]); - /* We do it in this order WPA3 first */ - /* No EAP supported - Is this required */ - ap->scan.security = WFX_SEC_UNSPECIFIED; - if (scan_result->security_mode.wpa3) - { - ap->scan.security = WFX_SEC_WPA3; - } - else if (scan_result->security_mode.wpa2) - { - ap->scan.security = WFX_SEC_WPA2; - } - else if (scan_result->security_mode.wpa) - { - ap->scan.security = WFX_SEC_WPA; - } - else if (scan_result->security_mode.wep) - { - ap->scan.security = WFX_SEC_WEP; - } - else - { - ap->scan.security = WFX_SEC_NONE; - } - ap->scan.chan = scan_result->channel; - ap->scan.rssi = scan_result->rcpi; - memcpy(&ap->scan.bssid[0], &scan_result->mac[0], kWifiMacAddressLength); - scan_count++; + ap->scan.security = WFX_SEC_NONE; } + + ap->scan.chan = scan_result->channel; + ap->scan.rssi = (scan_result->rcpi - 220) / 2; + + chip::ByteSpan scannedBssid(scan_result->mac, kWifiMacAddressLength); + chip::MutableByteSpan outputBssid(ap->scan.bssid, kWifiMacAddressLength); + chip::CopySpanToMutableSpan(scannedBssid, outputBssid); + + scan_count++; } /**************************************************************************** @@ -507,7 +540,6 @@ static void sl_wfx_scan_complete_callback(uint32_t status) /* Use scan_count value and reset it */ xEventGroupSetBits(sl_wfx_event_group, SL_WFX_SCAN_COMPLETE); } -#endif /* SL_WFX_CONFIG_SCAN */ /**************************************************************************** * @brief @@ -677,10 +709,7 @@ static void wfx_events_task(void * p_arg) #ifdef SL_WFX_CONFIG_SOFTAP | SL_WFX_START_AP | SL_WFX_STOP_AP #endif /* SL_WFX_CONFIG_SOFTAP */ -#ifdef SL_WFX_CONFIG_SCAN - | SL_WFX_SCAN_START | SL_WFX_SCAN_COMPLETE -#endif /* SL_WFX_CONFIG_SCAN */ - | BITS_TO_WAIT, + | SL_WFX_SCAN_START | SL_WFX_SCAN_COMPLETE | BITS_TO_WAIT, pdTRUE, pdFALSE, pdMS_TO_TICKS(250)); /* 250 msec delay converted to ticks */ if (flags & SL_WFX_RETRY_CONNECT) { @@ -764,27 +793,30 @@ static void wfx_events_task(void * p_arg) wfx_lwip_set_sta_link_down(); } -#ifdef SL_WFX_CONFIG_SCAN if (flags & SL_WFX_SCAN_START) { - /* - * Start the Scan - */ - sl_wfx_ssid_def_t ssid, *sp; - uint16_t num_ssid, slen; + + // Start the Scan + sl_wfx_ssid_def_t ssid = { 0 }; + sl_wfx_ssid_def_t * ssidPtr = nullptr; + uint16_t nbreScannedNetworks = 0; + if (scan_ssid) { - memset(&ssid, 0, sizeof(ssid)); - slen = strlen(scan_ssid); - memcpy(&ssid.ssid[0], scan_ssid, slen); - ssid.ssid_length = slen; - num_ssid = 1; - sp = &ssid; + + chip::ByteSpan requestedSsid(scan_ssid, scan_ssid_length); + chip::MutableByteSpan outputSsid(ssid.ssid, WFX_MAX_SSID_LENGTH); + + chip::CopySpanToMutableSpan(requestedSsid, outputSsid); + ssid.ssid_length = outputSsid.size(); + + nbreScannedNetworks = 1; + ssidPtr = &ssid; } else { - num_ssid = 0; - sp = (sl_wfx_ssid_def_t *) 0; + nbreScannedNetworks = 0; + ssidPtr = nullptr; } ChipLogDetail(DeviceLayer, @@ -792,9 +824,9 @@ static void wfx_events_task(void * p_arg) "Channel Time: %d, Number of prob: %d", ACTIVE_CHANNEL_TIME, PASSIVE_CHANNEL_TIME, NUM_PROBE_REQUEST); (void) sl_wfx_set_scan_parameters(ACTIVE_CHANNEL_TIME, PASSIVE_CHANNEL_TIME, NUM_PROBE_REQUEST); - (void) sl_wfx_send_scan_command(WFM_SCAN_MODE_ACTIVE, CHANNEL_LIST, /* Channel list */ - CHANNEL_COUNT, /* Scan all chans */ - sp, num_ssid, IE_DATA, /* IE we're looking for */ + (void) sl_wfx_send_scan_command(WFM_SCAN_MODE_ACTIVE, CHANNEL_LIST, /* Channel list */ + CHANNEL_COUNT, /* Scan all chans */ + ssidPtr, nbreScannedNetworks, IE_DATA, /* IE we're looking for */ IE_DATA_LENGTH, BSSID_SCAN); } if (flags & SL_WFX_SCAN_COMPLETE) @@ -805,21 +837,22 @@ static void wfx_events_task(void * p_arg) for (hp = scan_save; hp; hp = next) { next = hp->next; - (*scan_cb)(&hp->scan); + scan_cb(&hp->scan); chip::Platform::MemoryFree(hp); } - (*scan_cb)((wfx_wifi_scan_result *) 0); - scan_save = (struct scan_result_holder *) 0; + scan_cb(nullptr); + + // Clean up + scan_save = nullptr; scan_count = 0; + if (scan_ssid) { chip::Platform::MemoryFree(scan_ssid); scan_ssid = NULL; } - /* Terminate scan */ - scan_cb = 0; + scan_cb = nullptr; } -#endif /* SL_WFX_CONFIG_SCAN */ } } @@ -906,23 +939,31 @@ static void wfx_wifi_hw_start(void) **************************************************************************/ int32_t wfx_get_ap_info(wfx_wifi_scan_result_t * ap) { - int32_t signal_strength; + uint32_t signal_strength = 0; + + chip::ByteSpan apSsidSpan(ap_info.ssid, ap_info.ssid_length); + chip::MutableByteSpan apSsidMutableSpan(ap->ssid, WFX_MAX_SSID_LENGTH); + chip::CopySpanToMutableSpan(apSsidSpan, apSsidMutableSpan); + ap->ssid_length = apSsidMutableSpan.size(); + + chip::ByteSpan apBssidSpan(ap_info.bssid, kWifiMacAddressLength); + chip::MutableByteSpan apBssidMutableSpan(ap->bssid, kWifiMacAddressLength); + chip::CopySpanToMutableSpan(apBssidSpan, apBssidMutableSpan); - ap->ssid_length = strnlen(ap_info.ssid, std::min(sizeof(ap_info.ssid), WFX_MAX_SSID_LENGTH)); - chip::Platform::CopyString(ap->ssid, ap->ssid_length, ap_info.ssid); - memcpy(ap->bssid, ap_info.bssid, sizeof(ap_info.bssid)); ap->security = ap_info.security; ap->chan = ap_info.chan; - ChipLogDetail(DeviceLayer, "WIFI:SSID :: %s", &ap_info.ssid[0]); - ChipLogDetail(DeviceLayer, "WIFI:BSSID :: %02x:%02x:%02x:%02x:%02x:%02x", ap_info.bssid[0], ap_info.bssid[1], - ap_info.bssid[2], ap_info.bssid[3], ap_info.bssid[4], ap_info.bssid[5]); - ChipLogDetail(DeviceLayer, "WIFI:security :: %d", ap->security); - ChipLogDetail(DeviceLayer, "WIFI:channel :: %d", ap->chan); - sl_status_t status = sl_wfx_get_signal_strength((uint32_t *) &signal_strength); + sl_status_t status = sl_wfx_get_signal_strength(&signal_strength); VerifyOrReturnError(status == SL_STATUS_OK, status); - ChipLogDetail(DeviceLayer, "signal_strength: %ld", signal_strength); ap->rssi = (signal_strength - 220) / 2; + + ChipLogDetail(DeviceLayer, "WIFI:SSID : %s", ap_info.ssid); + ChipLogDetail(DeviceLayer, "WIFI:BSSID : %02x:%02x:%02x:%02x:%02x:%02x", ap_info.bssid[0], ap_info.bssid[1], + ap_info.bssid[2], ap_info.bssid[3], ap_info.bssid[4], ap_info.bssid[5]); + ChipLogDetail(DeviceLayer, "WIFI:security : %d", ap->security); + ChipLogDetail(DeviceLayer, "WIFI:channel : %d", ap->chan); + ChipLogDetail(DeviceLayer, "signal_strength: %ld", signal_strength); + return status; } @@ -1220,29 +1261,6 @@ void wfx_enable_sta_mode(void) place holder */ } -/**************************************************************************** - * @brief - * driver scan start - * @param[in] callback: Callback from the wifi scan results - * @return returns true if sucessful, - * false otherwise - *****************************************************************************/ -#ifdef SL_WFX_CONFIG_SCAN -bool wfx_start_scan(char * ssid, void (*callback)(wfx_wifi_scan_result_t *)) -{ - VerifyOrReturnError(scan_cb != nullptr, false); - if (ssid) - { - scan_ssid_length = strnlen(ssid, WFX_MAX_SSID_LENGTH); - scan_ssid = reinterpret_cast(chip::Platform::MemoryAlloc(scan_ssid_length)); - VerifyOrReturnError(scan_ssid != nullptr, false); - Platform::CopyString(scan_ssid, scan_ssid_length, ssid); - } - scan_cb = callback; - xEventGroupSetBits(sl_wfx_event_group, SL_WFX_SCAN_START); - return true; -} - /**************************************************************************** * @brief * driver scan cancelation @@ -1267,4 +1285,3 @@ void wfx_cancel_scan(void) } scan_cb = nullptr; } -#endif /* SL_WFX_CONFIG_SCAN */ diff --git a/src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.cpp b/src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.cpp index f0b863419855d0..d0805e4dd508e3 100644 --- a/src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.cpp +++ b/src/platform/silabs/wifi/wiseconnect-abstraction/WiseconnectInterfaceAbstraction.cpp @@ -50,6 +50,37 @@ CHIP_ERROR GetMacAddress(sl_wfx_interface_t interface, chip::MutableByteSpan & a return CopySpanToMutableSpan(byteSpan, address); } +CHIP_ERROR StartNetworkScan(chip::ByteSpan ssid, ScanCallback callback) +{ + VerifyOrReturnError(callback != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!wfx_rsi.dev_state.Has(WifiState::kScanStarted), CHIP_ERROR_IN_PROGRESS); + + // SSID Max Length that is supported by the Wi-Fi SDK is 32 + VerifyOrReturnError(ssid.size() <= WFX_MAX_SSID_LENGTH, CHIP_ERROR_INVALID_STRING_LENGTH); + + if (ssid.empty()) // Scan all networks + { + wfx_rsi.scan_ssid_length = 0; + wfx_rsi.scan_ssid = nullptr; + } + else // Scan specific SSID + { + wfx_rsi.scan_ssid_length = ssid.size(); + wfx_rsi.scan_ssid = reinterpret_cast(chip::Platform::MemoryAlloc(wfx_rsi.scan_ssid_length)); + VerifyOrReturnError(wfx_rsi.scan_ssid != nullptr, CHIP_ERROR_NO_MEMORY); + + chip::MutableByteSpan scanSsidSpan(wfx_rsi.scan_ssid, wfx_rsi.scan_ssid_length); + chip::CopySpanToMutableSpan(ssid, scanSsidSpan); + } + wfx_rsi.scan_cb = callback; + + // TODO: We should be calling the start function directly instead of doing it asynchronously + WifiPlatformEvent event = WifiPlatformEvent::kScan; + sl_matter_wifi_post_event(event); + + return CHIP_NO_ERROR; +} + /********************************************************************* * @fn sl_status_t wfx_wifi_start(void) * @brief @@ -302,33 +333,6 @@ int32_t wfx_reset_counts(void) return wfx_rsi_reset_count(); } -#ifdef SL_WFX_CONFIG_SCAN -/******************************************************************************* - * @fn bool wfx_start_scan(char *ssid, void (*callback)(wfx_wifi_scan_result_t *)) - * @brief - * called fuction when driver start scaning - * @param[in] ssid: - * @return returns ture if successful, - * false otherwise - *******************************************************************************/ -bool wfx_start_scan(char * ssid, void (*callback)(wfx_wifi_scan_result_t *)) -{ - // check if already in progress - VerifyOrReturnError(wfx_rsi.scan_cb != nullptr, false); - wfx_rsi.scan_cb = callback; - - VerifyOrReturnError(ssid != nullptr, false); - wfx_rsi.scan_ssid_length = strnlen(ssid, std::min(sizeof(ssid), WFX_MAX_SSID_LENGTH)); - wfx_rsi.scan_ssid = reinterpret_cast(chip::Platform::MemoryAlloc(wfx_rsi.scan_ssid_length)); - VerifyOrReturnError(wfx_rsi.scan_ssid != nullptr, false); - chip::Platform::CopyString(wfx_rsi.scan_ssid, wfx_rsi.scan_ssid_length, ssid); - - WifiPlatformEvent event = WifiPlatformEvent::kScan; - sl_matter_wifi_post_event(event); - - return true; -} - /*************************************************************************** * @fn void wfx_cancel_scan(void) * @brief @@ -342,4 +346,3 @@ void wfx_cancel_scan(void) /* Not possible */ ChipLogError(DeviceLayer, "cannot cancel scan"); } -#endif /* SL_WFX_CONFIG_SCAN */ diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index bb621e0dce84b5..7903e3c2011d69 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -577,7 +577,6 @@ template("efr32_sdk") { "EXP_BOARD=1", "CHIP_917", "SLI_SI917=1", - "SL_WFX_CONFIG_SCAN=1", "CHIP_9117", "SL_WIFI_COMPONENT_INCLUDED", ]