RF24Ethernet - TCP/IP over RF24Network v2.0.3
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)
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 RF24Network& network;
215 #if !defined(RF24_TAP) // Using RF24Mesh
216 RF24Mesh& mesh;
217 #endif
218#else
219 RF52Network& network;
220 #if !defined(RF24_TAP) // Using RF24Mesh
221 RF52Mesh& mesh;
222 #endif
223#endif
224
225#if USE_LWIP > 0
226
227 static bool useCoreLocking;
228 static constexpr unsigned MAX_FRAME_SIZE = MAX_PAYLOAD_SIZE; // packet size excluding FCS
229 static constexpr unsigned MIN_FRAME_SIZE = 60;
230 static constexpr unsigned MAX_RX_QUEUE = 2;
231 static constexpr uint32_t NetIF_Speed_BPS = 1000000;
232 static netif myNetif;
233
234 struct alignas(4) EthQueue
235 {
236 uint32_t nRead;
237 uint32_t nWrite;
238 uint8_t data[MAX_RX_QUEUE][MAX_FRAME_SIZE] __attribute__((aligned(4)));
239 uint16_t len[MAX_RX_QUEUE];
240 };
242
243 typedef uint32_t err_t;
244 static bool isUnicast(const uint8_t frame);
245 /** Used internally to initialize incoming data queue */
246 static void initRXQueue(EthQueue* RXQueue);
247 /** Used internally to write to the internal data queue */
248 static void writeRXQueue(EthQueue* RXQueue, const uint8_t* ethFrame, uint16_t lenEthFrame);
249
250private:
251 static constexpr uint16_t ETHERNET_MTU = 1500;
252 static constexpr uint8_t MacAddr[6] = {0, 1, 2, 3, 4};
253 static bool isConnected;
254
255 static pbuf* readRXQueue(EthQueue* RXQueue);
256
257 static void EthRX_Handler(const uint8_t* ethFrame, const uint16_t lenEthFrame);
258 alignas(4) static uint8_t networkBuffer[MAX_PAYLOAD_SIZE];
259
260#endif
261
262#if defined NRF52_RADIO_LIBRARY
263 nrf_to_nrf& radio;
264#else
265 RF24& radio;
266#endif
267
268#if USE_LWIP < 1
269 IPAddress _dnsServerAddress;
270#else
271 static IPAddress _dnsServerAddress;
272#endif
273
274 void configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet);
275
276 // tick() must be called at regular intervals to process the incoming serial
277 // data and issue IP events to the sketch. It does not return until all IP
278 // events have been processed.
279 static void tick();
280 static void network_send();
281
282 uint8_t RF24_Channel;
283
284#if USE_LWIP < 1
285 struct timer periodic_timer;
286 #if defined RF24_TAP
287 struct timer arp_timer;
288 #endif
289#endif
290
291 friend class RF24Server;
292 friend class RF24Client;
293 friend class RF24UDP;
294};
295
297
299
300/**
301 * @example Getting_Started_SimpleServer_Mesh.ino
302 * <b>Updated: TMRh20 2014 </b><br>
303 *
304 * This is an example of how to use the RF24Ethernet class to create a web server which will allow you to connect via
305 * any device with a web-browser. The url is http://your_chosen_IP:1000
306 */
307
308/**
309 * @example Getting_Started_SimpleClient_Mesh.ino
310 *
311 * This is an example of how to use the RF24Ethernet class to connect out to a web server and retrieve data via HTTP.
312 */
313
314/**
315 * @example Getting_Started_SimpleClient_Mesh_DNS.ino
316 *
317 * This is an example of how to use the RF24Ethernet class to connect out to a web server and retrieve data via HTTP,
318 * using DNS lookups instead of IP address.
319 */
320
321/**
322 * @example SimpleClient_Mesh.ino
323 *
324 * This is an example of how to use the RF24Ethernet class to connect out to a web server and retrieve data via HTTP.
325 * It also demonstrates how to read from the HTTP header to read the Content-Length before reading the data.
326 */
327
328/**
329 * @example InteractiveServer_Mesh.ino
330 *
331 * This is an example of how to create a more advanced interactive web server.<br>
332 * This example uses [HTML.h](InteractiveServer__Mesh_2HTML_8h.html) from the
333 * example's directory.
334 */
335
336/**
337 * @example mqtt_basic.ino
338 *
339 * This is the example taken from the MQTT library https://github.com/256dpi/arduino-mqtt/ & slightly modified to include RF24Ethernet/RF24Mesh.
340 */
341
342/**
343 * @example mqtt_basic_no_blk.ino
344 *
345 * This is similar to the mqtt_basic example, but uses a non-blocking connect function.
346 */
347/**
348 * @example mqtt_basic_2.ino
349 *
350 * A copy of the initial MQTT example using MQTT library https://github.com/256dpi/arduino-mqtt/ slightly modified to include RF24Ethernet/RF24Mesh.
351 */
352
353/**
354 * @example InteractiveServer_Mesh_Headless.ino
355 *
356 * This example demonstrates "headless' use of a server, without a gateway device like Raspberry Pi/Linux.
357 */
358
359/**
360 * @example SimpleClient_Mesh_Headless.ino
361 *
362 * This example demonstrates "headless" use of a client, without a gateway device like Raspberry Pi/Linux
363 */
364
365#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)))