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->security == WIFI_SECURITY_TYPE_WPA_AUTO_PERSONAL) &&
280 ((params->psk_length < 8) || (params->psk_length > 64) ||
281 (params->psk_length == 0U) || !params->psk)) ||
282 ((params->security == WIFI_SECURITY_TYPE_SAE) &&
283 ((params->psk_length == 0U) || !params->psk) &&
284 ((params->sae_password_length == 0U) || !params->sae_password)) ||
285 ((params->channel != WIFI_CHANNEL_ANY) &&
286 (params->channel > WIFI_CHANNEL_MAX)) ||
287 !params->ssid) {
288 return -EINVAL;
289 }
290
291 return wifi_mgmt_api->connect(dev, params);
292 }
293
294 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CONNECT, wifi_connect);
295
scan_result_cb(struct net_if * iface,int status,struct wifi_scan_result * entry)296 static void scan_result_cb(struct net_if *iface, int status,
297 struct wifi_scan_result *entry)
298 {
299 if (!iface) {
300 return;
301 }
302
303 if (!entry) {
304 struct wifi_status scan_status = {
305 .status = status,
306 };
307
308 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_SCAN_DONE,
309 iface, &scan_status,
310 sizeof(struct wifi_status));
311 return;
312 }
313
314 #ifndef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY
315 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_SCAN_RESULT, iface,
316 entry, sizeof(struct wifi_scan_result));
317 #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY */
318 }
319
wifi_scan(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)320 static int wifi_scan(uint32_t mgmt_request, struct net_if *iface,
321 void *data, size_t len)
322 {
323 const struct device *dev = net_if_get_device(iface);
324 struct wifi_scan_params *params = data;
325 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
326
327 if (wifi_mgmt_api == NULL || wifi_mgmt_api->scan == NULL) {
328 return -ENOTSUP;
329 }
330
331 #ifdef CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN
332 struct wifi_scan_params default_params = {0};
333
334 if (params == NULL) {
335 params = &default_params;
336 }
337 params->scan_type = WIFI_SCAN_TYPE_PASSIVE;
338 #endif /* CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN */
339
340 return wifi_mgmt_api->scan(dev, params, scan_result_cb);
341 }
342
343 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_SCAN, wifi_scan);
344
wifi_disconnect(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)345 static int wifi_disconnect(uint32_t mgmt_request, struct net_if *iface,
346 void *data, size_t len)
347 {
348 const struct device *dev = net_if_get_device(iface);
349 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
350
351 if (wifi_mgmt_api == NULL || wifi_mgmt_api->disconnect == NULL) {
352 return -ENOTSUP;
353 }
354
355 return wifi_mgmt_api->disconnect(dev);
356 }
357
358 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_DISCONNECT, wifi_disconnect);
359
wifi_mgmt_raise_connect_result_event(struct net_if * iface,int status)360 void wifi_mgmt_raise_connect_result_event(struct net_if *iface, int status)
361 {
362 struct wifi_status cnx_status = {
363 .status = status,
364 };
365
366 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_CONNECT_RESULT,
367 iface, &cnx_status,
368 sizeof(struct wifi_status));
369 }
370
wifi_mgmt_raise_disconnect_result_event(struct net_if * iface,int status)371 void wifi_mgmt_raise_disconnect_result_event(struct net_if *iface, int status)
372 {
373 struct wifi_status cnx_status = {
374 .status = status,
375 };
376
377 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_DISCONNECT_RESULT,
378 iface, &cnx_status,
379 sizeof(struct wifi_status));
380 }
381
wifi_ap_enable(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)382 static int wifi_ap_enable(uint32_t mgmt_request, struct net_if *iface,
383 void *data, size_t len)
384 {
385 struct wifi_connect_req_params *params =
386 (struct wifi_connect_req_params *)data;
387 const struct device *dev = net_if_get_device(iface);
388 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
389
390 if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_enable == NULL) {
391 return -ENOTSUP;
392 }
393
394 return wifi_mgmt_api->ap_enable(dev, params);
395 }
396
397 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_ENABLE, wifi_ap_enable);
398
wifi_ap_disable(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)399 static int wifi_ap_disable(uint32_t mgmt_request, struct net_if *iface,
400 void *data, size_t len)
401 {
402 const struct device *dev = net_if_get_device(iface);
403 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
404
405 if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_enable == NULL) {
406 return -ENOTSUP;
407 }
408
409 return wifi_mgmt_api->ap_disable(dev);
410 }
411
412 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_DISABLE, wifi_ap_disable);
413
wifi_ap_sta_disconnect(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)414 static int wifi_ap_sta_disconnect(uint32_t mgmt_request, struct net_if *iface,
415 void *data, size_t len)
416 {
417 const struct device *dev = net_if_get_device(iface);
418 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
419 uint8_t *mac = data;
420
421 if (dev == NULL) {
422 return -ENODEV;
423 }
424
425 if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_sta_disconnect == NULL) {
426 return -ENOTSUP;
427 }
428
429 if (!data || len != sizeof(uint8_t) * WIFI_MAC_ADDR_LEN) {
430 return -EINVAL;
431 }
432
433 return wifi_mgmt_api->ap_sta_disconnect(dev, mac);
434 }
435
436 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_STA_DISCONNECT, wifi_ap_sta_disconnect);
437
wifi_ap_config_params(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)438 static int wifi_ap_config_params(uint32_t mgmt_request, struct net_if *iface,
439 void *data, size_t len)
440 {
441 const struct device *dev = net_if_get_device(iface);
442 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
443 struct wifi_ap_config_params *params = data;
444
445 if (dev == NULL) {
446 return -ENODEV;
447 }
448
449 if (wifi_mgmt_api == NULL ||
450 wifi_mgmt_api->ap_config_params == NULL) {
451 return -ENOTSUP;
452 }
453
454 if (!data || len != sizeof(*params)) {
455 return -EINVAL;
456 }
457
458 if (params->type & WIFI_AP_CONFIG_PARAM_MAX_NUM_STA) {
459 if (params->max_num_sta > CONFIG_WIFI_MGMT_AP_MAX_NUM_STA) {
460 LOG_INF("Maximum number of stations(%d) "
461 "exceeded default configured value = %d.",
462 params->max_num_sta, CONFIG_WIFI_MGMT_AP_MAX_NUM_STA);
463 return -EINVAL;
464 }
465 }
466
467 return wifi_mgmt_api->ap_config_params(dev, params);
468 }
469
470 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_CONFIG_PARAM, wifi_ap_config_params);
471
wifi_iface_status(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)472 static int wifi_iface_status(uint32_t mgmt_request, struct net_if *iface,
473 void *data, size_t len)
474 {
475 const struct device *dev = net_if_get_device(iface);
476 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
477 struct wifi_iface_status *status = data;
478
479 if (wifi_mgmt_api == NULL || wifi_mgmt_api->iface_status == NULL) {
480 return -ENOTSUP;
481 }
482
483 if (!data || len != sizeof(*status)) {
484 return -EINVAL;
485 }
486
487 return wifi_mgmt_api->iface_status(dev, status);
488 }
489 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_IFACE_STATUS, wifi_iface_status);
490
wifi_mgmt_raise_iface_status_event(struct net_if * iface,struct wifi_iface_status * iface_status)491 void wifi_mgmt_raise_iface_status_event(struct net_if *iface,
492 struct wifi_iface_status *iface_status)
493 {
494 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_IFACE_STATUS,
495 iface, iface_status,
496 sizeof(struct wifi_iface_status));
497 }
498
499 #ifdef CONFIG_NET_STATISTICS_WIFI
wifi_iface_stats(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)500 static int wifi_iface_stats(uint32_t mgmt_request, struct net_if *iface,
501 void *data, size_t len)
502 {
503 const struct device *dev = net_if_get_device(iface);
504 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
505 struct net_stats_wifi *stats = data;
506
507 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_stats == NULL) {
508 return -ENOTSUP;
509 }
510
511 if (!data || len != sizeof(*stats)) {
512 return -EINVAL;
513 }
514
515 return wifi_mgmt_api->get_stats(dev, stats);
516 }
517 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_STATS_GET_WIFI, wifi_iface_stats);
518 #endif /* CONFIG_NET_STATISTICS_WIFI */
519
wifi_set_power_save(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)520 static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface,
521 void *data, size_t len)
522 {
523 const struct device *dev = net_if_get_device(iface);
524 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
525 struct wifi_ps_params *ps_params = data;
526 struct wifi_iface_status info = { 0 };
527
528 if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_power_save == NULL) {
529 return -ENOTSUP;
530 }
531
532 switch (ps_params->type) {
533 case WIFI_PS_PARAM_LISTEN_INTERVAL:
534 case WIFI_PS_PARAM_MODE:
535 if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info,
536 sizeof(struct wifi_iface_status))) {
537 ps_params->fail_reason =
538 WIFI_PS_PARAM_FAIL_UNABLE_TO_GET_IFACE_STATUS;
539 return -EIO;
540 }
541
542 if (info.state >= WIFI_STATE_ASSOCIATED) {
543 ps_params->fail_reason =
544 WIFI_PS_PARAM_FAIL_DEVICE_CONNECTED;
545 return -ENOTSUP;
546 }
547 break;
548 case WIFI_PS_PARAM_STATE:
549 case WIFI_PS_PARAM_WAKEUP_MODE:
550 case WIFI_PS_PARAM_TIMEOUT:
551 break;
552 default:
553 ps_params->fail_reason =
554 WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED;
555 return -ENOTSUP;
556 }
557
558 return wifi_mgmt_api->set_power_save(dev, ps_params);
559 }
560
561 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS, wifi_set_power_save);
562
wifi_get_power_save_config(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)563 static int wifi_get_power_save_config(uint32_t mgmt_request, struct net_if *iface,
564 void *data, size_t len)
565 {
566 const struct device *dev = net_if_get_device(iface);
567 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
568 struct wifi_ps_config *ps_config = data;
569
570 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_power_save_config == NULL) {
571 return -ENOTSUP;
572 }
573
574 if (!data || len != sizeof(*ps_config)) {
575 return -EINVAL;
576 }
577
578 return wifi_mgmt_api->get_power_save_config(dev, ps_config);
579 }
580
581 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_CONFIG, wifi_get_power_save_config);
582
wifi_set_twt(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)583 static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface,
584 void *data, size_t len)
585 {
586 const struct device *dev = net_if_get_device(iface);
587 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
588 struct wifi_twt_params *twt_params = data;
589 struct wifi_iface_status info = { 0 };
590
591 if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_twt == NULL) {
592 twt_params->fail_reason =
593 WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED;
594 return -ENOTSUP;
595 }
596
597 if (twt_params->operation == WIFI_TWT_TEARDOWN) {
598 return wifi_mgmt_api->set_twt(dev, twt_params);
599 }
600
601 if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info,
602 sizeof(struct wifi_iface_status))) {
603 twt_params->fail_reason =
604 WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS;
605 goto fail;
606 }
607
608 if (info.state != WIFI_STATE_COMPLETED) {
609 twt_params->fail_reason =
610 WIFI_TWT_FAIL_DEVICE_NOT_CONNECTED;
611 goto fail;
612 }
613
614 #ifdef CONFIG_WIFI_MGMT_TWT_CHECK_IP
615 if ((!net_if_ipv4_get_global_addr(iface, NET_ADDR_PREFERRED)) &&
616 (!net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface))) {
617 twt_params->fail_reason =
618 WIFI_TWT_FAIL_IP_NOT_ASSIGNED;
619 goto fail;
620 }
621 #else
622 NET_WARN("Check for valid IP address been disabled. "
623 "Device might be unreachable or might not receive traffic.\n");
624 #endif /* CONFIG_WIFI_MGMT_TWT_CHECK_IP */
625
626 if (info.link_mode < WIFI_6) {
627 twt_params->fail_reason =
628 WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB;
629 goto fail;
630 }
631
632 if (!info.twt_capable) {
633 twt_params->fail_reason =
634 WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB;
635 goto fail;
636 }
637
638 return wifi_mgmt_api->set_twt(dev, twt_params);
639 fail:
640 return -ENOEXEC;
641
642 }
643
644 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_TWT, wifi_set_twt);
645
wifi_mgmt_raise_twt_event(struct net_if * iface,struct wifi_twt_params * twt_params)646 void wifi_mgmt_raise_twt_event(struct net_if *iface, struct wifi_twt_params *twt_params)
647 {
648 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_TWT,
649 iface, twt_params,
650 sizeof(struct wifi_twt_params));
651 }
652
wifi_reg_domain(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)653 static int wifi_reg_domain(uint32_t mgmt_request, struct net_if *iface,
654 void *data, size_t len)
655 {
656 const struct device *dev = net_if_get_device(iface);
657 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
658 struct wifi_reg_domain *reg_domain = data;
659
660 if (wifi_mgmt_api == NULL || wifi_mgmt_api->reg_domain == NULL) {
661 return -ENOTSUP;
662 }
663
664 if (!data || len != sizeof(*reg_domain)) {
665 return -EINVAL;
666 }
667
668 return wifi_mgmt_api->reg_domain(dev, reg_domain);
669 }
670
671 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_REG_DOMAIN, wifi_reg_domain);
672
wifi_mgmt_raise_twt_sleep_state(struct net_if * iface,int twt_sleep_state)673 void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface,
674 int twt_sleep_state)
675 {
676 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_TWT_SLEEP_STATE,
677 iface, &twt_sleep_state,
678 sizeof(twt_sleep_state));
679 }
680
wifi_mode(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)681 static int wifi_mode(uint32_t mgmt_request, struct net_if *iface,
682 void *data, size_t len)
683 {
684 const struct device *dev = net_if_get_device(iface);
685 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
686 struct wifi_mode_info *mode_info = data;
687
688 if (dev == NULL) {
689 return -ENODEV;
690 }
691
692 if (wifi_mgmt_api == NULL || wifi_mgmt_api->mode == NULL) {
693 return -ENOTSUP;
694 }
695
696 return wifi_mgmt_api->mode(dev, mode_info);
697 }
698
699 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_MODE, wifi_mode);
700
wifi_packet_filter(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)701 static int wifi_packet_filter(uint32_t mgmt_request, struct net_if *iface,
702 void *data, size_t len)
703 {
704 const struct device *dev = net_if_get_device(iface);
705 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
706 struct wifi_filter_info *filter_info = data;
707
708 if (dev == NULL) {
709 return -ENODEV;
710 }
711
712 if (wifi_mgmt_api == NULL || wifi_mgmt_api->filter == NULL) {
713 return -ENOTSUP;
714 }
715
716 return wifi_mgmt_api->filter(dev, filter_info);
717 }
718
719 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PACKET_FILTER, wifi_packet_filter);
720
wifi_channel(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)721 static int wifi_channel(uint32_t mgmt_request, struct net_if *iface,
722 void *data, size_t len)
723 {
724 const struct device *dev = net_if_get_device(iface);
725 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
726 struct wifi_channel_info *channel_info = data;
727
728 if (dev == NULL) {
729 return -ENODEV;
730 }
731
732 if (wifi_mgmt_api == NULL || wifi_mgmt_api->channel == NULL) {
733 return -ENOTSUP;
734 }
735
736 return wifi_mgmt_api->channel(dev, channel_info);
737 }
738
739 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL, wifi_channel);
740
wifi_get_version(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)741 static int wifi_get_version(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 wifi_version *ver_params = data;
747
748 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_version == NULL) {
749 return -ENOTSUP;
750 }
751
752 return wifi_mgmt_api->get_version(dev, ver_params);
753 }
754
755 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_VERSION, wifi_get_version);
756
wifi_set_rts_threshold(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)757 static int wifi_set_rts_threshold(uint32_t mgmt_request, struct net_if *iface,
758 void *data, size_t len)
759 {
760 const struct device *dev = net_if_get_device(iface);
761 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
762 unsigned int *rts_threshold = data;
763
764 if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_rts_threshold == NULL) {
765 return -ENOTSUP;
766 }
767
768 if (!data || len != sizeof(*rts_threshold)) {
769 return -EINVAL;
770 }
771
772 return wifi_mgmt_api->set_rts_threshold(dev, *rts_threshold);
773 }
774
775 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_RTS_THRESHOLD, wifi_set_rts_threshold);
776
777 #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)778 void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface,
779 struct wifi_raw_scan_result *raw_scan_result)
780 {
781 if (raw_scan_result->frame_length > CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH) {
782 LOG_INF("raw scan result frame length = %d too big,"
783 "saving upto max raw scan length = %d",
784 raw_scan_result->frame_length,
785 CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH);
786 }
787
788 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_RAW_SCAN_RESULT,
789 iface, raw_scan_result,
790 sizeof(*raw_scan_result));
791 }
792 #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */
793
wifi_mgmt_raise_disconnect_complete_event(struct net_if * iface,int status)794 void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface,
795 int status)
796 {
797 struct wifi_status cnx_status = {
798 .status = status,
799 };
800
801 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_DISCONNECT_COMPLETE,
802 iface, &cnx_status,
803 sizeof(struct wifi_status));
804 }
805
wifi_mgmt_raise_ap_enable_result_event(struct net_if * iface,enum wifi_ap_status status)806 void wifi_mgmt_raise_ap_enable_result_event(struct net_if *iface,
807 enum wifi_ap_status status)
808 {
809 struct wifi_status cnx_status = {
810 .status = status,
811 };
812
813 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_ENABLE_RESULT,
814 iface, &cnx_status,
815 sizeof(enum wifi_ap_status));
816 }
817
wifi_mgmt_raise_ap_disable_result_event(struct net_if * iface,enum wifi_ap_status status)818 void wifi_mgmt_raise_ap_disable_result_event(struct net_if *iface,
819 enum wifi_ap_status status)
820 {
821 struct wifi_status cnx_status = {
822 .status = status,
823 };
824
825 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_DISABLE_RESULT,
826 iface, &cnx_status,
827 sizeof(enum wifi_ap_status));
828 }
829
wifi_mgmt_raise_ap_sta_connected_event(struct net_if * iface,struct wifi_ap_sta_info * sta_info)830 void wifi_mgmt_raise_ap_sta_connected_event(struct net_if *iface,
831 struct wifi_ap_sta_info *sta_info)
832 {
833 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_STA_CONNECTED,
834 iface, sta_info,
835 sizeof(struct wifi_ap_sta_info));
836 }
837
wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if * iface,struct wifi_ap_sta_info * sta_info)838 void wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if *iface,
839 struct wifi_ap_sta_info *sta_info)
840 {
841 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_AP_STA_DISCONNECTED,
842 iface, sta_info,
843 sizeof(struct wifi_ap_sta_info));
844 }
845