1 /*
2 * Copyright (c) 2016 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL);
9
10 #include <errno.h>
11 #include <string.h>
12
13 #include <zephyr/net/net_core.h>
14 #include <zephyr/net/net_if.h>
15 #include <zephyr/net/wifi_mgmt.h>
16 #ifdef CONFIG_WIFI_NM
17 #include <zephyr/net/wifi_nm.h>
18 #endif /* CONFIG_WIFI_NM */
19
wifi_security_txt(enum wifi_security_type security)20 const char *wifi_security_txt(enum wifi_security_type security)
21 {
22 switch (security) {
23 case WIFI_SECURITY_TYPE_NONE:
24 return "OPEN";
25 case WIFI_SECURITY_TYPE_WEP:
26 return "WEP";
27 case WIFI_SECURITY_TYPE_WPA_PSK:
28 return "WPA-PSK";
29 case WIFI_SECURITY_TYPE_PSK:
30 return "WPA2-PSK";
31 case WIFI_SECURITY_TYPE_PSK_SHA256:
32 return "WPA2-PSK-SHA256";
33 case WIFI_SECURITY_TYPE_SAE:
34 return "WPA3-SAE";
35 case WIFI_SECURITY_TYPE_WAPI:
36 return "WAPI";
37 case WIFI_SECURITY_TYPE_EAP:
38 return "EAP";
39 case WIFI_SECURITY_TYPE_UNKNOWN:
40 default:
41 return "UNKNOWN";
42 }
43 }
44
wifi_mfp_txt(enum wifi_mfp_options mfp)45 const char *wifi_mfp_txt(enum wifi_mfp_options mfp)
46 {
47 switch (mfp) {
48 case WIFI_MFP_DISABLE:
49 return "Disable";
50 case WIFI_MFP_OPTIONAL:
51 return "Optional";
52 case WIFI_MFP_REQUIRED:
53 return "Required";
54 case WIFI_MFP_UNKNOWN:
55 default:
56 return "UNKNOWN";
57 }
58 }
59
wifi_band_txt(enum wifi_frequency_bands band)60 const char *wifi_band_txt(enum wifi_frequency_bands band)
61 {
62 switch (band) {
63 case WIFI_FREQ_BAND_2_4_GHZ:
64 return "2.4GHz";
65 case WIFI_FREQ_BAND_5_GHZ:
66 return "5GHz";
67 case WIFI_FREQ_BAND_6_GHZ:
68 return "6GHz";
69 case WIFI_FREQ_BAND_UNKNOWN:
70 default:
71 return "UNKNOWN";
72 }
73 }
74
wifi_state_txt(enum wifi_iface_state state)75 const char *wifi_state_txt(enum wifi_iface_state state)
76 {
77 switch (state) {
78 case WIFI_STATE_DISCONNECTED:
79 return "DISCONNECTED";
80 case WIFI_STATE_INACTIVE:
81 return "INACTIVE";
82 case WIFI_STATE_INTERFACE_DISABLED:
83 return "INTERFACE_DISABLED";
84 case WIFI_STATE_SCANNING:
85 return "SCANNING";
86 case WIFI_STATE_AUTHENTICATING:
87 return "AUTHENTICATING";
88 case WIFI_STATE_ASSOCIATING:
89 return "ASSOCIATING";
90 case WIFI_STATE_ASSOCIATED:
91 return "ASSOCIATED";
92 case WIFI_STATE_4WAY_HANDSHAKE:
93 return "4WAY_HANDSHAKE";
94 case WIFI_STATE_GROUP_HANDSHAKE:
95 return "GROUP_HANDSHAKE";
96 case WIFI_STATE_COMPLETED:
97 return "COMPLETED";
98 case WIFI_STATE_UNKNOWN:
99 default:
100 return "UNKNOWN";
101 }
102 }
103
wifi_mode_txt(enum wifi_iface_mode mode)104 const char *wifi_mode_txt(enum wifi_iface_mode mode)
105 {
106 switch (mode) {
107 case WIFI_MODE_INFRA:
108 return "STATION";
109 case WIFI_MODE_IBSS:
110 return "ADHOC";
111 case WIFI_MODE_AP:
112 return "ACCESS POINT";
113 case WIFI_MODE_P2P_GO:
114 return "P2P GROUP OWNER";
115 case WIFI_MODE_P2P_GROUP_FORMATION:
116 return "P2P GROUP FORMATION";
117 case WIFI_MODE_MESH:
118 return "MESH";
119 case WIFI_MODE_UNKNOWN:
120 default:
121 return "UNKNOWN";
122 }
123 }
124
wifi_link_mode_txt(enum wifi_link_mode link_mode)125 const char *wifi_link_mode_txt(enum wifi_link_mode link_mode)
126 {
127 switch (link_mode) {
128 case WIFI_0:
129 return "WIFI 0 (802.11)";
130 case WIFI_1:
131 return "WIFI 1 (802.11b)";
132 case WIFI_2:
133 return "WIFI 2 (802.11a)";
134 case WIFI_3:
135 return "WIFI 3 (802.11g)";
136 case WIFI_4:
137 return "WIFI 4 (802.11n/HT)";
138 case WIFI_5:
139 return "WIFI 5 (802.11ac/VHT)";
140 case WIFI_6:
141 return "WIFI 6 (802.11ax/HE)";
142 case WIFI_6E:
143 return "WIFI 6E (802.11ax 6GHz/HE)";
144 case WIFI_7:
145 return "WIFI 7 (802.11be/EHT)";
146 case WIFI_LINK_MODE_UNKNOWN:
147 default:
148 return "UNKNOWN";
149 }
150 }
151
wifi_ps_txt(enum wifi_ps ps_name)152 const char *wifi_ps_txt(enum wifi_ps ps_name)
153 {
154 switch (ps_name) {
155 case WIFI_PS_DISABLED:
156 return "Power save disabled";
157 case WIFI_PS_ENABLED:
158 return "Power save enabled";
159 default:
160 return "UNKNOWN";
161 }
162 }
163
wifi_ps_mode_txt(enum wifi_ps_mode ps_mode)164 const char *wifi_ps_mode_txt(enum wifi_ps_mode ps_mode)
165 {
166 switch (ps_mode) {
167 case WIFI_PS_MODE_LEGACY:
168 return "Legacy power save";
169 case WIFI_PS_MODE_WMM:
170 return "WMM power save";
171 default:
172 return "UNKNOWN";
173 }
174 }
175
wifi_twt_operation_txt(enum wifi_twt_operation twt_operation)176 const char *wifi_twt_operation_txt(enum wifi_twt_operation twt_operation)
177 {
178 switch (twt_operation) {
179 case WIFI_TWT_SETUP:
180 return "TWT setup";
181 case WIFI_TWT_TEARDOWN:
182 return "TWT teardown";
183 default:
184 return "UNKNOWN";
185 }
186 }
187
wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation)188 const char *wifi_twt_negotiation_type_txt(enum wifi_twt_negotiation_type twt_negotiation)
189 {
190 switch (twt_negotiation) {
191 case WIFI_TWT_INDIVIDUAL:
192 return "TWT individual negotiation";
193 case WIFI_TWT_BROADCAST:
194 return "TWT broadcast negotiation";
195 case WIFI_TWT_WAKE_TBTT:
196 return "TWT wake TBTT negotiation";
197 default:
198 return "UNKNOWN";
199 }
200 }
201
wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup)202 const char *wifi_twt_setup_cmd_txt(enum wifi_twt_setup_cmd twt_setup)
203 {
204 switch (twt_setup) {
205 case WIFI_TWT_SETUP_CMD_REQUEST:
206 return "TWT request";
207 case WIFI_TWT_SETUP_CMD_SUGGEST:
208 return "TWT suggest";
209 case WIFI_TWT_SETUP_CMD_DEMAND:
210 return "TWT demand";
211 case WIFI_TWT_SETUP_CMD_GROUPING:
212 return "TWT grouping";
213 case WIFI_TWT_SETUP_CMD_ACCEPT:
214 return "TWT accept";
215 case WIFI_TWT_SETUP_CMD_ALTERNATE:
216 return "TWT alternate";
217 case WIFI_TWT_SETUP_CMD_DICTATE:
218 return "TWT dictate";
219 case WIFI_TWT_SETUP_CMD_REJECT:
220 return "TWT reject";
221 default:
222 return "UNKNOWN";
223 }
224 }
225
wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode)226 const char *wifi_ps_wakeup_mode_txt(enum wifi_ps_wakeup_mode ps_wakeup_mode)
227 {
228 switch (ps_wakeup_mode) {
229 case WIFI_PS_WAKEUP_MODE_DTIM:
230 return "PS wakeup mode DTIM";
231 case WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL:
232 return "PS wakeup mode listen interval";
233 default:
234 return "UNKNOWN";
235 }
236 }
237
get_wifi_api(struct net_if * iface)238 static const struct wifi_mgmt_ops *const get_wifi_api(struct net_if *iface)
239 {
240 const struct device *dev = net_if_get_device(iface);
241 struct net_wifi_mgmt_offload *off_api =
242 (struct net_wifi_mgmt_offload *) dev->api;
243 #ifdef CONFIG_WIFI_NM
244 struct wifi_nm_instance *nm = wifi_nm_get_instance_iface(iface);
245
246 if (nm) {
247 return nm->ops;
248 }
249 #endif /* CONFIG_WIFI_NM */
250 return off_api ? off_api->wifi_mgmt_api : NULL;
251 }
252
wifi_connect(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)253 static int wifi_connect(uint32_t mgmt_request, struct net_if *iface,
254 void *data, size_t len)
255 {
256 struct wifi_connect_req_params *params =
257 (struct wifi_connect_req_params *)data;
258 const struct device *dev = net_if_get_device(iface);
259
260 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
261
262 if (wifi_mgmt_api == NULL || wifi_mgmt_api->connect == NULL) {
263 return -ENOTSUP;
264 }
265
266 LOG_HEXDUMP_DBG(params->ssid, params->ssid_length, "ssid");
267 LOG_HEXDUMP_DBG(params->psk, params->psk_length, "psk");
268 if (params->sae_password) {
269 LOG_HEXDUMP_DBG(params->sae_password, params->sae_password_length, "sae");
270 }
271 NET_DBG("ch %u sec %u", params->channel, params->security);
272
273 if ((params->security > WIFI_SECURITY_TYPE_MAX) ||
274 (params->ssid_length > WIFI_SSID_MAX_LEN) ||
275 (params->ssid_length == 0U) ||
276 ((params->security == WIFI_SECURITY_TYPE_PSK ||
277 params->security == WIFI_SECURITY_TYPE_WPA_PSK ||
278 params->security == WIFI_SECURITY_TYPE_PSK_SHA256) &&
279 ((params->psk_length < 8) || (params->psk_length > 64) ||
280 (params->psk_length == 0U) || !params->psk)) ||
281 ((params->security == WIFI_SECURITY_TYPE_SAE) &&
282 ((params->psk_length == 0U) || !params->psk) &&
283 ((params->sae_password_length == 0U) || !params->sae_password)) ||
284 ((params->channel != WIFI_CHANNEL_ANY) &&
285 (params->channel > WIFI_CHANNEL_MAX)) ||
286 !params->ssid) {
287 return -EINVAL;
288 }
289
290 return wifi_mgmt_api->connect(dev, params);
291 }
292
293 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CONNECT, wifi_connect);
294
scan_result_cb(struct net_if * iface,int status,struct wifi_scan_result * entry)295 static void scan_result_cb(struct net_if *iface, int status,
296 struct wifi_scan_result *entry)
297 {
298 if (!iface) {
299 return;
300 }
301
302 if (!entry) {
303 struct wifi_status scan_status = {
304 .status = status,
305 };
306
307 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_SCAN_DONE,
308 iface, &scan_status,
309 sizeof(struct wifi_status));
310 return;
311 }
312
313 #ifndef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY
314 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_SCAN_RESULT, iface,
315 entry, sizeof(struct wifi_scan_result));
316 #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY */
317 }
318
wifi_scan(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)319 static int wifi_scan(uint32_t mgmt_request, struct net_if *iface,
320 void *data, size_t len)
321 {
322 const struct device *dev = net_if_get_device(iface);
323 struct wifi_scan_params *params = data;
324 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
325
326 if (wifi_mgmt_api == NULL || wifi_mgmt_api->scan == NULL) {
327 return -ENOTSUP;
328 }
329
330 #ifdef CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN
331 struct wifi_scan_params default_params = {0};
332
333 if (params == NULL) {
334 params = &default_params;
335 }
336 params->scan_type = WIFI_SCAN_TYPE_PASSIVE;
337 #endif /* CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN */
338
339 return wifi_mgmt_api->scan(dev, params, scan_result_cb);
340 }
341
342 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_SCAN, wifi_scan);
343
wifi_disconnect(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)344 static int wifi_disconnect(uint32_t mgmt_request, struct net_if *iface,
345 void *data, size_t len)
346 {
347 const struct device *dev = net_if_get_device(iface);
348 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
349
350 if (wifi_mgmt_api == NULL || wifi_mgmt_api->disconnect == NULL) {
351 return -ENOTSUP;
352 }
353
354 return wifi_mgmt_api->disconnect(dev);
355 }
356
357 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_DISCONNECT, wifi_disconnect);
358
wifi_mgmt_raise_connect_result_event(struct net_if * iface,int status)359 void wifi_mgmt_raise_connect_result_event(struct net_if *iface, int status)
360 {
361 struct wifi_status cnx_status = {
362 .status = status,
363 };
364
365 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_CONNECT_RESULT,
366 iface, &cnx_status,
367 sizeof(struct wifi_status));
368 }
369
wifi_mgmt_raise_disconnect_result_event(struct net_if * iface,int status)370 void wifi_mgmt_raise_disconnect_result_event(struct net_if *iface, int status)
371 {
372 struct wifi_status cnx_status = {
373 .status = status,
374 };
375
376 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_DISCONNECT_RESULT,
377 iface, &cnx_status,
378 sizeof(struct wifi_status));
379 }
380
wifi_ap_enable(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)381 static int wifi_ap_enable(uint32_t mgmt_request, struct net_if *iface,
382 void *data, size_t len)
383 {
384 struct wifi_connect_req_params *params =
385 (struct wifi_connect_req_params *)data;
386 const struct device *dev = net_if_get_device(iface);
387 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
388
389 if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_enable == NULL) {
390 return -ENOTSUP;
391 }
392
393 return wifi_mgmt_api->ap_enable(dev, params);
394 }
395
396 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_ENABLE, wifi_ap_enable);
397
wifi_ap_disable(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)398 static int wifi_ap_disable(uint32_t mgmt_request, struct net_if *iface,
399 void *data, size_t len)
400 {
401 const struct device *dev = net_if_get_device(iface);
402 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
403
404 if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_enable == NULL) {
405 return -ENOTSUP;
406 }
407
408 return wifi_mgmt_api->ap_disable(dev);
409 }
410
411 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_DISABLE, wifi_ap_disable);
412
wifi_ap_sta_disconnect(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)413 static int wifi_ap_sta_disconnect(uint32_t mgmt_request, struct net_if *iface,
414 void *data, size_t len)
415 {
416 const struct device *dev = net_if_get_device(iface);
417 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
418 uint8_t *mac = data;
419
420 if (dev == NULL) {
421 return -ENODEV;
422 }
423
424 if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_sta_disconnect == NULL) {
425 return -ENOTSUP;
426 }
427
428 if (!data || len != sizeof(uint8_t) * WIFI_MAC_ADDR_LEN) {
429 return -EINVAL;
430 }
431
432 return wifi_mgmt_api->ap_sta_disconnect(dev, mac);
433 }
434
435 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_STA_DISCONNECT, wifi_ap_sta_disconnect);
436
wifi_iface_status(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)437 static int wifi_iface_status(uint32_t mgmt_request, struct net_if *iface,
438 void *data, size_t len)
439 {
440 const struct device *dev = net_if_get_device(iface);
441 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
442 struct wifi_iface_status *status = data;
443
444 if (wifi_mgmt_api == NULL || wifi_mgmt_api->iface_status == NULL) {
445 return -ENOTSUP;
446 }
447
448 if (!data || len != sizeof(*status)) {
449 return -EINVAL;
450 }
451
452 return wifi_mgmt_api->iface_status(dev, status);
453 }
454 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_IFACE_STATUS, wifi_iface_status);
455
wifi_mgmt_raise_iface_status_event(struct net_if * iface,struct wifi_iface_status * iface_status)456 void wifi_mgmt_raise_iface_status_event(struct net_if *iface,
457 struct wifi_iface_status *iface_status)
458 {
459 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_IFACE_STATUS,
460 iface, iface_status,
461 sizeof(struct wifi_iface_status));
462 }
463
464 #ifdef CONFIG_NET_STATISTICS_WIFI
wifi_iface_stats(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)465 static int wifi_iface_stats(uint32_t mgmt_request, struct net_if *iface,
466 void *data, size_t len)
467 {
468 const struct device *dev = net_if_get_device(iface);
469 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
470 struct net_stats_wifi *stats = data;
471
472 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_stats == NULL) {
473 return -ENOTSUP;
474 }
475
476 if (!data || len != sizeof(*stats)) {
477 return -EINVAL;
478 }
479
480 return wifi_mgmt_api->get_stats(dev, stats);
481 }
482 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_STATS_GET_WIFI, wifi_iface_stats);
483 #endif /* CONFIG_NET_STATISTICS_WIFI */
484
wifi_set_power_save(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)485 static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface,
486 void *data, size_t len)
487 {
488 const struct device *dev = net_if_get_device(iface);
489 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
490 struct wifi_ps_params *ps_params = data;
491 struct wifi_iface_status info = { 0 };
492
493 if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_power_save == NULL) {
494 return -ENOTSUP;
495 }
496
497 switch (ps_params->type) {
498 case WIFI_PS_PARAM_LISTEN_INTERVAL:
499 case WIFI_PS_PARAM_MODE:
500 if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info,
501 sizeof(struct wifi_iface_status))) {
502 ps_params->fail_reason =
503 WIFI_PS_PARAM_FAIL_UNABLE_TO_GET_IFACE_STATUS;
504 return -EIO;
505 }
506
507 if (info.state == WIFI_STATE_COMPLETED) {
508 ps_params->fail_reason =
509 WIFI_PS_PARAM_FAIL_DEVICE_CONNECTED;
510 return -ENOTSUP;
511 }
512 break;
513 case WIFI_PS_PARAM_STATE:
514 case WIFI_PS_PARAM_WAKEUP_MODE:
515 case WIFI_PS_PARAM_TIMEOUT:
516 break;
517 default:
518 ps_params->fail_reason =
519 WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED;
520 return -ENOTSUP;
521 }
522
523 return wifi_mgmt_api->set_power_save(dev, ps_params);
524 }
525
526 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS, wifi_set_power_save);
527
wifi_get_power_save_config(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)528 static int wifi_get_power_save_config(uint32_t mgmt_request, struct net_if *iface,
529 void *data, size_t len)
530 {
531 const struct device *dev = net_if_get_device(iface);
532 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
533 struct wifi_ps_config *ps_config = data;
534
535 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_power_save_config == NULL) {
536 return -ENOTSUP;
537 }
538
539 if (!data || len != sizeof(*ps_config)) {
540 return -EINVAL;
541 }
542
543 return wifi_mgmt_api->get_power_save_config(dev, ps_config);
544 }
545
546 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_CONFIG, wifi_get_power_save_config);
547
wifi_set_twt(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)548 static int wifi_set_twt(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_twt_params *twt_params = data;
554 struct wifi_iface_status info = { 0 };
555
556 if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_twt == NULL) {
557 twt_params->fail_reason =
558 WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED;
559 return -ENOTSUP;
560 }
561
562 if (twt_params->operation == WIFI_TWT_TEARDOWN) {
563 return wifi_mgmt_api->set_twt(dev, twt_params);
564 }
565
566 if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info,
567 sizeof(struct wifi_iface_status))) {
568 twt_params->fail_reason =
569 WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS;
570 goto fail;
571 }
572
573 if (info.state != WIFI_STATE_COMPLETED) {
574 twt_params->fail_reason =
575 WIFI_TWT_FAIL_DEVICE_NOT_CONNECTED;
576 goto fail;
577 }
578
579 #ifdef CONFIG_WIFI_MGMT_TWT_CHECK_IP
580 if ((!net_if_ipv4_get_global_addr(iface, NET_ADDR_PREFERRED)) &&
581 (!net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface))) {
582 twt_params->fail_reason =
583 WIFI_TWT_FAIL_IP_NOT_ASSIGNED;
584 goto fail;
585 }
586 #else
587 NET_WARN("Check for valid IP address been disabled. "
588 "Device might be unreachable or might not receive traffic.\n");
589 #endif /* CONFIG_WIFI_MGMT_TWT_CHECK_IP */
590
591 if (info.link_mode < WIFI_6) {
592 twt_params->fail_reason =
593 WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB;
594 goto fail;
595 }
596
597 if (!info.twt_capable) {
598 twt_params->fail_reason =
599 WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB;
600 goto fail;
601 }
602
603 return wifi_mgmt_api->set_twt(dev, twt_params);
604 fail:
605 return -ENOEXEC;
606
607 }
608
609 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_TWT, wifi_set_twt);
610
wifi_mgmt_raise_twt_event(struct net_if * iface,struct wifi_twt_params * twt_params)611 void wifi_mgmt_raise_twt_event(struct net_if *iface, struct wifi_twt_params *twt_params)
612 {
613 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_TWT,
614 iface, twt_params,
615 sizeof(struct wifi_twt_params));
616 }
617
wifi_reg_domain(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)618 static int wifi_reg_domain(uint32_t mgmt_request, struct net_if *iface,
619 void *data, size_t len)
620 {
621 const struct device *dev = net_if_get_device(iface);
622 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
623 struct wifi_reg_domain *reg_domain = data;
624
625 if (wifi_mgmt_api == NULL || wifi_mgmt_api->reg_domain == NULL) {
626 return -ENOTSUP;
627 }
628
629 if (!data || len != sizeof(*reg_domain)) {
630 return -EINVAL;
631 }
632
633 return wifi_mgmt_api->reg_domain(dev, reg_domain);
634 }
635
636 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_REG_DOMAIN, wifi_reg_domain);
637
wifi_mgmt_raise_twt_sleep_state(struct net_if * iface,int twt_sleep_state)638 void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface,
639 int twt_sleep_state)
640 {
641 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_TWT_SLEEP_STATE,
642 iface, &twt_sleep_state,
643 sizeof(twt_sleep_state));
644 }
645
wifi_mode(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)646 static int wifi_mode(uint32_t mgmt_request, struct net_if *iface,
647 void *data, size_t len)
648 {
649 const struct device *dev = net_if_get_device(iface);
650 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
651 struct wifi_mode_info *mode_info = data;
652
653 if (dev == NULL) {
654 return -ENODEV;
655 }
656
657 if (wifi_mgmt_api == NULL || wifi_mgmt_api->mode == NULL) {
658 return -ENOTSUP;
659 }
660
661 return wifi_mgmt_api->mode(dev, mode_info);
662 }
663
664 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_MODE, wifi_mode);
665
wifi_packet_filter(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)666 static int wifi_packet_filter(uint32_t mgmt_request, struct net_if *iface,
667 void *data, size_t len)
668 {
669 const struct device *dev = net_if_get_device(iface);
670 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
671 struct wifi_filter_info *filter_info = data;
672
673 if (dev == NULL) {
674 return -ENODEV;
675 }
676
677 if (wifi_mgmt_api == NULL || wifi_mgmt_api->filter == NULL) {
678 return -ENOTSUP;
679 }
680
681 return wifi_mgmt_api->filter(dev, filter_info);
682 }
683
684 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PACKET_FILTER, wifi_packet_filter);
685
wifi_channel(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)686 static int wifi_channel(uint32_t mgmt_request, struct net_if *iface,
687 void *data, size_t len)
688 {
689 const struct device *dev = net_if_get_device(iface);
690 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
691 struct wifi_channel_info *channel_info = data;
692
693 if (dev == NULL) {
694 return -ENODEV;
695 }
696
697 if (wifi_mgmt_api == NULL || wifi_mgmt_api->channel == NULL) {
698 return -ENOTSUP;
699 }
700
701 return wifi_mgmt_api->channel(dev, channel_info);
702 }
703
704 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL, wifi_channel);
705
wifi_get_version(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)706 static int wifi_get_version(uint32_t mgmt_request, struct net_if *iface,
707 void *data, size_t len)
708 {
709 const struct device *dev = net_if_get_device(iface);
710 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
711 struct wifi_version *ver_params = data;
712
713 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_version == NULL) {
714 return -ENOTSUP;
715 }
716
717 return wifi_mgmt_api->get_version(dev, ver_params);
718 }
719
720 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_VERSION, wifi_get_version);
721
722 #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)723 void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface,
724 struct wifi_raw_scan_result *raw_scan_result)
725 {
726 if (raw_scan_result->frame_length > CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH) {
727 LOG_INF("raw scan result frame length = %d too big,"
728 "saving upto max raw scan length = %d",
729 raw_scan_result->frame_length,
730 CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH);
731 }
732
733 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_RAW_SCAN_RESULT,
734 iface, raw_scan_result,
735 sizeof(*raw_scan_result));
736 }
737 #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */
738
wifi_mgmt_raise_disconnect_complete_event(struct net_if * iface,int status)739 void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface,
740 int status)
741 {
742 struct wifi_status cnx_status = {
743 .status = status,
744 };
745
746 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_DISCONNECT_COMPLETE,
747 iface, &cnx_status,
748 sizeof(struct wifi_status));
749 }
750
wifi_mgmt_raise_ap_enable_result_event(struct net_if * iface,enum wifi_ap_status status)751 void wifi_mgmt_raise_ap_enable_result_event(struct net_if *iface,
752 enum wifi_ap_status status)
753 {
754 struct wifi_status cnx_status = {
755 .status = status,
756 };
757
758 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_ENABLE_RESULT,
759 iface, &cnx_status,
760 sizeof(enum wifi_ap_status));
761 }
762
wifi_mgmt_raise_ap_disable_result_event(struct net_if * iface,enum wifi_ap_status status)763 void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface,
764 enum wifi_ap_status status)
765 {
766 struct wifi_status cnx_status = {
767 .status = status,
768 };
769
770 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_DISABLE_RESULT,
771 iface, &cnx_status,
772 sizeof(enum wifi_ap_status));
773 }
774
wifi_mgmt_raise_ap_sta_connected_event(struct net_if * iface,struct wifi_ap_sta_info * sta_info)775 void wifi_mgmt_raise_ap_sta_connected_event(struct net_if *iface,
776 struct wifi_ap_sta_info *sta_info)
777 {
778 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_STA_CONNECTED,
779 iface, sta_info,
780 sizeof(struct wifi_ap_sta_info));
781 }
782
wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if * iface,struct wifi_ap_sta_info * sta_info)783 void wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if *iface,
784 struct wifi_ap_sta_info *sta_info)
785 {
786 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_STA_DISCONNECTED,
787 iface, sta_info,
788 sizeof(struct wifi_ap_sta_info));
789 }
790