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