1 /*
2 * Copyright (c) 2016 Intel Corporation.
3 * Copyright 2024 NXP
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #undef _POSIX_C_SOURCE
9 #define _POSIX_C_SOURCE 200809L /* For strnlen() */
10
11 #include <zephyr/logging/log.h>
12 LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL);
13
14 #include <errno.h>
15 #include <string.h>
16 #include <stdio.h>
17 #include <zephyr/net/net_core.h>
18 #include <zephyr/net/net_if.h>
19 #include <zephyr/net/wifi_mgmt.h>
20 #ifdef CONFIG_WIFI_NM
21 #include <zephyr/net/wifi_nm.h>
22 #endif /* CONFIG_WIFI_NM */
23
24 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_ROAMING
25 #define MAX_NEIGHBOR_AP_LIMIT 6U
26 #define MAX_EVENT_STR_LEN 32
27
28 struct wifi_rrm_neighbor_ap_t {
29 char ssid[WIFI_SSID_MAX_LEN + 1];
30 uint8_t bssid[WIFI_SSID_MAX_LEN];
31 uint8_t bssid_info[WIFI_SSID_MAX_LEN];
32 int op_class;
33 int channel;
34 int phy_type;
35 };
36
37 struct wifi_rrm_neighbor_report_t {
38 struct wifi_rrm_neighbor_ap_t neighbor_ap[MAX_NEIGHBOR_AP_LIMIT];
39 int neighbor_cnt;
40 };
41
42 struct wifi_roaming_params {
43 bool is_11r_used;
44 bool is_11k_enabled;
45 struct wifi_rrm_neighbor_report_t neighbor_rep;
46 };
47
48 static struct wifi_roaming_params roaming_params;
49 #endif
50
wifi_security_txt(enum wifi_security_type security)51 const char *wifi_security_txt(enum wifi_security_type security)
52 {
53 switch (security) {
54 case WIFI_SECURITY_TYPE_NONE:
55 return "OPEN";
56 case WIFI_SECURITY_TYPE_PSK:
57 return "WPA2-PSK";
58 case WIFI_SECURITY_TYPE_PSK_SHA256:
59 return "WPA2-PSK-SHA256";
60 case WIFI_SECURITY_TYPE_SAE_HNP:
61 return "WPA3-SAE-HNP";
62 case WIFI_SECURITY_TYPE_SAE_H2E:
63 return "WPA3-SAE-H2E";
64 case WIFI_SECURITY_TYPE_SAE_AUTO:
65 return "WPA3-SAE-AUTO";
66 case WIFI_SECURITY_TYPE_WAPI:
67 return "WAPI";
68 case WIFI_SECURITY_TYPE_EAP_TLS:
69 return "EAP-TLS";
70 case WIFI_SECURITY_TYPE_WEP:
71 return "WEP";
72 case WIFI_SECURITY_TYPE_WPA_PSK:
73 return "WPA-PSK";
74 case WIFI_SECURITY_TYPE_WPA_AUTO_PERSONAL:
75 return "WPA/WPA2/WPA3 PSK";
76 case WIFI_SECURITY_TYPE_DPP:
77 return "DPP";
78 case WIFI_SECURITY_TYPE_EAP_PEAP_MSCHAPV2:
79 return "EAP-PEAP-MSCHAPV2";
80 case WIFI_SECURITY_TYPE_EAP_PEAP_GTC:
81 return "EAP-PEAP-GTC";
82 case WIFI_SECURITY_TYPE_EAP_TTLS_MSCHAPV2:
83 return "EAP-TTLS-MSCHAPV2";
84 case WIFI_SECURITY_TYPE_EAP_PEAP_TLS:
85 return "EAP-PEAP-TLS";
86 case WIFI_SECURITY_TYPE_FT_PSK:
87 return "FT-PSK";
88 case WIFI_SECURITY_TYPE_FT_SAE:
89 return "FT-SAE";
90 case WIFI_SECURITY_TYPE_FT_EAP:
91 return "FT-EAP";
92 case WIFI_SECURITY_TYPE_FT_EAP_SHA384:
93 return "FT-EAP-SHA384";
94 case WIFI_SECURITY_TYPE_SAE_EXT_KEY:
95 return "WPA3-SAE-EXT-KEY";
96 case WIFI_SECURITY_TYPE_UNKNOWN:
97 default:
98 return "UNKNOWN";
99 }
100 }
101
wifi_wpa3_enterprise_txt(enum wifi_wpa3_enterprise_type wpa3_ent)102 const char *wifi_wpa3_enterprise_txt(enum wifi_wpa3_enterprise_type wpa3_ent)
103 {
104 switch (wpa3_ent) {
105 case WIFI_WPA3_ENTERPRISE_SUITEB:
106 return "WPA3-SuiteB";
107 case WIFI_WPA3_ENTERPRISE_SUITEB_192:
108 return "WPA3-SuiteB-192";
109 case WIFI_WPA3_ENTERPRISE_ONLY:
110 return "WPA3-Enterprise-Only";
111 default:
112 return "";
113 }
114 }
115
wifi_mfp_txt(enum wifi_mfp_options mfp)116 const char *wifi_mfp_txt(enum wifi_mfp_options mfp)
117 {
118 switch (mfp) {
119 case WIFI_MFP_DISABLE:
120 return "Disable";
121 case WIFI_MFP_OPTIONAL:
122 return "Optional";
123 case WIFI_MFP_REQUIRED:
124 return "Required";
125 case WIFI_MFP_UNKNOWN:
126 default:
127 return "UNKNOWN";
128 }
129 }
130
wifi_band_txt(enum wifi_frequency_bands band)131 const char *wifi_band_txt(enum wifi_frequency_bands band)
132 {
133 switch (band) {
134 case WIFI_FREQ_BAND_2_4_GHZ:
135 return "2.4GHz";
136 case WIFI_FREQ_BAND_5_GHZ:
137 return "5GHz";
138 case WIFI_FREQ_BAND_6_GHZ:
139 return "6GHz";
140 case WIFI_FREQ_BAND_UNKNOWN:
141 default:
142 return "UNKNOWN";
143 }
144 }
145
wifi_bandwidth_txt(enum wifi_frequency_bandwidths bandwidth)146 const char *const wifi_bandwidth_txt(enum wifi_frequency_bandwidths bandwidth)
147 {
148 switch (bandwidth) {
149 case WIFI_FREQ_BANDWIDTH_20MHZ:
150 return "20 MHz";
151 case WIFI_FREQ_BANDWIDTH_40MHZ:
152 return "40 MHz";
153 case WIFI_FREQ_BANDWIDTH_80MHZ:
154 return "80 MHz";
155 case WIFI_FREQ_BANDWIDTH_UNKNOWN:
156 default:
157 return "UNKNOWN";
158 }
159 }
160
wifi_state_txt(enum wifi_iface_state state)161 const char *wifi_state_txt(enum wifi_iface_state state)
162 {
163 switch (state) {
164 case WIFI_STATE_DISCONNECTED:
165 return "DISCONNECTED";
166 case WIFI_STATE_INACTIVE:
167 return "INACTIVE";
168 case WIFI_STATE_INTERFACE_DISABLED:
169 return "INTERFACE_DISABLED";
170 case WIFI_STATE_SCANNING:
171 return "SCANNING";
172 case WIFI_STATE_AUTHENTICATING:
173 return "AUTHENTICATING";
174 case WIFI_STATE_ASSOCIATING:
175 return "ASSOCIATING";
176 case WIFI_STATE_ASSOCIATED:
177 return "ASSOCIATED";
178 case WIFI_STATE_4WAY_HANDSHAKE:
179 return "4WAY_HANDSHAKE";
180 case WIFI_STATE_GROUP_HANDSHAKE:
181 return "GROUP_HANDSHAKE";
182 case WIFI_STATE_COMPLETED:
183 return "COMPLETED";
184 case WIFI_STATE_UNKNOWN:
185 default:
186 return "UNKNOWN";
187 }
188 }
189
wifi_mode_txt(enum wifi_iface_mode mode)190 const char *wifi_mode_txt(enum wifi_iface_mode mode)
191 {
192 switch (mode) {
193 case WIFI_MODE_INFRA:
194 return "STATION";
195 case WIFI_MODE_IBSS:
196 return "ADHOC";
197 case WIFI_MODE_AP:
198 return "ACCESS POINT";
199 case WIFI_MODE_P2P_GO:
200 return "P2P GROUP OWNER";
201 case WIFI_MODE_P2P_GROUP_FORMATION:
202 return "P2P GROUP FORMATION";
203 case WIFI_MODE_MESH:
204 return "MESH";
205 case WIFI_MODE_UNKNOWN:
206 default:
207 return "UNKNOWN";
208 }
209 }
210
wifi_link_mode_txt(enum wifi_link_mode link_mode)211 const char *wifi_link_mode_txt(enum wifi_link_mode link_mode)
212 {
213 switch (link_mode) {
214 case WIFI_0:
215 return "WIFI 0 (802.11)";
216 case WIFI_1:
217 return "WIFI 1 (802.11b)";
218 case WIFI_2:
219 return "WIFI 2 (802.11a)";
220 case WIFI_3:
221 return "WIFI 3 (802.11g)";
222 case WIFI_4:
223 return "WIFI 4 (802.11n/HT)";
224 case WIFI_5:
225 return "WIFI 5 (802.11ac/VHT)";
226 case WIFI_6:
227 return "WIFI 6 (802.11ax/HE)";
228 case WIFI_6E:
229 return "WIFI 6E (802.11ax 6GHz/HE)";
230 case WIFI_7:
231 return "WIFI 7 (802.11be/EHT)";
232 case WIFI_LINK_MODE_UNKNOWN:
233 default:
234 return "UNKNOWN";
235 }
236 }
237
wifi_ps_txt(enum wifi_ps ps_name)238 const char *wifi_ps_txt(enum wifi_ps ps_name)
239 {
240 switch (ps_name) {
241 case WIFI_PS_DISABLED:
242 return "Power save disabled";
243 case WIFI_PS_ENABLED:
244 return "Power save enabled";
245 default:
246 return "UNKNOWN";
247 }
248 }
249
wifi_ps_mode_txt(enum wifi_ps_mode ps_mode)250 const char *wifi_ps_mode_txt(enum wifi_ps_mode ps_mode)
251 {
252 switch (ps_mode) {
253 case WIFI_PS_MODE_LEGACY:
254 return "Legacy power save";
255 case WIFI_PS_MODE_WMM:
256 return "WMM power save";
257 default:
258 return "UNKNOWN";
259 }
260 }
261
wifi_twt_operation_txt(enum wifi_twt_operation twt_operation)262 const char *wifi_twt_operation_txt(enum wifi_twt_operation twt_operation)
263 {
264 switch (twt_operation) {
265 case WIFI_TWT_SETUP:
266 return "TWT setup";
267 case WIFI_TWT_TEARDOWN:
268 return "TWT teardown";
269 default:
270 return "UNKNOWN";
271 }
272 }
273
wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation)274 const char *wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation)
275 {
276 switch (twt_negotiation) {
277 case WIFI_TWT_INDIVIDUAL:
278 return "TWT individual negotiation";
279 case WIFI_TWT_BROADCAST:
280 return "TWT broadcast negotiation";
281 case WIFI_TWT_WAKE_TBTT:
282 return "TWT wake TBTT negotiation";
283 default:
284 return "UNKNOWN";
285 }
286 }
287
wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup)288 const char *wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup)
289 {
290 switch (twt_setup) {
291 case WIFI_TWT_SETUP_CMD_REQUEST:
292 return "TWT request";
293 case WIFI_TWT_SETUP_CMD_SUGGEST:
294 return "TWT suggest";
295 case WIFI_TWT_SETUP_CMD_DEMAND:
296 return "TWT demand";
297 case WIFI_TWT_SETUP_CMD_GROUPING:
298 return "TWT grouping";
299 case WIFI_TWT_SETUP_CMD_ACCEPT:
300 return "TWT accept";
301 case WIFI_TWT_SETUP_CMD_ALTERNATE:
302 return "TWT alternate";
303 case WIFI_TWT_SETUP_CMD_DICTATE:
304 return "TWT dictate";
305 case WIFI_TWT_SETUP_CMD_REJECT:
306 return "TWT reject";
307 default:
308 return "UNKNOWN";
309 }
310 }
311
wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode)312 const char *wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode)
313 {
314 switch (ps_wakeup_mode) {
315 case WIFI_PS_WAKEUP_MODE_DTIM:
316 return "PS wakeup mode DTIM";
317 case WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL:
318 return "PS wakeup mode listen interval";
319 default:
320 return "UNKNOWN";
321 }
322 }
323
wifi_ps_exit_strategy_txt(enum wifi_ps_exit_strategy ps_exit_strategy)324 const char *wifi_ps_exit_strategy_txt(enum wifi_ps_exit_strategy ps_exit_strategy)
325 {
326 switch (ps_exit_strategy) {
327 case WIFI_PS_EXIT_EVERY_TIM:
328 return "Every TIM";
329 case WIFI_PS_EXIT_CUSTOM_ALGO:
330 return "Custom algorithm";
331 default:
332 return "UNKNOWN";
333 }
334 }
335
get_wifi_api(struct net_if * iface)336 static const struct wifi_mgmt_ops *const get_wifi_api(struct net_if *iface)
337 {
338 const struct device *dev = net_if_get_device(iface);
339 struct net_wifi_mgmt_offload *off_api;
340
341 if (dev == NULL) {
342 return NULL;
343 }
344
345 off_api = (struct net_wifi_mgmt_offload *) dev->api;
346 #ifdef CONFIG_WIFI_NM
347 struct wifi_nm_instance *nm = wifi_nm_get_instance_iface(iface);
348
349 if (nm) {
350 return nm->ops;
351 }
352 #endif /* CONFIG_WIFI_NM */
353 return off_api ? off_api->wifi_mgmt_api : NULL;
354 }
355
wifi_connect(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)356 static int wifi_connect(uint32_t mgmt_request, struct net_if *iface,
357 void *data, size_t len)
358 {
359 struct wifi_connect_req_params *params =
360 (struct wifi_connect_req_params *)data;
361 const struct device *dev = net_if_get_device(iface);
362
363 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
364
365 if (wifi_mgmt_api == NULL || wifi_mgmt_api->connect == NULL) {
366 return -ENOTSUP;
367 }
368
369 if (!net_if_is_admin_up(iface)) {
370 return -ENETDOWN;
371 }
372
373 LOG_HEXDUMP_DBG(params->ssid, params->ssid_length, "ssid");
374 LOG_HEXDUMP_DBG(params->psk, params->psk_length, "psk");
375 if (params->sae_password) {
376 LOG_HEXDUMP_DBG(params->sae_password, params->sae_password_length, "sae");
377 }
378 NET_DBG("ch %u sec %u", params->channel, params->security);
379
380 if ((params->security > WIFI_SECURITY_TYPE_MAX) ||
381 (params->ssid_length > WIFI_SSID_MAX_LEN) ||
382 (params->ssid_length == 0U) ||
383 ((params->security == WIFI_SECURITY_TYPE_PSK ||
384 params->security == WIFI_SECURITY_TYPE_WPA_PSK ||
385 params->security == WIFI_SECURITY_TYPE_PSK_SHA256 ||
386 params->security == WIFI_SECURITY_TYPE_WPA_AUTO_PERSONAL) &&
387 ((params->psk_length < 8) || (params->psk_length > 64) ||
388 (params->psk_length == 0U) || !params->psk)) ||
389 ((params->security == WIFI_SECURITY_TYPE_SAE_HNP ||
390 params->security == WIFI_SECURITY_TYPE_SAE_H2E ||
391 params->security == WIFI_SECURITY_TYPE_SAE_AUTO) &&
392 ((params->psk_length == 0U) || !params->psk) &&
393 ((params->sae_password_length == 0U) || !params->sae_password)) ||
394 ((params->channel != WIFI_CHANNEL_ANY) &&
395 (params->channel > WIFI_CHANNEL_MAX)) ||
396 !params->ssid) {
397 return -EINVAL;
398 }
399
400 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_ROAMING
401 memset(&roaming_params, 0x0, sizeof(roaming_params));
402 roaming_params.is_11r_used = params->ft_used;
403 #endif
404
405 return wifi_mgmt_api->connect(dev, params);
406 }
407
408 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CONNECT, wifi_connect);
409
scan_result_cb(struct net_if * iface,int status,struct wifi_scan_result * entry)410 static void scan_result_cb(struct net_if *iface, int status,
411 struct wifi_scan_result *entry)
412 {
413 if (!iface) {
414 return;
415 }
416
417 if (!entry) {
418 struct wifi_status scan_status = {
419 .status = status,
420 };
421
422 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_SCAN_DONE,
423 iface, &scan_status,
424 sizeof(struct wifi_status));
425 return;
426 }
427
428 #ifndef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY
429 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_SCAN_RESULT, iface,
430 entry, sizeof(struct wifi_scan_result));
431 #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY */
432 }
433
wifi_scan(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)434 static int wifi_scan(uint32_t mgmt_request, struct net_if *iface,
435 void *data, size_t len)
436 {
437 const struct device *dev = net_if_get_device(iface);
438 struct wifi_scan_params *params = data;
439 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
440
441 if (wifi_mgmt_api == NULL || wifi_mgmt_api->scan == NULL) {
442 return -ENOTSUP;
443 }
444
445 if (!net_if_is_admin_up(iface)) {
446 return -ENETDOWN;
447 }
448
449 #ifdef CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN
450 struct wifi_scan_params default_params = {0};
451
452 if (params == NULL) {
453 params = &default_params;
454 }
455 params->scan_type = WIFI_SCAN_TYPE_PASSIVE;
456 #endif /* CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN */
457
458 return wifi_mgmt_api->scan(dev, params, scan_result_cb);
459 }
460
461 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_SCAN, wifi_scan);
462
wifi_disconnect(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)463 static int wifi_disconnect(uint32_t mgmt_request, struct net_if *iface,
464 void *data, size_t len)
465 {
466 const struct device *dev = net_if_get_device(iface);
467 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
468
469 if (wifi_mgmt_api == NULL || wifi_mgmt_api->disconnect == NULL) {
470 return -ENOTSUP;
471 }
472
473 if (!net_if_is_admin_up(iface)) {
474 return -ENETDOWN;
475 }
476
477 return wifi_mgmt_api->disconnect(dev);
478 }
479
480 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_DISCONNECT, wifi_disconnect);
481
wifi_mgmt_raise_connect_result_event(struct net_if * iface,int status)482 void wifi_mgmt_raise_connect_result_event(struct net_if *iface, int status)
483 {
484 struct wifi_status cnx_status = {
485 .status = status,
486 };
487
488 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_CONNECT_RESULT,
489 iface, &cnx_status,
490 sizeof(struct wifi_status));
491 }
492
wifi_mgmt_raise_disconnect_result_event(struct net_if * iface,int status)493 void wifi_mgmt_raise_disconnect_result_event(struct net_if *iface, int status)
494 {
495 struct wifi_status cnx_status = {
496 .status = status,
497 };
498
499 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_DISCONNECT_RESULT,
500 iface, &cnx_status,
501 sizeof(struct wifi_status));
502 }
503
504 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_ROAMING
wifi_start_roaming(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)505 static int wifi_start_roaming(uint32_t mgmt_request, struct net_if *iface,
506 void *data, size_t len)
507 {
508 const struct device *dev = net_if_get_device(iface);
509 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
510
511 if (wifi_mgmt_api == NULL) {
512 return -ENOTSUP;
513 }
514
515 if (!net_if_is_admin_up(iface)) {
516 return -ENETDOWN;
517 }
518
519 if (roaming_params.is_11r_used) {
520 if (wifi_mgmt_api->start_11r_roaming == NULL) {
521 return -ENOTSUP;
522 }
523
524 return wifi_mgmt_api->start_11r_roaming(dev);
525 } else if (roaming_params.is_11k_enabled) {
526 memset(&roaming_params.neighbor_rep, 0x0, sizeof(roaming_params.neighbor_rep));
527 if (wifi_mgmt_api->send_11k_neighbor_request == NULL) {
528 return -ENOTSUP;
529 }
530
531 return wifi_mgmt_api->send_11k_neighbor_request(dev, NULL);
532 } else if (wifi_mgmt_api->bss_ext_capab &&
533 wifi_mgmt_api->bss_ext_capab(dev, WIFI_EXT_CAPAB_BSS_TRANSITION)) {
534 if (wifi_mgmt_api->btm_query) {
535 return wifi_mgmt_api->btm_query(dev, 0x10);
536 } else {
537 return -ENOTSUP;
538 }
539 } else if (wifi_mgmt_api->legacy_roam) {
540 return wifi_mgmt_api->legacy_roam(dev);
541 } else {
542 return -ENOTSUP;
543 }
544 }
545
546 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_START_ROAMING, wifi_start_roaming);
547
wifi_neighbor_rep_complete(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)548 static int wifi_neighbor_rep_complete(uint32_t mgmt_request, struct net_if *iface,
549 void *data, size_t len)
550 {
551 const struct device *dev = net_if_get_device(iface);
552 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
553 struct wifi_scan_params params = {0};
554
555 if (!net_if_is_admin_up(iface)) {
556 return -ENETDOWN;
557 }
558
559 for (int i = 0; i < roaming_params.neighbor_rep.neighbor_cnt; i++) {
560 params.band_chan[i].channel = roaming_params.neighbor_rep.neighbor_ap[i].channel;
561 if (params.band_chan[i].channel > 14) {
562 params.band_chan[i].band = WIFI_FREQ_BAND_5_GHZ;
563 } else {
564 params.band_chan[i].band = WIFI_FREQ_BAND_2_4_GHZ;
565 }
566 }
567 if (wifi_mgmt_api == NULL || wifi_mgmt_api->candidate_scan == NULL) {
568 return -ENOTSUP;
569 }
570
571 return wifi_mgmt_api->candidate_scan(dev, ¶ms);
572 }
573
574 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_NEIGHBOR_REP_COMPLETE,
575 wifi_neighbor_rep_complete);
576
wifi_mgmt_raise_neighbor_rep_recv_event(struct net_if * iface,char * inbuf,size_t buf_len)577 void wifi_mgmt_raise_neighbor_rep_recv_event(struct net_if *iface, char *inbuf, size_t buf_len)
578 {
579 const uint8_t *buf = inbuf;
580 char event[MAX_EVENT_STR_LEN + 1] = {0};
581 char bssid[WIFI_SSID_MAX_LEN + 1] = {0};
582 char bssid_info[WIFI_SSID_MAX_LEN + 1] = {0};
583 int op_class, channel, phy_type;
584 int idx = roaming_params.neighbor_rep.neighbor_cnt;
585
586 if (!buf || buf[0] == '\0') {
587 return;
588 }
589
590 if (sscanf(buf,
591 "%" STRINGIFY(MAX_EVENT_STR_LEN) "s "
592 "bssid=%" STRINGIFY(WIFI_SSID_MAX_LEN) "s "
593 "info=%" STRINGIFY(WIFI_SSID_MAX_LEN) "s "
594 "op_class=%d chan=%d phy_type=%d",
595 event, bssid, bssid_info, &op_class, &channel, &phy_type) == 6) {
596 int i;
597 int match = 0;
598 size_t len = 0;
599
600 for (i = 0; i < roaming_params.neighbor_rep.neighbor_cnt; i++) {
601 if (strncmp((const char *)roaming_params.neighbor_rep.neighbor_ap[i].bssid,
602 bssid, sizeof(bssid)) == 0) {
603 match = 1;
604 break;
605 }
606
607 if (roaming_params.neighbor_rep.neighbor_ap[i].channel == channel) {
608 match = 1;
609 break;
610 }
611 }
612 if (!match && (roaming_params.neighbor_rep.neighbor_cnt < MAX_NEIGHBOR_AP_LIMIT)) {
613 memcpy((char *)roaming_params.neighbor_rep.neighbor_ap[idx].bssid,
614 bssid,
615 sizeof(roaming_params.neighbor_rep.neighbor_ap[idx].bssid));
616 len = strnlen(bssid, sizeof(bssid) - 1);
617 roaming_params.neighbor_rep.neighbor_ap[idx].bssid[len] = (uint8_t)'\0';
618
619 memcpy((char *)roaming_params.neighbor_rep.neighbor_ap[idx].bssid_info,
620 bssid_info,
621 sizeof(roaming_params.neighbor_rep.neighbor_ap[idx].bssid_info));
622 len = strnlen(bssid_info, sizeof(bssid_info) - 1);
623 roaming_params.neighbor_rep.neighbor_ap[idx].bssid_info[len] =
624 (uint8_t)'\0';
625
626 roaming_params.neighbor_rep.neighbor_ap[idx].channel = channel;
627 roaming_params.neighbor_rep.neighbor_ap[idx].op_class = op_class;
628 roaming_params.neighbor_rep.neighbor_ap[idx].phy_type = phy_type;
629
630 roaming_params.neighbor_rep.neighbor_cnt += 1;
631 } else if (match) {
632 LOG_INF("BSSID already present in neighbor list, Skipping %s ",
633 bssid);
634 } else {
635 LOG_INF("Maximum neighbors added to list, Skipping.");
636 }
637 } else {
638 LOG_INF("Failed to Parse Neighbor Report - Skipping entry\n");
639 }
640 }
641 #endif
642
wifi_ap_enable(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)643 static int wifi_ap_enable(uint32_t mgmt_request, struct net_if *iface,
644 void *data, size_t len)
645 {
646 struct wifi_connect_req_params *params =
647 (struct wifi_connect_req_params *)data;
648 const struct device *dev = net_if_get_device(iface);
649 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
650
651 if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_enable == NULL) {
652 return -ENOTSUP;
653 }
654
655 if (!net_if_is_admin_up(iface)) {
656 return -ENETDOWN;
657 }
658
659 return wifi_mgmt_api->ap_enable(dev, params);
660 }
661
662 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_ENABLE, wifi_ap_enable);
663
wifi_ap_disable(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)664 static int wifi_ap_disable(uint32_t mgmt_request, struct net_if *iface,
665 void *data, size_t len)
666 {
667 const struct device *dev = net_if_get_device(iface);
668 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
669
670 if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_disable == NULL) {
671 return -ENOTSUP;
672 }
673
674 if (!net_if_is_admin_up(iface)) {
675 return -ENETDOWN;
676 }
677
678 return wifi_mgmt_api->ap_disable(dev);
679 }
680
681 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_DISABLE, wifi_ap_disable);
682
wifi_ap_sta_disconnect(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)683 static int wifi_ap_sta_disconnect(uint32_t mgmt_request, struct net_if *iface,
684 void *data, size_t len)
685 {
686 const struct device *dev = net_if_get_device(iface);
687 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
688 uint8_t *mac = data;
689
690 if (dev == NULL) {
691 return -ENODEV;
692 }
693
694 if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_sta_disconnect == NULL) {
695 return -ENOTSUP;
696 }
697
698 if (!net_if_is_admin_up(iface)) {
699 return -ENETDOWN;
700 }
701
702 if (!data || len != sizeof(uint8_t) * WIFI_MAC_ADDR_LEN) {
703 return -EINVAL;
704 }
705
706 return wifi_mgmt_api->ap_sta_disconnect(dev, mac);
707 }
708
709 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_STA_DISCONNECT, wifi_ap_sta_disconnect);
710
wifi_ap_config_params(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)711 static int wifi_ap_config_params(uint32_t mgmt_request, struct net_if *iface,
712 void *data, size_t len)
713 {
714 const struct device *dev = net_if_get_device(iface);
715 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
716 struct wifi_ap_config_params *params = data;
717
718 if (dev == NULL) {
719 return -ENODEV;
720 }
721
722 if (wifi_mgmt_api == NULL ||
723 wifi_mgmt_api->ap_config_params == NULL) {
724 return -ENOTSUP;
725 }
726
727 if (!net_if_is_admin_up(iface)) {
728 return -ENETDOWN;
729 }
730
731 if (!data || len != sizeof(*params)) {
732 return -EINVAL;
733 }
734
735 if (params->type & WIFI_AP_CONFIG_PARAM_MAX_NUM_STA) {
736 if (params->max_num_sta > CONFIG_WIFI_MGMT_AP_MAX_NUM_STA) {
737 LOG_INF("Maximum number of stations(%d) "
738 "exceeded default configured value = %d.",
739 params->max_num_sta, CONFIG_WIFI_MGMT_AP_MAX_NUM_STA);
740 return -EINVAL;
741 }
742 }
743
744 return wifi_mgmt_api->ap_config_params(dev, params);
745 }
746
747 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_CONFIG_PARAM, wifi_ap_config_params);
748
wifi_ap_set_rts_threshold(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)749 static int wifi_ap_set_rts_threshold(uint32_t mgmt_request, struct net_if *iface,
750 void *data, size_t len)
751 {
752 const struct device *dev = net_if_get_device(iface);
753 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
754 unsigned int *rts_threshold = data;
755
756 if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_rts_threshold == NULL) {
757 return -ENOTSUP;
758 }
759
760 if (!net_if_is_admin_up(iface)) {
761 return -ENETDOWN;
762 }
763
764 if (data == NULL || len != sizeof(*rts_threshold)) {
765 return -EINVAL;
766 }
767
768 return wifi_mgmt_api->set_rts_threshold(dev, *rts_threshold);
769 }
770
771 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_RTS_THRESHOLD, wifi_ap_set_rts_threshold);
772
wifi_iface_status(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)773 static int wifi_iface_status(uint32_t mgmt_request, struct net_if *iface,
774 void *data, size_t len)
775 {
776 const struct device *dev = net_if_get_device(iface);
777 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
778 struct wifi_iface_status *status = data;
779
780 if (wifi_mgmt_api == NULL || wifi_mgmt_api->iface_status == NULL) {
781 return -ENOTSUP;
782 }
783
784 if (!data || len != sizeof(*status)) {
785 return -EINVAL;
786 }
787
788 return wifi_mgmt_api->iface_status(dev, status);
789 }
790 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_IFACE_STATUS, wifi_iface_status);
791
wifi_mgmt_raise_iface_status_event(struct net_if * iface,struct wifi_iface_status * iface_status)792 void wifi_mgmt_raise_iface_status_event(struct net_if *iface,
793 struct wifi_iface_status *iface_status)
794 {
795 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_IFACE_STATUS,
796 iface, iface_status,
797 sizeof(struct wifi_iface_status));
798 }
799
800 #ifdef CONFIG_NET_STATISTICS_WIFI
wifi_iface_stats(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)801 static int wifi_iface_stats(uint32_t mgmt_request, struct net_if *iface,
802 void *data, size_t len)
803 {
804 const struct device *dev = net_if_get_device(iface);
805 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
806 struct net_stats_wifi *stats = data;
807
808 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_stats == NULL) {
809 return -ENOTSUP;
810 }
811
812 if (!data || len != sizeof(*stats)) {
813 return -EINVAL;
814 }
815
816 return wifi_mgmt_api->get_stats(dev, stats);
817 }
818 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_STATS_GET_WIFI, wifi_iface_stats);
819
wifi_iface_stats_reset(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)820 static int wifi_iface_stats_reset(uint32_t mgmt_request, struct net_if *iface,
821 void *data, size_t len)
822 {
823 const struct device *dev = net_if_get_device(iface);
824 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
825
826 if (wifi_mgmt_api == NULL || wifi_mgmt_api->reset_stats == NULL) {
827 return -ENOTSUP;
828 }
829
830 return wifi_mgmt_api->reset_stats(dev);
831 }
832 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_STATS_RESET_WIFI, wifi_iface_stats_reset);
833 #endif /* CONFIG_NET_STATISTICS_WIFI */
834
wifi_11k_cfg(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)835 static int wifi_11k_cfg(uint32_t mgmt_request, struct net_if *iface,
836 void *data, size_t len)
837 {
838 const struct device *dev = net_if_get_device(iface);
839 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
840 struct wifi_11k_params *params = data;
841
842 if (wifi_mgmt_api == NULL || wifi_mgmt_api->cfg_11k == NULL) {
843 return -ENOTSUP;
844 }
845
846 if (!net_if_is_admin_up(iface)) {
847 return -ENETDOWN;
848 }
849
850 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_ROAMING
851 if (params->oper == WIFI_MGMT_SET) {
852 roaming_params.is_11k_enabled = params->enable_11k;
853 }
854 #endif
855
856 return wifi_mgmt_api->cfg_11k(dev, params);
857 }
858
859 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_11K_CONFIG, wifi_11k_cfg);
860
wifi_11k_neighbor_request(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)861 static int wifi_11k_neighbor_request(uint32_t mgmt_request, struct net_if *iface,
862 void *data, size_t len)
863 {
864 const struct device *dev = net_if_get_device(iface);
865 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
866 struct wifi_11k_params *params = data;
867
868 if (wifi_mgmt_api == NULL || wifi_mgmt_api->send_11k_neighbor_request == NULL) {
869 return -ENOTSUP;
870 }
871
872 if (!net_if_is_admin_up(iface)) {
873 return -ENETDOWN;
874 }
875
876 return wifi_mgmt_api->send_11k_neighbor_request(dev, params);
877 }
878
879 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_11K_NEIGHBOR_REQUEST,
880 wifi_11k_neighbor_request);
881
wifi_set_power_save(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)882 static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface,
883 void *data, size_t len)
884 {
885 const struct device *dev = net_if_get_device(iface);
886 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
887 struct wifi_ps_params *ps_params = data;
888 struct wifi_iface_status info = { 0 };
889
890 if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_power_save == NULL) {
891 return -ENOTSUP;
892 }
893
894 if (!net_if_is_admin_up(iface)) {
895 return -ENETDOWN;
896 }
897
898 switch (ps_params->type) {
899 case WIFI_PS_PARAM_LISTEN_INTERVAL:
900 case WIFI_PS_PARAM_MODE:
901 if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info,
902 sizeof(struct wifi_iface_status))) {
903 ps_params->fail_reason =
904 WIFI_PS_PARAM_FAIL_UNABLE_TO_GET_IFACE_STATUS;
905 return -EIO;
906 }
907
908 if (info.state >= WIFI_STATE_ASSOCIATED) {
909 ps_params->fail_reason =
910 WIFI_PS_PARAM_FAIL_DEVICE_CONNECTED;
911 return -ENOTSUP;
912 }
913 break;
914 case WIFI_PS_PARAM_STATE:
915 case WIFI_PS_PARAM_WAKEUP_MODE:
916 case WIFI_PS_PARAM_TIMEOUT:
917 break;
918 case WIFI_PS_PARAM_EXIT_STRATEGY:
919 if (ps_params->exit_strategy > WIFI_PS_EXIT_MAX) {
920 ps_params->fail_reason =
921 WIFI_PS_PARAM_FAIL_INVALID_EXIT_STRATEGY;
922 return -EINVAL;
923 }
924 break;
925 default:
926 ps_params->fail_reason =
927 WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED;
928 return -ENOTSUP;
929 }
930
931 return wifi_mgmt_api->set_power_save(dev, ps_params);
932 }
933
934 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS, wifi_set_power_save);
935
wifi_get_power_save_config(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)936 static int wifi_get_power_save_config(uint32_t mgmt_request, struct net_if *iface,
937 void *data, size_t len)
938 {
939 const struct device *dev = net_if_get_device(iface);
940 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
941 struct wifi_ps_config *ps_config = data;
942
943 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_power_save_config == NULL) {
944 return -ENOTSUP;
945 }
946
947 if (!net_if_is_admin_up(iface)) {
948 return -ENETDOWN;
949 }
950
951 if (!data || len != sizeof(*ps_config)) {
952 return -EINVAL;
953 }
954
955 return wifi_mgmt_api->get_power_save_config(dev, ps_config);
956 }
957
958 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_CONFIG, wifi_get_power_save_config);
959
wifi_set_twt(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)960 static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface,
961 void *data, size_t len)
962 {
963 const struct device *dev = net_if_get_device(iface);
964 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
965 struct wifi_twt_params *twt_params = data;
966 struct wifi_iface_status info = { 0 };
967
968 if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_twt == NULL) {
969 twt_params->fail_reason =
970 WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED;
971 return -ENOTSUP;
972 }
973
974 if (!net_if_is_admin_up(iface)) {
975 return -ENETDOWN;
976 }
977
978 if (twt_params->operation == WIFI_TWT_TEARDOWN) {
979 return wifi_mgmt_api->set_twt(dev, twt_params);
980 }
981
982 if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info,
983 sizeof(struct wifi_iface_status))) {
984 twt_params->fail_reason =
985 WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS;
986 goto fail;
987 }
988
989 if (info.state != WIFI_STATE_COMPLETED) {
990 twt_params->fail_reason =
991 WIFI_TWT_FAIL_DEVICE_NOT_CONNECTED;
992 goto fail;
993 }
994
995 #ifdef CONFIG_WIFI_MGMT_TWT_CHECK_IP
996 if ((!net_if_ipv4_get_global_addr(iface, NET_ADDR_PREFERRED)) &&
997 (!net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface))) {
998 twt_params->fail_reason =
999 WIFI_TWT_FAIL_IP_NOT_ASSIGNED;
1000 goto fail;
1001 }
1002 #else
1003 NET_WARN("Check for valid IP address been disabled. "
1004 "Device might be unreachable or might not receive traffic.\n");
1005 #endif /* CONFIG_WIFI_MGMT_TWT_CHECK_IP */
1006
1007 if (info.link_mode < WIFI_6) {
1008 twt_params->fail_reason =
1009 WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB;
1010 goto fail;
1011 }
1012
1013 if (!info.twt_capable) {
1014 twt_params->fail_reason =
1015 WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB;
1016 goto fail;
1017 }
1018
1019 return wifi_mgmt_api->set_twt(dev, twt_params);
1020 fail:
1021 return -ENOEXEC;
1022
1023 }
1024
1025 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_TWT, wifi_set_twt);
1026
wifi_set_btwt(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1027 static int wifi_set_btwt(uint32_t mgmt_request, struct net_if *iface,
1028 void *data, size_t len)
1029 {
1030 const struct device *dev = net_if_get_device(iface);
1031 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1032 struct wifi_twt_params *twt_params = data;
1033 struct wifi_iface_status info = { 0 };
1034
1035 if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_btwt == NULL) {
1036 twt_params->fail_reason =
1037 WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED;
1038 return -ENOTSUP;
1039 }
1040
1041 if (!net_if_is_admin_up(iface)) {
1042 return -ENETDOWN;
1043 }
1044
1045 if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info,
1046 sizeof(struct wifi_iface_status))) {
1047 twt_params->fail_reason =
1048 WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS;
1049 goto fail;
1050 }
1051
1052 return wifi_mgmt_api->set_btwt(dev, twt_params);
1053 fail:
1054 return -ENOEXEC;
1055
1056 }
1057
1058 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_BTWT, wifi_set_btwt);
1059
wifi_mgmt_raise_twt_event(struct net_if * iface,struct wifi_twt_params * twt_params)1060 void wifi_mgmt_raise_twt_event(struct net_if *iface, struct wifi_twt_params *twt_params)
1061 {
1062 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_TWT,
1063 iface, twt_params,
1064 sizeof(struct wifi_twt_params));
1065 }
1066
wifi_reg_domain(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1067 static int wifi_reg_domain(uint32_t mgmt_request, struct net_if *iface,
1068 void *data, size_t len)
1069 {
1070 const struct device *dev = net_if_get_device(iface);
1071 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1072 struct wifi_reg_domain *reg_domain = data;
1073
1074 if (wifi_mgmt_api == NULL || wifi_mgmt_api->reg_domain == NULL) {
1075 return -ENOTSUP;
1076 }
1077
1078 if (!net_if_is_admin_up(iface)) {
1079 return -ENETDOWN;
1080 }
1081
1082 if (!data || len != sizeof(*reg_domain)) {
1083 return -EINVAL;
1084 }
1085
1086 return wifi_mgmt_api->reg_domain(dev, reg_domain);
1087 }
1088
1089 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_REG_DOMAIN, wifi_reg_domain);
1090
wifi_mgmt_raise_twt_sleep_state(struct net_if * iface,int twt_sleep_state)1091 void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface,
1092 int twt_sleep_state)
1093 {
1094 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_TWT_SLEEP_STATE,
1095 iface, &twt_sleep_state,
1096 sizeof(twt_sleep_state));
1097 }
1098
wifi_mode(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1099 static int wifi_mode(uint32_t mgmt_request, struct net_if *iface,
1100 void *data, size_t len)
1101 {
1102 const struct device *dev = net_if_get_device(iface);
1103 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1104 struct wifi_mode_info *mode_info = data;
1105
1106 if (dev == NULL) {
1107 return -ENODEV;
1108 }
1109
1110 if (wifi_mgmt_api == NULL || wifi_mgmt_api->mode == NULL) {
1111 return -ENOTSUP;
1112 }
1113
1114 if (!net_if_is_admin_up(iface)) {
1115 return -ENETDOWN;
1116 }
1117
1118 return wifi_mgmt_api->mode(dev, mode_info);
1119 }
1120
1121 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_MODE, wifi_mode);
1122
wifi_packet_filter(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1123 static int wifi_packet_filter(uint32_t mgmt_request, struct net_if *iface,
1124 void *data, size_t len)
1125 {
1126 const struct device *dev = net_if_get_device(iface);
1127 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1128 struct wifi_filter_info *filter_info = data;
1129
1130 if (dev == NULL) {
1131 return -ENODEV;
1132 }
1133
1134 if (wifi_mgmt_api == NULL || wifi_mgmt_api->filter == NULL) {
1135 return -ENOTSUP;
1136 }
1137
1138 if (!net_if_is_admin_up(iface)) {
1139 return -ENETDOWN;
1140 }
1141
1142 return wifi_mgmt_api->filter(dev, filter_info);
1143 }
1144
1145 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PACKET_FILTER, wifi_packet_filter);
1146
wifi_channel(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1147 static int wifi_channel(uint32_t mgmt_request, struct net_if *iface,
1148 void *data, size_t len)
1149 {
1150 const struct device *dev = net_if_get_device(iface);
1151 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1152 struct wifi_channel_info *channel_info = data;
1153
1154 if (dev == NULL) {
1155 return -ENODEV;
1156 }
1157
1158 if (wifi_mgmt_api == NULL || wifi_mgmt_api->channel == NULL) {
1159 return -ENOTSUP;
1160 }
1161
1162 if (!net_if_is_admin_up(iface)) {
1163 return -ENETDOWN;
1164 }
1165
1166 return wifi_mgmt_api->channel(dev, channel_info);
1167 }
1168
1169 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL, wifi_channel);
1170
wifi_get_version(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1171 static int wifi_get_version(uint32_t mgmt_request, struct net_if *iface,
1172 void *data, size_t len)
1173 {
1174 const struct device *dev = net_if_get_device(iface);
1175 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1176 struct wifi_version *ver_params = data;
1177
1178 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_version == NULL) {
1179 return -ENOTSUP;
1180 }
1181
1182 return wifi_mgmt_api->get_version(dev, ver_params);
1183 }
1184
1185 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_VERSION, wifi_get_version);
1186
wifi_btm_query(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1187 static int wifi_btm_query(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len)
1188 {
1189 const struct device *dev = net_if_get_device(iface);
1190 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1191 uint8_t query_reason = *((uint8_t *)data);
1192
1193 if (wifi_mgmt_api == NULL || wifi_mgmt_api->btm_query == NULL) {
1194 return -ENOTSUP;
1195 }
1196
1197 if (!net_if_is_admin_up(iface)) {
1198 return -ENETDOWN;
1199 }
1200
1201 if (query_reason >= WIFI_BTM_QUERY_REASON_UNSPECIFIED &&
1202 query_reason <= WIFI_BTM_QUERY_REASON_LEAVING_ESS) {
1203 return wifi_mgmt_api->btm_query(dev, query_reason);
1204 }
1205
1206 return -EINVAL;
1207 }
1208
1209 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_BTM_QUERY, wifi_btm_query);
1210
wifi_get_connection_params(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1211 static int wifi_get_connection_params(uint32_t mgmt_request, struct net_if *iface,
1212 void *data, size_t len)
1213 {
1214 const struct device *dev = net_if_get_device(iface);
1215 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1216 struct wifi_connect_req_params *conn_params = data;
1217
1218 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_conn_params == NULL) {
1219 return -ENOTSUP;
1220 }
1221
1222 if (!net_if_is_admin_up(iface)) {
1223 return -ENETDOWN;
1224 }
1225
1226 return wifi_mgmt_api->get_conn_params(dev, conn_params);
1227 }
1228
1229 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CONN_PARAMS, wifi_get_connection_params);
1230
wifi_wps_config(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1231 static int wifi_wps_config(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len)
1232 {
1233 const struct device *dev = net_if_get_device(iface);
1234 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1235 struct wifi_wps_config_params *params = data;
1236
1237 if (wifi_mgmt_api == NULL || wifi_mgmt_api->wps_config == NULL) {
1238 return -ENOTSUP;
1239 }
1240
1241 if (!net_if_is_admin_up(iface)) {
1242 return -ENETDOWN;
1243 }
1244
1245 return wifi_mgmt_api->wps_config(dev, params);
1246 }
1247
1248 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_WPS_CONFIG, wifi_wps_config);
1249
wifi_set_rts_threshold(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1250 static int wifi_set_rts_threshold(uint32_t mgmt_request, struct net_if *iface,
1251 void *data, size_t len)
1252 {
1253 const struct device *dev = net_if_get_device(iface);
1254 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1255 unsigned int *rts_threshold = data;
1256
1257 if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_rts_threshold == NULL) {
1258 return -ENOTSUP;
1259 }
1260
1261 if (!net_if_is_admin_up(iface)) {
1262 return -ENETDOWN;
1263 }
1264
1265 if (!data || len != sizeof(*rts_threshold)) {
1266 return -EINVAL;
1267 }
1268
1269 return wifi_mgmt_api->set_rts_threshold(dev, *rts_threshold);
1270 }
1271
1272 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_RTS_THRESHOLD, wifi_set_rts_threshold);
1273
1274 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP
wifi_dpp(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1275 static int wifi_dpp(uint32_t mgmt_request, struct net_if *iface,
1276 void *data, size_t len)
1277 {
1278 const struct device *dev = net_if_get_device(iface);
1279 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1280 struct wifi_dpp_params *params = data;
1281
1282 if (wifi_mgmt_api == NULL || wifi_mgmt_api->dpp_dispatch == NULL) {
1283 return -ENOTSUP;
1284 }
1285
1286 if (!net_if_is_admin_up(iface)) {
1287 return -ENETDOWN;
1288 }
1289
1290 return wifi_mgmt_api->dpp_dispatch(dev, params);
1291 }
1292
1293 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_DPP, wifi_dpp);
1294
1295 #endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_DPP */
1296
wifi_pmksa_flush(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1297 static int wifi_pmksa_flush(uint32_t mgmt_request, struct net_if *iface,
1298 void *data, size_t len)
1299 {
1300 const struct device *dev = net_if_get_device(iface);
1301 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1302
1303 if (wifi_mgmt_api == NULL || wifi_mgmt_api->pmksa_flush == NULL) {
1304 return -ENOTSUP;
1305 }
1306
1307 if (!net_if_is_admin_up(iface)) {
1308 return -ENETDOWN;
1309 }
1310
1311 return wifi_mgmt_api->pmksa_flush(dev);
1312 }
1313
1314 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PMKSA_FLUSH, wifi_pmksa_flush);
1315
wifi_get_rts_threshold(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1316 static int wifi_get_rts_threshold(uint32_t mgmt_request, struct net_if *iface,
1317 void *data, size_t len)
1318 {
1319 const struct device *dev = net_if_get_device(iface);
1320 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1321 unsigned int *rts_threshold = data;
1322
1323 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_rts_threshold == NULL) {
1324 return -ENOTSUP;
1325 }
1326
1327 if (!net_if_is_admin_up(iface)) {
1328 return -ENETDOWN;
1329 }
1330
1331 if (!data || len != sizeof(*rts_threshold)) {
1332 return -EINVAL;
1333 }
1334
1335 return wifi_mgmt_api->get_rts_threshold(dev, rts_threshold);
1336 }
1337
1338 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_RTS_THRESHOLD_CONFIG, wifi_get_rts_threshold);
1339
1340 #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_CRYPTO_ENTERPRISE
wifi_set_enterprise_creds(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1341 static int wifi_set_enterprise_creds(uint32_t mgmt_request, struct net_if *iface,
1342 void *data, size_t len)
1343 {
1344 const struct device *dev = net_if_get_device(iface);
1345 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1346 struct wifi_enterprise_creds_params *params = data;
1347
1348 if (wifi_mgmt_api == NULL || wifi_mgmt_api->enterprise_creds == NULL) {
1349 return -ENOTSUP;
1350 }
1351
1352 if (!net_if_is_admin_up(iface)) {
1353 return -ENETDOWN;
1354 }
1355
1356 return wifi_mgmt_api->enterprise_creds(dev, params);
1357 }
1358
1359 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_ENTERPRISE_CREDS, wifi_set_enterprise_creds);
1360 #endif
1361
1362 #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS
wifi_mgmt_raise_raw_scan_result_event(struct net_if * iface,struct wifi_raw_scan_result * raw_scan_result)1363 void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface,
1364 struct wifi_raw_scan_result *raw_scan_result)
1365 {
1366 if (raw_scan_result->frame_length > CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH) {
1367 LOG_INF("raw scan result frame length = %d too big,"
1368 "saving upto max raw scan length = %d",
1369 raw_scan_result->frame_length,
1370 CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH);
1371 }
1372
1373 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_RAW_SCAN_RESULT,
1374 iface, raw_scan_result,
1375 sizeof(*raw_scan_result));
1376 }
1377 #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */
1378
wifi_mgmt_raise_disconnect_complete_event(struct net_if * iface,int status)1379 void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface,
1380 int status)
1381 {
1382 struct wifi_status cnx_status = {
1383 .status = status,
1384 };
1385
1386 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_DISCONNECT_COMPLETE,
1387 iface, &cnx_status,
1388 sizeof(struct wifi_status));
1389 }
1390
wifi_mgmt_raise_ap_enable_result_event(struct net_if * iface,enum wifi_ap_status status)1391 void wifi_mgmt_raise_ap_enable_result_event(struct net_if *iface,
1392 enum wifi_ap_status status)
1393 {
1394 struct wifi_status cnx_status = {
1395 .status = status,
1396 };
1397
1398 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_ENABLE_RESULT,
1399 iface, &cnx_status,
1400 sizeof(enum wifi_ap_status));
1401 }
1402
wifi_mgmt_raise_ap_disable_result_event(struct net_if * iface,enum wifi_ap_status status)1403 void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface,
1404 enum wifi_ap_status status)
1405 {
1406 struct wifi_status cnx_status = {
1407 .status = status,
1408 };
1409
1410 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_DISABLE_RESULT,
1411 iface, &cnx_status,
1412 sizeof(enum wifi_ap_status));
1413 }
1414
wifi_mgmt_raise_ap_sta_connected_event(struct net_if * iface,struct wifi_ap_sta_info * sta_info)1415 void wifi_mgmt_raise_ap_sta_connected_event(struct net_if *iface,
1416 struct wifi_ap_sta_info *sta_info)
1417 {
1418 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_STA_CONNECTED,
1419 iface, sta_info,
1420 sizeof(struct wifi_ap_sta_info));
1421 }
1422
wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if * iface,struct wifi_ap_sta_info * sta_info)1423 void wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if *iface,
1424 struct wifi_ap_sta_info *sta_info)
1425 {
1426 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_STA_DISCONNECTED,
1427 iface, sta_info,
1428 sizeof(struct wifi_ap_sta_info));
1429 }
1430
1431 #ifdef CONFIG_WIFI_CREDENTIALS_CONNECT_STORED
1432
1433 #include <zephyr/net/wifi_credentials.h>
1434
1435 #if defined(CONFIG_WIFI_CREDENTIALS_STATIC)
1436 BUILD_ASSERT(sizeof(CONFIG_WIFI_CREDENTIALS_STATIC_SSID) != 1,
1437 "CONFIG_WIFI_CREDENTIALS_STATIC_SSID required");
1438 #endif /* defined(CONFIG_WIFI_CREDENTIALS_STATIC) */
1439
__stored_creds_to_params(struct wifi_credentials_personal * creds,struct wifi_connect_req_params * params)1440 static int __stored_creds_to_params(struct wifi_credentials_personal *creds,
1441 struct wifi_connect_req_params *params)
1442 {
1443 char *ssid = NULL;
1444 char *psk = NULL;
1445 int ret;
1446
1447 /* SSID */
1448 ssid = (char *)k_malloc(creds->header.ssid_len + 1);
1449 if (!ssid) {
1450 LOG_ERR("Failed to allocate memory for SSID\n");
1451 ret = -ENOMEM;
1452 goto err_out;
1453 }
1454
1455 memset(ssid, 0, creds->header.ssid_len + 1);
1456 ret = snprintf(ssid, creds->header.ssid_len + 1, "%s", creds->header.ssid);
1457 if (ret > creds->header.ssid_len) {
1458 LOG_ERR("SSID string truncated\n");
1459 ret = -EINVAL;
1460 goto err_out;
1461 }
1462
1463 params->ssid = ssid;
1464 params->ssid_length = creds->header.ssid_len;
1465
1466 /* PSK (optional) */
1467 if (creds->password_len > 0) {
1468 psk = (char *)k_malloc(creds->password_len + 1);
1469 if (!psk) {
1470 LOG_ERR("Failed to allocate memory for PSK\n");
1471 ret = -ENOMEM;
1472 goto err_out;
1473 }
1474
1475 memset(psk, 0, creds->password_len + 1);
1476 ret = snprintf(psk, creds->password_len + 1, "%s", creds->password);
1477 if (ret > creds->password_len) {
1478 LOG_ERR("PSK string truncated\n");
1479 ret = -EINVAL;
1480 goto err_out;
1481 }
1482
1483 params->psk = psk;
1484 params->psk_length = creds->password_len;
1485 }
1486
1487 /* Defaults */
1488 params->security = creds->header.type;
1489
1490 /* If channel is set to 0 we default to ANY. 0 is not a valid Wi-Fi channel. */
1491 params->channel = (creds->header.channel != 0) ? creds->header.channel : WIFI_CHANNEL_ANY;
1492 params->timeout = (creds->header.timeout != 0)
1493 ? creds->header.timeout
1494 : CONFIG_WIFI_CREDENTIALS_CONNECT_STORED_CONNECTION_TIMEOUT;
1495
1496 /* Security type (optional) */
1497 if (creds->header.type > WIFI_SECURITY_TYPE_MAX) {
1498 params->security = WIFI_SECURITY_TYPE_NONE;
1499 }
1500
1501 if (creds->header.flags & WIFI_CREDENTIALS_FLAG_2_4GHz) {
1502 params->band = WIFI_FREQ_BAND_2_4_GHZ;
1503 } else if (creds->header.flags & WIFI_CREDENTIALS_FLAG_5GHz) {
1504 params->band = WIFI_FREQ_BAND_5_GHZ;
1505 } else {
1506 params->band = WIFI_FREQ_BAND_UNKNOWN;
1507 }
1508
1509 /* MFP setting (default: optional) */
1510 if (creds->header.flags & WIFI_CREDENTIALS_FLAG_MFP_DISABLED) {
1511 params->mfp = WIFI_MFP_DISABLE;
1512 } else if (creds->header.flags & WIFI_CREDENTIALS_FLAG_MFP_REQUIRED) {
1513 params->mfp = WIFI_MFP_REQUIRED;
1514 } else {
1515 params->mfp = WIFI_MFP_OPTIONAL;
1516 }
1517
1518 return 0;
1519 err_out:
1520 if (ssid) {
1521 k_free(ssid);
1522 ssid = NULL;
1523 }
1524
1525 if (psk) {
1526 k_free(psk);
1527 psk = NULL;
1528 }
1529
1530 return ret;
1531 }
1532
wpa_supp_security_txt(enum wifi_security_type security)1533 static inline const char *wpa_supp_security_txt(enum wifi_security_type security)
1534 {
1535 switch (security) {
1536 case WIFI_SECURITY_TYPE_NONE:
1537 return "NONE";
1538 case WIFI_SECURITY_TYPE_PSK:
1539 return "WPA-PSK";
1540 case WIFI_SECURITY_TYPE_PSK_SHA256:
1541 return "WPA-PSK-SHA256";
1542 case WIFI_SECURITY_TYPE_SAE:
1543 return "SAE";
1544 case WIFI_SECURITY_TYPE_UNKNOWN:
1545 default:
1546 return "UNKNOWN";
1547 }
1548 }
1549
add_network_from_credentials_struct_personal(struct wifi_credentials_personal * creds,struct net_if * iface)1550 static int add_network_from_credentials_struct_personal(struct wifi_credentials_personal *creds,
1551 struct net_if *iface)
1552 {
1553 int ret = 0;
1554 struct wifi_connect_req_params cnx_params = {0};
1555
1556 if (__stored_creds_to_params(creds, &cnx_params)) {
1557 ret = -ENOEXEC;
1558 goto out;
1559 }
1560
1561 if (net_mgmt(NET_REQUEST_WIFI_CONNECT, iface, &cnx_params,
1562 sizeof(struct wifi_connect_req_params))) {
1563 LOG_ERR("Connection request failed\n");
1564
1565 return -ENOEXEC;
1566 }
1567
1568 LOG_INF("Connection requested");
1569
1570 out:
1571 if (cnx_params.psk) {
1572 k_free((void *)cnx_params.psk);
1573 }
1574
1575 if (cnx_params.ssid) {
1576 k_free((void *)cnx_params.ssid);
1577 }
1578
1579 return ret;
1580 }
1581
add_stored_network(void * cb_arg,const char * ssid,size_t ssid_len)1582 static void add_stored_network(void *cb_arg, const char *ssid, size_t ssid_len)
1583 {
1584 int ret = 0;
1585 struct wifi_credentials_personal creds;
1586
1587 /* load stored data */
1588 ret = wifi_credentials_get_by_ssid_personal_struct(ssid, ssid_len, &creds);
1589
1590 if (ret) {
1591 LOG_ERR("Loading WiFi credentials failed for SSID [%.*s], len: %d, err: %d",
1592 ssid_len, ssid, ssid_len, ret);
1593 return;
1594 }
1595
1596 add_network_from_credentials_struct_personal(&creds, (struct net_if *)cb_arg);
1597 }
1598
add_static_network_config(struct net_if * iface)1599 static int add_static_network_config(struct net_if *iface)
1600 {
1601 #if defined(CONFIG_WIFI_CREDENTIALS_STATIC)
1602
1603 struct wifi_credentials_personal creds = {
1604 .header = {
1605 .ssid_len = strlen(CONFIG_WIFI_CREDENTIALS_STATIC_SSID),
1606 },
1607 .password_len = strlen(CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD),
1608 };
1609
1610 int ret = wifi_credentials_get_by_ssid_personal_struct(
1611 CONFIG_WIFI_CREDENTIALS_STATIC_SSID, strlen(CONFIG_WIFI_CREDENTIALS_STATIC_SSID),
1612 &creds);
1613
1614 if (!ret) {
1615 LOG_WRN("Statically configured WiFi network was overridden by storage.");
1616 return 0;
1617 }
1618
1619 #if defined(CONFIG_WIFI_CREDENTIALS_STATIC_TYPE_OPEN)
1620 creds.header.type = WIFI_SECURITY_TYPE_NONE;
1621 #elif defined(CONFIG_WIFI_CREDENTIALS_STATIC_TYPE_PSK)
1622 creds.header.type = WIFI_SECURITY_TYPE_PSK;
1623 #elif defined(CONFIG_WIFI_CREDENTIALS_STATIC_TYPE_PSK_SHA256)
1624 creds.header.type = WIFI_SECURITY_TYPE_PSK_SHA256;
1625 #elif defined(CONFIG_WIFI_CREDENTIALS_STATIC_TYPE_SAE)
1626 creds.header.type = WIFI_SECURITY_TYPE_SAE;
1627 #elif defined(CONFIG_WIFI_CREDENTIALS_STATIC_TYPE_WPA_PSK)
1628 creds.header.type = WIFI_SECURITY_TYPE_WPA_PSK;
1629 #else
1630 #error "invalid CONFIG_WIFI_CREDENTIALS_STATIC_TYPE"
1631 #endif
1632
1633 memcpy(creds.header.ssid, CONFIG_WIFI_CREDENTIALS_STATIC_SSID,
1634 strlen(CONFIG_WIFI_CREDENTIALS_STATIC_SSID));
1635 memcpy(creds.password, CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD,
1636 strlen(CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD));
1637
1638 LOG_DBG("Adding statically configured WiFi network [%s] to internal list.",
1639 creds.header.ssid);
1640
1641 return add_network_from_credentials_struct_personal(&creds, iface);
1642 #else
1643 return 0;
1644 #endif /* defined(CONFIG_WIFI_CREDENTIALS_STATIC) */
1645 }
1646
connect_stored_command(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)1647 static int connect_stored_command(uint32_t mgmt_request, struct net_if *iface, void *data,
1648 size_t len)
1649 {
1650 int ret = 0;
1651
1652 ret = add_static_network_config(iface);
1653 if (ret) {
1654 return ret;
1655 }
1656
1657 wifi_credentials_for_each_ssid(add_stored_network, iface);
1658
1659 return ret;
1660 };
1661
1662 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CONNECT_STORED, connect_stored_command);
1663
1664 #endif /* CONFIG_WIFI_CREDENTIALS_CONNECT_STORED */
1665