Skip to content

Commit c1afc02

Browse files
[Silabs] Refactor network scan wifi abstraction function (project-chip#36802)
* Refactor scan operation for the 917 SoC * Refactor scan operation for the wf200 * Add instant scan configuration * fix rs911x scan function * restyle * Finish mutable span use * finish clean up * restyle * fix lenght change for wf200 * remove scan define since the feature always need to be present * Restyled by clang-format * address review comments * Restyled by clang-format --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent ea94ef7 commit c1afc02

File tree

8 files changed

+341
-290
lines changed

8 files changed

+341
-290
lines changed

src/platform/silabs/NetworkCommissioningWiFiDriver.cpp

+10-12
Original file line numberDiff line numberDiff line change
@@ -265,26 +265,24 @@ chip::BitFlags<WiFiSecurity> SlWiFiDriver::ConvertSecuritytype(wfx_sec_t securit
265265

266266
bool SlWiFiDriver::StartScanWiFiNetworks(ByteSpan ssid)
267267
{
268-
bool scanStarted = false;
269268
ChipLogProgress(DeviceLayer, "Start Scan WiFi Networks");
270-
if (!ssid.empty()) // ssid is given, only scan this network
271-
{
272-
char cSsid[DeviceLayer::Internal::kMaxWiFiSSIDLength] = {};
273-
memcpy(cSsid, ssid.data(), ssid.size());
274-
scanStarted = wfx_start_scan(cSsid, OnScanWiFiNetworkDone);
275-
}
276-
else // scan all networks
269+
CHIP_ERROR err = StartNetworkScan(ssid, OnScanWiFiNetworkDone);
270+
271+
if (err != CHIP_NO_ERROR)
277272
{
278-
scanStarted = wfx_start_scan(nullptr, OnScanWiFiNetworkDone);
273+
ChipLogError(DeviceLayer, "StartNetworkScan failed: %s", chip::ErrorStr(err));
274+
return false;
279275
}
280-
return scanStarted;
276+
277+
return true;
281278
}
282279

283280
void SlWiFiDriver::OnScanWiFiNetworkDone(wfx_wifi_scan_result_t * aScanResult)
284281
{
285-
ChipLogProgress(DeviceLayer, "OnScanWiFiNetworkDone");
286282
if (!aScanResult)
287283
{
284+
ChipLogProgress(DeviceLayer, "OnScanWiFiNetworkDone: Receive all scanned networks information.");
285+
288286
if (GetInstance().mpScanCallback != nullptr)
289287
{
290288
if (mScanResponseIter.Count() == 0)
@@ -309,7 +307,7 @@ void SlWiFiDriver::OnScanWiFiNetworkDone(wfx_wifi_scan_result_t * aScanResult)
309307
scanResponse.security.Set(GetInstance().ConvertSecuritytype(aScanResult->security));
310308
scanResponse.channel = aScanResult->chan;
311309
scanResponse.rssi = aScanResult->rssi;
312-
scanResponse.ssidLen = strnlen(aScanResult->ssid, DeviceLayer::Internal::kMaxWiFiSSIDLength);
310+
scanResponse.ssidLen = aScanResult->ssid_length;
313311
memcpy(scanResponse.ssid, aScanResult->ssid, scanResponse.ssidLen);
314312
memcpy(scanResponse.bssid, aScanResult->bssid, sizeof(scanResponse.bssid));
315313

src/platform/silabs/wifi/BUILD.gn

-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import("${chip_root}/third_party/silabs/silabs_board.gni")
2121
declare_args() {
2222
# Wifi related stuff - they are overridden by gn -args="use_wf200=true"
2323
sl_wfx_config_softap = false
24-
sl_wfx_config_scan = true
2524

2625
# Argument to force enable WPA3 security on rs91x
2726
rs91x_wpa3_transition = true
@@ -85,10 +84,6 @@ config("wifi-platform-config") {
8584
defines += [ "SL_WFX_CONFIG_SOFTAP" ]
8685
}
8786

88-
if (sl_wfx_config_scan) {
89-
defines += [ "SL_WFX_CONFIG_SCAN" ]
90-
}
91-
9287
if (chip_enable_wifi_ipv4) {
9388
defines += [ "CHIP_DEVICE_CONFIG_ENABLE_IPV4" ]
9489
}

src/platform/silabs/wifi/SiWx/WifiInterface.cpp

+120-88
Original file line numberDiff line numberDiff line change
@@ -187,13 +187,80 @@ constexpr uint8_t kAdvActiveScanDuration = 15;
187187
constexpr uint8_t kAdvPassiveScanDuration = 20;
188188
constexpr uint8_t kAdvMultiProbe = 1;
189189
constexpr uint8_t kAdvScanPeriodicity = 10;
190+
constexpr uint8_t kAdvEnableInstantbgScan = 1;
190191

191192
// TODO: Confirm that this value works for size and timing
192193
constexpr uint8_t kWfxQueueSize = 10;
193194

194195
// TODO: Figure out why we actually need this, we are already handling failure and retries somewhere else.
195196
constexpr uint16_t kWifiScanTimeoutTicks = 10000;
196197

198+
/**
199+
* @brief Network Scan callback when the device receive a scan operation from the controller.
200+
* This callback is used whe the Network Commission Driver send a ScanNetworks command.
201+
*
202+
* If the scan network was requested for a specific SSID - wfx_rsi.scan_ssid had a valid value,
203+
* the callback will only forward that specific networks information.
204+
* If no ssid is provided, wfx_rsi.scan_ssid is a nullptr, we return the information of all scanned networks.
205+
*/
206+
sl_status_t BackgroundScanCallback(sl_wifi_event_t event, sl_wifi_scan_result_t * result, uint32_t result_length, void * arg)
207+
{
208+
VerifyOrReturnError(result != nullptr, SL_STATUS_NULL_POINTER);
209+
VerifyOrReturnError(wfx_rsi.scan_cb != nullptr, SL_STATUS_INVALID_HANDLE);
210+
211+
uint32_t nbreResults = result->scan_count;
212+
chip::ByteSpan requestedSsidSpan(wfx_rsi.scan_ssid, wfx_rsi.scan_ssid_length);
213+
214+
for (uint32_t i = 0; i < nbreResults; i++)
215+
{
216+
wfx_wifi_scan_result_t currentScanResult = { 0 };
217+
218+
// Lenght excludes null-character
219+
size_t scannedSsidLenght = strnlen(reinterpret_cast<char *>(result->scan_info[i].ssid), WFX_MAX_SSID_LENGTH);
220+
chip::ByteSpan scannedSsidSpan(result->scan_info[i].ssid, scannedSsidLenght);
221+
222+
// Copy the scanned SSID to the current scan ssid buffer that will be forwarded to the callback
223+
chip::MutableByteSpan currentScanSsid(currentScanResult.ssid, WFX_MAX_SSID_LENGTH);
224+
chip::CopySpanToMutableSpan(scannedSsidSpan, currentScanSsid);
225+
currentScanResult.ssid_length = currentScanSsid.size();
226+
227+
chip::ByteSpan inBssid(result->scan_info[i].bssid, kWifiMacAddressLength);
228+
chip::MutableByteSpan outBssid(currentScanResult.bssid, kWifiMacAddressLength);
229+
chip::CopySpanToMutableSpan(inBssid, outBssid);
230+
231+
// TODO: We should revisit this to make sure we are setting the correct values
232+
currentScanResult.security = static_cast<wfx_sec_t>(result->scan_info[i].security_mode);
233+
currentScanResult.rssi = (-1) * result->scan_info[i].rssi_val; // The returned value is positive - we need to flip it
234+
currentScanResult.chan = result->scan_info[i].rf_channel;
235+
236+
// if user has provided ssid, check if the current scan result ssid matches the user provided ssid
237+
if (!requestedSsidSpan.empty())
238+
{
239+
if (requestedSsidSpan.data_equal(currentScanSsid))
240+
{
241+
wfx_rsi.scan_cb(&currentScanResult);
242+
}
243+
}
244+
else // No ssid was provide - forward all results
245+
{
246+
wfx_rsi.scan_cb(&currentScanResult);
247+
}
248+
}
249+
250+
// cleanup and return
251+
wfx_rsi.dev_state.Clear(WifiState::kScanStarted);
252+
wfx_rsi.scan_cb(nullptr);
253+
wfx_rsi.scan_cb = nullptr;
254+
if (wfx_rsi.scan_ssid)
255+
{
256+
chip::Platform::MemoryFree(wfx_rsi.scan_ssid);
257+
wfx_rsi.scan_ssid = nullptr;
258+
}
259+
osSemaphoreRelease(sScanCompleteSemaphore);
260+
261+
return SL_STATUS_OK;
262+
}
263+
197264
void DHCPTimerEventHandler(void * arg)
198265
{
199266
WifiPlatformEvent event = WifiPlatformEvent::kStationDhcpPoll;
@@ -474,16 +541,26 @@ sl_status_t sl_matter_wifi_platform_init(void)
474541
*********************************************************************/
475542
int32_t wfx_rsi_get_ap_info(wfx_wifi_scan_result_t * ap)
476543
{
477-
sl_status_t status = SL_STATUS_OK;
478-
int32_t rssi = 0;
479-
ap->ssid_length = wfx_rsi.sec.ssid_length;
480-
ap->security = wfx_rsi.sec.security;
481-
ap->chan = wfx_rsi.ap_chan;
482-
chip::Platform::CopyString(ap->ssid, ap->ssid_length, wfx_rsi.sec.ssid);
483-
memcpy(&ap->bssid[0], wfx_rsi.ap_mac.data(), kWifiMacAddressLength);
484-
sl_wifi_get_signal_strength(SL_WIFI_CLIENT_INTERFACE, &rssi);
544+
// TODO: Convert this to a int8
545+
int32_t rssi = 0;
546+
ap->security = wfx_rsi.sec.security;
547+
ap->chan = wfx_rsi.ap_chan;
548+
549+
chip::MutableByteSpan output(ap->ssid, WFX_MAX_SSID_LENGTH);
550+
// Cast is a workaround until the wfx_rsi structure is refactored
551+
chip::ByteSpan ssid(reinterpret_cast<uint8_t *>(wfx_rsi.sec.ssid), wfx_rsi.sec.ssid_length);
552+
chip::CopySpanToMutableSpan(ssid, output);
553+
ap->ssid_length = output.size();
554+
555+
chip::ByteSpan apMacSpan(wfx_rsi.ap_mac.data(), wfx_rsi.ap_mac.size());
556+
chip::MutableByteSpan bssidSpan(ap->bssid, kWifiMacAddressLength);
557+
chip::CopySpanToMutableSpan(apMacSpan, bssidSpan);
558+
559+
// TODO: add error processing
560+
sl_wifi_get_signal_strength(SL_WIFI_CLIENT_INTERFACE, &(rssi));
485561
ap->rssi = rssi;
486-
return status;
562+
563+
return SL_STATUS_OK;
487564
}
488565

489566
/******************************************************************
@@ -547,59 +624,6 @@ int32_t sl_wifi_platform_disconnect(void)
547624
return sl_net_down((sl_net_interface_t) SL_NET_WIFI_CLIENT_INTERFACE);
548625
}
549626

550-
sl_status_t show_scan_results(sl_wifi_scan_result_t * scan_result)
551-
{
552-
SL_WIFI_ARGS_CHECK_NULL_POINTER(scan_result);
553-
VerifyOrReturnError(wfx_rsi.scan_cb != nullptr, SL_STATUS_INVALID_HANDLE);
554-
555-
wfx_wifi_scan_result_t cur_scan_result;
556-
for (int idx = 0; idx < (int) scan_result->scan_count; idx++)
557-
{
558-
memset(&cur_scan_result, 0, sizeof(cur_scan_result));
559-
560-
cur_scan_result.ssid_length = strnlen((char *) scan_result->scan_info[idx].ssid,
561-
std::min<size_t>(sizeof(scan_result->scan_info[idx].ssid), WFX_MAX_SSID_LENGTH));
562-
chip::Platform::CopyString(cur_scan_result.ssid, cur_scan_result.ssid_length, (char *) scan_result->scan_info[idx].ssid);
563-
564-
// if user has provided ssid, then check if the current scan result ssid matches the user provided ssid
565-
if (wfx_rsi.scan_ssid != nullptr &&
566-
(strncmp(wfx_rsi.scan_ssid, cur_scan_result.ssid, std::min(strlen(wfx_rsi.scan_ssid), strlen(cur_scan_result.ssid))) ==
567-
0))
568-
{
569-
continue;
570-
}
571-
cur_scan_result.security = static_cast<wfx_sec_t>(scan_result->scan_info[idx].security_mode);
572-
cur_scan_result.rssi = (-1) * scan_result->scan_info[idx].rssi_val;
573-
memcpy(cur_scan_result.bssid, scan_result->scan_info[idx].bssid, kWifiMacAddressLength);
574-
wfx_rsi.scan_cb(&cur_scan_result);
575-
576-
// if user has not provided the ssid, then call the callback for each scan result
577-
if (wfx_rsi.scan_ssid == nullptr)
578-
{
579-
continue;
580-
}
581-
break;
582-
}
583-
584-
// cleanup and return
585-
wfx_rsi.dev_state.Clear(WifiState::kScanStarted);
586-
wfx_rsi.scan_cb((wfx_wifi_scan_result_t *) 0);
587-
wfx_rsi.scan_cb = nullptr;
588-
if (wfx_rsi.scan_ssid)
589-
{
590-
chip::Platform::MemoryFree(wfx_rsi.scan_ssid);
591-
wfx_rsi.scan_ssid = nullptr;
592-
}
593-
return SL_STATUS_OK;
594-
}
595-
596-
sl_status_t bg_scan_callback_handler(sl_wifi_event_t event, sl_wifi_scan_result_t * result, uint32_t result_length, void * arg)
597-
{
598-
show_scan_results(result); // To do Check error
599-
osSemaphoreRelease(sScanCompleteSemaphore);
600-
return SL_STATUS_OK;
601-
}
602-
603627
/// NotifyConnectivity
604628
/// @brief Notify the application about the connectivity status if it has not been notified yet.
605629
/// Helper function for HandleDHCPPolling.
@@ -711,53 +735,61 @@ void ProcessEvent(WifiPlatformEvent event)
711735

712736
case WifiPlatformEvent::kScan:
713737
ChipLogDetail(DeviceLayer, "WifiPlatformEvent::kScan");
714-
715-
#ifdef SL_WFX_CONFIG_SCAN
716738
if (!(wfx_rsi.dev_state.Has(WifiState::kScanStarted)))
717739
{
718740
ChipLogDetail(DeviceLayer, "WifiPlatformEvent::kScan");
719-
sl_wifi_scan_configuration_t wifi_scan_configuration;
720-
memset(&wifi_scan_configuration, 0, sizeof(wifi_scan_configuration));
721-
722-
// TODO: Add scan logic
723-
sl_wifi_advanced_scan_configuration_t advanced_scan_configuration = { 0 };
724-
int32_t status;
725-
advanced_scan_configuration.active_channel_time = kAdvActiveScanDuration;
726-
advanced_scan_configuration.passive_channel_time = kAdvPassiveScanDuration;
727-
advanced_scan_configuration.trigger_level = kAdvScanThreshold;
728-
advanced_scan_configuration.trigger_level_change = kAdvRssiToleranceThreshold;
729-
advanced_scan_configuration.enable_multi_probe = kAdvMultiProbe;
730-
status = sl_wifi_set_advanced_scan_configuration(&advanced_scan_configuration);
731-
if (SL_STATUS_OK != status)
732-
{
733-
// TODO: Seems like Chipdie should be called here, the device should be initialized here
734-
ChipLogError(DeviceLayer, "sl_wifi_set_advanced_scan_configuration failed: 0x%lx", static_cast<uint32_t>(status));
735-
return;
736-
}
741+
sl_status_t status = SL_STATUS_OK;
737742

743+
sl_wifi_scan_configuration_t wifi_scan_configuration = default_wifi_scan_configuration;
738744
if (wfx_rsi.dev_state.Has(WifiState::kStationConnected))
739745
{
740746
/* Terminate with end of scan which is no ap sent back */
741747
wifi_scan_configuration.type = SL_WIFI_SCAN_TYPE_ADV_SCAN;
742748
wifi_scan_configuration.periodic_scan_interval = kAdvScanPeriodicity;
743749
}
744-
else
750+
751+
sl_wifi_advanced_scan_configuration_t advanced_scan_configuration = {
752+
.trigger_level = kAdvScanThreshold,
753+
.trigger_level_change = kAdvRssiToleranceThreshold,
754+
.active_channel_time = kAdvActiveScanDuration,
755+
.passive_channel_time = kAdvPassiveScanDuration,
756+
.enable_instant_scan = kAdvEnableInstantbgScan,
757+
.enable_multi_probe = kAdvMultiProbe,
758+
};
759+
760+
status = sl_wifi_set_advanced_scan_configuration(&advanced_scan_configuration);
761+
762+
// TODO: Seems like Chipdie should be called here, the device should be initialized here
763+
VerifyOrReturn(
764+
status == SL_STATUS_OK,
765+
ChipLogError(DeviceLayer, "sl_wifi_set_advanced_scan_configuration failed: 0x%lx", static_cast<uint32_t>(status)));
766+
767+
sl_wifi_set_scan_callback(BackgroundScanCallback, nullptr);
768+
wfx_rsi.dev_state.Set(WifiState::kScanStarted);
769+
770+
// If an ssid was not provided, we need to call the scan API with nullptr to scan all Wi-Fi networks
771+
sl_wifi_ssid_t ssid = { 0 };
772+
sl_wifi_ssid_t * ssidPtr = nullptr;
773+
774+
if (wfx_rsi.scan_ssid != nullptr)
745775
{
746-
wifi_scan_configuration = default_wifi_scan_configuration;
776+
chip::ByteSpan requestedSsid(wfx_rsi.scan_ssid, wfx_rsi.scan_ssid_length);
777+
chip::MutableByteSpan ouputSsid(ssid.value, sizeof(ssid.value));
778+
chip::CopySpanToMutableSpan(requestedSsid, ouputSsid);
779+
780+
ssid.length = ouputSsid.size();
781+
ssidPtr = &ssid;
747782
}
748-
sl_wifi_set_scan_callback(bg_scan_callback_handler, nullptr);
749-
wfx_rsi.dev_state.Set(WifiState::kScanStarted);
750783

751784
osSemaphoreAcquire(sScanInProgressSemaphore, osWaitForever);
752-
status = sl_wifi_start_scan(SL_WIFI_CLIENT_2_4GHZ_INTERFACE, nullptr, &wifi_scan_configuration);
785+
status = sl_wifi_start_scan(SL_WIFI_CLIENT_2_4GHZ_INTERFACE, ssidPtr, &wifi_scan_configuration);
753786
if (SL_STATUS_IN_PROGRESS == status)
754787
{
755788
osSemaphoreAcquire(sScanCompleteSemaphore, kWifiScanTimeoutTicks);
756789
}
757790

758791
osSemaphoreRelease(sScanInProgressSemaphore);
759792
}
760-
#endif /* SL_WFX_CONFIG_SCAN */
761793
break;
762794

763795
case WifiPlatformEvent::kStationStartJoin:

src/platform/silabs/wifi/WifiInterfaceAbstraction.h

+20-6
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,14 @@ typedef enum
131131

132132
typedef struct wfx_wifi_scan_result
133133
{
134-
char ssid[WFX_MAX_SSID_LENGTH + 1];
134+
uint8_t ssid[WFX_MAX_SSID_LENGTH]; // excludes null-character
135135
size_t ssid_length;
136136
wfx_sec_t security;
137137
uint8_t bssid[kWifiMacAddressLength];
138138
uint8_t chan;
139139
int16_t rssi; /* I suspect this is in dBm - so signed */
140140
} wfx_wifi_scan_result_t;
141+
using ScanCallback = void (*)(wfx_wifi_scan_result_t *);
141142

142143
typedef struct wfx_wifi_scan_ext
143144
{
@@ -167,11 +168,9 @@ typedef struct wfx_rsi_s
167168
chip::BitFlags<WifiState> dev_state;
168169
uint16_t ap_chan; /* The chan our STA is using */
169170
wfx_wifi_provision_t sec;
170-
#ifdef SL_WFX_CONFIG_SCAN
171-
void (*scan_cb)(wfx_wifi_scan_result_t *);
172-
char * scan_ssid; /* Which one are we scanning for */
171+
ScanCallback scan_cb;
172+
uint8_t * scan_ssid; /* Which one are we scanning for */
173173
size_t scan_ssid_length;
174-
#endif
175174
#ifdef SL_WFX_CONFIG_SOFTAP
176175
MacAddress softap_mac;
177176
#endif
@@ -234,6 +233,22 @@ void NotifyConnection(const MacAddress & ap);
234233
*/
235234
CHIP_ERROR GetMacAddress(sl_wfx_interface_t interface, chip::MutableByteSpan & addr);
236235

236+
/**
237+
* @brief Triggers a network scan
238+
* The function is asynchronous and the result is provided via the callback.
239+
*
240+
* @param ssid The SSID to scan for. If empty, all networks are scanned
241+
* @param callback The callback to be called when the scan is complete. Cannot be nullptr.
242+
* The callback is called asynchrounously.
243+
*
244+
* @return CHIP_ERROR CHIP_NO_ERROR if the network scan was successfully started
245+
* CHIP_INVALID_ARGUMENT if the callback is nullptr
246+
* CHIP_ERROR_IN_PROGRESS, if there is already a network scan in progress
247+
* CHIP_ERROR_INVALID_STRING_LENGTH, if there SSID length exceeds handled limit
248+
* other, if there is a platform error when starting the scan
249+
*/
250+
CHIP_ERROR StartNetworkScan(chip::ByteSpan ssid, ScanCallback callback);
251+
237252
/* Function to update */
238253

239254
sl_status_t wfx_wifi_start(void);
@@ -256,7 +271,6 @@ bool wfx_have_ipv4_addr(sl_wfx_interface_t);
256271

257272
bool wfx_have_ipv6_addr(sl_wfx_interface_t);
258273
wifi_mode_t wfx_get_wifi_mode(void);
259-
bool wfx_start_scan(char * ssid, void (*scan_cb)(wfx_wifi_scan_result_t *)); /* true returned if successfully started */
260274
void wfx_cancel_scan(void);
261275

262276
/*

0 commit comments

Comments
 (0)