Skip to content

Commit 76a3152

Browse files
committed
ZEP-55: Implemented WiFi.scan() functionality.
1 parent 13d666d commit 76a3152

File tree

3 files changed

+105
-16
lines changed

3 files changed

+105
-16
lines changed

libraries/SocketWrapper/WiFi.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
#include "WiFi.h"
22

33
WiFiClass WiFi;
4+
5+
WiFiClass* WiFiClass::instance = nullptr;

libraries/SocketWrapper/WiFi.h

Lines changed: 102 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
#include "utility/wl_definitions.h"
44
#include <zephyr/net/wifi_mgmt.h>
55

6+
// Max number of scan results to store
7+
#define MAX_SCAN_RESULTS 20
8+
69
#define NET_EVENT_WIFI_MASK \
710
(NET_EVENT_WIFI_CONNECT_RESULT | NET_EVENT_WIFI_DISCONNECT_RESULT | \
811
NET_EVENT_WIFI_AP_ENABLE_RESULT | NET_EVENT_WIFI_AP_DISABLE_RESULT | \
@@ -23,22 +26,28 @@ class WiFiClass: public NetworkInterface
2326
sta_config.ssid_length = strlen(ssid);
2427
sta_config.psk = (const uint8_t *)passphrase;
2528
sta_config.psk_length = strlen(passphrase);
26-
// TODO: change these fields with scan() results
27-
sta_config.security = WIFI_SECURITY_TYPE_PSK;
28-
sta_config.channel = WIFI_CHANNEL_ANY;
29-
sta_config.band = WIFI_FREQ_BAND_2_4_GHZ;
30-
sta_config.bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ;
3129

32-
int ret = net_mgmt(NET_REQUEST_WIFI_CONNECT, sta_iface, &sta_config,
33-
sizeof(struct wifi_connect_req_params));
34-
if (ret) {
35-
return false;
36-
}
30+
// Register the Wi-Fi event callback
31+
net_mgmt_init_event_callback(&wifiCb, scanEventDispatcher, NET_EVENT_WIFI_SCAN_RESULT | NET_EVENT_WIFI_SCAN_DONE);
3732

38-
NetworkInterface::begin(false, NET_EVENT_WIFI_MASK);
39-
if (blocking) {
40-
net_mgmt_event_wait_on_iface(sta_iface, NET_EVENT_WIFI_CONNECT_RESULT, NULL, NULL, NULL, K_FOREVER);
41-
}
33+
net_mgmt_add_event_callback(&wifiCb);
34+
35+
(void)scanNetworks();
36+
37+
// Check if the network we were seekin was found and attempt to connect to it
38+
if(getSoughtNetworkFound() != true)
39+
{
40+
int ret = net_mgmt(NET_REQUEST_WIFI_CONNECT, sta_iface, &sta_config,
41+
sizeof(struct wifi_connect_req_params));
42+
if (ret) {
43+
return false;
44+
}
45+
46+
NetworkInterface::begin(false, NET_EVENT_WIFI_MASK);
47+
if (blocking) {
48+
net_mgmt_event_wait_on_iface(sta_iface, NET_EVENT_WIFI_CONNECT_RESULT, NULL, NULL, NULL, K_FOREVER);
49+
}
50+
}
4251

4352
return status();
4453
}
@@ -90,8 +99,18 @@ class WiFiClass: public NetworkInterface
9099
return WL_NO_SHIELD;
91100
}
92101

93-
int8_t scanNetworks() {
94-
// TODO: borrow code from mbed core for scan results handling
102+
uint8_t scanNetworks() {
103+
resultCount = 0u;
104+
setScanSequenceFinished(false);
105+
setSoughtNetworkFound(false);
106+
107+
// Trigger a new scan
108+
net_mgmt(NET_REQUEST_WIFI_SCAN, sta_iface, nullptr, 0u);
109+
110+
// Wait for the scan to finish. This is by design a blocking call
111+
while(getScanSequenceFinished() != true);
112+
113+
return resultCount;
95114
}
96115

97116
char* SSID() {
@@ -108,6 +127,66 @@ class WiFiClass: public NetworkInterface
108127
return 0;
109128
}
110129

130+
static void scanEventDispatcher(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, struct net_if *iface)
131+
{
132+
if (instance != nullptr)
133+
{
134+
instance->handleScanEvent(cb, mgmt_event, iface);
135+
}
136+
}
137+
138+
void handleScanEvent(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, struct net_if *iface) {
139+
if (mgmt_event == NET_EVENT_WIFI_SCAN_RESULT) {
140+
const struct wifi_scan_result *entry = reinterpret_cast<const struct wifi_scan_result *>(cb->info);
141+
if (resultCount < MAX_SCAN_RESULTS) {
142+
memcpy(&scanResults[resultCount], entry, sizeof(struct wifi_scan_result));
143+
resultCount++;
144+
145+
//for each new result found, compare network name with desired one
146+
if(!memcmp(entry->ssid, sta_config.ssid, entry->ssid_length))
147+
{
148+
// if a match is found, add missing info to config before attempting to connect
149+
sta_config.security = entry->security;
150+
sta_config.channel = entry->channel;
151+
sta_config.band = entry->band;
152+
sta_config.bandwidth = WIFI_FREQ_BANDWIDTH_20MHZ;
153+
154+
setSoughtNetworkFound(true);
155+
}
156+
}
157+
}
158+
159+
if (mgmt_event == NET_EVENT_WIFI_SCAN_DONE) {
160+
setScanSequenceFinished(true);
161+
162+
if (resultCount = 0) {
163+
printk("No networks found.\n");
164+
}
165+
}
166+
}
167+
168+
void setScanSequenceFinished(bool scanFinished)
169+
{
170+
scanSequenceFinished = scanFinished;
171+
}
172+
173+
void setSoughtNetworkFound(bool networkFound)
174+
{
175+
soughtNetworkFound = networkFound;
176+
}
177+
178+
bool getScanSequenceFinished(void)
179+
{
180+
return scanSequenceFinished;
181+
}
182+
183+
bool getSoughtNetworkFound(void)
184+
{
185+
return soughtNetworkFound;
186+
}
187+
188+
static WiFiClass* instance;
189+
111190
private:
112191
struct net_if *sta_iface = nullptr;
113192
struct net_if *ap_iface = nullptr;
@@ -116,6 +195,13 @@ class WiFiClass: public NetworkInterface
116195
struct wifi_connect_req_params sta_config;
117196

118197
struct wifi_iface_status sta_state = { 0 };
198+
199+
struct wifi_scan_result scanResults[MAX_SCAN_RESULTS];
200+
uint8_t resultCount;
201+
struct net_mgmt_event_callback wifiCb;
202+
203+
bool soughtNetworkFound = false;
204+
bool scanSequenceFinished = false;
119205
};
120206

121207
extern WiFiClass WiFi;

loader/llext_exports.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ FORCE_EXPORT_SYM(tls_credential_add);
106106
FORCE_EXPORT_SYM(net_if_get_wifi_sta);
107107
FORCE_EXPORT_SYM(net_if_get_wifi_sap);
108108
FORCE_EXPORT_SYM(net_mgmt_NET_REQUEST_WIFI_CONNECT);
109+
FORCE_EXPORT_SYM(net_mgmt_NET_REQUEST_WIFI_SCAN);
109110
FORCE_EXPORT_SYM(net_mgmt_NET_REQUEST_WIFI_IFACE_STATUS);
110111
FORCE_EXPORT_SYM(net_mgmt_NET_REQUEST_WIFI_AP_ENABLE);
111112
#endif

0 commit comments

Comments
 (0)