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