RF24Gateway - TCP/IP over RF24Network v2.2.0
TMRh20 - Pushing the practical limits of RF24 modules
Loading...
Searching...
No Matches
RF24Gateway.cpp
1/**
2 * @file RF24Gateway.cpp
3 *
4 * Class definitions for RF24Gateway
5 */
6
7#include "RF24Gateway.h"
8#include "RF24Mesh/RF24Mesh_config.h"
9#if defined(RF24NETWORK_CCM)
10 #include <RF24Network/RF24CCM.h>
11#endif
12
13/***************************************************************************************/
14
15template<class mesh_t, class network_t, class radio_t>
16ESBGateway<mesh_t, network_t, radio_t>::ESBGateway(radio_t& _radio, network_t& _network, mesh_t& _mesh) : radio(_radio), network(_network), mesh(_mesh)
17{
18 gotInterrupt = false;
21}
22
23/***************************************************************************************/
24
25template<class mesh_t, class network_t, class radio_t>
26void ESBGateway<mesh_t, network_t, radio_t>::begin(uint8_t nodeID, uint8_t _channel, rf24_datarate_e data_rate)
27{
28 mesh_enabled = true;
29 begin(true, mesh_enabled, 0, nodeID, data_rate, _channel);
30}
31
32/***************************************************************************************/
33
34template<class mesh_t, class network_t, class radio_t>
35void ESBGateway<mesh_t, network_t, radio_t>::begin(uint16_t address, uint8_t _channel, rf24_datarate_e data_rate, bool meshEnable, uint8_t nodeID)
36{
37 begin(0, mesh_enabled, address, nodeID, data_rate, _channel);
38}
39
40/***************************************************************************************/
41
42template<class mesh_t, class network_t, class radio_t>
43bool ESBGateway<mesh_t, network_t, radio_t>::begin(bool configTUN, bool meshEnable, uint16_t address, uint8_t mesh_nodeID, rf24_datarate_e data_rate, uint8_t _channel)
44{
45#if (RF24GATEWAY_DEBUG_LEVEL >= 1)
46 printf("GW Begin\n");
47 printf("Config Device address 0%o nodeID %d\n", address, mesh_nodeID);
48#endif
49 config_TUN = configTUN;
50
51 /// FIX
52
53 channel = _channel; // 97;
54
55 dataRate = data_rate;
56
57 if (configDevice(address) < 0) {
58 return false;
59 }
60 mesh_enabled = meshEnable;
61 thisNodeID = mesh_nodeID;
62 thisNodeAddress = address;
63
64 if (meshEnable) {
65 // GW radio channel setting takes precedence over mesh_default_channel
66 if (channel == 97 && MESH_DEFAULT_CHANNEL != 97) {
67 channel = MESH_DEFAULT_CHANNEL;
68 }
69
70 if (!thisNodeAddress && !mesh_nodeID) {
71 mesh.setNodeID(0);
72 }
73 else {
74 if (!mesh_nodeID) {
75 mesh_nodeID = 253;
76 }
77 mesh.setNodeID(mesh_nodeID); // Try not to conflict with any low-numbered node-ids
78 }
79 mesh.begin(channel, data_rate);
80 thisNodeAddress = mesh.mesh_address;
81 }
82 else {
83 radio.begin();
84 delay(5);
85 const uint16_t this_node = address;
86 radio.setDataRate(dataRate);
87 radio.setChannel(channel);
88
89 network.begin(/*node address*/ this_node);
90 thisNodeAddress = this_node;
91 }
92 network.multicastRelay = 1;
93
94 //#if (RF24GATEWAY_DEBUG_LEVEL >= 1)
95 radio.printDetails();
96 //#endif
97
98 setupSocket();
99 loadRoutingTable();
100
101 return true;
102}
103
104/***************************************************************************************/
105
106template<class mesh_t, class network_t, class radio_t>
107void ESBGateway<mesh_t, network_t, radio_t>::loadRoutingTable()
108{
109 std::ifstream infile("routing.txt", std::ifstream::in);
110 if (!infile) {
111 return;
112 }
113
114 std::string str;
115 std::string ip, mask, gw;
116 uint16_t count = 0;
117 std::string space = " ";
118
119 while (std::getline(infile, str)) {
120 size_t startLen = 0;
121 size_t subLen = str.find(space);
122 if (subLen != std::string::npos) {
123 ip = str.substr(0, subLen);
124 }
125 else {
126 continue;
127 }
128 startLen = subLen + 1;
129 subLen = str.find(space, startLen);
130 if (subLen != std::string::npos) {
131 subLen -= (startLen);
132 mask = str.substr(startLen, subLen);
133 }
134 else {
135 continue;
136 }
137 startLen = startLen + subLen + 1;
138 subLen = str.length() - (startLen);
139 gw = str.substr(startLen, subLen);
140
141 routingStruct[count].ip.s_addr = ntohl(inet_network(ip.c_str()));
142 routingStruct[count].mask.s_addr = ntohl(inet_network(mask.c_str()));
143 routingStruct[count].gw.s_addr = ntohl(inet_network(gw.c_str()));
144
145 count++;
146 if (count >= 256) {
147 break;
148 }
149 }
150 routingTableSize = count;
151
152 // for(int i=0; i<count; i++){
153 // std::cout << inet_ntoa(routingStruct[i].ip) << ";" << inet_ntoa(routingStruct[i].mask) << ";" << inet_ntoa(routingStruct[i].gw) << std::endl;
154 // }
155}
156
157/***************************************************************************************/
158
159template<class mesh_t, class network_t, class radio_t>
161{
162 return mesh_enabled;
163}
164
165/***************************************************************************************/
166
167template<class mesh_t, class network_t, class radio_t>
168int ESBGateway<mesh_t, network_t, radio_t>::configDevice(uint16_t address)
169{
170 std::string tunTapDevice = "tun_nrf24";
171 strcpy(tunName, tunTapDevice.c_str());
172
173 int flags;
174 if (config_TUN) {
175 flags = IFF_TUN | IFF_NO_PI | IFF_MULTI_QUEUE;
176 }
177 else {
178 flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
179 }
180 tunFd = allocateTunDevice(tunName, flags, address);
181 if (tunFd < 0) {
182 std::cerr << "RF24Gw: Error allocating tun/tap interface: " << tunFd << std::endl;
183 return tunFd;
184 }
185#if RF24GATEWAY_DEBUG_LEVEL >= 1
186 std::cout << "RF24Gw: Successfully attached to tun/tap device " << tunTapDevice << std::endl;
187#endif
188 return tunFd;
189}
190
191/***************************************************************************************/
192
193template<class mesh_t, class network_t, class radio_t>
194int ESBGateway<mesh_t, network_t, radio_t>::allocateTunDevice(char* dev, int flags, uint16_t address)
195{
196 struct ifreq ifr;
197 int fd;
198
199 // open the device
200 if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {
201 return fd;
202 }
203
204 memset(&ifr, 0, sizeof(ifr));
205
206 ifr.ifr_flags = flags; // IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI
207
208 if (*dev) {
209 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
210 }
211
212 // Create device
213 if (ioctl(fd, TUNSETIFF, (void*)&ifr) < 0) {
214 close(fd);
215 std::cerr << "RF24Gw: Error: enabling TUNSETIFF" << std::endl;
216 uint32_t UID = getuid();
217 if (UID) {
218 const char* login = getlogin();
219 std::cout << "Not running as root, preconfigure the interface as follows" << std::endl;
220 std::cout << "sudo ip tuntap add dev tun_nrf24 mode tun user " << (login ? login : "<user>") << " multi_queue" << std::endl;
221 std::cout << "sudo ifconfig tun_nrf24 10.10.2.2/24" << std::endl;
222 }
223 return -1;
224 }
225
226 // Make persistent
227 if (ioctl(fd, TUNSETPERSIST, 1) < 0) {
228 close(fd);
229 std::cerr << "RF24Gw: Error: enabling TUNSETPERSIST" << std::endl;
230 return -1;
231 }
232
233 if (!config_TUN) {
234 struct sockaddr sap;
235 sap.sa_family = ARPHRD_ETHER;
236 ((char*)sap.sa_data)[4] = address;
237 ((char*)sap.sa_data)[5] = address >> 8;
238 ((char*)sap.sa_data)[0] = 0x52;
239 ((char*)sap.sa_data)[1] = 0x46;
240 ((char*)sap.sa_data)[2] = 0x32;
241 ((char*)sap.sa_data)[3] = 0x34;
242
243 // printf("Address 0%o first %u last %u\n",address,sap.sa_data[0],sap.sa_data[1]);
244 memcpy((char*)&ifr.ifr_hwaddr, (char*)&sap, sizeof(struct sockaddr));
245
246 if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) {
247#if RF24GATEWAY_DEBUG_LEVEL >= 1
248 fprintf(stderr, "RF24Gw: Failed to set MAC address\n");
249#endif
250 }
251 }
252
253 strcpy(dev, ifr.ifr_name);
254 return fd;
255}
256
257/***************************************************************************************/
258
259template<class mesh_t, class network_t, class radio_t>
261{
262 struct ifreq ifr;
263 struct sockaddr_in sin;
264 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
265 if (sockfd == -1) {
266 fprintf(stderr, "Could not get socket.\n");
267 return -1;
268 }
269
270 sin.sin_family = AF_INET;
271 // inet_aton(ip_addr,&sin.sin_addr.s_addr);
272 inet_aton(ip_addr, &sin.sin_addr);
273 strncpy(ifr.ifr_name, tunName, IFNAMSIZ);
274
275 if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
276 fprintf(stderr, "ifdown: shutdown ");
277 perror(ifr.ifr_name);
278 return -1;
279 }
280
281#ifdef ifr_flags
282 #define IRFFLAGS ifr_flags
283#else /* Present on kFreeBSD */
284 #define IRFFLAGS ifr_flagshigh
285#endif
286
287 if (!(ifr.IRFFLAGS & IFF_UP)) {
288 // fprintf(stdout, "Device is currently down..setting up.-- %u\n", ifr.IRFFLAGS);
289 ifr.IRFFLAGS |= IFF_UP;
290 if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
291 fprintf(stderr, "ifup: failed ");
292 perror(ifr.ifr_name);
293 return -1;
294 }
295 }
296
297 memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
298
299 // Set interface address
300 if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
301 fprintf(stderr, "Cannot set IP address. ");
302 perror(ifr.ifr_name);
303 return -1;
304 }
305
306 inet_aton(mask, &sin.sin_addr);
307 memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
308
309 if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) {
310 fprintf(stderr, "Cannot define subnet mask for this device");
311 perror(ifr.ifr_name);
312 return -1;
313 }
314
315#undef IRFFLAGS
316 return 0;
317}
318
319/***************************************************************************************/
320
321template<class mesh_t, class network_t, class radio_t>
323{
324 // No longer required
325}
326
327/***************************************************************************************/
328
329template<class mesh_t, class network_t, class radio_t>
331{
332
333 if (interrupts) {
334 gotInterrupt = true;
335 }
336 else {
337 handleRadioIn();
338 handleTX();
339 handleRX();
340 handleRadioOut();
341 }
342}
343
344/***************************************************************************************/
345
346template<class mesh_t, class network_t, class radio_t>
348{
349 if (!gotInterrupt && radio.available()) {
350 fifoCleared = true;
351 }
352 else {
353 if (!gotInterrupt) {
354 delay(waitDelay);
355 }
356 }
357 gotInterrupt = false;
358 handleRadioIn();
359 handleTX();
360 handleRX();
361 handleRadioOut();
362}
363
364/***************************************************************************************/
365
366template<class mesh_t, class network_t, class radio_t>
367void ESBGateway<mesh_t, network_t, radio_t>::handleRadioIn()
368{
369
370 uint8_t returnVal = 0;
371
372 if (mesh_enabled) {
373 while ((returnVal = mesh.update())) {
374 if (returnVal == NETWORK_OVERRUN) {
375 ++networkOverruns;
376 }
377 else if (returnVal == NETWORK_CORRUPTION) {
378 ++networkCorruption;
379 }
380 if (!thisNodeAddress) {
381 mesh.DHCP();
382 }
383 }
384 }
385 else {
386 while ((returnVal = network.update())) {
387 if (returnVal == NETWORK_OVERRUN) {
388 ++networkOverruns;
389 }
390 else if (returnVal == NETWORK_CORRUPTION) {
391 ++networkCorruption;
392 }
393 }
394 }
395
396 RF24NetworkFrame f;
397 while (network.external_queue.size() > 0) {
398 f = network.external_queue.front();
399
400 msgStruct msg;
401
402 if (f.message_size > 0 && f.message_size <= MAX_PAYLOAD_SIZE) {
403 if (!validSource(f)) {
404 ++droppedSpoofed;
405 network.external_queue.pop();
406 continue;
407 }
408 memcpy(&msg.message, &f.message_buffer, f.message_size);
409 msg.size = f.message_size;
410
411#if (RF24GATEWAY_DEBUG_LEVEL >= 1)
412 std::cout << "Radio: Received " << f.message_size << " bytes ... " << std::endl;
413#endif
414#if (RF24GATEWAY_DEBUG_LEVEL >= 3)
415 // printPayload(msg.getPayloadStr(),"radio RX");
416 std::cout << "TunRead: " << std::endl;
417 for (size_t i = 0; i < msg.size; i++) {
418 // std::cout << std::hex << buffer[i];
419 printf(":%0x :", msg.message[i]);
420 }
421 std::cout << std::endl;
422
423#endif
424
425 rxQueue.push(msg);
426 }
427 else {
428 // std::cerr << "Radio: Error reading data from radio. Read '" << f.message_size << "' Bytes." << std::endl;
429 }
430 network.external_queue.pop();
431 }
432}
433
434/***************************************************************************************/
435
436template<class mesh_t, class network_t, class radio_t>
437bool ESBGateway<mesh_t, network_t, radio_t>::validSource(RF24NetworkFrame& frame)
438{
439 // Only the master assigns mesh addresses, so only it can match a sender to its IP.
440 // TAP frames carry Ethernet headers and are left to ARP.
441 if (!config_TUN || !mesh_enabled || thisNodeID > 0) {
442 return true;
443 }
444
445 // IPv4 only, with at least a full IP header
446 if (frame.message_size < 20 || (frame.message_buffer[0] >> 4) != 4) {
447 return false;
448 }
449
450 int16_t senderID = mesh.getNodeID(frame.header.from_node);
451 if (senderID < 0) {
452 return false; // Sender has no address assigned by this master
453 }
454
455 struct in_addr ipSource;
456 memcpy(&ipSource.s_addr, &frame.message_buffer[12], 4);
457
458 // Inside the RF24Mesh network: the last octet must be the sender's nodeID
459 if ((getLocalIP().s_addr & 0x00FFFFFF) == (ipSource.s_addr & 0x00FFFFFF)) {
460 return frame.message_buffer[15] == (uint8_t)senderID;
461 }
462
463 // Outside it: only a node listed as the gateway for that subnet in routing.txt may send
464 for (int i = 0; i < routingTableSize; i++) {
465 uint32_t mask = routingStruct[i].mask.s_addr;
466 if ((ipSource.s_addr & mask) == (routingStruct[i].ip.s_addr & mask) && (uint8_t)(routingStruct[i].gw.s_addr >> 24) == (uint8_t)senderID) {
467 return true;
468 }
469 }
470 return false;
471}
472
473/***************************************************************************************/
474
475template<class mesh_t, class network_t, class radio_t>
476struct in_addr ESBGateway<mesh_t, network_t, radio_t>::getLocalIP()
477{
478 struct ifaddrs *ifap, *ifa;
479 int family, s, n;
480 char host[NI_MAXHOST];
481 struct in_addr myNet;
482 memset(&myNet, 0, sizeof(myNet));
483
484 getifaddrs(&ifap);
485 for (ifa = ifap, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
486 if (std::string("tun_nrf24").compare(ifa->ifa_name) != 0 || ifa->ifa_addr == NULL) {
487 if (ifa->ifa_next == NULL) {
488 break;
489 }
490 else {
491 continue;
492 }
493 }
494
495 family = ifa->ifa_addr->sa_family;
496
497 // This is an IPv4 interface, get the IP
498 if (family == AF_INET) {
499 s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
500 if (s == 0) {
501 myNet.s_addr = ntohl(inet_network(host));
502 freeifaddrs(ifap);
503 return myNet;
504 }
505 }
506 }
507 freeifaddrs(ifap);
508 return myNet;
509}
510
511/***************************************************************************************/
512
513template<class mesh_t, class network_t, class radio_t>
514void ESBGateway<mesh_t, network_t, radio_t>::handleRadioOut()
515{
516 bool ok = 0;
517
518 uint32_t txQueueTimer = millis();
519
520 while (!txQueue.empty() && network.external_queue.size() == 0) {
521
522 uint32_t queueSize = txQueue.size();
523 if (millis() - txQueueTimer > 750 && queueSize >= 10) {
524 for (uint32_t i = 0; i < queueSize; i++) {
525 droppedIncoming++;
526 txQueue.pop();
527 }
528 return;
529 }
530 msgStruct* msgTx = &txQueue.front();
531
532#if (RF24GATEWAY_DEBUG_LEVEL >= 1)
533 std::cout << "Radio: Sending " << msgTx->size << " bytes ... ";
534 std::cout << std::endl;
535#endif
536#if (RF24GATEWAY_DEBUG_LEVEL >= 3)
537
538 // PrintDebug == 1 does not have an endline.
539 // printPayload(msg.getPayloadStr(),"radio TX");
540#endif
541
542 std::uint8_t* tmp = msgTx->message;
543
544 // Ensure that at the length of the payload includes at least the MAC address
545 if (msgTx->size < 6) {
546 txQueue.pop();
547 continue;
548 }
549
550 if (!config_TUN) { // TAP can use RF24Mesh for address assignment, but will still use ARP for address resolution
551
552 uint32_t RF24_STR = 0x34324652; // Identifies the mac as an RF24 mac
553 uint32_t ARP_BC = 0xFFFFFFFF; // Broadcast address
554 struct macStruct
555 {
556 uint32_t rf24_Verification;
557 uint16_t rf24_Addr;
558 };
559
560 macStruct macData;
561 memcpy(&macData.rf24_Addr, tmp + 4, 2);
562 memcpy(&macData.rf24_Verification, tmp, 4);
563
564 if (macData.rf24_Verification == RF24_STR) {
565 const uint16_t other_node = macData.rf24_Addr;
566 RF24NetworkHeader header(/*to node*/ other_node, EXTERNAL_DATA_TYPE);
567 ok = network.write(header, &msgTx->message, msgTx->size);
568 }
569 else if (macData.rf24_Verification == ARP_BC) {
570 RF24NetworkHeader header(/*to node*/ 00, EXTERNAL_DATA_TYPE); // Set to master node, will be modified by RF24Network if multi-casting
571 if (msgTx->size <= 42) {
572 if (thisNodeAddress == 00) { // Master Node
573
574 uint32_t arp_timeout = millis();
575
576 ok = network.multicast(header, &msgTx->message, msgTx->size, 1); // Send to Level 1
577 while (millis() - arp_timeout < 5) {
578 uint8_t returnVal = network.update();
579 if (returnVal == NETWORK_OVERRUN) {
580 ++networkOverruns;
581 }
582 else if (returnVal == NETWORK_CORRUPTION) {
583 ++networkCorruption;
584 }
585 }
586 network.multicast(header, &msgTx->message, msgTx->size, 1); // Send to Level 1
587 arp_timeout = millis();
588 while (millis() - arp_timeout < 15) {
589 uint8_t returnVal = network.update();
590 if (returnVal == NETWORK_OVERRUN) {
591 ++networkOverruns;
592 }
593 else if (returnVal == NETWORK_CORRUPTION) {
594 ++networkCorruption;
595 }
596 }
597 network.multicast(header, &msgTx->message, msgTx->size, 1); // Send to Level 1
598 }
599 else {
600 ok = network.write(header, &msgTx->message, msgTx->size);
601 }
602 }
603 }
604 }
605 else { // TUN always needs to use RF24Mesh for address assignment AND resolution
606
607 // Ensure that at least the 20-byte TCP/IP header is available
608 if (msgTx->size < 20) {
609 txQueue.pop();
610 continue;
611 }
612
613 uint8_t lastOctet = tmp[19];
614 int16_t meshAddr;
615
616 RF24NetworkHeader header(00, EXTERNAL_DATA_TYPE);
617 bool sendData = false;
618
619 struct in_addr ipDestination;
620 memcpy(&ipDestination.s_addr, &tmp[16], 4);
621
622 if ((getLocalIP().s_addr & 0x00FFFFFF) == (ipDestination.s_addr & 0x00FFFFFF)) { // Is inside the RF24Mesh network
623 if ((meshAddr = mesh.getAddress(lastOctet)) > 0) {
624 header.to_node = meshAddr;
625 sendData = true;
626 }
627 else {
628 if (thisNodeID > 0) { // If IP is in mesh range, address lookup fails, and this is not master,
629 sendData = true; // send to 00 anyway in case destination is master, or the lookup just failed
630 }
631 // printf("Could not find matching mesh nodeID for IP ending in %d\n",lastOctet);
632 }
633 }
634 else if (thisNodeID > 0) { // If not master, send to master for routing etc. if target not within mesh
635 sendData = true;
636 }
637 else if (routingTableSize > 0) {
638 for (int i = 0; i < routingTableSize; i++) {
639 struct in_addr network;
640 network.s_addr = routingStruct[i].ip.s_addr & routingStruct[i].mask.s_addr;
641 struct in_addr destNet;
642 destNet.s_addr = ipDestination.s_addr & routingStruct[i].mask.s_addr;
643 // printf("network %s destNet: %s\n",inet_ntoa(network),inet_ntoa(destNet));
644 if (destNet.s_addr == network.s_addr) {
645 uint8_t toNode = routingStruct[i].gw.s_addr >> 24;
646 int16_t netAddr = 0;
647 if ((netAddr = mesh.getAddress(toNode)) > 0) {
648 header.to_node = netAddr;
649 sendData = true;
650 break;
651 }
652 }
653 }
654 }
655
656 if (sendData) {
657 ok = network.write(header, msgTx->message, msgTx->size);
658 // std::cout << "SendData " << header.to_node << std::endl;
659 }
660 }
661 // delay( rf24_min(msgTx->size/48,20));
662 txQueue.pop();
663
664 // printf("Addr: 0%#x\n",macData.rf24_Addr);
665 // printf("Verif: 0%#x\n",macData.rf24_Verification);
666 if (ok) {
667 // std::cout << "ok." << std::endl;
668 }
669 else {
670 // std::cerr << "failed." << std::endl;
671 }
672
673 } // End Tx
674}
675
676/***************************************************************************************/
677
678template<class mesh_t, class network_t, class radio_t>
679void ESBGateway<mesh_t, network_t, radio_t>::handleRX(uint32_t waitDelay)
680{
681 fd_set socketSet;
682 struct timeval selectTimeout;
683 uint8_t buffer[MAX_PAYLOAD_SIZE];
684 int nread;
685
686 if (tunFd < 0) {
687 return;
688 }
689
690 uint32_t tunTimeout = millis();
691
692 while (true) {
693 // select() modifies both of these, so they must be reset before every call
694 FD_ZERO(&socketSet);
695 FD_SET(tunFd, &socketSet);
696 selectTimeout.tv_sec = 0;
697 selectTimeout.tv_usec = waitDelay * 1000;
698
699 int ready = select(tunFd + 1, &socketSet, NULL, NULL, &selectTimeout);
700 if (ready == 0) {
701 return;
702 }
703 if (ready < 0) {
704 if (errno == EINTR && millis() - tunTimeout <= 750) {
705 continue;
706 }
707 return;
708 }
709 if (FD_ISSET(tunFd, &socketSet)) {
710 if ((nread = read(tunFd, buffer, MAX_PAYLOAD_SIZE)) >= 0) {
711#if (RF24GATEWAY_DEBUG_LEVEL >= 1)
712 std::cout << "Tun: Successfully read " << nread << " bytes from tun device" << std::endl;
713#endif
714#if (RF24GATEWAY_DEBUG_LEVEL >= 3)
715 std::cout << "TunRead: " << std::endl;
716 for (int i = 0; i < nread; i++)
717 {
718 printf(":%0x :", buffer[i]);
719 }
720 std::cout << std::endl;
721#endif
722 msgStruct msg;
723 memcpy(&msg.message, &buffer, nread);
724 msg.size = nread;
725 txQueue.push(msg);
726 }
727 else {
728#if (RF24GATEWAY_DEBUG_LEVEL >= 1)
729 std::cerr << "Tun: Error while reading from tun/tap interface." << std::endl;
730#endif
731 }
732 }
733 if (millis() - tunTimeout > 750) {
734 return;
735 }
736 }
737}
738
739/***************************************************************************************/
740
741template<class mesh_t, class network_t, class radio_t>
742void ESBGateway<mesh_t, network_t, radio_t>::handleTX()
743{
744
745 if (rxQueue.size() < 1 || tunFd < 0)
746 {
747 return;
748 }
749 msgStruct* msg = &rxQueue.front();
750
751 if (msg->size > MAX_PAYLOAD_SIZE)
752 {
753 // printf("*****WTF OVER *****");
754 rxQueue.pop();
755 return;
756 }
757
758 if (msg->size > 0)
759 {
760
761 size_t writtenBytes = write(tunFd, &msg->message, msg->size);
762 if (writtenBytes != msg->size)
763 {
764// std::cerr << "Tun: Less bytes written to tun/tap device then requested." << std::endl;
765#if RF24GATEWAY_DEBUG_LEVEL >= 1
766 printf("Tun: Less bytes written %d to tun/tap device then requested %d.", writtenBytes, msg->size);
767#endif
768 }
769 else
770 {
771#if (RF24GATEWAY_DEBUG_LEVEL >= 1)
772 std::cout << "Tun: Successfully wrote " << writtenBytes << " bytes to tun device" << std::endl;
773#endif
774 }
775
776#if (RF24GATEWAY_DEBUG_LEVEL >= 3)
777 // printPayload(msg.message,"tun write");
778 std::cout << "TunRead: " << std::endl;
779 for (size_t i = 0; i < msg->size; i++) {
780 // printf(":%0x :",msg->message[i]);
781 }
782 std::cout << std::endl;
783#endif
784 }
785
786 rxQueue.pop();
787}
788
789/***************************************************************************************
790
791template<class mesh_t, class network_t, class radio_t>
792void ESBGateway<mesh_t, network_t, radio_t>::printPayload(std::string buffer, std::string debugMsg)
793{
794}
795*/
796/***************************************************************************************
797
798template<class mesh_t, class network_t, class radio_t>
799void ESBGateway<mesh_t, network_t, radio_t>::printPayload(char* buffer, int nread, std::string debugMsg)
800{
801}
802*/
803/***************************************************************************************/
804
805template<class mesh_t, class network_t, class radio_t>
806void ESBGateway<mesh_t, network_t, radio_t>::setupSocket()
807{
808 int ret;
809 const char* myAddr = "127.0.0.1";
810
811 addr.sin_family = AF_INET;
812 ret = inet_aton(myAddr, &addr.sin_addr);
813 if (ret == 0) {
814 perror("inet_aton");
815 exit(1);
816 }
817 addr.sin_port = htons(32001);
818 // buf = "Hello UDP";
819 s = socket(PF_INET, SOCK_DGRAM, 0);
820 if (s == -1) {
821 perror("socket");
822 exit(1);
823 }
824}
825
826/***************************************************************************************/
827
828template<class mesh_t, class network_t, class radio_t>
829void ESBGateway<mesh_t, network_t, radio_t>::sendUDP(uint8_t nodeID, RF24NetworkFrame frame)
830{
831
832 uint8_t buffer[MAX_PAYLOAD_SIZE + 11];
833
834 if (frame.message_size > MAX_PAYLOAD_SIZE) {
835 return;
836 }
837 memcpy(&buffer[0], &nodeID, 1);
838 memcpy(&buffer[1], &frame.header, 8);
839 memcpy(&buffer[9], &frame.message_size, 2);
840 memcpy(&buffer[11], &frame.message_buffer, frame.message_size);
841
842 int ret = sendto(s, &buffer, frame.message_size + 11, 0, (struct sockaddr*)&addr, sizeof(addr));
843 if (ret == -1)
844 {
845 perror("sendto");
846 exit(1);
847 }
848}
849
850// ensure the compiler is aware of the possible datatype for the template class
851template class ESBGateway<ESBMesh<ESBNetwork<RF24>, RF24>, ESBNetwork<RF24>, RF24>;
852#if defined(RF24NETWORK_CCM)
853template class ESBGateway<ESBMesh<ESBNetwork<RF24CCM>, RF24CCM>, ESBNetwork<RF24CCM>, RF24CCM>;
854#endif
bool meshEnabled()
int setIP(char *ip_addr, char *mask)
uint32_t droppedSpoofed
uint16_t routingTableSize
void interrupts(bool enable=1)
void poll(uint32_t waitDelay=3)
ESBGateway(radio_t &_radio, network_t &_network, mesh_t &_mesh)
void begin(uint8_t nodeID=0, uint8_t channel=97, rf24_datarate_e data_rate=RF24_1MBPS)
void update(bool interrupts=0)
bool fifoCleared
void sendUDP(uint8_t nodeID, RF24NetworkFrame frame)