RF24Ethernet - TCP/IP over RF24Network v2.1.0
TMRh20 - Pushing the practical limits of RF24 modules
Loading...
Searching...
No Matches
RF24Ethernet.h
Go to the documentation of this file.
1/*
2 RF24Ethernet by TMRh20 2014-2015
3
4 https://github.com/TMRh20
5
6 RF24Ethernet.h - Arduino implementation of a uIP wrapper class.
7 Copyright (c) 2014 tmrh20@gmail.com, github.com/TMRh20
8 Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
9 All rights reserved.
10 This program is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#ifndef RF24Ethernet_h
23#define RF24Ethernet_h
24
25/**
26 * @file RF24Ethernet.h
27 *
28 * Class declaration for RF24Ethernet
29 */
30
31#include <Arduino.h>
32#include "RF24BoardConfig.h"
33
34/**************************************/
35#if USE_LWIP < 1
36extern "C" {
37 #include "uip-conf.h"
38 #include "utility/uip.h"
39
40 #include "utility/uiptimer.h"
41 #include "utility/uip_arp.h"
42}
43#endif
44
45/**************************************/
46
47#include "RF24Ethernet_config.h"
48#if defined(ARDUINO_ARCH_NRF52) || defined(ARDUINO_ARCH_NRF52840) || defined(ARDUINO_ARCH_NRF52833) || defined ARDUINO_NRF54L15
49 #include <nrf_to_nrf.h>
50#endif
51#include <RF24.h>
52#include <RF24Network.h>
53#include <RF24Mesh.h>
54#if !defined(RF24_TAP) // Using RF24Mesh
55 #include <RF24Mesh.h>
56#endif
57
58/**************************************/
59
60#if USE_LWIP < 1
61 #include "ethernet_comp.h"
62 #include "IPAddress.h"
63 #include "RF24Client.h"
64 #include "RF24Server.h"
65
66 #if UIP_CONF_UDP > 0 || USE_LWIP > 0
67 #include "RF24Udp.h"
68 #include "Dns.h"
69 #endif
70
71 #define UIPETHERNET_FREEPACKET 1
72 #define UIPETHERNET_SENDPACKET 2
73
74 //#define TUN // Use only the tcp protocol, no ethernet headers or arps
75 #define TAP // Include ethernet headers
76
77 #if defined(TAP)
78 #define BUF ((struct uip_eth_hdr*)&uip_buf[0])
79 #endif
80 //#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
81
82 #define uip_seteth_addr(eaddr) \
83 do { \
84 uip_ethaddr.addr[0] = eaddr[0]; \
85 uip_ethaddr.addr[1] = eaddr[1]; \
86 uip_ethaddr.addr[2] = eaddr[2]; \
87 uip_ethaddr.addr[3] = eaddr[3]; \
88 uip_ethaddr.addr[4] = eaddr[4]; \
89 uip_ethaddr.addr[5] = eaddr[5]; \
90 } while (0)
91 #define uip_ip_addr(addr, ip) memcpy(addr, &ip[0], 4)
92
93 #define ip_addr_uip(a) IPAddress(a[0] & 0xFF, a[0] >> 8, a[1] & 0xFF, a[1] >> 8) // TODO this is not IPV6 capable
94
95 #define uip_seteth_addr(eaddr) \
96 do { \
97 uip_ethaddr.addr[0] = eaddr[0]; \
98 uip_ethaddr.addr[1] = eaddr[1]; \
99 uip_ethaddr.addr[2] = eaddr[2]; \
100 uip_ethaddr.addr[3] = eaddr[3]; \
101 uip_ethaddr.addr[4] = eaddr[4]; \
102 uip_ethaddr.addr[5] = eaddr[5]; \
103 } while (0)
104
105#endif //USE_LWIP < 1
106
107/**************************************/
108
109/**
110 * @warning <b>This is used internally. Use IPAddress instead. </b>
111 */
112typedef struct
113{
114 int a, b, c, d;
115} IP_ADDR;
116
117/**************************************/
118
119class RF24;
120template<class radio_t>
122
123/**************************************/
124
126{ //: public Print {
127public:
128/**
129 * Constructor to set up the Ethernet layer. Requires the radio and network to be configured by the user
130 * this allows users to set custom settings at the radio or network level
131 */
132#if !defined(RF24_TAP) // Using RF24Mesh
133 RF24EthernetClass(RF24& _radio, RF24Network& _network, RF24Mesh& _mesh);
134#else
135 RF24EthernetClass(RF24& _radio, RF24Network& _network);
136#endif
137#if defined NRF52_RADIO_LIBRARY
138 #if !defined(RF24_TAP)
139 RF24EthernetClass(nrf_to_nrf& _radio, RF52Network& _network, RF52Mesh& _mesh);
140 #else
141 RF24EthernetClass(nrf_to_nrf& _radio, RF52Network& _network);
142 #endif
143#endif
144
145 /** Basic constructor */
147
148 /**
149 * @note Deprecated, maintained for backwards compatibility with old examples
150 *
151 * This function is no longer needed, and does nothing
152 */
153 void use_device();
154
155 /**
156 * Configure the IP address and subnet mask of the node. This is independent of the RF24Network layer, so the IP
157 * and subnet only have to conform to standard IP routing rules within your network
158 */
159 void begin(IP_ADDR myIP, IP_ADDR subnet);
160
161 /**
162 * Configure the IP address and subnet mask of the node. This is independent of the RF24Network layer, so the IP
163 * and subnet only have to conform to standard IP routing rules within your network
164 */
165 void begin(IPAddress ip);
166 void begin(IPAddress ip, IPAddress dns);
167 void begin(IPAddress ip, IPAddress dns, IPAddress gateway);
168 void begin(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
169
170 /**
171 * Configure the gateway IP address. This is generally going to be your master node with RF24Network address 00.
172 */
173 void set_gateway(IPAddress gwIP);
174
175 /**
176 * Listen to a specified port - This will likely be changed to closer match the Arduino Ethernet API with server.begin();
177 */
178 void listen(uint16_t port);
179
180 /**
181 * Sets the MAC address of the RF24 module, which is an RF24Network address
182 * Specify an Octal address to assign to this node, which will be used as the Ethernet mac address
183 * If setting up only a few nodes, use 01 to 05
184 * Please reference the RF24Network documentation for information on setting up a static network
185 * RF24Mesh will be integrated to provide this automatically
186 */
187 void setMac(uint16_t address);
188
189 /** Sets the Radio channel/frequency to use (0-127) */
190 void setChannel(uint8_t channel);
191
192 /** Indicates whether data is available. */
194
195 /** Returns the local IP address */
196 IPAddress localIP();
197
198 /** Returns the subnet mask */
199 IPAddress subnetMask();
200
201 /** Returns the gateway IP address */
202 IPAddress gatewayIP();
203
204 /** Returns the DNS server IP address */
205 IPAddress dnsServerIP();
206
207 /** Keeps the TCP/IP stack running & processing incoming data */
208 void update();
209 // uint8_t *key;
210
212
213#if defined NRF52_RADIO_LIBRARY
214 nrf_to_nrf& radio;
215#else
216 RF24& radio;
217#endif
218
219#if !defined NRF52_RADIO_LIBRARY
220 RF24Network& network;
221 #if !defined(RF24_TAP) // Using RF24Mesh
222 RF24Mesh& mesh;
223 #endif
224#else
225 RF52Network& network;
226 #if !defined(RF24_TAP) // Using RF24Mesh
227 RF52Mesh& mesh;
228 #endif
229#endif
230
231#if USE_LWIP > 0
232
233 static bool useCoreLocking;
234 static constexpr unsigned MAX_FRAME_SIZE = MAX_PAYLOAD_SIZE; // packet size excluding FCS
235 static constexpr unsigned MIN_FRAME_SIZE = 60;
236 static constexpr unsigned MAX_RX_QUEUE = 2;
237 static constexpr uint32_t NetIF_Speed_BPS = 1000000;
238 static netif myNetif;
239
240 struct alignas(4) EthQueue
241 {
242 uint32_t nRead;
243 uint32_t nWrite;
244 uint8_t data[MAX_RX_QUEUE][MAX_FRAME_SIZE] __attribute__((aligned(4)));
245 uint16_t len[MAX_RX_QUEUE];
246 };
248
249 static bool isUnicast(const uint8_t frame);
250 /** Used internally to initialize incoming data queue */
251 static void initRXQueue(EthQueue* RXQueue);
252 /** Used internally to write to the internal data queue */
253 static void writeRXQueue(EthQueue* RXQueue, const uint8_t* ethFrame, uint16_t lenEthFrame);
254
255private:
256 static constexpr uint16_t ETHERNET_MTU = 1500;
257 static constexpr uint8_t MacAddr[6] = {0, 1, 2, 3, 4};
258 static bool isConnected;
259
260 static pbuf* readRXQueue(EthQueue* RXQueue);
261
262 static void EthRX_Handler(const uint8_t* ethFrame, const uint16_t lenEthFrame);
263 alignas(4) static uint8_t networkBuffer[MAX_PAYLOAD_SIZE];
264
265#endif
266
267#if USE_LWIP < 1
268 IPAddress _dnsServerAddress;
269#else
270 static IPAddress _dnsServerAddress;
271#endif
272
273 void configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
274
275 // tick() must be called at regular intervals to process the incoming serial
276 // data and issue IP events to the sketch. It does not return until all IP
277 // events have been processed.
278 static void tick();
279 static void network_send();
280
281 uint8_t RF24_Channel;
282
283#if USE_LWIP < 1
284 struct timer periodic_timer;
285 #if defined RF24_TAP
286 struct timer arp_timer;
287 #endif
288#endif
289
290 friend class RF24Server;
291 friend class RF24Client;
292 friend class RF24UDP;
293};
294
296
298
299/**
300 * @example Getting_Started_SimpleServer_Mesh.ino
301 * <b>Updated: TMRh20 2014 </b><br>
302 *
303 * This is an example of how to use the RF24Ethernet class to create a web server which will allow you to connect via
304 * any device with a web-browser. The url is http://your_chosen_IP:1000
305 */
306
307/**
308 * @example Getting_Started_SimpleClient_Mesh.ino
309 *
310 * This is an example of how to use the RF24Ethernet class to connect out to a web server and retrieve data via HTTP.
311 */
312
313/**
314 * @example Getting_Started_SimpleClient_Mesh_DNS.ino
315 *
316 * This is an example of how to use the RF24Ethernet class to connect out to a web server and retrieve data via HTTP,
317 * using DNS lookups instead of IP address.
318 */
319
320/**
321 * @example SimpleClient_Mesh.ino
322 *
323 * This is an example of how to use the RF24Ethernet class to connect out to a web server and retrieve data via HTTP.
324 * It also demonstrates how to read from the HTTP header to read the Content-Length before reading the data.
325 */
326
327/**
328 * @example InteractiveServer_Mesh.ino
329 *
330 * This is an example of how to create a more advanced interactive web server.<br>
331 * This example uses [HTML.h](InteractiveServer__Mesh_2HTML_8h.html) from the
332 * example's directory.
333 */
334
335/**
336 * @example mqtt_basic.ino
337 *
338 * This is the example taken from the MQTT library https://github.com/256dpi/arduino-mqtt/ & slightly modified to include RF24Ethernet/RF24Mesh.
339 */
340
341/**
342 * @example mqtt_basic_no_blk.ino
343 *
344 * This is similar to the mqtt_basic example, but uses a non-blocking connect function.
345 */
346/**
347 * @example mqtt_basic_2.ino
348 *
349 * A copy of the initial MQTT example using MQTT library https://github.com/256dpi/arduino-mqtt/ slightly modified to include RF24Ethernet/RF24Mesh.
350 */
351
352/**
353 * @example InteractiveServer_Mesh_Headless.ino
354 *
355 * This example demonstrates "headless' use of a server, without a gateway device like Raspberry Pi/Linux.
356 */
357
358/**
359 * @example SimpleClient_Mesh_Headless.ino
360 *
361 * This example demonstrates "headless" use of a client, without a gateway device like Raspberry Pi/Linux
362 */
363
364#endif // RF24Ethernet_h
RF24EthernetClass RF52EthernetClass
RF24EthernetClass RF24Ethernet
uint32_t networkCorruption
friend class RF24UDP
static EthQueue RXQueue
void setMac(uint16_t address)
void setChannel(uint8_t channel)
RF24EthernetClass(RF24 &_radio, RF24Network &_network, RF24Mesh &_mesh)
friend class RF24Server
static constexpr unsigned MIN_FRAME_SIZE
static void writeRXQueue(EthQueue *RXQueue, const uint8_t *ethFrame, uint16_t lenEthFrame)
static void initRXQueue(EthQueue *RXQueue)
IPAddress dnsServerIP()
void listen(uint16_t port)
IPAddress subnetMask()
void set_gateway(IPAddress gwIP)
static constexpr unsigned MAX_FRAME_SIZE
static bool isUnicast(const uint8_t frame)
RF24Network & network
static netif myNetif
static constexpr unsigned MAX_RX_QUEUE
friend class RF24Client
void begin(IP_ADDR myIP, IP_ADDR subnet)
static constexpr uint32_t NetIF_Speed_BPS
static bool useCoreLocking
IPAddress gatewayIP()
uint16_t len[MAX_RX_QUEUE]
uint8_t data[MAX_RX_QUEUE][MAX_FRAME_SIZE] __attribute__((aligned(4)))