1 /*
2  * Copyright (c) 2020 Espressif Systems (Shanghai) Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT espressif_esp32_wifi
8 
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(esp32_wifi, CONFIG_WIFI_LOG_LEVEL);
11 
12 #include <zephyr/net/ethernet.h>
13 #include <zephyr/net/net_pkt.h>
14 #include <zephyr/net/net_if.h>
15 #include <zephyr/net/wifi_mgmt.h>
16 #include <zephyr/net/conn_mgr/connectivity_wifi_mgmt.h>
17 #include <zephyr/device.h>
18 #include <soc.h>
19 #include "esp_private/wifi.h"
20 #include "esp_event.h"
21 #include "esp_timer.h"
22 #include "esp_system.h"
23 #include "esp_wpa.h"
24 #include <esp_mac.h>
25 #include "wifi/wifi_event.h"
26 
27 #define DHCPV4_MASK (NET_EVENT_IPV4_DHCP_BOUND | NET_EVENT_IPV4_DHCP_STOP)
28 
29 /* use global iface pointer to support any ethernet driver */
30 /* necessary for wifi callback functions */
31 static struct net_if *esp32_wifi_iface;
32 static struct esp32_wifi_runtime esp32_data;
33 
34 enum esp32_state_flag {
35 	ESP32_STA_STOPPED,
36 	ESP32_STA_STARTED,
37 	ESP32_STA_CONNECTING,
38 	ESP32_STA_CONNECTED,
39 	ESP32_AP_CONNECTED,
40 	ESP32_AP_DISCONNECTED,
41 	ESP32_AP_STOPPED,
42 };
43 
44 struct esp32_wifi_status {
45 	char ssid[WIFI_SSID_MAX_LEN + 1];
46 	char pass[WIFI_PSK_MAX_LEN + 1];
47 	wifi_auth_mode_t security;
48 	bool connected;
49 	uint8_t channel;
50 	int rssi;
51 };
52 
53 struct esp32_wifi_runtime {
54 	uint8_t mac_addr[6];
55 	uint8_t frame_buf[NET_ETH_MAX_FRAME_SIZE];
56 #if defined(CONFIG_NET_STATISTICS_WIFI)
57 	struct net_stats_wifi stats;
58 #endif
59 	struct esp32_wifi_status status;
60 	scan_result_cb_t scan_cb;
61 	uint8_t state;
62 	uint8_t ap_connection_cnt;
63 };
64 
65 static struct net_mgmt_event_callback esp32_dhcp_cb;
66 
wifi_event_handler(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)67 static void wifi_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
68 			       struct net_if *iface)
69 {
70 	const struct wifi_status *status = (const struct wifi_status *)cb->info;
71 
72 	switch (mgmt_event) {
73 	case NET_EVENT_IPV4_DHCP_BOUND:
74 		wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, 0);
75 		break;
76 	default:
77 		break;
78 	}
79 }
80 
esp32_wifi_send(const struct device * dev,struct net_pkt * pkt)81 static int esp32_wifi_send(const struct device *dev, struct net_pkt *pkt)
82 {
83 	struct esp32_wifi_runtime *data = dev->data;
84 	const int pkt_len = net_pkt_get_len(pkt);
85 	esp_interface_t ifx =
86 		esp32_data.state == ESP32_AP_CONNECTED ? ESP_IF_WIFI_AP : ESP_IF_WIFI_STA;
87 
88 	/* Read the packet payload */
89 	if (net_pkt_read(pkt, data->frame_buf, pkt_len) < 0) {
90 		goto out;
91 	}
92 
93 	/* Enqueue packet for transmission */
94 	if (esp_wifi_internal_tx(ifx, (void *)data->frame_buf, pkt_len) != ESP_OK) {
95 		goto out;
96 	}
97 
98 #if defined(CONFIG_NET_STATISTICS_WIFI)
99 	data->stats.bytes.sent += pkt_len;
100 	data->stats.pkts.tx++;
101 #endif
102 
103 	LOG_DBG("pkt sent %p len %d", pkt, pkt_len);
104 	return 0;
105 
106 out:
107 
108 	LOG_ERR("Failed to send packet");
109 #if defined(CONFIG_NET_STATISTICS_WIFI)
110 	data->stats.errors.tx++;
111 #endif
112 	return -EIO;
113 }
114 
eth_esp32_rx(void * buffer,uint16_t len,void * eb)115 static esp_err_t eth_esp32_rx(void *buffer, uint16_t len, void *eb)
116 {
117 	struct net_pkt *pkt;
118 
119 	if (esp32_wifi_iface == NULL) {
120 		esp_wifi_internal_free_rx_buffer(eb);
121 		LOG_ERR("network interface unavailable");
122 		return -EIO;
123 	}
124 
125 	pkt = net_pkt_rx_alloc_with_buffer(esp32_wifi_iface, len, AF_UNSPEC, 0, K_MSEC(100));
126 	if (!pkt) {
127 		LOG_ERR("Failed to allocate net buffer");
128 		esp_wifi_internal_free_rx_buffer(eb);
129 		return -EIO;
130 	}
131 
132 	if (net_pkt_write(pkt, buffer, len) < 0) {
133 		LOG_ERR("Failed to write to net buffer");
134 		goto pkt_unref;
135 	}
136 
137 	if (net_recv_data(esp32_wifi_iface, pkt) < 0) {
138 		LOG_ERR("Failed to push received data");
139 		goto pkt_unref;
140 	}
141 
142 #if defined(CONFIG_NET_STATISTICS_WIFI)
143 	esp32_data.stats.bytes.received += len;
144 	esp32_data.stats.pkts.rx++;
145 #endif
146 
147 	esp_wifi_internal_free_rx_buffer(eb);
148 	return 0;
149 
150 pkt_unref:
151 	esp_wifi_internal_free_rx_buffer(eb);
152 	net_pkt_unref(pkt);
153 
154 #if defined(CONFIG_NET_STATISTICS_WIFI)
155 	esp32_data.stats.errors.rx++;
156 #endif
157 
158 	return -EIO;
159 }
160 
scan_done_handler(void)161 static void scan_done_handler(void)
162 {
163 	uint16_t aps = 0;
164 	wifi_ap_record_t *ap_list_buffer;
165 	struct wifi_scan_result res = { 0 };
166 
167 	esp_wifi_scan_get_ap_num(&aps);
168 	if (!aps) {
169 		LOG_INF("No Wi-Fi AP found");
170 		goto out;
171 	}
172 
173 	ap_list_buffer = k_malloc(aps * sizeof(wifi_ap_record_t));
174 	if (ap_list_buffer == NULL) {
175 		LOG_INF("Failed to malloc buffer to print scan results");
176 		goto out;
177 	}
178 
179 	if (esp_wifi_scan_get_ap_records(&aps, (wifi_ap_record_t *)ap_list_buffer) == ESP_OK) {
180 		for (int k = 0; k < aps; k++) {
181 			memset(&res, 0, sizeof(struct wifi_scan_result));
182 			int ssid_len = strnlen(ap_list_buffer[k].ssid, WIFI_SSID_MAX_LEN);
183 
184 			res.ssid_length = ssid_len;
185 			strncpy(res.ssid, ap_list_buffer[k].ssid, ssid_len);
186 			res.rssi = ap_list_buffer[k].rssi;
187 			res.channel = ap_list_buffer[k].primary;
188 
189 			memcpy(res.mac, ap_list_buffer[k].bssid, WIFI_MAC_ADDR_LEN);
190 			res.mac_length = WIFI_MAC_ADDR_LEN;
191 
192 			switch (ap_list_buffer[k].authmode) {
193 			case WIFI_AUTH_OPEN:
194 				res.security = WIFI_SECURITY_TYPE_NONE;
195 				break;
196 			case WIFI_AUTH_WPA2_PSK:
197 				res.security = WIFI_SECURITY_TYPE_PSK;
198 				break;
199 			case WIFI_AUTH_WPA3_PSK:
200 				res.security = WIFI_SECURITY_TYPE_SAE;
201 				break;
202 			case WIFI_AUTH_WAPI_PSK:
203 				res.security = WIFI_SECURITY_TYPE_WAPI;
204 				break;
205 			case WIFI_AUTH_WPA2_ENTERPRISE:
206 				res.security = WIFI_SECURITY_TYPE_EAP;
207 				break;
208 			case WIFI_AUTH_WEP:
209 				res.security = WIFI_SECURITY_TYPE_WEP;
210 				break;
211 			case WIFI_AUTH_WPA_PSK:
212 				res.security = WIFI_SECURITY_TYPE_WPA_PSK;
213 				break;
214 			default:
215 				res.security = WIFI_SECURITY_TYPE_UNKNOWN;
216 				break;
217 			}
218 
219 			if (esp32_data.scan_cb) {
220 				esp32_data.scan_cb(esp32_wifi_iface, 0, &res);
221 
222 				/* ensure notifications get delivered */
223 				k_yield();
224 			}
225 		}
226 	} else {
227 		LOG_INF("Unable to retrieve AP records");
228 	}
229 
230 	k_free(ap_list_buffer);
231 
232 out:
233 	/* report end of scan event */
234 	esp32_data.scan_cb(esp32_wifi_iface, 0, NULL);
235 	esp32_data.scan_cb = NULL;
236 }
237 
esp_wifi_handle_sta_connect_event(void * event_data)238 static void esp_wifi_handle_sta_connect_event(void *event_data)
239 {
240 	ARG_UNUSED(event_data);
241 	esp32_data.state = ESP32_STA_CONNECTED;
242 #if defined(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)
243 	net_dhcpv4_start(esp32_wifi_iface);
244 #else
245 	wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, 0);
246 #endif
247 }
248 
esp_wifi_handle_sta_disconnect_event(void * event_data)249 static void esp_wifi_handle_sta_disconnect_event(void *event_data)
250 {
251 	wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data;
252 
253 	if (esp32_data.state == ESP32_STA_CONNECTED) {
254 #if defined(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)
255 		net_dhcpv4_stop(esp32_wifi_iface);
256 #endif
257 		wifi_mgmt_raise_disconnect_result_event(esp32_wifi_iface, 0);
258 	} else {
259 		wifi_mgmt_raise_disconnect_result_event(esp32_wifi_iface, -1);
260 	}
261 
262 	LOG_DBG("Disconnect reason: %d", event->reason);
263 	switch (event->reason) {
264 	case WIFI_REASON_AUTH_EXPIRE:
265 	case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
266 	case WIFI_REASON_AUTH_FAIL:
267 	case WIFI_REASON_HANDSHAKE_TIMEOUT:
268 	case WIFI_REASON_MIC_FAILURE:
269 		LOG_DBG("STA Auth Error");
270 		break;
271 	case WIFI_REASON_NO_AP_FOUND:
272 		LOG_DBG("AP Not found");
273 		break;
274 	default:
275 		break;
276 	}
277 
278 	if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_RECONNECT) &&
279 	    (event->reason != WIFI_REASON_ASSOC_LEAVE)) {
280 		esp32_data.state = ESP32_STA_CONNECTING;
281 		esp_wifi_connect();
282 	} else {
283 		esp32_data.state = ESP32_STA_STARTED;
284 	}
285 }
286 
esp_wifi_handle_ap_connect_event(void * event_data)287 static void esp_wifi_handle_ap_connect_event(void *event_data)
288 {
289 	wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *) event_data;
290 
291 	LOG_DBG("Station " MACSTR " join, AID=%d", MAC2STR(event->mac), event->aid);
292 	wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, 0);
293 
294 	if (!(esp32_data.ap_connection_cnt++)) {
295 		esp_wifi_internal_reg_rxcb(WIFI_IF_AP, eth_esp32_rx);
296 	}
297 }
298 
esp_wifi_handle_ap_disconnect_event(void * event_data)299 static void esp_wifi_handle_ap_disconnect_event(void *event_data)
300 {
301 	wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
302 
303 	LOG_DBG("station "MACSTR" leave, AID=%d", MAC2STR(event->mac), event->aid);
304 	wifi_mgmt_raise_disconnect_result_event(esp32_wifi_iface, 0);
305 
306 	if (!(--esp32_data.ap_connection_cnt)) {
307 		esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL);
308 	}
309 }
310 
esp_wifi_event_handler(const char * event_base,int32_t event_id,void * event_data,size_t event_data_size,uint32_t ticks_to_wait)311 void esp_wifi_event_handler(const char *event_base, int32_t event_id, void *event_data,
312 			    size_t event_data_size, uint32_t ticks_to_wait)
313 {
314 	LOG_DBG("Wi-Fi event: %d", event_id);
315 	switch (event_id) {
316 	case WIFI_EVENT_STA_START:
317 		esp32_data.state = ESP32_STA_STARTED;
318 		net_eth_carrier_on(esp32_wifi_iface);
319 		break;
320 	case WIFI_EVENT_STA_STOP:
321 		esp32_data.state = ESP32_STA_STOPPED;
322 		net_eth_carrier_off(esp32_wifi_iface);
323 		break;
324 	case WIFI_EVENT_STA_CONNECTED:
325 		esp_wifi_handle_sta_connect_event(event_data);
326 		break;
327 	case WIFI_EVENT_STA_DISCONNECTED:
328 		esp_wifi_handle_sta_disconnect_event(event_data);
329 		break;
330 	case WIFI_EVENT_SCAN_DONE:
331 		scan_done_handler();
332 		break;
333 	case WIFI_EVENT_AP_STOP:
334 		esp32_data.state = ESP32_AP_STOPPED;
335 		net_eth_carrier_off(esp32_wifi_iface);
336 		break;
337 	case WIFI_EVENT_AP_STACONNECTED:
338 		esp32_data.state = ESP32_AP_CONNECTED;
339 		esp_wifi_handle_ap_connect_event(event_data);
340 		break;
341 	case WIFI_EVENT_AP_STADISCONNECTED:
342 		esp32_data.state = ESP32_AP_DISCONNECTED;
343 		esp_wifi_handle_ap_disconnect_event(event_data);
344 		break;
345 	default:
346 		break;
347 	}
348 }
349 
esp32_wifi_disconnect(const struct device * dev)350 static int esp32_wifi_disconnect(const struct device *dev)
351 {
352 	struct esp32_wifi_runtime *data = dev->data;
353 	int ret = esp_wifi_disconnect();
354 
355 	if (ret != ESP_OK) {
356 		LOG_INF("Failed to disconnect from hotspot");
357 		return -EAGAIN;
358 	}
359 
360 	return 0;
361 }
362 
esp32_wifi_connect(const struct device * dev,struct wifi_connect_req_params * params)363 static int esp32_wifi_connect(const struct device *dev,
364 			    struct wifi_connect_req_params *params)
365 {
366 	struct esp32_wifi_runtime *data = dev->data;
367 	wifi_mode_t mode;
368 	int ret;
369 
370 	if (data->state == ESP32_STA_CONNECTING || data->state == ESP32_STA_CONNECTED) {
371 		wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, -1);
372 		return -EALREADY;
373 	}
374 
375 	ret = esp_wifi_get_mode(&mode);
376 	if (ret) {
377 		LOG_ERR("Failed to get Wi-Fi mode (%d)", ret);
378 		return -EAGAIN;
379 	}
380 
381 	if (mode != ESP32_WIFI_MODE_STA) {
382 		ret = esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
383 		if (ret) {
384 			LOG_ERR("Failed to set Wi-Fi mode (%d)", ret);
385 			return -EAGAIN;
386 		}
387 		ret = esp_wifi_start();
388 		if (ret) {
389 			LOG_ERR("Failed to start Wi-Fi driver (%d)", ret);
390 			return -EAGAIN;
391 		}
392 	}
393 
394 	if (data->state != ESP32_STA_STARTED) {
395 		LOG_ERR("Wi-Fi not in station mode");
396 		wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, -1);
397 		return -EIO;
398 	}
399 
400 	data->state = ESP32_STA_CONNECTING;
401 
402 	memcpy(data->status.ssid, params->ssid, params->ssid_length);
403 	data->status.ssid[params->ssid_length] = '\0';
404 
405 	wifi_config_t wifi_config;
406 
407 	memset(&wifi_config, 0, sizeof(wifi_config_t));
408 
409 	memcpy(wifi_config.sta.ssid, params->ssid, params->ssid_length);
410 	wifi_config.sta.ssid[params->ssid_length] = '\0';
411 	switch (params->security) {
412 	case WIFI_SECURITY_TYPE_NONE:
413 		wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN;
414 		data->status.security = WIFI_AUTH_OPEN;
415 		wifi_config.sta.pmf_cfg.required = false;
416 		break;
417 	case WIFI_SECURITY_TYPE_PSK:
418 		memcpy(wifi_config.sta.password, params->psk, params->psk_length);
419 		wifi_config.sta.password[params->psk_length] = '\0';
420 		wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
421 		wifi_config.sta.pmf_cfg.required = false;
422 		data->status.security = WIFI_AUTH_WPA2_PSK;
423 		break;
424 	case WIFI_SECURITY_TYPE_SAE:
425 #if defined(CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE)
426 		if (params->sae_password) {
427 			memcpy(wifi_config.sta.password, params->sae_password,
428 			       params->sae_password_length);
429 			wifi_config.sta.password[params->sae_password_length] = '\0';
430 		} else {
431 			memcpy(wifi_config.sta.password, params->psk, params->psk_length);
432 			wifi_config.sta.password[params->psk_length] = '\0';
433 		}
434 		data->status.security = WIFI_AUTH_WPA3_PSK;
435 		wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA3_PSK;
436 		wifi_config.sta.sae_pwe_h2e = WPA3_SAE_PWE_BOTH;
437 		break;
438 #else
439 		LOG_ERR("WPA3 not supported for STA mode. Enable "
440 			"CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE");
441 		return -EINVAL;
442 #endif /* CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE */
443 	default:
444 		LOG_ERR("Authentication method not supported");
445 		return -EIO;
446 	}
447 
448 	if (params->channel == WIFI_CHANNEL_ANY) {
449 		wifi_config.sta.channel = 0U;
450 		data->status.channel = 0U;
451 	} else {
452 		wifi_config.sta.channel = params->channel;
453 		data->status.channel = params->channel;
454 	}
455 
456 	ret = esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
457 	if (ret) {
458 		LOG_ERR("Failed to set Wi-Fi configuration (%d)", ret);
459 		return -EINVAL;
460 	}
461 
462 	ret = esp_wifi_connect();
463 	if (ret) {
464 		LOG_ERR("Failed to connect to Wi-Fi access point (%d)", ret);
465 		return -EAGAIN;
466 	}
467 
468 	return 0;
469 }
470 
esp32_wifi_scan(const struct device * dev,struct wifi_scan_params * params,scan_result_cb_t cb)471 static int esp32_wifi_scan(const struct device *dev,
472 			   struct wifi_scan_params *params,
473 			   scan_result_cb_t cb)
474 {
475 	struct esp32_wifi_runtime *data = dev->data;
476 	int ret = 0;
477 
478 	if (data->scan_cb != NULL) {
479 		LOG_INF("Scan callback in progress");
480 		return -EINPROGRESS;
481 	}
482 
483 	data->scan_cb = cb;
484 
485 	wifi_scan_config_t scan_config = { 0 };
486 
487 	if (params) {
488 		/* The enum values are same, so, no conversion needed */
489 		scan_config.scan_type = params->scan_type;
490 	}
491 
492 	ret = esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
493 	ret |= esp_wifi_scan_start(&scan_config, false);
494 
495 	if (ret != ESP_OK) {
496 		LOG_ERR("Failed to start Wi-Fi scanning");
497 		return -EAGAIN;
498 	}
499 
500 	return 0;
501 };
502 
esp32_wifi_ap_enable(const struct device * dev,struct wifi_connect_req_params * params)503 static int esp32_wifi_ap_enable(const struct device *dev,
504 			 struct wifi_connect_req_params *params)
505 {
506 	struct esp32_wifi_runtime *data = dev->data;
507 	esp_err_t err = 0;
508 
509 	/* Build Wi-Fi configuration for AP mode */
510 	wifi_config_t wifi_config = {
511 		.ap = {
512 			.max_connection = 5,
513 			.channel = params->channel == WIFI_CHANNEL_ANY ?
514 				0 : params->channel,
515 		},
516 	};
517 
518 	memcpy(data->status.ssid, params->ssid, params->ssid_length);
519 	data->status.ssid[params->ssid_length] = '\0';
520 
521 	strncpy((char *) wifi_config.ap.ssid, params->ssid, params->ssid_length);
522 	wifi_config.ap.ssid_len = params->ssid_length;
523 
524 	switch (params->security) {
525 	case WIFI_SECURITY_TYPE_NONE:
526 		memset(wifi_config.ap.password, 0, sizeof(wifi_config.ap.password));
527 		wifi_config.ap.authmode = WIFI_AUTH_OPEN;
528 		data->status.security = WIFI_AUTH_OPEN;
529 		wifi_config.ap.pmf_cfg.required = false;
530 		break;
531 	case WIFI_SECURITY_TYPE_PSK:
532 		strncpy((char *) wifi_config.ap.password, params->psk, params->psk_length);
533 		wifi_config.ap.authmode = WIFI_AUTH_WPA2_PSK;
534 		data->status.security = WIFI_AUTH_WPA2_PSK;
535 		wifi_config.ap.pmf_cfg.required = false;
536 		break;
537 	default:
538 		LOG_ERR("Authentication method not supported");
539 		return -EINVAL;
540 	}
541 
542 	/* Start Wi-Fi in AP mode with configuration built above */
543 	err = esp_wifi_set_mode(ESP32_WIFI_MODE_AP);
544 	if (err) {
545 		LOG_ERR("Failed to set Wi-Fi mode (%d)", err);
546 		return -EINVAL;
547 	}
548 
549 	err = esp_wifi_set_config(WIFI_IF_AP, &wifi_config);
550 	if (err) {
551 		LOG_ERR("Failed to set Wi-Fi configuration (%d)", err);
552 		return -EINVAL;
553 	}
554 
555 	err = esp_wifi_start();
556 	if (err) {
557 		LOG_ERR("Failed to enable Wi-Fi AP mode");
558 		return -EAGAIN;
559 	}
560 
561 	net_eth_carrier_on(esp32_wifi_iface);
562 
563 	return 0;
564 };
565 
esp32_wifi_ap_disable(const struct device * dev)566 static int esp32_wifi_ap_disable(const struct device *dev)
567 {
568 	int err = 0;
569 
570 	err = esp_wifi_stop();
571 	if (err) {
572 		LOG_ERR("Failed to disable Wi-Fi AP mode: (%d)", err);
573 		return -EAGAIN;
574 	}
575 
576 	return 0;
577 };
578 
esp32_wifi_status(const struct device * dev,struct wifi_iface_status * status)579 static int esp32_wifi_status(const struct device *dev, struct wifi_iface_status *status)
580 {
581 	struct esp32_wifi_runtime *data = dev->data;
582 	wifi_mode_t mode;
583 	wifi_config_t conf;
584 	wifi_ap_record_t ap_info;
585 
586 	switch (data->state) {
587 	case ESP32_STA_STOPPED:
588 	case ESP32_AP_STOPPED:
589 		status->state = WIFI_STATE_INACTIVE;
590 		break;
591 	case ESP32_STA_STARTED:
592 	case ESP32_AP_DISCONNECTED:
593 		status->state = WIFI_STATE_DISCONNECTED;
594 		break;
595 	case ESP32_STA_CONNECTING:
596 		status->state = WIFI_STATE_SCANNING;
597 		break;
598 	case ESP32_STA_CONNECTED:
599 	case ESP32_AP_CONNECTED:
600 		status->state = WIFI_STATE_COMPLETED;
601 		break;
602 	default:
603 		break;
604 	}
605 
606 	strncpy(status->ssid, data->status.ssid, WIFI_SSID_MAX_LEN);
607 	status->ssid_len = strnlen(data->status.ssid, WIFI_SSID_MAX_LEN);
608 	status->band = WIFI_FREQ_BAND_2_4_GHZ;
609 	status->link_mode = WIFI_LINK_MODE_UNKNOWN;
610 	status->mfp = WIFI_MFP_DISABLE;
611 
612 	if (esp_wifi_get_mode(&mode) == ESP_OK) {
613 		if (mode == ESP32_WIFI_MODE_STA) {
614 			esp_wifi_get_config(ESP_IF_WIFI_STA, &conf);
615 			esp_wifi_sta_get_ap_info(&ap_info);
616 
617 			status->iface_mode = WIFI_MODE_INFRA;
618 			status->channel = ap_info.primary;
619 			status->rssi = ap_info.rssi;
620 			memcpy(status->bssid, ap_info.bssid, WIFI_MAC_ADDR_LEN);
621 
622 			if (ap_info.phy_11b) {
623 				status->link_mode = WIFI_1;
624 			} else if (ap_info.phy_11g) {
625 				status->link_mode = WIFI_3;
626 			} else if (ap_info.phy_11n) {
627 				status->link_mode = WIFI_4;
628 			} else if (ap_info.phy_11ax) {
629 				status->link_mode = WIFI_6;
630 			}
631 
632 			status->beacon_interval = conf.sta.listen_interval;
633 		} else if (mode == ESP32_WIFI_MODE_AP) {
634 			esp_wifi_get_config(ESP_IF_WIFI_AP, &conf);
635 			status->iface_mode = WIFI_MODE_AP;
636 			status->link_mode = WIFI_LINK_MODE_UNKNOWN;
637 			status->channel = conf.ap.channel;
638 			status->beacon_interval = conf.ap.beacon_interval;
639 
640 		} else {
641 			status->iface_mode = WIFI_MODE_UNKNOWN;
642 			status->link_mode = WIFI_LINK_MODE_UNKNOWN;
643 			status->channel = 0;
644 		}
645 	}
646 
647 	switch (data->status.security) {
648 	case WIFI_AUTH_OPEN:
649 		status->security = WIFI_SECURITY_TYPE_NONE;
650 		break;
651 	case WIFI_AUTH_WPA2_PSK:
652 		status->security = WIFI_SECURITY_TYPE_PSK;
653 		break;
654 	case WIFI_AUTH_WPA3_PSK:
655 		status->security = WIFI_SECURITY_TYPE_SAE;
656 		break;
657 	default:
658 		status->security = WIFI_SECURITY_TYPE_UNKNOWN;
659 	}
660 
661 	return 0;
662 }
663 
esp32_wifi_init(struct net_if * iface)664 static void esp32_wifi_init(struct net_if *iface)
665 {
666 	const struct device *dev = net_if_get_device(iface);
667 	struct esp32_wifi_runtime *dev_data = dev->data;
668 	struct ethernet_context *eth_ctx = net_if_l2_data(iface);
669 
670 	eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI;
671 	esp32_wifi_iface = iface;
672 	dev_data->state = ESP32_STA_STOPPED;
673 
674 	/* Start interface when we are actually connected with Wi-Fi network */
675 	esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_STA);
676 
677 	/* Assign link local address. */
678 	net_if_set_link_addr(iface, dev_data->mac_addr, 6, NET_LINK_ETHERNET);
679 
680 	ethernet_init(iface);
681 	net_if_carrier_off(iface);
682 
683 	wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
684 
685 	esp_err_t ret = esp_wifi_init(&config);
686 
687 	esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, eth_esp32_rx);
688 
689 	ret |= esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
690 	ret |= esp_wifi_start();
691 
692 	if (ret != ESP_OK) {
693 		LOG_ERR("Failed to start Wi-Fi driver");
694 	}
695 }
696 
697 #if defined(CONFIG_NET_STATISTICS_WIFI)
esp32_wifi_stats(const struct device * dev,struct net_stats_wifi * stats)698 static int esp32_wifi_stats(const struct device *dev, struct net_stats_wifi *stats)
699 {
700 	struct esp32_wifi_runtime *data = dev->data;
701 
702 	stats->bytes.received = data->stats.bytes.received;
703 	stats->bytes.sent = data->stats.bytes.sent;
704 	stats->pkts.rx = data->stats.pkts.rx;
705 	stats->pkts.tx = data->stats.pkts.tx;
706 	stats->errors.rx = data->stats.errors.rx;
707 	stats->errors.tx = data->stats.errors.tx;
708 	stats->broadcast.rx = data->stats.broadcast.rx;
709 	stats->broadcast.tx = data->stats.broadcast.tx;
710 	stats->multicast.rx = data->stats.multicast.rx;
711 	stats->multicast.tx = data->stats.multicast.tx;
712 	stats->sta_mgmt.beacons_rx = data->stats.sta_mgmt.beacons_rx;
713 	stats->sta_mgmt.beacons_miss = data->stats.sta_mgmt.beacons_miss;
714 
715 	return 0;
716 }
717 #endif
718 
esp32_wifi_dev_init(const struct device * dev)719 static int esp32_wifi_dev_init(const struct device *dev)
720 {
721 	esp_timer_init();
722 
723 	if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)) {
724 		net_mgmt_init_event_callback(&esp32_dhcp_cb, wifi_event_handler, DHCPV4_MASK);
725 		net_mgmt_add_event_callback(&esp32_dhcp_cb);
726 	}
727 
728 	return 0;
729 }
730 
731 static const struct wifi_mgmt_ops esp32_wifi_mgmt = {
732 	.scan		   = esp32_wifi_scan,
733 	.connect	   = esp32_wifi_connect,
734 	.disconnect	   = esp32_wifi_disconnect,
735 	.ap_enable	   = esp32_wifi_ap_enable,
736 	.ap_disable	   = esp32_wifi_ap_disable,
737 	.iface_status	   = esp32_wifi_status,
738 #if defined(CONFIG_NET_STATISTICS_WIFI)
739 	.get_stats	   = esp32_wifi_stats,
740 #endif
741 };
742 
743 static const struct net_wifi_mgmt_offload esp32_api = {
744 	.wifi_iface.iface_api.init	  = esp32_wifi_init,
745 	.wifi_iface.send = esp32_wifi_send,
746 	.wifi_mgmt_api = &esp32_wifi_mgmt,
747 };
748 
749 NET_DEVICE_DT_INST_DEFINE(0,
750 		esp32_wifi_dev_init, NULL,
751 		&esp32_data, NULL, CONFIG_WIFI_INIT_PRIORITY,
752 		&esp32_api, ETHERNET_L2,
753 		NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU);
754 
755 CONNECTIVITY_WIFI_MGMT_BIND(Z_DEVICE_DT_DEV_ID(DT_DRV_INST(0)));
756