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