esp32_wifi_driver.c
Go to the documentation of this file.
1 /**
2  * @file esp32_wifi_driver.c
3  * @brief ESP32 Wi-Fi controller
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "esp_private/wifi.h"
36 #include "core/net.h"
38 #include "debug.h"
39 
40 //Underlying network interface
41 static NetInterface *esp32WifiStaInterface = NULL;
42 static NetInterface *esp32WifiApInterface = NULL;
43 
44 //Forward declaration of functions
45 esp_err_t esp32WifiStaRxCallback(void *buffer, uint16_t length, void *eb);
46 esp_err_t esp32WifiApRxCallback(void *buffer, uint16_t length, void *eb);
47 
48 void esp32WifiStaStartEvent(void *arg, esp_event_base_t eventBase,
49  int32_t eventId, void *eventData);
50 
51 void esp32WifiStaStopEvent(void *arg, esp_event_base_t eventBase,
52  int32_t eventId, void *eventData);
53 
54 void esp32WifiStaConnectedEvent(void *arg, esp_event_base_t eventBase,
55  int32_t eventId, void *eventData);
56 
57 void esp32WifiStaDisconnectedEvent(void *arg, esp_event_base_t eventBase,
58  int32_t eventId, void *eventData);
59 
60 void esp32WifiApStartEvent(void *arg, esp_event_base_t eventBase,
61  int32_t eventId, void *eventData);
62 
63 void esp32WifiApStopEvent(void *arg, esp_event_base_t eventBase,
64  int32_t eventId, void *eventData);
65 
66 
67 /**
68  * @brief ESP32 Wi-Fi driver (STA mode)
69  **/
70 
72 {
74  ETH_MTU,
82  NULL,
83  NULL,
84  NULL,
85  TRUE,
86  TRUE,
87  TRUE,
88  TRUE
89 };
90 
91 
92 /**
93  * @brief ESP32 Wi-Fi driver (AP mode)
94  **/
95 
97 {
99  ETH_MTU,
107  NULL,
108  NULL,
109  NULL,
110  TRUE,
111  TRUE,
112  TRUE,
113  TRUE
114 };
115 
116 
117 /**
118  * @brief ESP32_WIFI initialization
119  * @param[in] interface Underlying network interface
120  * @return Error code
121  **/
122 
124 {
125  esp_err_t ret;
126 
127  //Initialize status code
128  ret = ESP_OK;
129 
130  //STA or AP mode?
131  if(interface->nicDriver == &esp32WifiStaDriver)
132  {
133  //Debug message
134  TRACE_INFO("Initializing ESP32 Wi-Fi (STA mode)...\r\n");
135  }
136  else
137  {
138  //Debug message
139  TRACE_INFO("Initializing ESP32 Wi-Fi (AP mode)...\r\n");
140  }
141 
142  //Initialization sequence is performed once at startup
143  if(esp32WifiStaInterface == NULL && esp32WifiApInterface == NULL)
144  {
145  //Set default configuration
146  wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
147 
148  //Initialize Wi-Fi driver
149  ret = esp_wifi_init(&config);
150  }
151 
152  //Check status code
153  if(ret == ESP_OK)
154  {
155  //STA or AP mode?
156  if(interface->nicDriver == &esp32WifiStaDriver)
157  {
158  //Save underlying network interface (STA mode)
159  esp32WifiStaInterface = interface;
160 
161  //Register event handlers
162  esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_START,
163  esp32WifiStaStartEvent, NULL);
164 
165  esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_STOP,
166  esp32WifiStaStopEvent, NULL);
167 
168  esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED,
170 
171  esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED,
173 
174  //Optionally set the MAC address
175  if(macCompAddr(&interface->macAddr, &MAC_UNSPECIFIED_ADDR))
176  {
177  //Use the factory preprogrammed station address
178  ret = esp_wifi_get_mac(ESP_IF_WIFI_STA, interface->macAddr.b);
179 
180  //Check status code
181  if(ret == ESP_OK)
182  {
183  //Generate the 64-bit interface identifier
184  macAddrToEui64(&interface->macAddr, &interface->eui64);
185  }
186  }
187  else
188  {
189  //Override the factory preprogrammed address
190  ret = esp_wifi_set_mac(ESP_IF_WIFI_STA, interface->macAddr.b);
191  }
192  }
193  else
194  {
195  //Save underlying network interface (AP mode)
196  esp32WifiApInterface = interface;
197 
198  //Register event handlers
199  esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_START,
200  esp32WifiApStartEvent, NULL);
201 
202  esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_STOP,
203  esp32WifiApStopEvent, NULL);
204 
205  //Optionally set the MAC address
206  if(macCompAddr(&interface->macAddr, &MAC_UNSPECIFIED_ADDR))
207  {
208  //Use the factory preprogrammed station address
209  ret = esp_wifi_get_mac(ESP_IF_WIFI_AP, interface->macAddr.b);
210 
211  //Check status code
212  if(ret == ESP_OK)
213  {
214  //Generate the 64-bit interface identifier
215  macAddrToEui64(&interface->macAddr, &interface->eui64);
216  }
217  }
218  else
219  {
220  //Override the factory preprogrammed address
221  ret = esp_wifi_set_mac(ESP_IF_WIFI_AP, interface->macAddr.b);
222  }
223  }
224  }
225 
226  //ESP32 Wi-Fi is now ready to send
227  osSetEvent(&interface->nicTxEvent);
228 
229  //Return status code
230  if(ret == ESP_OK)
231  {
232  return NO_ERROR;
233  }
234  else
235  {
236  return ERROR_FAILURE;
237  }
238 }
239 
240 
241 /**
242  * @brief ESP32 Wi-Fi timer handler
243  *
244  * This routine is periodically called by the TCP/IP stack to handle periodic
245  * operations such as polling the link state
246  *
247  * @param[in] interface Underlying network interface
248  **/
249 
250 void esp32WifiTick(NetInterface *interface)
251 {
252 }
253 
254 
255 /**
256  * @brief Enable interrupts
257  * @param[in] interface Underlying network interface
258  **/
259 
261 {
262 }
263 
264 
265 /**
266  * @brief Disable interrupts
267  * @param[in] interface Underlying network interface
268  **/
269 
271 {
272 }
273 
274 
275 /**
276  * @brief ESP32 Wi-Fi event handler
277  * @param[in] interface Underlying network interface
278  **/
279 
281 {
282 }
283 
284 
285 /**
286  * @brief Send a packet
287  * @param[in] interface Underlying network interface
288  * @param[in] buffer Multi-part buffer containing the data to send
289  * @param[in] offset Offset to the first data byte
290  * @param[in] ancillary Additional options passed to the stack along with
291  * the packet
292  * @return Error code
293  **/
294 
296  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
297 {
298  static uint8_t temp[2048];
299  size_t length;
300  int_t ret;
301 
302  //Retrieve the length of the packet
303  length = netBufferGetLength(buffer) - offset;
304 
305  //Copy user data
306  netBufferRead(temp, buffer, offset, length);
307 
308  //STA or AP mode?
309  if(interface == esp32WifiStaInterface)
310  {
311  //Send packet
312  ret = esp_wifi_internal_tx(ESP_IF_WIFI_STA, temp, length);
313  }
314  else
315  {
316  //Send packet
317  ret = esp_wifi_internal_tx(ESP_IF_WIFI_AP, temp, length);
318  }
319 
320  //The transmitter can accept another packet
321  osSetEvent(&interface->nicTxEvent);
322 
323  //Return status code
324  if(ret == ESP_OK)
325  {
326  return NO_ERROR;
327  }
328  else
329  {
330  return ERROR_FAILURE;
331  }
332 }
333 
334 
335 /**
336  * @brief Configure MAC address filtering
337  * @param[in] interface Underlying network interface
338  * @return Error code
339  **/
340 
342 {
343  //Not implemented
344  return NO_ERROR;
345 }
346 
347 
348 /**
349  * @brief Process incoming packets (STA interface)
350  * @param[in] buffer Incoming packet
351  * @param[in] length Length of the packet, in bytes
352  * @param[in] eb Pointer to the buffer allocated by the Wi-Fi driver
353  * @return Error code
354  **/
355 
356 esp_err_t esp32WifiStaRxCallback(void *buffer, uint16_t length, void *eb)
357 {
358  NetRxAncillary ancillary;
359 
360  //Valid STA interface?
361  if(esp32WifiStaInterface != NULL)
362  {
363  //Get exclusive access
365 
366  //Additional options can be passed to the stack along with the packet
367  ancillary = NET_DEFAULT_RX_ANCILLARY;
368 
369  //Pass the packet to the upper layer
370  nicProcessPacket(esp32WifiStaInterface, buffer, length, &ancillary);
371 
372  //Release exclusive access
374  }
375 
376  //Valid buffer?
377  if(eb != NULL)
378  {
379  //Release buffer
380  esp_wifi_internal_free_rx_buffer(eb);
381  }
382 
383  //Successful processing
384  return ESP_OK;
385 }
386 
387 
388 /**
389  * @brief Process incoming packets (AP interface)
390  * @param[in] buffer Incoming packet
391  * @param[in] length Length of the packet, in bytes
392  * @param[in] eb Pointer to the buffer allocated by the Wi-Fi driver
393  * @return Error code
394  **/
395 
396 esp_err_t esp32WifiApRxCallback(void *buffer, uint16_t length, void *eb)
397 {
398  NetRxAncillary ancillary;
399 
400  //Valid AP interface?
401  if(esp32WifiApInterface != NULL)
402  {
403  //Get exclusive access
405 
406  //Additional options can be passed to the stack along with the packet
407  ancillary = NET_DEFAULT_RX_ANCILLARY;
408 
409  //Pass the packet to the upper layer
410  nicProcessPacket(esp32WifiApInterface, buffer, length, &ancillary);
411 
412  //Release exclusive access
414  }
415 
416  //Valid buffer?
417  if(eb != NULL)
418  {
419  //Release buffer
420  esp_wifi_internal_free_rx_buffer(eb);
421  }
422 
423  //Successful processing
424  return ESP_OK;
425 }
426 
427 
428 /**
429  * @brief Station start (event handler)
430  * @param[in] arg User-specific parameter
431  * @param[in] eventBase Event base
432  * @param[in] eventId Event identifier
433  * @param[in] eventData Event-specific data
434  **/
435 
436 void esp32WifiStaStartEvent(void *arg, esp_event_base_t eventBase,
437  int32_t eventId, void *eventData)
438 {
439  //Debug message
440  TRACE_INFO("ESP32: STA start event\r\n");
441 }
442 
443 
444 /**
445  * @brief Station stop (event handler)
446  * @param[in] arg User-specific parameter
447  * @param[in] eventBase Event base
448  * @param[in] eventId Event identifier
449  * @param[in] eventData Event-specific data
450  **/
451 
452 void esp32WifiStaStopEvent(void *arg, esp_event_base_t eventBase,
453  int32_t eventId, void *eventData)
454 {
455  //Debug message
456  TRACE_INFO("ESP32: STA stop event\r\n");
457 }
458 
459 
460 /**
461  * @brief Station connected to AP (event handler)
462  * @param[in] arg User-specific parameter
463  * @param[in] eventBase Event base
464  * @param[in] eventId Event identifier
465  * @param[in] eventData Event-specific data
466  **/
467 
468 void esp32WifiStaConnectedEvent(void *arg, esp_event_base_t eventBase,
469  int32_t eventId, void *eventData)
470 {
471  esp_err_t ret;
472 
473  //Debug message
474  TRACE_INFO("ESP32: STA connected event\r\n");
475 
476  //Register RX callback
477  ret = esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, esp32WifiStaRxCallback);
478 
479  //Check status code
480  if(ret == ESP_OK)
481  {
482  //Valid STA interface?
483  if(esp32WifiStaInterface != NULL)
484  {
485  //The link is up
486  esp32WifiStaInterface->linkState = TRUE;
487 
488  //Get exclusive access
490  //Process link state change event
491  nicNotifyLinkChange(esp32WifiStaInterface);
492  //Release exclusive access
494  }
495  }
496 }
497 
498 
499 /**
500  * @brief Station disconnected from AP (event handler)
501  * @param[in] arg User-specific parameter
502  * @param[in] eventBase Event base
503  * @param[in] eventId Event identifier
504  * @param[in] eventData Event-specific data
505  **/
506 
507 void esp32WifiStaDisconnectedEvent(void *arg, esp_event_base_t eventBase,
508  int32_t eventId, void *eventData)
509 {
510  esp_err_t ret;
511 
512  //Debug message
513  TRACE_INFO("ESP32: STA disconnected event\r\n");
514 
515  //Unregister RX callback
516  ret = esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, NULL);
517 
518  //Check status code
519  if(ret == ESP_OK)
520  {
521  //Valid STA interface?
522  if(esp32WifiStaInterface != NULL)
523  {
524  //The link is down
525  esp32WifiStaInterface->linkState = FALSE;
526 
527  //Get exclusive access
529  //Process link state change event
530  nicNotifyLinkChange(esp32WifiStaInterface);
531  //Release exclusive access
533  }
534  }
535 }
536 
537 
538 /**
539  * @brief Soft-AP start (event handler)
540  * @param[in] arg User-specific parameter
541  * @param[in] eventBase Event base
542  * @param[in] eventId Event identifier
543  * @param[in] eventData Event-specific data
544  **/
545 
546 void esp32WifiApStartEvent(void *arg, esp_event_base_t eventBase,
547  int32_t eventId, void *eventData)
548 {
549  esp_err_t ret;
550 
551  //Debug message
552  TRACE_INFO("ESP32: AP start event\r\n");
553 
554  //Register RX callback
555  ret = esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, esp32WifiApRxCallback);
556 
557  //Check status code
558  if(ret == ESP_OK)
559  {
560  //Valid AP interface?
561  if(esp32WifiApInterface != NULL)
562  {
563  //The link is up
564  esp32WifiApInterface->linkState = TRUE;
565 
566  //Get exclusive access
568  //Process link state change event
569  nicNotifyLinkChange(esp32WifiApInterface);
570  //Release exclusive access
572  }
573  }
574 }
575 
576 
577 /**
578  * @brief Soft-AP stop (event handler)
579  * @param[in] arg User-specific parameter
580  * @param[in] eventBase Event base
581  * @param[in] eventId Event identifier
582  * @param[in] eventData Event-specific data
583  **/
584 
585 void esp32WifiApStopEvent(void *arg, esp_event_base_t eventBase,
586  int32_t eventId, void *eventData)
587 {
588  esp_err_t ret;
589 
590  //Debug message
591  TRACE_INFO("ESP32: AP stop event\r\n");
592 
593  //Unregister RX callback
594  ret = esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, NULL);
595 
596  //Check status code
597  if(ret == ESP_OK)
598  {
599  //Valid AP interface?
600  if(esp32WifiApInterface != NULL)
601  {
602  //The link is down
603  esp32WifiApInterface->linkState = FALSE;
604 
605  //Get exclusive access
607  //Process link state change event
608  nicNotifyLinkChange(esp32WifiApInterface);
609  //Release exclusive access
611  }
612  }
613 }
signed int int_t
Definition: compiler_port.h:49
Debugging facilities.
#define TRACE_INFO(...)
Definition: debug.h:95
error_t
Error codes.
Definition: error.h:43
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
void esp32WifiEventHandler(NetInterface *interface)
ESP32 Wi-Fi event handler.
const NicDriver esp32WifiStaDriver
ESP32 Wi-Fi driver (STA mode)
void esp32WifiStaDisconnectedEvent(void *arg, esp_event_base_t eventBase, int32_t eventId, void *eventData)
Station disconnected from AP (event handler)
void esp32WifiStaConnectedEvent(void *arg, esp_event_base_t eventBase, int32_t eventId, void *eventData)
Station connected to AP (event handler)
void esp32WifiTick(NetInterface *interface)
ESP32 Wi-Fi timer handler.
error_t esp32WifiUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
void esp32WifiApStartEvent(void *arg, esp_event_base_t eventBase, int32_t eventId, void *eventData)
Soft-AP start (event handler)
esp_err_t esp32WifiApRxCallback(void *buffer, uint16_t length, void *eb)
Process incoming packets (AP interface)
esp_err_t esp32WifiStaRxCallback(void *buffer, uint16_t length, void *eb)
Process incoming packets (STA interface)
void esp32WifiApStopEvent(void *arg, esp_event_base_t eventBase, int32_t eventId, void *eventData)
Soft-AP stop (event handler)
void esp32WifiStaStopEvent(void *arg, esp_event_base_t eventBase, int32_t eventId, void *eventData)
Station stop (event handler)
error_t esp32WifiInit(NetInterface *interface)
ESP32_WIFI initialization.
const NicDriver esp32WifiApDriver
ESP32 Wi-Fi driver (AP mode)
void esp32WifiEnableIrq(NetInterface *interface)
Enable interrupts.
void esp32WifiStaStartEvent(void *arg, esp_event_base_t eventBase, int32_t eventId, void *eventData)
Station start (event handler)
void esp32WifiDisableIrq(NetInterface *interface)
Disable interrupts.
error_t esp32WifiSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
ESP32 Wi-Fi controller.
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:53
void macAddrToEui64(const MacAddr *macAddr, Eui64 *interfaceId)
Map a MAC address to the IPv6 modified EUI-64 identifier.
Definition: ethernet.c:944
#define ETH_MTU
Definition: ethernet.h:116
#define macCompAddr(macAddr1, macAddr2)
Definition: ethernet.h:130
TCP/IP stack core.
#define NetInterface
Definition: net.h:36
#define netMutex
Definition: net_legacy.h:195
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
Definition: net_mem.c:674
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:101
#define NetRxAncillary
Definition: net_misc.h:40
#define NetTxAncillary
Definition: net_misc.h:36
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:391
void nicNotifyLinkChange(NetInterface *interface)
Process link state change notification.
Definition: nic.c:548
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
NIC driver.
Definition: nic.h:283
uint8_t length
Definition: tcp.h:368