RF24Ethernet - TCP/IP over RF24Network v1.6.12
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(RF24_TAP)
28RF24EthernetClass::RF24EthernetClass(RF24& _radio, RF24Network& _network) : radio(_radio), network(_network) //fn_uip_cb(NULL)
29{
30}
31
32#else // Using RF24Mesh
33RF24EthernetClass::RF24EthernetClass(RF24& _radio, RF24Network& _network, RF24Mesh& _mesh) : radio(_radio), network(_network), mesh(_mesh) //fn_uip_cb(NULL)
34{
35}
36#endif
37
38/*************************************************************/
39
41{
42 Ethernet.tick();
43}
44
45/*************************************************************/
46
48{
49 // Kept for backwards compatibility only
50}
51
52/*******************************************************/
53
54void RF24EthernetClass::setMac(uint16_t address)
55{
56 if (!network.multicastRelay) { // Radio has not been started yet
57 radio.begin();
58 }
59
60 const uint8_t mac[6] = {0x52, 0x46, 0x32, 0x34, (uint8_t)address, (uint8_t)(address >> 8)};
61 //printf("MAC: %o %d\n", address, mac[0]);
62
63#if defined(RF24_TAP)
64 uip_seteth_addr(mac);
65 network.multicastRelay = 1;
66#else
67 if (mac[0] == 1) {
68 //Dummy operation to prevent warnings if TAP not defined
69 };
70#endif
71 RF24_Channel = RF24_Channel ? RF24_Channel : 97;
72 network.begin(RF24_Channel, address);
73}
74
75/*******************************************************/
76
77void RF24EthernetClass::setChannel(uint8_t channel)
78{
79 RF24_Channel = channel;
80 if (network.multicastRelay) { // Radio has not been started yet
81 radio.setChannel(RF24_Channel);
82 }
83}
84
85/*******************************************************/
86
87void RF24EthernetClass::begin(IPAddress ip)
88{
89 IPAddress dns = ip;
90 dns[3] = 1;
91 begin(ip, dns);
92}
93
94/*******************************************************/
95
96void RF24EthernetClass::begin(IPAddress ip, IPAddress dns)
97{
98 IPAddress gateway = ip;
99 gateway[3] = 1;
100 begin(ip, dns, gateway);
101}
102
103/*******************************************************/
104
105void RF24EthernetClass::begin(IPAddress ip, IPAddress dns, IPAddress gateway)
106{
107 IPAddress subnet(255, 255, 255, 0);
108 begin(ip, dns, gateway, subnet);
109}
110
111/*******************************************************/
112
113void RF24EthernetClass::begin(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)
114{
115 configure(ip, dns, gateway, subnet);
116}
117
118/*******************************************************/
119
120void RF24EthernetClass::configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)
121{
122#if !defined(RF24_TAP) // Using RF24Mesh
123 mesh.setNodeID(ip[3]);
124#endif
125
126 uip_buf = (uint8_t*)&network.frag_ptr->message_buffer[0];
127
128 uip_ipaddr_t ipaddr;
129 uip_ip_addr(ipaddr, ip);
130 uip_sethostaddr(ipaddr);
131 uip_ip_addr(ipaddr, gateway);
132 uip_setdraddr(ipaddr);
133 uip_ip_addr(ipaddr, subnet);
134 uip_setnetmask(ipaddr);
135 _dnsServerAddress = dns;
136
137 timer_set(&this->periodic_timer, CLOCK_SECOND / UIP_TIMER_DIVISOR);
138
139#if defined(RF24_TAP)
140 timer_set(&this->arp_timer, CLOCK_SECOND * 2);
141#endif
142
143 uip_init();
144#if defined(RF24_TAP)
145 uip_arp_init();
146#endif
147}
148
149/*******************************************************/
150
152{
153 uip_ipaddr_t ipaddr;
154 uip_ip_addr(ipaddr, gwIP);
155 uip_setdraddr(ipaddr);
156}
157
158/*******************************************************/
159
160void RF24EthernetClass::listen(uint16_t port)
161{
162 uip_listen(HTONS(port));
163}
164
165/*******************************************************/
166
168{
169 IPAddress ret;
170 uip_ipaddr_t a;
171 uip_gethostaddr(a);
172 return ip_addr_uip(a);
173}
174
175/*******************************************************/
176
178{
179 IPAddress ret;
180 uip_ipaddr_t a;
181 uip_getnetmask(a);
182 return ip_addr_uip(a);
183}
184
185/*******************************************************/
186
188{
189 IPAddress ret;
190 uip_ipaddr_t a;
191 uip_getdraddr(a);
192 return ip_addr_uip(a);
193}
194
195/*******************************************************/
196
198{
199 return _dnsServerAddress;
200}
201
202/*******************************************************/
203
204void RF24EthernetClass::tick()
205{
206#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_RP2040)
207 yield();
208#endif
209 if (RF24Ethernet.network.update() == EXTERNAL_DATA_TYPE) {
210 if (RF24Ethernet.network.frag_ptr->message_size <= UIP_BUFSIZE) {
211 uip_len = RF24Ethernet.network.frag_ptr->message_size;
212 }
213 }
214
215#if !defined(RF24_TAP)
216 if (uip_len > 0) {
217 uip_input();
218 if (uip_len > 0) {
219 network_send();
220 }
221 }
222 else if (timer_expired(&Ethernet.periodic_timer)) {
223 timer_reset(&Ethernet.periodic_timer);
224 for (int i = 0; i < UIP_CONNS; i++) {
225 uip_periodic(i);
226 /* If the above function invocation resulted in data that
227 should be sent out on the network, the global variable
228 uip_len is set to a value > 0. */
229 if (uip_len > 0) {
230 network_send();
231 }
232 }
233 }
234#else // defined (RF24_TAP)
235 if (uip_len > 0) {
236 if (BUF->type == htons(UIP_ETHTYPE_IP)) {
237 uip_arp_ipin();
238 uip_input();
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 uip_arp_out();
244 network_send();
245 }
246 }
247 else if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
248 uip_arp_arpin();
249 /* If the above function invocation resulted in data that
250 should be sent out on the network, the global variable
251 uip_len is set to a value > 0. */
252 if (uip_len > 0) {
253 network_send();
254 }
255 }
256 }
257 else if (timer_expired(&Ethernet.periodic_timer)) {
258 timer_reset(&Ethernet.periodic_timer);
259 for (int i = 0; i < UIP_CONNS; i++) {
260 uip_periodic(i);
261 /* If the above function invocation resulted in data that
262 should be sent out on the network, the global variable
263 uip_len is set to a value > 0. */
264 if (uip_len > 0) {
265 uip_arp_out();
266 network_send();
267 }
268 }
269#endif // defined (RF24_TAP)
270#if UIP_UDP
271 for (int i = 0; i < UIP_UDP_CONNS; i++) {
272 uip_udp_periodic(i);
273 /* If the above function invocation resulted in data that
274 should be sent out on the network, the global variable
275 uip_len is set to a value > 0. */
276 if (uip_len > 0) {
277 //uip_arp_out();
278 //network_send();
279 RF24UDP::_send((uip_udp_userdata_t*)(uip_udp_conns[i].appstate));
280 }
281 }
282#endif /* UIP_UDP */
283#if defined(RF24_TAP)
284 /* Call the ARP timer function every 10 seconds. */
285
286 if (timer_expired(&Ethernet.arp_timer)) {
287 timer_reset(&Ethernet.arp_timer);
288 uip_arp_timer();
289 }
290}
291#endif //RF24_TAP
292}
293
294/*******************************************************/
295
296void RF24EthernetClass::network_send()
297{
298 RF24NetworkHeader headerOut(00, EXTERNAL_DATA_TYPE);
299
300 bool ok = RF24Ethernet.network.write(headerOut, uip_buf, uip_len);
301
302 if (!ok) {
303 ok = RF24Ethernet.network.write(headerOut, uip_buf, uip_len);
304#if defined ETH_DEBUG_L1 || defined ETH_DEBUG_L2
305 if (!ok) {
306 Serial.println();
307 Serial.print(millis());
308 Serial.println(F(" *** RF24Ethernet Network Write Fail ***"));
309 }
310#endif
311 }
312
313#if defined ETH_DEBUG_L2
314 if (ok) {
315 Serial.println();
316 Serial.print(millis());
317 Serial.println(F(" RF24Ethernet Network Write OK"));
318 }
319#endif
320}
321
322/*******************************************************/
323/*
324void uipudp_appcall() {
325
326}*/
#define BUF
Definition: RF24Ethernet.h:64
#define uip_ip_addr(addr, ip)
Definition: RF24Ethernet.h:77
#define ip_addr_uip(a)
Definition: RF24Ethernet.h:79
#define uip_seteth_addr(eaddr)
Definition: RF24Ethernet.h:81
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