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+
111190private:
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
121207extern WiFiClass WiFi;
0 commit comments