RF24Ethernet - TCP/IP over RF24Network v1.6.14
TMRh20 - Pushing the practical limits of RF24 modules
Loading...
Searching...
No Matches
RF24Ethernet.cpp
Go to the documentation of this file.
1/*
2 RF24Ethernet.cpp - Arduino implementation of a uIP wrapper class.
3 Copyright (c) 2014 tmrh20@gmail.com, github.com/TMRh20
4 Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
5 All rights reserved.
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include "RF24Ethernet.h"
22
23IPAddress RF24EthernetClass::_dnsServerAddress;
24// DhcpClass* RF24EthernetClass::_dhcp(NULL);
25
26/*************************************************************/
27#if !defined NRF52_RADIO_LIBRARY
28 #if defined(RF24_TAP)
29RF24EthernetClass::RF24EthernetClass(RF24& _radio, RF24Network& _network) : radio(_radio), network(_network) // fn_uip_cb(NULL)
30{
31}
32
33 #else // Using RF24Mesh
34RF24EthernetClass::RF24EthernetClass(RF24& _radio, RF24Network& _network, RF24Mesh& _mesh) : radio(_radio), network(_network), mesh(_mesh) // fn_uip_cb(NULL)
35{
36}
37 #endif
38
39#else
40 #if defined(RF24_TAP)
41RF24EthernetClass::RF24EthernetClass(nrf_to_nrf& _radio, RF52Network& _network) : radio(_radio), network(_network) // fn_uip_cb(NULL)
42{
43}
44
45 #else // Using RF24Mesh
46RF24EthernetClass::RF24EthernetClass(nrf_to_nrf& _radio, RF52Network& _network, RF52Mesh& _mesh) : radio(_radio), network(_network), mesh(_mesh) // fn_uip_cb(NULL)
47{
48}
49 #endif
50#endif
51/*************************************************************/
52
54{
55 Ethernet.tick();
56}
57
58/*************************************************************/
59
61{
62 // Kept for backwards compatibility only
63}
64
65/*******************************************************/
66
67void RF24EthernetClass::setMac(uint16_t address)
68{
69 if (!network.multicastRelay) { // Radio has not been started yet
70 radio.begin();
71 }
72
73 const uint8_t mac[6] = {0x52, 0x46, 0x32, 0x34, (uint8_t)address, (uint8_t)(address >> 8)};
74 // printf("MAC: %o %d\n", address, mac[0]);
75
76#if defined(RF24_TAP)
77 uip_seteth_addr(mac);
78 network.multicastRelay = 1;
79#else
80 if (mac[0] == 1) {
81 // Dummy operation to prevent warnings if TAP not defined
82 };
83#endif
84 RF24_Channel = RF24_Channel ? RF24_Channel : 97;
85 network.begin(RF24_Channel, address);
86}
87
88/*******************************************************/
89
90void RF24EthernetClass::setChannel(uint8_t channel)
91{
92 RF24_Channel = channel;
93 if (network.multicastRelay) { // Radio has not been started yet
94 radio.setChannel(RF24_Channel);
95 }
96}
97
98/*******************************************************/
99
100void RF24EthernetClass::begin(IPAddress ip)
101{
102 IPAddress dns = ip;
103 dns[3] = 1;
104 begin(ip, dns);
105}
106
107/*******************************************************/
108
109void RF24EthernetClass::begin(IPAddress ip, IPAddress dns)
110{
111 IPAddress gateway = ip;
112 gateway[3] = 1;
113 begin(ip, dns, gateway);
114}
115
116/*******************************************************/
117
118void RF24EthernetClass::begin(IPAddress ip, IPAddress dns, IPAddress gateway)
119{
120 IPAddress subnet(255, 255, 255, 0);
121 begin(ip, dns, gateway, subnet);
122}
123
124/*******************************************************/
125
126void RF24EthernetClass::begin(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)
127{
128 configure(ip, dns, gateway, subnet);
129}
130
131/*******************************************************/
132
133void RF24EthernetClass::configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)
134{
135#if !defined(RF24_TAP) // Using RF24Mesh
136 mesh.setNodeID(ip[3]);
137#endif
138
139 uip_buf = (uint8_t*)&network.frag_ptr->message_buffer[0];
140
141 uip_ipaddr_t ipaddr;
142 uip_ip_addr(ipaddr, ip);
143 uip_sethostaddr(ipaddr);
144 uip_ip_addr(ipaddr, gateway);
145 uip_setdraddr(ipaddr);
146 uip_ip_addr(ipaddr, subnet);
147 uip_setnetmask(ipaddr);
148 _dnsServerAddress = dns;
149
150 timer_set(&this->periodic_timer, CLOCK_SECOND / UIP_TIMER_DIVISOR);
151
152#if defined(RF24_TAP)
153 timer_set(&this->arp_timer, CLOCK_SECOND * 2);
154#endif
155
156 uip_init();
157#if defined(RF24_TAP)
158 uip_arp_init();
159#endif
160}
161
162/*******************************************************/
163
165{
166 uip_ipaddr_t ipaddr;
167 uip_ip_addr(ipaddr, gwIP);
168 uip_setdraddr(ipaddr);
169}
170
171/*******************************************************/
172
173void RF24EthernetClass::listen(uint16_t port)
174{
175 uip_listen(HTONS(port));
176}
177
178/*******************************************************/
179
181{
182 IPAddress ret;
183 uip_ipaddr_t a;
184 uip_gethostaddr(a);
185 return ip_addr_uip(a);
186}
187
188/*******************************************************/
189
191{
192 IPAddress ret;
193 uip_ipaddr_t a;
194 uip_getnetmask(a);
195 return ip_addr_uip(a);
196}
197
198/*******************************************************/
199
201{
202 IPAddress ret;
203 uip_ipaddr_t a;
204 uip_getdraddr(a);
205 return ip_addr_uip(a);
206}
207
208/*******************************************************/
209
211{
212 return _dnsServerAddress;
213}
214
215/*******************************************************/
216
217void RF24EthernetClass::tick()
218{
219#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_RP2040)
220 yield();
221#endif
222#if defined(ARDUINO_ARCH_ESP32)
223 const TickType_t xDelay = 1 / portTICK_PERIOD_MS;
224 vTaskDelay(xDelay);
225#endif
226
227 if (RF24Ethernet.network.update() == EXTERNAL_DATA_TYPE) {
228 if (RF24Ethernet.network.frag_ptr->message_size <= UIP_BUFSIZE) {
229 uip_len = RF24Ethernet.network.frag_ptr->message_size;
230 }
231 }
232
233#if !defined(RF24_TAP)
234 if (uip_len > 0) {
235 uip_input();
236 if (uip_len > 0) {
237 network_send();
238 }
239 }
240 else if (timer_expired(&Ethernet.periodic_timer)) {
241 timer_reset(&Ethernet.periodic_timer);
242 for (int i = 0; i < UIP_CONNS; i++) {
243 uip_periodic(i);
244 /* If the above function invocation resulted in data that
245 should be sent out on the network, the global variable
246 uip_len is set to a value > 0. */
247 if (uip_len > 0) {
248 network_send();
249 }
250 }
251 }
252#else // defined (RF24_TAP)
253 if (uip_len > 0) {
254 if (BUF->type == htons(UIP_ETHTYPE_IP)) {
255 uip_arp_ipin();
256 uip_input();
257 /* If the above function invocation resulted in data that
258 should be sent out on the network, the global variable
259 uip_len is set to a value > 0. */
260 if (uip_len > 0) {
261 uip_arp_out();
262 network_send();
263 }
264 }
265 else if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
266 uip_arp_arpin();
267 /* If the above function invocation resulted in data that
268 should be sent out on the network, the global variable
269 uip_len is set to a value > 0. */
270 if (uip_len > 0) {
271 network_send();
272 }
273 }
274 }
275 else if (timer_expired(&Ethernet.periodic_timer)) {
276 timer_reset(&Ethernet.periodic_timer);
277 for (int i = 0; i < UIP_CONNS; i++) {
278 uip_periodic(i);
279 /* If the above function invocation resulted in data that
280 should be sent out on the network, the global variable
281 uip_len is set to a value > 0. */
282 if (uip_len > 0) {
283 uip_arp_out();
284 network_send();
285 }
286 }
287#endif // defined (RF24_TAP)
288#if UIP_UDP
289 for (int i = 0; i < UIP_UDP_CONNS; i++) {
290 uip_udp_periodic(i);
291 /* If the above function invocation resulted in data that
292 should be sent out on the network, the global variable
293 uip_len is set to a value > 0. */
294 if (uip_len > 0) {
295 // uip_arp_out();
296 // network_send();
297 RF24UDP::_send((uip_udp_userdata_t*)(uip_udp_conns[i].appstate));
298 }
299 }
300#endif /* UIP_UDP */
301#if defined(RF24_TAP)
302 /* Call the ARP timer function every 10 seconds. */
303
304 if (timer_expired(&Ethernet.arp_timer)) {
305 timer_reset(&Ethernet.arp_timer);
306 uip_arp_timer();
307 }
308}
309#endif // RF24_TAP
310}
311
312/*******************************************************/
313
314void RF24EthernetClass::network_send()
315{
316 RF24NetworkHeader headerOut(00, EXTERNAL_DATA_TYPE);
317
318 bool ok = RF24Ethernet.network.write(headerOut, uip_buf, uip_len);
319
320 if (!ok) {
321 ok = RF24Ethernet.network.write(headerOut, uip_buf, uip_len);
322#if defined ETH_DEBUG_L1 || defined ETH_DEBUG_L2
323 if (!ok) {
324 Serial.println();
325 Serial.print(millis());
326 Serial.println(F(" *** RF24Ethernet Network Write Fail ***"));
327 }
328#endif
329 }
330
331#if defined ETH_DEBUG_L2
332 if (ok) {
333 Serial.println();
334 Serial.print(millis());
335 Serial.println(F(" RF24Ethernet Network Write OK"));
336 }
337#endif
338}
339
340/*******************************************************/
341/*
342void uipudp_appcall() {
343
344}*/
#define BUF
#define uip_ip_addr(addr, ip)
#define ip_addr_uip(a)
#define uip_seteth_addr(eaddr)
RF24EthernetClass RF24Ethernet
void setMac(uint16_t address)
void setChannel(uint8_t channel)
IPAddress dnsServerIP()
void listen(uint16_t port)
IPAddress subnetMask()
void set_gateway(IPAddress gwIP)
void begin(IP_ADDR myIP, IP_ADDR subnet)
IPAddress gatewayIP()
#define Ethernet
#define UIP_TIMER_DIVISOR
Adjust the rate at which the IP stack performs periodic processing.
Definition uip-conf.h:127