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