3
3
#include " utility/wl_definitions.h"
4
4
#include < zephyr/net/wifi_mgmt.h>
5
5
6
+ // Max number of scan results to store
7
+ #define MAX_SCAN_RESULTS 20
8
+
6
9
#define NET_EVENT_WIFI_MASK \
7
10
(NET_EVENT_WIFI_CONNECT_RESULT | NET_EVENT_WIFI_DISCONNECT_RESULT | \
8
11
NET_EVENT_WIFI_AP_ENABLE_RESULT | NET_EVENT_WIFI_AP_DISABLE_RESULT | \
@@ -23,22 +26,28 @@ class WiFiClass: public NetworkInterface
23
26
sta_config.ssid_length = strlen (ssid);
24
27
sta_config.psk = (const uint8_t *)passphrase;
25
28
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;
31
29
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);
37
32
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
+ }
42
51
43
52
return status ();
44
53
}
@@ -90,8 +99,18 @@ class WiFiClass: public NetworkInterface
90
99
return WL_NO_SHIELD;
91
100
}
92
101
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;
95
114
}
96
115
97
116
char * SSID () {
@@ -108,6 +127,66 @@ class WiFiClass: public NetworkInterface
108
127
return 0 ;
109
128
}
110
129
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
+
111
190
private:
112
191
struct net_if *sta_iface = nullptr ;
113
192
struct net_if *ap_iface = nullptr ;
@@ -116,6 +195,13 @@ class WiFiClass: public NetworkInterface
116
195
struct wifi_connect_req_params sta_config;
117
196
118
197
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 ;
119
205
};
120
206
121
207
extern WiFiClass WiFi;
0 commit comments