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 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
17 #include <zephyr/net/wifi_nm.h>
18 #include <zephyr/net/conn_mgr/connectivity_wifi_mgmt.h>
19 #endif
20 #include <zephyr/device.h>
21 #include <soc.h>
22 #include "esp_private/wifi.h"
23 #include "esp_event.h"
24 #include "esp_timer.h"
25 #include "esp_system.h"
26 #include "esp_wpa.h"
27 #include <esp_mac.h>
28 #include "wifi/wifi_event.h"
29 
30 #if CONFIG_SOC_SERIES_ESP32S2 || CONFIG_SOC_SERIES_ESP32C3
31 #include <esp_private/adc_share_hw_ctrl.h>
32 #endif /* CONFIG_SOC_SERIES_ESP32S2 || CONFIG_SOC_SERIES_ESP32C3 */
33 
34 #define DHCPV4_MASK (NET_EVENT_IPV4_DHCP_BOUND | NET_EVENT_IPV4_DHCP_STOP)
35 
36 /* use global iface pointer to support any ethernet driver */
37 /* necessary for wifi callback functions */
38 static struct net_if *esp32_wifi_iface;
39 static struct esp32_wifi_runtime esp32_data;
40 
41 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
42 static struct net_if *esp32_wifi_iface_ap;
43 static struct esp32_wifi_runtime esp32_ap_sta_data;
44 #endif
45 
46 enum esp32_state_flag {
47 	ESP32_STA_STOPPED,
48 	ESP32_STA_STARTED,
49 	ESP32_STA_CONNECTING,
50 	ESP32_STA_CONNECTED,
51 	ESP32_AP_STARTED,
52 	ESP32_AP_CONNECTED,
53 	ESP32_AP_DISCONNECTED,
54 	ESP32_AP_STOPPED,
55 };
56 
57 struct esp32_wifi_status {
58 	char ssid[WIFI_SSID_MAX_LEN + 1];
59 	char pass[WIFI_PSK_MAX_LEN + 1];
60 	wifi_auth_mode_t security;
61 	bool connected;
62 	uint8_t channel;
63 	int rssi;
64 };
65 
66 struct esp32_wifi_runtime {
67 	uint8_t mac_addr[6];
68 	uint8_t frame_buf[NET_ETH_MAX_FRAME_SIZE];
69 #if defined(CONFIG_NET_STATISTICS_WIFI)
70 	struct net_stats_wifi stats;
71 #endif
72 	struct esp32_wifi_status status;
73 	scan_result_cb_t scan_cb;
74 	uint8_t state;
75 	uint8_t ap_connection_cnt;
76 };
77 
78 static struct net_mgmt_event_callback esp32_dhcp_cb;
79 
wifi_event_handler(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)80 static void wifi_event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
81 			       struct net_if *iface)
82 {
83 	switch (mgmt_event) {
84 	case NET_EVENT_IPV4_DHCP_BOUND:
85 		wifi_mgmt_raise_connect_result_event(iface, 0);
86 		break;
87 	default:
88 		break;
89 	}
90 }
91 
esp32_wifi_send(const struct device * dev,struct net_pkt * pkt)92 static int esp32_wifi_send(const struct device *dev, struct net_pkt *pkt)
93 {
94 	struct esp32_wifi_runtime *data = dev->data;
95 	const int pkt_len = net_pkt_get_len(pkt);
96 	esp_interface_t ifx = data->state == ESP32_AP_CONNECTED ? ESP_IF_WIFI_AP : ESP_IF_WIFI_STA;
97 
98 	if (esp32_data.state != ESP32_STA_CONNECTED && esp32_data.state != ESP32_AP_CONNECTED) {
99 		return -EIO;
100 	}
101 
102 	/* Read the packet payload */
103 	if (net_pkt_read(pkt, data->frame_buf, pkt_len) < 0) {
104 		goto out;
105 	}
106 
107 	/* Enqueue packet for transmission */
108 	if (esp_wifi_internal_tx(ifx, (void *)data->frame_buf, pkt_len) != ESP_OK) {
109 		goto out;
110 	}
111 
112 #if defined(CONFIG_NET_STATISTICS_WIFI)
113 	data->stats.bytes.sent += pkt_len;
114 	data->stats.pkts.tx++;
115 #endif
116 
117 	LOG_DBG("pkt sent %p len %d", pkt, pkt_len);
118 	return 0;
119 
120 out:
121 
122 	LOG_ERR("Failed to send packet");
123 #if defined(CONFIG_NET_STATISTICS_WIFI)
124 	data->stats.errors.tx++;
125 #endif
126 	return -EIO;
127 }
128 
eth_esp32_rx(void * buffer,uint16_t len,void * eb)129 static esp_err_t eth_esp32_rx(void *buffer, uint16_t len, void *eb)
130 {
131 	struct net_pkt *pkt;
132 
133 	if (esp32_wifi_iface == NULL) {
134 		esp_wifi_internal_free_rx_buffer(eb);
135 		LOG_ERR("network interface unavailable");
136 		return -EIO;
137 	}
138 
139 	pkt = net_pkt_rx_alloc_with_buffer(esp32_wifi_iface, len, AF_UNSPEC, 0, K_MSEC(100));
140 	if (!pkt) {
141 		LOG_ERR("Failed to allocate net buffer");
142 		esp_wifi_internal_free_rx_buffer(eb);
143 		return -EIO;
144 	}
145 
146 	if (net_pkt_write(pkt, buffer, len) < 0) {
147 		LOG_ERR("Failed to write to net buffer");
148 		goto pkt_unref;
149 	}
150 
151 	if (net_recv_data(esp32_wifi_iface, pkt) < 0) {
152 		LOG_ERR("Failed to push received data");
153 		goto pkt_unref;
154 	}
155 
156 #if defined(CONFIG_NET_STATISTICS_WIFI)
157 	esp32_data.stats.bytes.received += len;
158 	esp32_data.stats.pkts.rx++;
159 #endif
160 
161 	esp_wifi_internal_free_rx_buffer(eb);
162 	return 0;
163 
164 pkt_unref:
165 	esp_wifi_internal_free_rx_buffer(eb);
166 	net_pkt_unref(pkt);
167 
168 #if defined(CONFIG_NET_STATISTICS_WIFI)
169 	esp32_data.stats.errors.rx++;
170 #endif
171 
172 	return -EIO;
173 }
174 
175 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
wifi_esp32_ap_iface_rx(void * buffer,uint16_t len,void * eb)176 static esp_err_t wifi_esp32_ap_iface_rx(void *buffer, uint16_t len, void *eb)
177 {
178 	struct net_pkt *pkt;
179 
180 	if (esp32_wifi_iface_ap == NULL) {
181 		esp_wifi_internal_free_rx_buffer(eb);
182 		LOG_ERR("network interface unavailable");
183 		return -EIO;
184 	}
185 
186 	pkt = net_pkt_rx_alloc_with_buffer(esp32_wifi_iface_ap, len, AF_UNSPEC, 0, K_MSEC(100));
187 	if (!pkt) {
188 		esp_wifi_internal_free_rx_buffer(eb);
189 		LOG_ERR("Failed to get net buffer");
190 		return -EIO;
191 	}
192 
193 	if (net_pkt_write(pkt, buffer, len) < 0) {
194 		LOG_ERR("Failed to write pkt");
195 		goto pkt_unref;
196 	}
197 
198 	if (net_recv_data(esp32_wifi_iface_ap, pkt) < 0) {
199 		LOG_ERR("Failed to push received data");
200 		goto pkt_unref;
201 	}
202 
203 #if defined(CONFIG_NET_STATISTICS_WIFI)
204 	esp32_ap_sta_data.stats.bytes.received += len;
205 	esp32_ap_sta_data.stats.pkts.rx++;
206 #endif
207 
208 	esp_wifi_internal_free_rx_buffer(eb);
209 	return 0;
210 
211 pkt_unref:
212 	esp_wifi_internal_free_rx_buffer(eb);
213 	net_pkt_unref(pkt);
214 
215 #if defined(CONFIG_NET_STATISTICS_WIFI)
216 	esp32_ap_sta_data.stats.errors.rx++;
217 #endif
218 	return -EIO;
219 }
220 #endif
221 
scan_done_handler(void)222 static void scan_done_handler(void)
223 {
224 	uint16_t aps = 0;
225 	wifi_ap_record_t *ap_list_buffer;
226 	struct wifi_scan_result res = { 0 };
227 
228 	esp_wifi_scan_get_ap_num(&aps);
229 	if (!aps) {
230 		LOG_INF("No Wi-Fi AP found");
231 		goto out;
232 	}
233 
234 	ap_list_buffer = k_malloc(aps * sizeof(wifi_ap_record_t));
235 	if (ap_list_buffer == NULL) {
236 		LOG_INF("Failed to malloc buffer to print scan results");
237 		goto out;
238 	}
239 
240 	if (esp_wifi_scan_get_ap_records(&aps, (wifi_ap_record_t *)ap_list_buffer) == ESP_OK) {
241 		for (int k = 0; k < aps; k++) {
242 			memset(&res, 0, sizeof(struct wifi_scan_result));
243 			int ssid_len = strnlen(ap_list_buffer[k].ssid, WIFI_SSID_MAX_LEN);
244 
245 			res.ssid_length = ssid_len;
246 			strncpy(res.ssid, ap_list_buffer[k].ssid, ssid_len);
247 			res.rssi = ap_list_buffer[k].rssi;
248 			res.channel = ap_list_buffer[k].primary;
249 
250 			memcpy(res.mac, ap_list_buffer[k].bssid, WIFI_MAC_ADDR_LEN);
251 			res.mac_length = WIFI_MAC_ADDR_LEN;
252 
253 			switch (ap_list_buffer[k].authmode) {
254 			case WIFI_AUTH_OPEN:
255 				res.security = WIFI_SECURITY_TYPE_NONE;
256 				break;
257 			case WIFI_AUTH_WPA2_PSK:
258 				res.security = WIFI_SECURITY_TYPE_PSK;
259 				break;
260 			case WIFI_AUTH_WPA3_PSK:
261 				res.security = WIFI_SECURITY_TYPE_SAE;
262 				break;
263 			case WIFI_AUTH_WAPI_PSK:
264 				res.security = WIFI_SECURITY_TYPE_WAPI;
265 				break;
266 			case WIFI_AUTH_WPA2_ENTERPRISE:
267 				res.security = WIFI_SECURITY_TYPE_EAP;
268 				break;
269 			case WIFI_AUTH_WEP:
270 				res.security = WIFI_SECURITY_TYPE_WEP;
271 				break;
272 			case WIFI_AUTH_WPA_PSK:
273 				res.security = WIFI_SECURITY_TYPE_WPA_PSK;
274 				break;
275 			default:
276 				res.security = WIFI_SECURITY_TYPE_UNKNOWN;
277 				break;
278 			}
279 
280 			if (esp32_data.scan_cb) {
281 				esp32_data.scan_cb(esp32_wifi_iface, 0, &res);
282 
283 				/* ensure notifications get delivered */
284 				k_yield();
285 			}
286 		}
287 	} else {
288 		LOG_INF("Unable to retrieve AP records");
289 	}
290 
291 	k_free(ap_list_buffer);
292 
293 out:
294 	/* report end of scan event */
295 	esp32_data.scan_cb(esp32_wifi_iface, 0, NULL);
296 	esp32_data.scan_cb = NULL;
297 }
298 
esp_wifi_handle_sta_connect_event(void * event_data)299 static void esp_wifi_handle_sta_connect_event(void *event_data)
300 {
301 	ARG_UNUSED(event_data);
302 	esp32_data.state = ESP32_STA_CONNECTED;
303 #if defined(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)
304 	net_dhcpv4_start(esp32_wifi_iface);
305 #else
306 	wifi_mgmt_raise_connect_result_event(esp32_wifi_iface, 0);
307 #endif
308 }
309 
esp_wifi_handle_sta_disconnect_event(void * event_data)310 static void esp_wifi_handle_sta_disconnect_event(void *event_data)
311 {
312 	wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data;
313 
314 	if (esp32_data.state == ESP32_STA_CONNECTED) {
315 #if defined(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)
316 		net_dhcpv4_stop(esp32_wifi_iface);
317 #endif
318 		wifi_mgmt_raise_disconnect_result_event(esp32_wifi_iface, 0);
319 	} else {
320 		wifi_mgmt_raise_disconnect_result_event(esp32_wifi_iface, -1);
321 	}
322 
323 	LOG_DBG("Disconnect reason: %d", event->reason);
324 	switch (event->reason) {
325 	case WIFI_REASON_AUTH_EXPIRE:
326 	case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
327 	case WIFI_REASON_AUTH_FAIL:
328 	case WIFI_REASON_HANDSHAKE_TIMEOUT:
329 	case WIFI_REASON_MIC_FAILURE:
330 		LOG_DBG("STA Auth Error");
331 		break;
332 	case WIFI_REASON_NO_AP_FOUND:
333 		LOG_DBG("AP Not found");
334 		break;
335 	default:
336 		break;
337 	}
338 
339 	if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_RECONNECT) &&
340 	    (event->reason != WIFI_REASON_ASSOC_LEAVE)) {
341 		esp32_data.state = ESP32_STA_CONNECTING;
342 		esp_wifi_connect();
343 	} else {
344 		esp32_data.state = ESP32_STA_STARTED;
345 	}
346 }
347 
esp_wifi_handle_ap_connect_event(void * event_data)348 static void esp_wifi_handle_ap_connect_event(void *event_data)
349 {
350 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
351 	struct net_if *iface = esp32_wifi_iface_ap;
352 	wifi_rxcb_t esp32_rx = wifi_esp32_ap_iface_rx;
353 #else
354 	struct net_if *iface = esp32_wifi_iface;
355 	wifi_rxcb_t esp32_rx = eth_esp32_rx;
356 #endif
357 	wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data;
358 
359 	LOG_DBG("Station " MACSTR " join, AID=%d", MAC2STR(event->mac), event->aid);
360 
361 	wifi_sta_list_t sta_list;
362 	struct wifi_ap_sta_info sta_info;
363 
364 	sta_info.link_mode = WIFI_LINK_MODE_UNKNOWN;
365 	sta_info.twt_capable = false; /* Only support in 802.11ax */
366 	sta_info.mac_length = WIFI_MAC_ADDR_LEN;
367 	memcpy(sta_info.mac, event->mac, WIFI_MAC_ADDR_LEN);
368 
369 	/* Expect the return value to always be ESP_OK,
370 	 * since it is called in esp_wifi_event_handler()
371 	 */
372 	(void)esp_wifi_ap_get_sta_list(&sta_list);
373 	for (int i = 0; i < sta_list.num; i++) {
374 		wifi_sta_info_t *sta = &sta_list.sta[i];
375 
376 		if (memcmp(event->mac, sta->mac, 6) == 0) {
377 			if (sta->phy_11n) {
378 				sta_info.link_mode = WIFI_4;
379 			} else if (sta->phy_11g) {
380 				sta_info.link_mode = WIFI_3;
381 			} else if (sta->phy_11b) {
382 				sta_info.link_mode = WIFI_1;
383 			} else {
384 				sta_info.link_mode = WIFI_LINK_MODE_UNKNOWN;
385 			}
386 			break;
387 		}
388 	}
389 
390 	wifi_mgmt_raise_ap_sta_connected_event(iface, &sta_info);
391 
392 	if (!(esp32_data.ap_connection_cnt++)) {
393 		esp_wifi_internal_reg_rxcb(WIFI_IF_AP, esp32_rx);
394 	}
395 }
396 
esp_wifi_handle_ap_disconnect_event(void * event_data)397 static void esp_wifi_handle_ap_disconnect_event(void *event_data)
398 {
399 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
400 	struct net_if *iface = esp32_wifi_iface_ap;
401 #else
402 	struct net_if *iface = esp32_wifi_iface;
403 #endif
404 	wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data;
405 
406 	LOG_DBG("station " MACSTR " leave, AID=%d", MAC2STR(event->mac), event->aid);
407 	struct wifi_ap_sta_info sta_info;
408 
409 	sta_info.link_mode = WIFI_LINK_MODE_UNKNOWN;
410 	sta_info.twt_capable = false; /* Only support in 802.11ax */
411 	sta_info.mac_length = WIFI_MAC_ADDR_LEN;
412 	memcpy(sta_info.mac, event->mac, WIFI_MAC_ADDR_LEN);
413 	wifi_mgmt_raise_ap_sta_disconnected_event(iface, &sta_info);
414 
415 	if (!(--esp32_data.ap_connection_cnt)) {
416 		esp_wifi_internal_reg_rxcb(WIFI_IF_AP, NULL);
417 	}
418 }
419 
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)420 void esp_wifi_event_handler(const char *event_base, int32_t event_id, void *event_data,
421 			    size_t event_data_size, uint32_t ticks_to_wait)
422 {
423 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
424 	struct net_if *iface_ap = esp32_wifi_iface_ap;
425 	struct esp32_wifi_runtime *ap_data = &esp32_ap_sta_data;
426 #else
427 	struct net_if *iface_ap = esp32_wifi_iface;
428 	struct esp32_wifi_runtime *ap_data = &esp32_data;
429 #endif
430 
431 	LOG_DBG("Wi-Fi event: %d", event_id);
432 	switch (event_id) {
433 	case WIFI_EVENT_STA_START:
434 		esp32_data.state = ESP32_STA_STARTED;
435 		net_eth_carrier_on(esp32_wifi_iface);
436 		break;
437 	case WIFI_EVENT_STA_STOP:
438 		esp32_data.state = ESP32_STA_STOPPED;
439 		net_eth_carrier_off(esp32_wifi_iface);
440 		break;
441 	case WIFI_EVENT_STA_CONNECTED:
442 		esp_wifi_handle_sta_connect_event(event_data);
443 		break;
444 	case WIFI_EVENT_STA_DISCONNECTED:
445 		esp_wifi_handle_sta_disconnect_event(event_data);
446 		break;
447 	case WIFI_EVENT_SCAN_DONE:
448 		scan_done_handler();
449 		break;
450 	case WIFI_EVENT_AP_START:
451 		ap_data->state = ESP32_AP_STARTED;
452 		net_eth_carrier_on(iface_ap);
453 		wifi_mgmt_raise_ap_enable_result_event(iface_ap, 0);
454 		break;
455 	case WIFI_EVENT_AP_STOP:
456 		ap_data->state = ESP32_AP_STOPPED;
457 		net_eth_carrier_off(iface_ap);
458 		wifi_mgmt_raise_ap_disable_result_event(iface_ap, 0);
459 		break;
460 	case WIFI_EVENT_AP_STACONNECTED:
461 		ap_data->state = ESP32_AP_CONNECTED;
462 		esp_wifi_handle_ap_connect_event(event_data);
463 		break;
464 	case WIFI_EVENT_AP_STADISCONNECTED:
465 		ap_data->state = ESP32_AP_DISCONNECTED;
466 		esp_wifi_handle_ap_disconnect_event(event_data);
467 		break;
468 	default:
469 		break;
470 	}
471 }
472 
esp32_wifi_disconnect(const struct device * dev)473 static int esp32_wifi_disconnect(const struct device *dev)
474 {
475 	int ret = esp_wifi_disconnect();
476 
477 	if (ret != ESP_OK) {
478 		LOG_INF("Failed to disconnect from hotspot");
479 		return -EAGAIN;
480 	}
481 
482 	return 0;
483 }
484 
esp32_wifi_connect(const struct device * dev,struct wifi_connect_req_params * params)485 static int esp32_wifi_connect(const struct device *dev,
486 			    struct wifi_connect_req_params *params)
487 {
488 	struct esp32_wifi_runtime *data = dev->data;
489 	struct net_if *iface = net_if_lookup_by_dev(dev);
490 	wifi_mode_t mode;
491 	int ret;
492 
493 	if (data->state == ESP32_STA_CONNECTING || data->state == ESP32_STA_CONNECTED) {
494 		wifi_mgmt_raise_connect_result_event(iface, -1);
495 		return -EALREADY;
496 	}
497 
498 	ret = esp_wifi_get_mode(&mode);
499 	if (ret) {
500 		LOG_ERR("Failed to get Wi-Fi mode (%d)", ret);
501 		return -EAGAIN;
502 	}
503 
504 	if (IS_ENABLED(CONFIG_ESP32_WIFI_AP_STA_MODE) &&
505 	    (mode == ESP32_WIFI_MODE_AP || mode == ESP32_WIFI_MODE_APSTA)) {
506 		ret = esp_wifi_set_mode(ESP32_WIFI_MODE_APSTA);
507 	} else {
508 		ret = esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
509 	}
510 
511 	if (ret) {
512 		LOG_ERR("Failed to set Wi-Fi mode (%d)", ret);
513 		return -EAGAIN;
514 	}
515 	ret = esp_wifi_start();
516 	if (ret) {
517 		LOG_ERR("Failed to start Wi-Fi driver (%d)", ret);
518 		return -EAGAIN;
519 	}
520 
521 	if (data->state != ESP32_STA_STARTED) {
522 		LOG_ERR("Wi-Fi not in station mode");
523 		wifi_mgmt_raise_connect_result_event(iface, -1);
524 		return -EIO;
525 	}
526 
527 	data->state = ESP32_STA_CONNECTING;
528 
529 	memcpy(data->status.ssid, params->ssid, params->ssid_length);
530 	data->status.ssid[params->ssid_length] = '\0';
531 
532 	wifi_config_t wifi_config;
533 
534 	memset(&wifi_config, 0, sizeof(wifi_config_t));
535 
536 	memcpy(wifi_config.sta.ssid, params->ssid, params->ssid_length);
537 	wifi_config.sta.ssid[params->ssid_length] = '\0';
538 	switch (params->security) {
539 	case WIFI_SECURITY_TYPE_NONE:
540 		wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN;
541 		data->status.security = WIFI_AUTH_OPEN;
542 		wifi_config.sta.pmf_cfg.required = false;
543 		break;
544 	case WIFI_SECURITY_TYPE_PSK:
545 		memcpy(wifi_config.sta.password, params->psk, params->psk_length);
546 		wifi_config.sta.password[params->psk_length] = '\0';
547 		wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
548 		wifi_config.sta.pmf_cfg.required = false;
549 		data->status.security = WIFI_AUTH_WPA2_PSK;
550 		break;
551 	case WIFI_SECURITY_TYPE_SAE:
552 #if defined(CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE)
553 		if (params->sae_password) {
554 			memcpy(wifi_config.sta.password, params->sae_password,
555 			       params->sae_password_length);
556 			wifi_config.sta.password[params->sae_password_length] = '\0';
557 		} else {
558 			memcpy(wifi_config.sta.password, params->psk, params->psk_length);
559 			wifi_config.sta.password[params->psk_length] = '\0';
560 		}
561 		data->status.security = WIFI_AUTH_WPA3_PSK;
562 		wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA3_PSK;
563 		wifi_config.sta.sae_pwe_h2e = WPA3_SAE_PWE_BOTH;
564 		break;
565 #else
566 		LOG_ERR("WPA3 not supported for STA mode. Enable "
567 			"CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE");
568 		return -EINVAL;
569 #endif /* CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE */
570 	default:
571 		LOG_ERR("Authentication method not supported");
572 		return -EIO;
573 	}
574 
575 #if defined(CONFIG_ESP32_WIFI_STA_SCAN_ALL)
576 	wifi_config.sta.scan_method = WIFI_ALL_CHANNEL_SCAN;
577 	wifi_config.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL;
578 #endif
579 
580 	if (params->channel == WIFI_CHANNEL_ANY) {
581 		wifi_config.sta.channel = 0U;
582 		data->status.channel = 0U;
583 	} else {
584 		wifi_config.sta.channel = params->channel;
585 		data->status.channel = params->channel;
586 	}
587 
588 	ret = esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
589 	if (ret) {
590 		LOG_ERR("Failed to set Wi-Fi configuration (%d)", ret);
591 		return -EINVAL;
592 	}
593 
594 	ret = esp_wifi_connect();
595 	if (ret) {
596 		LOG_ERR("Failed to connect to Wi-Fi access point (%d)", ret);
597 		return -EAGAIN;
598 	}
599 
600 	return 0;
601 }
602 
esp32_wifi_scan(const struct device * dev,struct wifi_scan_params * params,scan_result_cb_t cb)603 static int esp32_wifi_scan(const struct device *dev, struct wifi_scan_params *params,
604 			   scan_result_cb_t cb)
605 {
606 	struct esp32_wifi_runtime *data = dev->data;
607 	int ret = 0;
608 
609 	if (data->scan_cb != NULL) {
610 		LOG_INF("Scan callback in progress");
611 		return -EINPROGRESS;
612 	}
613 
614 	data->scan_cb = cb;
615 
616 	wifi_scan_config_t scan_config = { 0 };
617 
618 	if (params) {
619 		/* The enum values are same, so, no conversion needed */
620 		scan_config.scan_type = params->scan_type;
621 	}
622 
623 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
624 	wifi_mode_t mode;
625 
626 	esp_wifi_get_mode(&mode);
627 	if (mode == ESP32_WIFI_MODE_AP || mode == ESP32_WIFI_MODE_APSTA) {
628 		ret = esp_wifi_set_mode(ESP32_WIFI_MODE_APSTA);
629 	} else {
630 		ret = esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
631 	}
632 #else
633 	ret = esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
634 #endif
635 
636 	if (ret) {
637 		LOG_ERR("Failed to set Wi-Fi mode (%d)", ret);
638 		return -EINVAL;
639 	}
640 
641 	ret = esp_wifi_start();
642 	if (ret) {
643 		LOG_ERR("Failed to start Wi-Fi driver (%d)", ret);
644 		return -EAGAIN;
645 	}
646 
647 	ret = esp_wifi_scan_start(&scan_config, false);
648 	if (ret != ESP_OK) {
649 		LOG_ERR("Failed to start Wi-Fi scanning");
650 		return -EAGAIN;
651 	}
652 
653 	return 0;
654 };
655 
esp32_wifi_ap_enable(const struct device * dev,struct wifi_connect_req_params * params)656 static int esp32_wifi_ap_enable(const struct device *dev,
657 			 struct wifi_connect_req_params *params)
658 {
659 	struct esp32_wifi_runtime *data = dev->data;
660 	esp_err_t err = 0;
661 
662 	/* Build Wi-Fi configuration for AP mode */
663 	wifi_config_t wifi_config = {
664 		.ap = {
665 			.max_connection = 5,
666 			.channel = params->channel == WIFI_CHANNEL_ANY ?
667 				0 : params->channel,
668 		},
669 	};
670 
671 	memcpy(data->status.ssid, params->ssid, params->ssid_length);
672 	data->status.ssid[params->ssid_length] = '\0';
673 
674 	strncpy((char *) wifi_config.ap.ssid, params->ssid, params->ssid_length);
675 	wifi_config.ap.ssid_len = params->ssid_length;
676 
677 	switch (params->security) {
678 	case WIFI_SECURITY_TYPE_NONE:
679 		memset(wifi_config.ap.password, 0, sizeof(wifi_config.ap.password));
680 		wifi_config.ap.authmode = WIFI_AUTH_OPEN;
681 		data->status.security = WIFI_AUTH_OPEN;
682 		wifi_config.ap.pmf_cfg.required = false;
683 		break;
684 	case WIFI_SECURITY_TYPE_PSK:
685 		strncpy((char *) wifi_config.ap.password, params->psk, params->psk_length);
686 		wifi_config.ap.authmode = WIFI_AUTH_WPA2_PSK;
687 		data->status.security = WIFI_AUTH_WPA2_PSK;
688 		wifi_config.ap.pmf_cfg.required = false;
689 		break;
690 	default:
691 		LOG_ERR("Authentication method not supported");
692 		return -EINVAL;
693 	}
694 
695 	/* Start Wi-Fi in AP mode with configuration built above */
696 	wifi_mode_t mode;
697 
698 	err = esp_wifi_get_mode(&mode);
699 	if (IS_ENABLED(CONFIG_ESP32_WIFI_AP_STA_MODE) &&
700 	    (mode == ESP32_WIFI_MODE_STA || mode == ESP32_WIFI_MODE_APSTA)) {
701 		err |= esp_wifi_set_mode(ESP32_WIFI_MODE_APSTA);
702 	} else {
703 		err |= esp_wifi_set_mode(ESP32_WIFI_MODE_AP);
704 	}
705 	if (err) {
706 		LOG_ERR("Failed to set Wi-Fi mode (%d)", err);
707 		return -EINVAL;
708 	}
709 
710 	err = esp_wifi_set_config(WIFI_IF_AP, &wifi_config);
711 	if (err) {
712 		LOG_ERR("Failed to set Wi-Fi configuration (%d)", err);
713 		return -EINVAL;
714 	}
715 
716 	err = esp_wifi_start();
717 	if (err) {
718 		LOG_ERR("Failed to enable Wi-Fi AP mode");
719 		return -EAGAIN;
720 	}
721 
722 	return 0;
723 };
724 
esp32_wifi_ap_disable(const struct device * dev)725 static int esp32_wifi_ap_disable(const struct device *dev)
726 {
727 	int err = 0;
728 	wifi_mode_t mode;
729 
730 	esp_wifi_get_mode(&mode);
731 	if (mode == ESP32_WIFI_MODE_APSTA) {
732 		err = esp_wifi_set_mode(ESP32_WIFI_MODE_STA);
733 		err |= esp_wifi_start();
734 	} else {
735 		err = esp_wifi_stop();
736 	}
737 	if (err) {
738 		LOG_ERR("Failed to disable Wi-Fi AP mode: (%d)", err);
739 		return -EAGAIN;
740 	}
741 
742 	return 0;
743 };
744 
esp32_wifi_status(const struct device * dev,struct wifi_iface_status * status)745 static int esp32_wifi_status(const struct device *dev, struct wifi_iface_status *status)
746 {
747 	struct esp32_wifi_runtime *data = dev->data;
748 	wifi_mode_t mode;
749 	wifi_config_t conf;
750 	wifi_ap_record_t ap_info;
751 
752 	switch (data->state) {
753 	case ESP32_STA_STOPPED:
754 	case ESP32_AP_STOPPED:
755 		status->state = WIFI_STATE_INACTIVE;
756 		break;
757 	case ESP32_STA_STARTED:
758 	case ESP32_AP_DISCONNECTED:
759 		status->state = WIFI_STATE_DISCONNECTED;
760 		break;
761 	case ESP32_STA_CONNECTING:
762 		status->state = WIFI_STATE_SCANNING;
763 		break;
764 	case ESP32_STA_CONNECTED:
765 	case ESP32_AP_CONNECTED:
766 		status->state = WIFI_STATE_COMPLETED;
767 		break;
768 	default:
769 		break;
770 	}
771 
772 	strncpy(status->ssid, data->status.ssid, WIFI_SSID_MAX_LEN);
773 	status->ssid_len = strnlen(data->status.ssid, WIFI_SSID_MAX_LEN);
774 	status->ssid[status->ssid_len] = '\0';
775 	status->band = WIFI_FREQ_BAND_2_4_GHZ;
776 	status->link_mode = WIFI_LINK_MODE_UNKNOWN;
777 	status->mfp = WIFI_MFP_DISABLE;
778 
779 	if (esp_wifi_get_mode(&mode) == ESP_OK) {
780 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
781 		if (mode == ESP32_WIFI_MODE_APSTA && data == &esp32_data) {
782 			mode = ESP32_WIFI_MODE_STA;
783 		} else if (mode == ESP32_WIFI_MODE_APSTA && data == &esp32_ap_sta_data) {
784 			mode = ESP32_WIFI_MODE_AP;
785 		}
786 #endif
787 		if (mode == ESP32_WIFI_MODE_STA) {
788 			wifi_phy_mode_t phy_mode;
789 			esp_err_t err;
790 
791 			esp_wifi_get_config(ESP_IF_WIFI_STA, &conf);
792 			esp_wifi_sta_get_ap_info(&ap_info);
793 
794 			status->iface_mode = WIFI_MODE_INFRA;
795 			status->channel = ap_info.primary;
796 			status->rssi = ap_info.rssi;
797 			memcpy(status->bssid, ap_info.bssid, WIFI_MAC_ADDR_LEN);
798 
799 			err = esp_wifi_sta_get_negotiated_phymode(&phy_mode);
800 			if (err == ESP_OK) {
801 				if (phy_mode == WIFI_PHY_MODE_11B) {
802 					status->link_mode = WIFI_1;
803 				} else if (phy_mode == WIFI_PHY_MODE_11G) {
804 					status->link_mode = WIFI_3;
805 				} else if ((phy_mode == WIFI_PHY_MODE_HT20) ||
806 					   (phy_mode == WIFI_PHY_MODE_HT40)) {
807 					status->link_mode = WIFI_4;
808 				} else if (phy_mode == WIFI_PHY_MODE_HE20) {
809 					status->link_mode = WIFI_6;
810 				}
811 			}
812 
813 			status->beacon_interval = conf.sta.listen_interval;
814 		} else if (mode == ESP32_WIFI_MODE_AP) {
815 			esp_wifi_get_config(ESP_IF_WIFI_AP, &conf);
816 			status->iface_mode = WIFI_MODE_AP;
817 			status->link_mode = WIFI_LINK_MODE_UNKNOWN;
818 			status->channel = conf.ap.channel;
819 			status->beacon_interval = conf.ap.beacon_interval;
820 
821 		} else {
822 			status->iface_mode = WIFI_MODE_UNKNOWN;
823 			status->link_mode = WIFI_LINK_MODE_UNKNOWN;
824 			status->channel = 0;
825 		}
826 	}
827 
828 	switch (data->status.security) {
829 	case WIFI_AUTH_OPEN:
830 		status->security = WIFI_SECURITY_TYPE_NONE;
831 		break;
832 	case WIFI_AUTH_WPA2_PSK:
833 		status->security = WIFI_SECURITY_TYPE_PSK;
834 		break;
835 	case WIFI_AUTH_WPA3_PSK:
836 		status->security = WIFI_SECURITY_TYPE_SAE;
837 		break;
838 	default:
839 		status->security = WIFI_SECURITY_TYPE_UNKNOWN;
840 	}
841 
842 	return 0;
843 }
844 
esp32_wifi_init(struct net_if * iface)845 static void esp32_wifi_init(struct net_if *iface)
846 {
847 	const struct device *dev = net_if_get_device(iface);
848 	struct esp32_wifi_runtime *dev_data = dev->data;
849 	struct ethernet_context *eth_ctx = net_if_l2_data(iface);
850 
851 	eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI;
852 
853 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
854 	struct wifi_nm_instance *nm = wifi_nm_get_instance("esp32_wifi_nm");
855 
856 	esp32_wifi_iface = iface;
857 	dev_data->state = ESP32_STA_STOPPED;
858 
859 	/* Start interface when we are actually connected with Wi-Fi network */
860 	esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_STA);
861 	esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, eth_esp32_rx);
862 	wifi_nm_register_mgd_type_iface(nm, WIFI_TYPE_STA, esp32_wifi_iface);
863 
864 #else
865 
866 	esp32_wifi_iface = iface;
867 	dev_data->state = ESP32_STA_STOPPED;
868 
869 	/* Start interface when we are actually connected with Wi-Fi network */
870 	esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_STA);
871 	esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, eth_esp32_rx);
872 
873 #endif
874 
875 	/* Assign link local address. */
876 	net_if_set_link_addr(iface, dev_data->mac_addr, 6, NET_LINK_ETHERNET);
877 
878 	ethernet_init(iface);
879 	net_if_carrier_off(iface);
880 }
881 
882 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
esp32_wifi_init_ap(struct net_if * iface)883 static void esp32_wifi_init_ap(struct net_if *iface)
884 {
885 	const struct device *dev = net_if_get_device(iface);
886 	struct esp32_wifi_runtime *dev_data = dev->data;
887 	struct ethernet_context *eth_ctx = net_if_l2_data(iface);
888 
889 	eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI;
890 
891 	struct wifi_nm_instance *nm = wifi_nm_get_instance("esp32_wifi_nm");
892 
893 	esp32_wifi_iface_ap = iface;
894 	dev_data->state = ESP32_AP_STOPPED;
895 
896 	esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_SOFTAP);
897 	wifi_nm_register_mgd_type_iface(nm, WIFI_TYPE_SAP, esp32_wifi_iface_ap);
898 
899 	/* Assign link local address. */
900 	net_if_set_link_addr(iface, dev_data->mac_addr, 6, NET_LINK_ETHERNET);
901 
902 	ethernet_init(iface);
903 	net_if_carrier_off(iface);
904 }
905 #endif
906 
907 #if defined(CONFIG_NET_STATISTICS_WIFI)
esp32_wifi_stats(const struct device * dev,struct net_stats_wifi * stats)908 static int esp32_wifi_stats(const struct device *dev, struct net_stats_wifi *stats)
909 {
910 	struct esp32_wifi_runtime *data = dev->data;
911 
912 	stats->bytes.received = data->stats.bytes.received;
913 	stats->bytes.sent = data->stats.bytes.sent;
914 	stats->pkts.rx = data->stats.pkts.rx;
915 	stats->pkts.tx = data->stats.pkts.tx;
916 	stats->errors.rx = data->stats.errors.rx;
917 	stats->errors.tx = data->stats.errors.tx;
918 	stats->broadcast.rx = data->stats.broadcast.rx;
919 	stats->broadcast.tx = data->stats.broadcast.tx;
920 	stats->multicast.rx = data->stats.multicast.rx;
921 	stats->multicast.tx = data->stats.multicast.tx;
922 	stats->sta_mgmt.beacons_rx = data->stats.sta_mgmt.beacons_rx;
923 	stats->sta_mgmt.beacons_miss = data->stats.sta_mgmt.beacons_miss;
924 
925 	return 0;
926 }
927 #endif
928 
esp32_wifi_dev_init(const struct device * dev)929 static int esp32_wifi_dev_init(const struct device *dev)
930 {
931 #if CONFIG_SOC_SERIES_ESP32S2 || CONFIG_SOC_SERIES_ESP32C3
932 	adc2_init_code_calibration();
933 #endif /* CONFIG_SOC_SERIES_ESP32S2 || CONFIG_SOC_SERIES_ESP32C3 */
934 
935 	wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
936 	esp_err_t ret = esp_wifi_init(&config);
937 	esp_wifi_set_mode(ESP32_WIFI_MODE_NULL);
938 
939 	if (ret == ESP_ERR_NO_MEM) {
940 		LOG_ERR("Not enough memory to initialize Wi-Fi.");
941 		LOG_ERR("Consider increasing CONFIG_HEAP_MEM_POOL_SIZE value.");
942 		return -ENOMEM;
943 	} else if (ret != ESP_OK) {
944 		LOG_ERR("Unable to initialize the Wi-Fi: %d", ret);
945 		return -EIO;
946 	}
947 	if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_AUTO_DHCPV4)) {
948 		net_mgmt_init_event_callback(&esp32_dhcp_cb, wifi_event_handler, DHCPV4_MASK);
949 		net_mgmt_add_event_callback(&esp32_dhcp_cb);
950 	}
951 
952 	return 0;
953 }
954 
955 static const struct wifi_mgmt_ops esp32_wifi_mgmt = {
956 	.scan		   = esp32_wifi_scan,
957 	.connect	   = esp32_wifi_connect,
958 	.disconnect	   = esp32_wifi_disconnect,
959 	.ap_enable	   = esp32_wifi_ap_enable,
960 	.ap_disable	   = esp32_wifi_ap_disable,
961 	.iface_status	   = esp32_wifi_status,
962 #if defined(CONFIG_NET_STATISTICS_WIFI)
963 	.get_stats	   = esp32_wifi_stats,
964 #endif
965 };
966 
967 static const struct net_wifi_mgmt_offload esp32_api = {
968 	.wifi_iface.iface_api.init	  = esp32_wifi_init,
969 	.wifi_iface.send = esp32_wifi_send,
970 	.wifi_mgmt_api = &esp32_wifi_mgmt,
971 };
972 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
973 static const struct net_wifi_mgmt_offload esp32_api_ap = {
974 	.wifi_iface.iface_api.init = esp32_wifi_init_ap,
975 	.wifi_iface.send = esp32_wifi_send,
976 	.wifi_mgmt_api = &esp32_wifi_mgmt,
977 };
978 #endif
979 
980 NET_DEVICE_DT_INST_DEFINE(0,
981 		esp32_wifi_dev_init, NULL,
982 		&esp32_data, NULL, CONFIG_WIFI_INIT_PRIORITY,
983 		&esp32_api, ETHERNET_L2,
984 		NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU);
985 
986 #if defined(CONFIG_ESP32_WIFI_AP_STA_MODE)
987 NET_DEVICE_DT_INST_DEFINE(1,
988 		NULL, NULL,
989 		&esp32_ap_sta_data, NULL, CONFIG_WIFI_INIT_PRIORITY,
990 		&esp32_api_ap, ETHERNET_L2,
991 		NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU);
992 
993 DEFINE_WIFI_NM_INSTANCE(esp32_wifi_nm, &esp32_wifi_mgmt);
994 
995 CONNECTIVITY_WIFI_MGMT_BIND(Z_DEVICE_DT_DEV_ID(DT_DRV_INST(0)));
996 #endif
997