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 * const 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 * const 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 * const 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 * const 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 * const 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 * const 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 * const 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 * const 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 * const 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 * const 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 * const 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 * const 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_PSK_SHA256) &&
278 ((params->psk_length < 8) || (params->psk_length > 64) ||
279 (params->psk_length == 0U) || !params->psk)) ||
280 ((params->security == WIFI_SECURITY_TYPE_SAE) &&
281 ((params->psk_length == 0U) || !params->psk) &&
282 ((params->sae_password_length == 0U) || !params->sae_password)) ||
283 ((params->channel != WIFI_CHANNEL_ANY) &&
284 (params->channel > WIFI_CHANNEL_MAX)) ||
285 !params->ssid) {
286 return -EINVAL;
287 }
288
289 return wifi_mgmt_api->connect(dev, params);
290 }
291
292 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CONNECT, wifi_connect);
293
scan_result_cb(struct net_if * iface,int status,struct wifi_scan_result * entry)294 static void scan_result_cb(struct net_if *iface, int status,
295 struct wifi_scan_result *entry)
296 {
297 if (!iface) {
298 return;
299 }
300
301 if (!entry) {
302 struct wifi_status scan_status = {
303 .status = status,
304 };
305
306 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_SCAN_DONE,
307 iface, &scan_status,
308 sizeof(struct wifi_status));
309 return;
310 }
311
312 #ifndef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY
313 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_SCAN_RESULT, iface,
314 entry, sizeof(struct wifi_scan_result));
315 #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY */
316 }
317
wifi_scan(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)318 static int wifi_scan(uint32_t mgmt_request, struct net_if *iface,
319 void *data, size_t len)
320 {
321 const struct device *dev = net_if_get_device(iface);
322 struct wifi_scan_params *params = data;
323 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
324
325 if (wifi_mgmt_api == NULL || wifi_mgmt_api->scan == NULL) {
326 return -ENOTSUP;
327 }
328
329 #ifdef CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN
330 struct wifi_scan_params default_params = {0};
331
332 if (params == NULL) {
333 params = &default_params;
334 }
335 params->scan_type = WIFI_SCAN_TYPE_PASSIVE;
336 #endif /* CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN */
337
338 return wifi_mgmt_api->scan(dev, params, scan_result_cb);
339 }
340
341 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_SCAN, wifi_scan);
342
wifi_disconnect(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)343 static int wifi_disconnect(uint32_t mgmt_request, struct net_if *iface,
344 void *data, size_t len)
345 {
346 const struct device *dev = net_if_get_device(iface);
347 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
348
349 if (wifi_mgmt_api == NULL || wifi_mgmt_api->disconnect == NULL) {
350 return -ENOTSUP;
351 }
352
353 return wifi_mgmt_api->disconnect(dev);
354 }
355
356 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_DISCONNECT, wifi_disconnect);
357
wifi_mgmt_raise_connect_result_event(struct net_if * iface,int status)358 void wifi_mgmt_raise_connect_result_event(struct net_if *iface, int status)
359 {
360 struct wifi_status cnx_status = {
361 .status = status,
362 };
363
364 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_CONNECT_RESULT,
365 iface, &cnx_status,
366 sizeof(struct wifi_status));
367 }
368
wifi_mgmt_raise_disconnect_result_event(struct net_if * iface,int status)369 void wifi_mgmt_raise_disconnect_result_event(struct net_if *iface, int status)
370 {
371 struct wifi_status cnx_status = {
372 .status = status,
373 };
374
375 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_DISCONNECT_RESULT,
376 iface, &cnx_status,
377 sizeof(struct wifi_status));
378 }
379
wifi_ap_enable(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)380 static int wifi_ap_enable(uint32_t mgmt_request, struct net_if *iface,
381 void *data, size_t len)
382 {
383 struct wifi_connect_req_params *params =
384 (struct wifi_connect_req_params *)data;
385 const struct device *dev = net_if_get_device(iface);
386 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
387
388 if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_enable == NULL) {
389 return -ENOTSUP;
390 }
391
392 return wifi_mgmt_api->ap_enable(dev, params);
393 }
394
395 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_ENABLE, wifi_ap_enable);
396
wifi_ap_disable(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)397 static int wifi_ap_disable(uint32_t mgmt_request, struct net_if *iface,
398 void *data, size_t len)
399 {
400 const struct device *dev = net_if_get_device(iface);
401 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
402
403 if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_enable == NULL) {
404 return -ENOTSUP;
405 }
406
407 return wifi_mgmt_api->ap_disable(dev);
408 }
409
410 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_DISABLE, wifi_ap_disable);
411
wifi_iface_status(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)412 static int wifi_iface_status(uint32_t mgmt_request, struct net_if *iface,
413 void *data, size_t len)
414 {
415 const struct device *dev = net_if_get_device(iface);
416 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
417 struct wifi_iface_status *status = data;
418
419 if (wifi_mgmt_api == NULL || wifi_mgmt_api->iface_status == NULL) {
420 return -ENOTSUP;
421 }
422
423 if (!data || len != sizeof(*status)) {
424 return -EINVAL;
425 }
426
427 return wifi_mgmt_api->iface_status(dev, status);
428 }
429 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_IFACE_STATUS, wifi_iface_status);
430
wifi_mgmt_raise_iface_status_event(struct net_if * iface,struct wifi_iface_status * iface_status)431 void wifi_mgmt_raise_iface_status_event(struct net_if *iface,
432 struct wifi_iface_status *iface_status)
433 {
434 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_IFACE_STATUS,
435 iface, iface_status,
436 sizeof(struct wifi_iface_status));
437 }
438
439 #ifdef CONFIG_NET_STATISTICS_WIFI
wifi_iface_stats(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)440 static int wifi_iface_stats(uint32_t mgmt_request, struct net_if *iface,
441 void *data, size_t len)
442 {
443 const struct device *dev = net_if_get_device(iface);
444 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
445 struct net_stats_wifi *stats = data;
446
447 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_stats == NULL) {
448 return -ENOTSUP;
449 }
450
451 if (!data || len != sizeof(*stats)) {
452 return -EINVAL;
453 }
454
455 return wifi_mgmt_api->get_stats(dev, stats);
456 }
457 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_STATS_GET_WIFI, wifi_iface_stats);
458 #endif /* CONFIG_NET_STATISTICS_WIFI */
459
wifi_set_power_save(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)460 static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface,
461 void *data, size_t len)
462 {
463 const struct device *dev = net_if_get_device(iface);
464 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
465 struct wifi_ps_params *ps_params = data;
466 struct wifi_iface_status info = { 0 };
467
468 if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_power_save == NULL) {
469 return -ENOTSUP;
470 }
471
472 switch (ps_params->type) {
473 case WIFI_PS_PARAM_LISTEN_INTERVAL:
474 case WIFI_PS_PARAM_MODE:
475 if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info,
476 sizeof(struct wifi_iface_status))) {
477 ps_params->fail_reason =
478 WIFI_PS_PARAM_FAIL_UNABLE_TO_GET_IFACE_STATUS;
479 return -EIO;
480 }
481
482 if (info.state == WIFI_STATE_COMPLETED) {
483 ps_params->fail_reason =
484 WIFI_PS_PARAM_FAIL_DEVICE_CONNECTED;
485 return -ENOTSUP;
486 }
487 break;
488 case WIFI_PS_PARAM_STATE:
489 case WIFI_PS_PARAM_WAKEUP_MODE:
490 case WIFI_PS_PARAM_TIMEOUT:
491 break;
492 default:
493 ps_params->fail_reason =
494 WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED;
495 return -ENOTSUP;
496 }
497
498 return wifi_mgmt_api->set_power_save(dev, ps_params);
499 }
500
501 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS, wifi_set_power_save);
502
wifi_get_power_save_config(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)503 static int wifi_get_power_save_config(uint32_t mgmt_request, struct net_if *iface,
504 void *data, size_t len)
505 {
506 const struct device *dev = net_if_get_device(iface);
507 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
508 struct wifi_ps_config *ps_config = data;
509
510 if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_power_save_config == NULL) {
511 return -ENOTSUP;
512 }
513
514 if (!data || len != sizeof(*ps_config)) {
515 return -EINVAL;
516 }
517
518 return wifi_mgmt_api->get_power_save_config(dev, ps_config);
519 }
520
521 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_CONFIG, wifi_get_power_save_config);
522
wifi_set_twt(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)523 static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface,
524 void *data, size_t len)
525 {
526 const struct device *dev = net_if_get_device(iface);
527 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
528 struct wifi_twt_params *twt_params = data;
529 struct wifi_iface_status info = { 0 };
530
531 if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_twt == NULL) {
532 twt_params->fail_reason =
533 WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED;
534 return -ENOTSUP;
535 }
536
537 if (twt_params->operation == WIFI_TWT_TEARDOWN) {
538 return wifi_mgmt_api->set_twt(dev, twt_params);
539 }
540
541 if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info,
542 sizeof(struct wifi_iface_status))) {
543 twt_params->fail_reason =
544 WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS;
545 goto fail;
546 }
547
548 if (info.state != WIFI_STATE_COMPLETED) {
549 twt_params->fail_reason =
550 WIFI_TWT_FAIL_DEVICE_NOT_CONNECTED;
551 goto fail;
552 }
553
554 #ifdef CONFIG_WIFI_MGMT_TWT_CHECK_IP
555 if ((!net_if_ipv4_get_global_addr(iface, NET_ADDR_PREFERRED)) &&
556 (!net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface))) {
557 twt_params->fail_reason =
558 WIFI_TWT_FAIL_IP_NOT_ASSIGNED;
559 goto fail;
560 }
561 #else
562 NET_WARN("Check for valid IP address been disabled. "
563 "Device might be unreachable or might not receive traffic.\n");
564 #endif /* CONFIG_WIFI_MGMT_TWT_CHECK_IP */
565
566 if (info.link_mode < WIFI_6) {
567 twt_params->fail_reason =
568 WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB;
569 goto fail;
570 }
571
572 if (!info.twt_capable) {
573 twt_params->fail_reason =
574 WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB;
575 goto fail;
576 }
577
578 return wifi_mgmt_api->set_twt(dev, twt_params);
579 fail:
580 return -ENOEXEC;
581
582 }
583
584 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_TWT, wifi_set_twt);
585
wifi_mgmt_raise_twt_event(struct net_if * iface,struct wifi_twt_params * twt_params)586 void wifi_mgmt_raise_twt_event(struct net_if *iface, struct wifi_twt_params *twt_params)
587 {
588 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_TWT,
589 iface, twt_params,
590 sizeof(struct wifi_twt_params));
591 }
592
wifi_reg_domain(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)593 static int wifi_reg_domain(uint32_t mgmt_request, struct net_if *iface,
594 void *data, size_t len)
595 {
596 const struct device *dev = net_if_get_device(iface);
597 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
598 struct wifi_reg_domain *reg_domain = data;
599
600 if (wifi_mgmt_api == NULL || wifi_mgmt_api->reg_domain == NULL) {
601 return -ENOTSUP;
602 }
603
604 if (!data || len != sizeof(*reg_domain)) {
605 return -EINVAL;
606 }
607
608 return wifi_mgmt_api->reg_domain(dev, reg_domain);
609 }
610
611 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_REG_DOMAIN, wifi_reg_domain);
612
wifi_mgmt_raise_twt_sleep_state(struct net_if * iface,int twt_sleep_state)613 void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface,
614 int twt_sleep_state)
615 {
616 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_TWT_SLEEP_STATE,
617 iface, &twt_sleep_state,
618 sizeof(twt_sleep_state));
619 }
620
wifi_mode(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)621 static int wifi_mode(uint32_t mgmt_request, struct net_if *iface,
622 void *data, size_t len)
623 {
624 const struct device *dev = net_if_get_device(iface);
625 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
626 struct wifi_mode_info *mode_info = data;
627
628 if (dev == NULL) {
629 return -ENODEV;
630 }
631
632 if (wifi_mgmt_api == NULL || wifi_mgmt_api->mode == NULL) {
633 return -ENOTSUP;
634 }
635
636 return wifi_mgmt_api->mode(dev, mode_info);
637 }
638
639 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_MODE, wifi_mode);
640
wifi_packet_filter(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)641 static int wifi_packet_filter(uint32_t mgmt_request, struct net_if *iface,
642 void *data, size_t len)
643 {
644 const struct device *dev = net_if_get_device(iface);
645 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
646 struct wifi_filter_info *filter_info = data;
647
648 if (dev == NULL) {
649 return -ENODEV;
650 }
651
652 if (wifi_mgmt_api == NULL || wifi_mgmt_api->filter == NULL) {
653 return -ENOTSUP;
654 }
655
656 return wifi_mgmt_api->filter(dev, filter_info);
657 }
658
659 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PACKET_FILTER, wifi_packet_filter);
660
wifi_channel(uint32_t mgmt_request,struct net_if * iface,void * data,size_t len)661 static int wifi_channel(uint32_t mgmt_request, struct net_if *iface,
662 void *data, size_t len)
663 {
664 const struct device *dev = net_if_get_device(iface);
665 const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
666 struct wifi_channel_info *channel_info = data;
667
668 if (dev == NULL) {
669 return -ENODEV;
670 }
671
672 if (wifi_mgmt_api == NULL || wifi_mgmt_api->channel == NULL) {
673 return -ENOTSUP;
674 }
675
676 return wifi_mgmt_api->channel(dev, channel_info);
677 }
678
679 NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL, wifi_channel);
680
681 #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)682 void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface,
683 struct wifi_raw_scan_result *raw_scan_result)
684 {
685 if (raw_scan_result->frame_length > CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH) {
686 LOG_INF("raw scan result frame length = %d too big,"
687 "saving upto max raw scan length = %d",
688 raw_scan_result->frame_length,
689 CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH);
690 }
691
692 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_RAW_SCAN_RESULT,
693 iface, raw_scan_result,
694 sizeof(*raw_scan_result));
695 }
696 #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */
697
wifi_mgmt_raise_disconnect_complete_event(struct net_if * iface,int status)698 void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface,
699 int status)
700 {
701 struct wifi_status cnx_status = {
702 .status = status,
703 };
704
705 net_mgmt_event_notify_with_info(NET_EVENT_WIFI_DISCONNECT_COMPLETE,
706 iface, &cnx_status,
707 sizeof(struct wifi_status));
708 }
709