RF24Ethernet - TCP/IP over RF24Network v2.0.3
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
23#if USE_LWIP > 0
27uint8_t RF24EthernetClass::networkBuffer[MAX_PAYLOAD_SIZE];
28IPAddress RF24EthernetClass::_dnsServerAddress;
29
30/*************************************************************/
31
33{
34 RXQueue->nWrite = 0;
35 RXQueue->nRead = 0;
36}
37
38/*************************************************************/
39
40//Saves RX ethernet frame to the buffer to be processed in the main loop
41void RF24EthernetClass::writeRXQueue(EthQueue* RXQueue, const uint8_t* ethFrame, uint16_t lenEthFrame)
42{
43 if (lenEthFrame > MAX_FRAME_SIZE)
44 {
45 lenEthFrame = MAX_FRAME_SIZE;
46 }
47 memcpy(&RXQueue->data[RXQueue->nWrite], ethFrame, lenEthFrame);
48 RXQueue->len[RXQueue->nWrite] = lenEthFrame;
49 RXQueue->nWrite++;
50 RXQueue->nWrite %= MAX_RX_QUEUE;
51}
52
53/*************************************************************/
54
55pbuf* RF24EthernetClass::readRXQueue(EthQueue* RXQueue)
56{
57 if (RXQueue->nWrite == RXQueue->nRead)
58 return nullptr;
59
60 uint16_t frameLen = RXQueue->len[RXQueue->nRead];
61
62 if (frameLen > MAX_FRAME_SIZE) {
64 return nullptr;
65 }
66
67 pbuf* p = pbuf_alloc(PBUF_IP, frameLen, PBUF_RAM);
68
69 if (p) {
70 if (pbuf_take(p, &RXQueue->data[RXQueue->nRead], frameLen) == ERR_OK) {
71 RXQueue->nRead = (RXQueue->nRead + 1) % MAX_RX_QUEUE;
72 return p;
73 }
74 pbuf_free(p);
75 }
76
77 return nullptr;
78}
79
80/*************************************************************/
81
82bool RF24EthernetClass::isUnicast(const uint8_t frame)
83{
84 return (frame & 0x01) == 0;
85}
86
87/*************************************************************/
88
89err_t netif_output(struct netif* netif, struct pbuf* p)
90{
91 void* context = netif->state;
92 uint16_t total_len = 0;
93 alignas(4) char buf[Ethernet.MAX_FRAME_SIZE]; /* max packet size including VLAN excluding FCS */
94
95 if (p->tot_len > sizeof(buf))
96 {
97 MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
98 return ERR_IF;
99 }
100 pbuf_copy_partial(p, buf, p->tot_len, 0);
101 LINK_STATS_INC(link.xmit);
102 MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
103
104 if (p->tot_len < Ethernet.MIN_FRAME_SIZE) // Pad to minimum ETH size
105 {
106 total_len = Ethernet.MIN_FRAME_SIZE;
107 }
108 else
109 {
110 total_len = p->tot_len;
111 }
112
113 if (Ethernet.isUnicast(buf[0]))
114 {
115 MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
116 }
117 else
118 {
119 MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
120 }
121
122 IPAddress gwIP = Ethernet.gatewayIP();
123 int16_t nodeAddress = 0;
124
125 //If not the master node
126 if (Ethernet.mesh.mesh_address != 0) {
127 if (gwIP[3] != buf[19]) { // If not sending to the gateway
128 IPAddress local_ip = Ethernet.localIP();
129 if (local_ip[0] == buf[16] && local_ip[1] == buf[17]) { // If we are local within the nRF24 network
130 //Request an address lookup from the Master node
131 nodeAddress = Ethernet.mesh.getAddress((char)buf[19]); // Do an address lookup
132 if (nodeAddress < 0) {
133 nodeAddress = 0; // If the result is negative, send to master
134 }
135 } // If this address is outside the nRF24 network, it will be send to master (00)
136 }
137 }
138 else {
139 IPAddress local_ip = Ethernet.localIP();
140 if (local_ip[0] == buf[16] && local_ip[1] == buf[17]) { // If within the nRF24 radio network, do a lookup, else send to self (00)
141 nodeAddress = Ethernet.mesh.getAddress((char)buf[19]);
142 if (nodeAddress < 0) {
143 return ERR_OK;
144 }
145 }
146 }
147
148 IF_ETH_DEBUG_L1(Serial.print("Net: Out "); Serial.println(nodeAddress, OCT););
149
150 RF24NetworkHeader headerOut(nodeAddress, EXTERNAL_DATA_TYPE);
151
152 if (total_len && total_len <= MAX_PAYLOAD_SIZE) {
153 if (!RF24Ethernet.network.write(headerOut, buf, total_len)) {
154 return ERR_OK;
155 }
156 }
157 return ERR_OK;
158}
159
160/*************************************************************/
161
162err_t tun_netif_output(struct netif* netif, struct pbuf* p, const ip4_addr_t* ipaddr)
163{
164 /* Since this is a TUN/L3 interface, we skip ARP (etharp_output).
165 We simply call the linkoutput function to send the raw IP packet. */
166 return netif->linkoutput(netif, p);
167}
168
169/*************************************************************/
170
171err_t netif_init(struct netif* myNetif)
172{
173
174 myNetif->name[0] = 'e';
175 myNetif->name[1] = '0';
176 myNetif->linkoutput = netif_output;
177 myNetif->output = tun_netif_output;
178 myNetif->mtu = MAX_PAYLOAD_SIZE; //ETHERNET_MTU;
179 myNetif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6 | NETIF_FLAG_LINK_UP;
180 myNetif->hostname = "TmrNet";
181 MIB2_INIT_NETIF(&Ethernet.myNetif, snmp_ifType_ppp, Ethernet.NetIF_Speed_BPS);
182 //SMEMCPY(myNetif->hwaddr, &Ethernet.MacAddr, sizeof(myNetif->hwaddr));
183 myNetif->hwaddr_len = 0; //sizeof(netif->hwaddr);
184 Ethernet.initRXQueue(&Ethernet.RXQueue);
185 netif_set_link_up(myNetif);
186 return ERR_OK;
187}
188
189#endif
190
191/*************************************************************/
192#if !defined NRF52_RADIO_LIBRARY
193 #if defined(RF24_TAP)
194RF24EthernetClass::RF24EthernetClass(RF24& _radio, RF24Network& _network) : radio(_radio), network(_network) // fn_uip_cb(NULL)
195{
196 #if USE_LWIP > 0
199 #endif
200}
201
202 #else // Using RF24Mesh
203RF24EthernetClass::RF24EthernetClass(RF24& _radio, RF24Network& _network, RF24Mesh& _mesh) : radio(_radio), network(_network), mesh(_mesh) // fn_uip_cb(NULL)
204{
205 #if USE_LWIP > 0
208 #endif
209}
210 #endif
211
212#else
213 #if defined(RF24_TAP)
214RF24EthernetClass::RF24EthernetClass(nrf_to_nrf& _radio, RF52Network& _network) : radio(_radio), network(_network) // fn_uip_cb(NULL)
215{
216 #if USE_LWIP > 0
219 #endif
220}
221
222 #else // Using RF24Mesh
223RF24EthernetClass::RF24EthernetClass(nrf_to_nrf& _radio, RF52Network& _network, RF52Mesh& _mesh) : radio(_radio), network(_network), mesh(_mesh) // fn_uip_cb(NULL)
224{
225 #if USE_LWIP > 0
226 RF24Client::gState[0] = new RF24Client::ConnectState;
227 RF24Client::gState[1] = new RF24Client::ConnectState;
228 #endif
229}
230 #endif
231#endif
232/*************************************************************/
233
235{
236 Ethernet.tick();
237}
238
239/*************************************************************/
240
242{
243 // Kept for backwards compatibility only
244}
245
246/*******************************************************/
247
248void RF24EthernetClass::setMac(uint16_t address)
249{
250 if (!network.multicastRelay) { // Radio has not been started yet
251 radio.begin();
252 }
253
254 const uint8_t mac[6] = {0x52, 0x46, 0x32, 0x34, (uint8_t)address, (uint8_t)(address >> 8)};
255 // printf("MAC: %o %d\n", address, mac[0]);
256
257#if defined(RF24_TAP)
258 uip_seteth_addr(mac);
259 network.multicastRelay = 1;
260#else
261 if (mac[0] == 1) {
262 // Dummy operation to prevent warnings if TAP not defined
263 };
264#endif
265 RF24_Channel = RF24_Channel ? RF24_Channel : 97;
266 network.begin(RF24_Channel, address);
267}
268
269/*******************************************************/
270
271void RF24EthernetClass::setChannel(uint8_t channel)
272{
273 RF24_Channel = channel;
274 if (network.multicastRelay) { // Radio has not been started yet
275 radio.setChannel(RF24_Channel);
276 }
277}
278
279/*******************************************************/
280
281void RF24EthernetClass::begin(IPAddress ip)
282{
283 IPAddress dns = {8, 8, 8, 8};
284 begin(ip, dns);
285}
286
287/*******************************************************/
288
289void RF24EthernetClass::begin(IPAddress ip, IPAddress dns)
290{
291 IPAddress gateway = ip;
292 gateway[3] = 1;
293 begin(ip, dns, gateway);
294}
295
296/*******************************************************/
297
298void RF24EthernetClass::begin(IPAddress ip, IPAddress dns, IPAddress gateway)
299{
300 IPAddress subnet(255, 255, 255, 0);
301 begin(ip, dns, gateway, subnet);
302}
303
304/*******************************************************/
305
306void RF24EthernetClass::begin(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)
307{
308 configure(ip, dns, gateway, subnet);
309}
310
311/*******************************************************/
312
313void RF24EthernetClass::configure(IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet)
314{
315#if !defined(RF24_TAP) // Using RF24Mesh
316 mesh.setNodeID(ip[3]);
317#endif
318
319#if USE_LWIP < 1
320 uip_buf = (uint8_t*)&network.frag_ptr->message_buffer[0];
321
322 uip_ipaddr_t ipaddr;
323 uip_ip_addr(ipaddr, ip);
324 uip_sethostaddr(ipaddr);
325 uip_ip_addr(ipaddr, gateway);
326 uip_setdraddr(ipaddr);
327 uip_ip_addr(ipaddr, subnet);
328 uip_setnetmask(ipaddr);
329 _dnsServerAddress = dns;
330
331 timer_set(&this->periodic_timer, CLOCK_SECOND / UIP_TIMER_DIVISOR);
332
333 #if defined(RF24_TAP)
334 timer_set(&this->arp_timer, CLOCK_SECOND * 2);
335 #endif
336
337 uip_init();
338 #if defined(RF24_TAP)
339 uip_arp_init();
340 #endif
341#else
342
344 // Allocate data for a single client
345 RF24Client::incomingData[RF24Client::activeState] = (char*)malloc(INCOMING_DATA_SIZE);
346 RF24Client::clientConnectionTimeout = 0;
347 RF24Client::serverConnectionTimeout = 30000;
348
349 #if defined RF24ETHERNET_CORE_REQUIRES_LOCKING && defined ESP32
350 wifi_mode_t mode;
351 esp_err_t err = esp_wifi_get_mode(&mode);
352 if (err == ESP_OK) {
353 useCoreLocking = true;
354 }
355 else {
356 useCoreLocking = false;
357 }
358 #elif defined RF24ETHERNET_CORE_REQUIRES_LOCKING
359 useCoreLocking = true;
360 #endif
361
362 ip4_addr_t myIp, myMask, myGateway;
363 IP4_ADDR(&myIp, ip[0], ip[1], ip[2], ip[3]);
364 IP4_ADDR(&myMask, subnet[0], subnet[1], subnet[2], subnet[3]);
365 IP4_ADDR(&myGateway, gateway[0], gateway[1], gateway[2], gateway[3]);
366 _dnsServerAddress = dns;
367
368 void* context = nullptr;
369 #if defined RF24ETHERNET_CORE_REQUIRES_LOCKING
370 if (useCoreLocking) {
371 ETHERNET_APPLY_LOCK();
372 }
373 #endif
374 netif_add(&Ethernet.myNetif, &myIp, &myMask, &myGateway, context, netif_init, ip_input);
375 netif_set_default(&Ethernet.myNetif);
376 netif_set_up(&Ethernet.myNetif);
377 #if defined RF24ETHERNET_CORE_REQUIRES_LOCKING
378 if (useCoreLocking) {
379 ETHERNET_REMOVE_LOCK();
380 }
381 #endif
382
383#endif
384}
385
386/*******************************************************/
387
389{
390#if USE_LWIP < 1
391 uip_ipaddr_t ipaddr;
392 uip_ip_addr(ipaddr, gwIP);
393 uip_setdraddr(ipaddr);
394#else
395 ip4_addr_t new_gw;
396 IP4_ADDR(&new_gw, gwIP[0], gwIP[1], gwIP[2], gwIP[3]);
397 #if defined RF24ETHERNET_CORE_REQUIRES_LOCKING
398 if (useCoreLocking) {
399 ETHERNET_APPLY_LOCK();
400 }
401 #endif
402 netif_set_gw(&Ethernet.myNetif, &new_gw);
403 #if defined RF24ETHERNET_CORE_REQUIRES_LOCKING
404 if (useCoreLocking) {
405 ETHERNET_REMOVE_LOCK();
406 }
407 #endif
408#endif
409}
410
411/*******************************************************/
412
413void RF24EthernetClass::listen(uint16_t port)
414{
415#if USE_LWIP < 1
416 uip_listen(HTONS(port));
417#else
418
419 #if defined RF24ETHERNET_CORE_REQUIRES_LOCKING
420 if (useCoreLocking) {
421 ETHERNET_APPLY_LOCK();
422 }
423 #endif
424 RF24Client::myPcb = tcp_new();
425 tcp_err(RF24Client::myPcb, RF24Client::error_callback);
426
427 err_t err = tcp_bind(RF24Client::myPcb, IP_ADDR_ANY, port);
428 if (err != ERR_OK) {
429 IF_RF24ETHERNET_DEBUG_CLIENT(Serial.println("Server: Unable to bind to port"););
430 }
431
432 RF24Client::gState[0]->finished = false;
433 RF24Client::gState[0]->connected = false;
434 RF24Client::gState[0]->result = 0;
435 RF24Client::gState[0]->waiting_for_ack = false;
436
437 RF24Client::myPcb = tcp_listen(RF24Client::myPcb);
438
439 tcp_arg(RF24Client::myPcb, &RF24Client::gState[0]);
440 tcp_accept(RF24Client::myPcb, RF24Client::accept);
441
442 #if defined RF24ETHERNET_CORE_REQUIRES_LOCKING
443 if (useCoreLocking) {
444 ETHERNET_REMOVE_LOCK();
445 }
446 #endif
447#endif
448}
449
450/*******************************************************/
451
453{
454#if USE_LWIP < 1
455 uip_ipaddr_t a;
456 uip_gethostaddr(a);
457 return ip_addr_uip(a);
458#else
459 if (netif_is_up(&myNetif)) {
460 // Get the IP address structure
461 const ip4_addr_t* ip_addr = netif_ip4_addr(&myNetif);
462 return (IPAddress(ip_addr->addr));
463 }
464 return IPAddress {0, 0, 0, 0};
465#endif
466}
467
468/*******************************************************/
469
471{
472#if USE_LWIP < 1
473 uip_ipaddr_t a;
474 uip_getnetmask(a);
475 return ip_addr_uip(a);
476#else
477 if (netif_is_up(&myNetif)) {
478 // Get the IP address structure
479 const ip4_addr_t* ip_addr = netif_ip4_netmask(&myNetif);
480 return (IPAddress(ip_addr->addr));
481 }
482 return IPAddress {0, 0, 0, 0};
483#endif
484}
485
486/*******************************************************/
487
489{
490#if USE_LWIP < 1
491 uip_ipaddr_t a;
492 uip_getdraddr(a);
493 return ip_addr_uip(a);
494#else
495 if (netif_is_up(&myNetif)) {
496 // Get the IP address structure
497 const ip4_addr_t* ip_addr = netif_ip4_gw(&myNetif);
498 return (IPAddress(ip_addr->addr));
499 }
500 return IPAddress {0, 0, 0, 0};
501#endif
502}
503
504/*******************************************************/
505
507{
508 return _dnsServerAddress;
509}
510
511/*******************************************************/
512#if USE_LWIP > 0
513//Should be call inside PHY RX Ethernet IRQ
514void RF24EthernetClass::EthRX_Handler(const uint8_t* ethFrame, const uint16_t lenEthFrame)
515{
516 LINK_STATS_INC(link.recv);
517 MIB2_STATS_NETIF_ADD(&Ethernet.myNetif, ifinoctets, lenEthFrame);
518 if (Ethernet.isUnicast(ethFrame[0]))
519 {
520 MIB2_STATS_NETIF_INC(&Ethernet.myNetif, ifinucastpkts);
521 }
522 else
523 {
524 MIB2_STATS_NETIF_INC(&Ethernet.myNetif, ifinnucastpkts);
525 }
526
527 writeRXQueue(&RXQueue, ethFrame, lenEthFrame);
528}
529
530#endif
531
532/*******************************************************/
533
534void RF24EthernetClass::tick()
535{
536
537#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_ARCH_NRF52) || defined ARDUINO_ARCH_RP2350
538 yield();
539#elif defined(ARDUINO_ARCH_ESP32)
540 const TickType_t xDelay = pdMS_TO_TICKS(1);
541 vTaskDelay(xDelay);
542#endif
543
544#if USE_LWIP < 1
545 uint8_t result = RF24Ethernet.mesh.update();
546
547 if (Ethernet.mesh.mesh_address == 0) {
548 Ethernet.mesh.DHCP();
549 }
550
551 if (result == EXTERNAL_DATA_TYPE) {
552 if (RF24Ethernet.network.frag_ptr->message_size <= UIP_BUFSIZE && RF24Ethernet.network.frag_ptr->message_size >= 28) {
553 uip_len = RF24Ethernet.network.frag_ptr->message_size;
554 }
555 }
556 else if (result == NETWORK_CORRUPTION) {
558 }
559
560 #if !defined(RF24_TAP)
561 if (uip_len > 0) {
562 uip_input();
563 if (uip_len > 0) {
564 network_send();
565 }
566 }
567 else if (timer_expired(&Ethernet.periodic_timer)) {
568 timer_reset(&Ethernet.periodic_timer);
569 for (int i = 0; i < UIP_CONNS; i++) {
570 uip_periodic(i);
571 /* If the above function invocation resulted in data that
572 should be sent out on the network, the global variable
573 uip_len is set to a value > 0. */
574 if (uip_len > 0) {
575 network_send();
576 }
577 }
578 }
579 #else // defined (RF24_TAP)
580 if (uip_len > 0) {
581 if (BUF->type == htons(UIP_ETHTYPE_IP)) {
582 uip_arp_ipin();
583 uip_input();
584 /* If the above function invocation resulted in data that
585 should be sent out on the network, the global variable
586 uip_len is set to a value > 0. */
587 if (uip_len > 0) {
588 uip_arp_out();
589 network_send();
590 }
591 }
592 else if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
593 uip_arp_arpin();
594 /* If the above function invocation resulted in data that
595 should be sent out on the network, the global variable
596 uip_len is set to a value > 0. */
597 if (uip_len > 0) {
598 network_send();
599 }
600 }
601 }
602 else if (timer_expired(&Ethernet.periodic_timer)) {
603 timer_reset(&Ethernet.periodic_timer);
604 for (int i = 0; i < UIP_CONNS; i++) {
605 uip_periodic(i);
606 /* If the above function invocation resulted in data that
607 should be sent out on the network, the global variable
608 uip_len is set to a value > 0. */
609 if (uip_len > 0) {
610 uip_arp_out();
611 network_send();
612 }
613 }
614 #endif // defined (RF24_TAP)
615 #if UIP_UDP
616 for (int i = 0; i < UIP_UDP_CONNS; i++) {
617 uip_udp_periodic(i);
618 /* If the above function invocation resulted in data that
619 should be sent out on the network, the global variable
620 uip_len is set to a value > 0. */
621 if (uip_len > 0) {
622 // uip_arp_out();
623 // network_send();
624 RF24UDP::_send((uip_udp_userdata_t*)(uip_udp_conns[i].appstate));
625 }
626 }
627 #endif /* UIP_UDP */
628 #if defined(RF24_TAP)
629 /* Call the ARP timer function every 10 seconds. */
630
631 if (timer_expired(&Ethernet.arp_timer)) {
632 timer_reset(&Ethernet.arp_timer);
633 uip_arp_timer();
634 }
635}
636 #endif // RF24_TAP
637
638#else // Using LWIP
639
640 uint8_t result = RF24Ethernet.mesh.update();
641
642 if (Ethernet.mesh.mesh_address == 0) {
643 Ethernet.mesh.DHCP();
644 }
645
646 if (result == EXTERNAL_DATA_TYPE) {
647 if (RF24Ethernet.network.frag_ptr->message_size > 28) {
648 uint16_t len = RF24Ethernet.network.frag_ptr->message_size;
649 memcpy(networkBuffer, RF24Ethernet.network.frag_ptr->message_buffer, len);
650 Ethernet.EthRX_Handler(networkBuffer, len);
651 IF_ETH_DEBUG_L1(Serial.println("Net: In"););
652 }
653 }
654
655 #if defined RF24ETHERNET_CORE_REQUIRES_LOCKING
656 if (useCoreLocking) {
657 ETHERNET_APPLY_LOCK();
658 }
659 #endif
660 sys_check_timeouts();
661
662 #if defined RF24ETHERNET_CORE_REQUIRES_LOCKING
663 if (useCoreLocking) {
664 ETHERNET_REMOVE_LOCK();
665 }
666 #endif
667
668 pbuf* p = readRXQueue(&RXQueue);
669 if (p != nullptr)
670 {
671
672 #if defined RF24ETHERNET_CORE_REQUIRES_LOCKING
673 if (useCoreLocking) {
674 ETHERNET_APPLY_LOCK();
675 }
676 #endif
677 if (myNetif.input(p, &myNetif) != ERR_OK)
678 {
679 LWIP_DEBUGF(NETIF_DEBUG, ("IP input error\r\n"));
680 if (p != nullptr) {
681 pbuf_free(p);
682 p = NULL;
683 }
684 }
685
686 #if defined RF24ETHERNET_CORE_REQUIRES_LOCKING
687 if (useCoreLocking) {
688 ETHERNET_REMOVE_LOCK();
689 }
690 #endif
691 }
692
693#endif
694}
695
696/*******************************************************/
697
698void RF24EthernetClass::network_send()
699{
700
701#if USE_LWIP < 1
702 IPAddress gwIP = Ethernet.gatewayIP();
703 int16_t nodeAddress = 0;
704
705 //If not the master node
706 if (Ethernet.mesh.mesh_address != 0) {
707 if (gwIP[3] != uip_buf[19]) { // If not sending to the gateway
708 IPAddress local_ip = Ethernet.localIP();
709 if (local_ip[0] == uip_buf[16] && local_ip[1] == uip_buf[17]) { // If we are local within the nRF24 network
710 //Request an address lookup from the Master node
711 nodeAddress = Ethernet.mesh.getAddress((char)uip_buf[19]); // Do an address lookup
712 if (nodeAddress < 0) {
713 nodeAddress = 0; // If the result is negative, send to master
714 }
715 } // If this address is outside the nRF24 network, it will be send to master (00)
716 }
717 }
718 else {
719 IPAddress local_ip = Ethernet.localIP();
720 if (local_ip[0] == uip_buf[16] && local_ip[1] == uip_buf[17]) { // If within the nRF24 radio network, do a lookup, else send to self (00)
721 nodeAddress = Ethernet.mesh.getAddress((char)uip_buf[19]);
722 if (nodeAddress < 0) {
723 return;
724 }
725 }
726 }
727 RF24NetworkHeader headerOut(nodeAddress, EXTERNAL_DATA_TYPE);
728
729 #if defined ETH_DEBUG_L1 || defined ETH_DEBUG_L2
730 bool ok = RF24Ethernet.network.write(headerOut, uip_buf, uip_len);
731 if (!ok) {
732 Serial.println();
733 Serial.print(millis());
734 Serial.println(F(" *** RF24Ethernet Network Write Fail ***"));
735 }
736 #else
737 RF24Ethernet.network.write(headerOut, uip_buf, uip_len);
738 #endif
739
740 #if defined ETH_DEBUG_L2
741 if (ok) {
742 Serial.println();
743 Serial.print(millis());
744 Serial.println(F(" RF24Ethernet Network Write OK"));
745 }
746 #endif
747#else
748
749#endif
750}
751
752/*******************************************************/
753/*
754void uipudp_appcall() {
755
756}*/
#define HTONS
volatile err_t result
Definition RF24Client.h:8
#define INCOMING_DATA_SIZE
Definition RF24Client.h:78
err_t tun_netif_output(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
err_t netif_init(struct netif *myNetif)
err_t netif_output(struct netif *netif, struct pbuf *p)
RF24EthernetClass RF24Ethernet
static void error_callback(void *arg, err_t err)
static ConnectState * gState[2]
Definition RF24Client.h:218
static bool activeState
Definition RF24Client.h:233
uint32_t networkCorruption
static EthQueue RXQueue
void setMac(uint16_t address)
void setChannel(uint8_t channel)
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
void begin(IP_ADDR myIP, IP_ADDR subnet)
static bool useCoreLocking
IPAddress gatewayIP()
#define Ethernet
#define IF_RF24ETHERNET_DEBUG_CLIENT(x)
#define IF_ETH_DEBUG_L1(x)
#define UIP_TIMER_DIVISOR
Adjust the rate at which the IP stack performs periodic processing.
Definition uip-conf.h:127
uint16_t len[MAX_RX_QUEUE]