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