RF24Ethernet - TCP/IP over RF24Network v1.6.13
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 (RF24Ethernet.network.update() == EXTERNAL_DATA_TYPE) {
223 if (RF24Ethernet.network.frag_ptr->message_size <= UIP_BUFSIZE) {
224 uip_len = RF24Ethernet.network.frag_ptr->message_size;
225 }
226 }
227
228#if !defined(RF24_TAP)
229 if (uip_len > 0) {
230 uip_input();
231 if (uip_len > 0) {
232 network_send();
233 }
234 }
235 else if (timer_expired(&Ethernet.periodic_timer)) {
236 timer_reset(&Ethernet.periodic_timer);
237 for (int i = 0; i < UIP_CONNS; i++) {
238 uip_periodic(i);
239 /* If the above function invocation resulted in data that
240 should be sent out on the network, the global variable
241 uip_len is set to a value > 0. */
242 if (uip_len > 0) {
243 network_send();
244 }
245 }
246 }
247#else // defined (RF24_TAP)
248 if (uip_len > 0) {
249 if (BUF->type == htons(UIP_ETHTYPE_IP)) {
250 uip_arp_ipin();
251 uip_input();
252 /* If the above function invocation resulted in data that
253 should be sent out on the network, the global variable
254 uip_len is set to a value > 0. */
255 if (uip_len > 0) {
256 uip_arp_out();
257 network_send();
258 }
259 }
260 else if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
261 uip_arp_arpin();
262 /* If the above function invocation resulted in data that
263 should be sent out on the network, the global variable
264 uip_len is set to a value > 0. */
265 if (uip_len > 0) {
266 network_send();
267 }
268 }
269 }
270 else if (timer_expired(&Ethernet.periodic_timer)) {
271 timer_reset(&Ethernet.periodic_timer);
272 for (int i = 0; i < UIP_CONNS; i++) {
273 uip_periodic(i);
274 /* If the above function invocation resulted in data that
275 should be sent out on the network, the global variable
276 uip_len is set to a value > 0. */
277 if (uip_len > 0) {
278 uip_arp_out();
279 network_send();
280 }
281 }
282#endif // defined (RF24_TAP)
283#if UIP_UDP
284 for (int i = 0; i < UIP_UDP_CONNS; i++) {
285 uip_udp_periodic(i);
286 /* If the above function invocation resulted in data that
287 should be sent out on the network, the global variable
288 uip_len is set to a value > 0. */
289 if (uip_len > 0) {
290 // uip_arp_out();
291 // network_send();
292 RF24UDP::_send((uip_udp_userdata_t*)(uip_udp_conns[i].appstate));
293 }
294 }
295#endif /* UIP_UDP */
296#if defined(RF24_TAP)
297 /* Call the ARP timer function every 10 seconds. */
298
299 if (timer_expired(&Ethernet.arp_timer)) {
300 timer_reset(&Ethernet.arp_timer);
301 uip_arp_timer();
302 }
303}
304#endif // RF24_TAP
305}
306
307/*******************************************************/
308
309void RF24EthernetClass::network_send()
310{
311 RF24NetworkHeader headerOut(00, EXTERNAL_DATA_TYPE);
312
313 bool ok = RF24Ethernet.network.write(headerOut, uip_buf, uip_len);
314
315 if (!ok) {
316 ok = RF24Ethernet.network.write(headerOut, uip_buf, uip_len);
317#if defined ETH_DEBUG_L1 || defined ETH_DEBUG_L2
318 if (!ok) {
319 Serial.println();
320 Serial.print(millis());
321 Serial.println(F(" *** RF24Ethernet Network Write Fail ***"));
322 }
323#endif
324 }
325
326#if defined ETH_DEBUG_L2
327 if (ok) {
328 Serial.println();
329 Serial.print(millis());
330 Serial.println(F(" RF24Ethernet Network Write OK"));
331 }
332#endif
333}
334
335/*******************************************************/
336/*
337void uipudp_appcall() {
338
339}*/
#define BUF
Definition: RF24Ethernet.h:67
#define uip_ip_addr(addr, ip)
Definition: RF24Ethernet.h:80
#define ip_addr_uip(a)
Definition: RF24Ethernet.h:82
#define uip_seteth_addr(eaddr)
Definition: RF24Ethernet.h:84
RF24EthernetClass RF24Ethernet
void setMac(uint16_t address)
void setChannel(uint8_t channel)
IPAddress dnsServerIP()
void listen(uint16_t port)
IPAddress localIP()
IPAddress subnetMask()
void set_gateway(IPAddress gwIP)
void begin(IP_ADDR myIP, IP_ADDR subnet)
IPAddress gatewayIP()
#define Ethernet
Definition: ethernet_comp.h:4
#define UIP_TIMER_DIVISOR
Adjust the rate at which the IP stack performs periodic processing.
Definition: uip-conf.h:127