esp8266_driver.c
Go to the documentation of this file.
1 /**
2  * @file esp8266_driver.c
3  * @brief ESP8266 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.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "espressif/esp_wifi.h"
36 #include "espressif/esp_system.h"
37 #include "lwip/pbuf.h"
38 #include "core/net.h"
40 #include "debug.h"
41 
42 //Underlying network interface
43 static NetInterface *esp8266WifiStaInterface = NULL;
44 static NetInterface *esp8266WifiApInterface = NULL;
45 
46 
47 /**
48  * @brief ESP8266 Wi-Fi driver (STA mode)
49  **/
50 
52 {
54  ETH_MTU,
62  NULL,
63  NULL,
64  NULL,
65  TRUE,
66  TRUE,
67  TRUE,
68  TRUE
69 };
70 
71 
72 /**
73  * @brief ESP8266 Wi-Fi driver (AP mode)
74  **/
75 
77 {
79  ETH_MTU,
87  NULL,
88  NULL,
89  NULL,
90  TRUE,
91  TRUE,
92  TRUE,
93  TRUE
94 };
95 
96 
97 /**
98  * @brief ESP8266_WIFI initialization
99  * @param[in] interface Underlying network interface
100  * @return Error code
101  **/
102 
104 {
105  bool_t ret;
106 
107  //STA or AP mode?
108  if(interface->nicDriver == &esp8266WifiStaDriver)
109  {
110  //Debug message
111  TRACE_INFO("Initializing ESP8266 Wi-Fi (STA mode)...\r\n");
112 
113  //Save underlying network interface (STA mode)
114  esp8266WifiStaInterface = interface;
115 
116  //Optionally set the MAC address
117  if(macCompAddr(&interface->macAddr, &MAC_UNSPECIFIED_ADDR))
118  {
119  //Use the factory preprogrammed station address
120  ret = sdk_wifi_get_macaddr(STATION_IF, interface->macAddr.b);
121 
122  //Check status code
123  if(ret)
124  {
125  //Generate the 64-bit interface identifier
126  macAddrToEui64(&interface->macAddr, &interface->eui64);
127  }
128  }
129  else
130  {
131  //Override the factory preprogrammed address
132  ret = sdk_wifi_set_macaddr(STATION_IF, interface->macAddr.b);
133  }
134  }
135  else
136  {
137  //Debug message
138  TRACE_INFO("Initializing ESP8266 Wi-Fi (AP mode)...\r\n");
139 
140  //Save underlying network interface (AP mode)
141  esp8266WifiApInterface = interface;
142 
143  //Optionally set the MAC address
144  if(macCompAddr(&interface->macAddr, &MAC_UNSPECIFIED_ADDR))
145  {
146  //Use the factory preprogrammed station address
147  ret = sdk_wifi_get_macaddr(SOFTAP_IF, interface->macAddr.b);
148 
149  //Check status code
150  if(ret)
151  {
152  //Generate the 64-bit interface identifier
153  macAddrToEui64(&interface->macAddr, &interface->eui64);
154  }
155  }
156  else
157  {
158  //Override the factory preprogrammed address
159  ret = sdk_wifi_set_macaddr(SOFTAP_IF, interface->macAddr.b);
160  }
161  }
162 
163  //ESP8266 Wi-Fi is now ready to send
164  osSetEvent(&interface->nicTxEvent);
165 
166  //Return status code
167  if(ret)
168  {
169  return NO_ERROR;
170  }
171  else
172  {
173  return ERROR_FAILURE;
174  }
175 }
176 
177 
178 /**
179  * @brief ESP8266 Wi-Fi timer handler
180  *
181  * This routine is periodically called by the TCP/IP stack to handle periodic
182  * operations such as polling the link state
183  *
184  * @param[in] interface Underlying network interface
185  **/
186 
188 {
189 }
190 
191 
192 /**
193  * @brief Enable interrupts
194  * @param[in] interface Underlying network interface
195  **/
196 
198 {
199 }
200 
201 
202 /**
203  * @brief Disable interrupts
204  * @param[in] interface Underlying network interface
205  **/
206 
208 {
209 }
210 
211 
212 /**
213  * @brief ESP8266 Wi-Fi event handler
214  * @param[in] interface Underlying network interface
215  **/
216 
218 {
219 }
220 
221 
222 /**
223  * @brief Send a packet
224  * @param[in] interface Underlying network interface
225  * @param[in] buffer Multi-part buffer containing the data to send
226  * @param[in] offset Offset to the first data byte
227  * @param[in] ancillary Additional options passed to the stack along with
228  * the packet
229  * @return Error code
230  **/
231 
233  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
234 {
235  int_t ret;
236  size_t length;
237  struct netif *netif;
238  struct pbuf *p;
239 
240  //STA or AP mode?
241  if(interface == esp8266WifiStaInterface)
242  {
243  netif = sdk_system_get_netif(STATION_IF);
244  }
245  else
246  {
247  netif = sdk_system_get_netif(SOFTAP_IF);
248  }
249 
250  //Sanity check
251  if(netif != NULL)
252  {
253  //Retrieve the length of the packet
254  length = netBufferGetLength(buffer) - offset;
255 
256  //Allocate a buffer
257  p = pbuf_alloc(PBUF_RAW_TX, length, PBUF_RAM);
258 
259  //Successful memory allocation?
260  if(p != NULL)
261  {
262  //Copy user data
263  netBufferRead(p->payload, buffer, offset, length);
264 
265  //Send packet
266  ret = sdk_ieee80211_output_pbuf(netif, p);
267 
268  //Release buffer
269  pbuf_free(p);
270  }
271  }
272 
273  //The transmitter can accept another packet
274  osSetEvent(&interface->nicTxEvent);
275 
276  //Return status code
277  if(!ret)
278  {
279  return NO_ERROR;
280  }
281  else
282  {
283  return ERROR_FAILURE;
284  }
285 }
286 
287 
288 /**
289  * @brief Configure MAC address filtering
290  * @param[in] interface Underlying network interface
291  * @return Error code
292  **/
293 
295 {
296  //Not implemented
297  return NO_ERROR;
298 }
299 
300 
301 /**
302  * @brief Process link-up event
303  * @param[in] netif Underlying network interface
304  **/
305 
306 void netif_set_up(struct netif *netif)
307 {
308  NetInterface *interface;
309 
310  //Check the interface where the event is occurring
311  if(netif == sdk_system_get_netif(STATION_IF))
312  {
313  interface = esp8266WifiStaInterface;
314  }
315  else if(netif == sdk_system_get_netif(SOFTAP_IF))
316  {
317  interface = esp8266WifiApInterface;
318  }
319  else
320  {
321  interface = NULL;
322  }
323 
324  //Valid interface?
325  if(interface != NULL)
326  {
327  //The link is up
328  interface->linkState = TRUE;
329 
330  //Get exclusive access
332  //Process link state change event
333  nicNotifyLinkChange(interface);
334  //Release exclusive access
336  }
337 }
338 
339 
340 /**
341  * @brief Process link-down event
342  * @param[in] netif Underlying network interface
343  **/
344 
345 void netif_set_down(struct netif *netif)
346 {
347  NetInterface *interface;
348 
349  //Check the interface where the event is occurring
350  if(netif == sdk_system_get_netif(STATION_IF))
351  {
352  interface = esp8266WifiStaInterface;
353  }
354  else if(netif == sdk_system_get_netif(SOFTAP_IF))
355  {
356  interface = esp8266WifiApInterface;
357  }
358  else
359  {
360  interface = NULL;
361  }
362 
363  //Valid interface?
364  if(interface != NULL)
365  {
366  //The link is down
367  interface->linkState = FALSE;
368 
369  //Get exclusive access
371  //Process link state change event
372  nicNotifyLinkChange(interface);
373  //Release exclusive access
375  }
376 }
377 
378 
379 /**
380  * @brief Process incoming packets
381  * @param[in] netif Underlying network interface
382  * @param[in] p Pointer to the buffer allocated by the Wi-Fi driver
383  **/
384 
385 void ethernetif_input(struct netif *netif, struct pbuf *p)
386 {
387  NetInterface *interface;
388  NetRxAncillary ancillary;
389 
390  //Check the interface where the event is occurring
391  if(netif == sdk_system_get_netif(STATION_IF))
392  {
393  interface = esp8266WifiStaInterface;
394  }
395  else if(netif == sdk_system_get_netif(SOFTAP_IF))
396  {
397  interface = esp8266WifiApInterface;
398  }
399  else
400  {
401  interface = NULL;
402  }
403 
404  //Valid buffer?
405  if(p != NULL)
406  {
407  //Valid interface?
408  if(interface != NULL)
409  {
410  //Get exclusive access
412 
413  //Additional options can be passed to the stack along with the packet
414  ancillary = NET_DEFAULT_RX_ANCILLARY;
415 
416  //Pass the packet to the upper layer
417  nicProcessPacket(interface, p->payload, p->len, &ancillary);
418 
419  //Release exclusive access
421  }
422 
423  //Release buffer
424  pbuf_free(p);
425  }
426 }
void nicNotifyLinkChange(NetInterface *interface)
Process link state change notification.
Definition: nic.c:559
void netif_set_up(struct netif *netif)
Process link-up event.
void ethernetif_input(struct netif *netif, struct pbuf *p)
Process incoming packets.
int bool_t
Definition: compiler_port.h:53
void esp8266WifiEventHandler(NetInterface *interface)
ESP8266 Wi-Fi event handler.
signed int int_t
Definition: compiler_port.h:49
#define netMutex
Definition: net_legacy.h:195
void macAddrToEui64(const MacAddr *macAddr, Eui64 *interfaceId)
Map a MAC address to the IPv6 modified EUI-64 identifier.
Definition: ethernet.c:946
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:690
uint8_t p
Definition: ndp.h:300
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
#define TRUE
Definition: os_port.h:50
void esp8266WifiDisableIrq(NetInterface *interface)
Disable interrupts.
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:392
#define FALSE
Definition: os_port.h:46
error_t
Error codes.
Definition: error.h:43
void esp8266WifiTick(NetInterface *interface)
ESP8266 Wi-Fi timer handler.
void netif_set_down(struct netif *netif)
Process link-down event.
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:104
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
const NicDriver esp8266WifiStaDriver
ESP8266 Wi-Fi driver (STA mode)
#define NetRxAncillary
Definition: net_misc.h:40
#define NetInterface
Definition: net.h:36
#define NetTxAncillary
Definition: net_misc.h:36
void esp8266WifiEnableIrq(NetInterface *interface)
Enable interrupts.
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t length
Definition: tcp.h:368
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
const NicDriver esp8266WifiApDriver
ESP8266 Wi-Fi driver (AP mode)
#define ETH_MTU
Definition: ethernet.h:116
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
#define macCompAddr(macAddr1, macAddr2)
Definition: ethernet.h:130
error_t esp8266WifiInit(NetInterface *interface)
ESP8266_WIFI initialization.
error_t esp8266WifiSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
TCP/IP stack core.
NIC driver.
Definition: nic.h:286
error_t esp8266WifiUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
ESP8266 Wi-Fi controller.
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:53
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83