7#include "RF24Gateway.h"
8#include "RF24Mesh/RF24Mesh_config.h"
12template<
class mesh_t,
class network_t,
class radio_t>
15 interruptInProgress = 0;
16 interruptsEnabled = 1;
21template<
class mesh_t,
class network_t,
class radio_t>
25 begin(
true, mesh_enabled, 0, nodeID, data_rate, _channel);
30template<
class mesh_t,
class network_t,
class radio_t>
33 begin(0, mesh_enabled, address, nodeID, data_rate, _channel);
38template<
class mesh_t,
class network_t,
class radio_t>
43 printf(
"Config Device address 0%o nodeID %d\n", address, mesh_nodeID);
45 config_TUN = configTUN;
53 configDevice(address);
54 mesh_enabled = meshEnable;
55 thisNodeID = mesh_nodeID;
56 thisNodeAddress = address;
60 if (channel == 97 && MESH_DEFAULT_CHANNEL != 97) {
61 channel = MESH_DEFAULT_CHANNEL;
64 if (!thisNodeAddress && !mesh_nodeID) {
71 mesh.setNodeID(mesh_nodeID);
73 mesh.begin(channel, data_rate);
74 thisNodeAddress = mesh.mesh_address;
79 const uint16_t this_node = address;
80 radio.setDataRate(dataRate);
81 radio.setChannel(channel);
83 network.begin( this_node);
84 thisNodeAddress = this_node;
86 network.multicastRelay = 1;
100template<
class mesh_t,
class network_t,
class radio_t>
103 std::ifstream infile(
"routing.txt", std::ifstream::in);
109 std::string ip, mask, gw;
111 std::string space =
" ";
113 while (std::getline(infile, str)) {
115 size_t subLen = str.find(space);
116 if (subLen != std::string::npos) {
117 ip = str.substr(0, subLen);
122 startLen = subLen + 1;
123 subLen = str.find(space, startLen);
124 if (subLen != std::string::npos) {
125 subLen -= (startLen);
126 mask = str.substr(startLen, subLen);
131 startLen = startLen + subLen + 1;
132 subLen = str.length() - (startLen);
133 gw = str.substr(startLen, subLen);
135 routingStruct[count].ip.s_addr = ntohl(inet_network(ip.c_str()));
136 routingStruct[count].mask.s_addr = ntohl(inet_network(mask.c_str()));
137 routingStruct[count].gw.s_addr = ntohl(inet_network(gw.c_str()));
144 routingTableSize = count;
153template<
class mesh_t,
class network_t,
class radio_t>
161template<
class mesh_t,
class network_t,
class radio_t>
164 std::string tunTapDevice =
"tun_nrf24";
165 strcpy(tunName, tunTapDevice.c_str());
169 flags = IFF_TUN | IFF_NO_PI | IFF_MULTI_QUEUE;
172 flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
174 tunFd = allocateTunDevice(tunName, flags, address);
177 std::cout <<
"RF24Gw: Successfully attached to tun/tap device " << tunTapDevice << std::endl;
180 std::cerr <<
"RF24Gw: Error allocating tun/tap interface: " << tunFd << std::endl;
189template<
class mesh_t,
class network_t,
class radio_t>
196 if ((fd = open(
"/dev/net/tun", O_RDWR)) < 0) {
200 memset(&ifr, 0,
sizeof(ifr));
202 ifr.ifr_flags = flags;
205 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
209 if (ioctl(fd, TUNSETIFF, (
void*)&ifr) < 0) {
212 std::cerr <<
"RF24Gw: Error: enabling TUNSETIFF" << std::endl;
213 std::cerr <<
"RF24Gw: If changing from TAP/TUN, run 'sudo ip link delete tun_nrf24' to remove the interface" << std::endl;
219 if (ioctl(fd, TUNSETPERSIST, 1) < 0) {
220#if (DEBUG_LEVEL >= 1)
221 std::cerr <<
"RF24Gw: Error: enabling TUNSETPERSIST" << std::endl;
228 sap.sa_family = ARPHRD_ETHER;
229 ((
char*)sap.sa_data)[4] = address;
230 ((
char*)sap.sa_data)[5] = address >> 8;
231 ((
char*)sap.sa_data)[0] = 0x52;
232 ((
char*)sap.sa_data)[1] = 0x46;
233 ((
char*)sap.sa_data)[2] = 0x32;
234 ((
char*)sap.sa_data)[3] = 0x34;
237 memcpy((
char*)&ifr.ifr_hwaddr, (
char*)&sap,
sizeof(
struct sockaddr));
239 if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) {
241 fprintf(stderr,
"RF24Gw: Failed to set MAC address\n");
246 strcpy(dev, ifr.ifr_name);
252template<
class mesh_t,
class network_t,
class radio_t>
256 struct sockaddr_in sin;
257 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
259 fprintf(stderr,
"Could not get socket.\n");
263 sin.sin_family = AF_INET;
265 inet_aton(ip_addr, &sin.sin_addr);
266 strncpy(ifr.ifr_name, tunName, IFNAMSIZ);
268 if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
269 fprintf(stderr,
"ifdown: shutdown ");
270 perror(ifr.ifr_name);
275 #define IRFFLAGS ifr_flags
277 #define IRFFLAGS ifr_flagshigh
280 if (!(ifr.IRFFLAGS & IFF_UP)) {
282 ifr.IRFFLAGS |= IFF_UP;
283 if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
284 fprintf(stderr,
"ifup: failed ");
285 perror(ifr.ifr_name);
290 memcpy(&ifr.ifr_addr, &sin,
sizeof(
struct sockaddr));
293 if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
294 fprintf(stderr,
"Cannot set IP address. ");
295 perror(ifr.ifr_name);
299 inet_aton(mask, &sin.sin_addr);
300 memcpy(&ifr.ifr_addr, &sin,
sizeof(
struct sockaddr));
302 if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) {
303 fprintf(stderr,
"Cannot define subnet mask for this device");
304 perror(ifr.ifr_name);
314template<
class mesh_t,
class network_t,
class radio_t>
318 interruptsEnabled = enable;
321 while (interruptInProgress) {
324 interruptsEnabled = 0;
325 while (interruptInProgress) {
333template<
class mesh_t,
class network_t,
class radio_t>
338 interruptInProgress = 1;
339 uint32_t intTimer = millis();
340 while (!interruptsEnabled) {
342 if (millis() - intTimer > 1000) {
343 interruptInProgress = 0;
349 interruptInProgress = 0;
361template<
class mesh_t,
class network_t,
class radio_t>
367 while (interruptInProgress) {
370 interruptsEnabled = 0;
371 while (interruptInProgress) {
376 if (radio.rxFifoFull()) {
379 interruptsEnabled = 1;
383 interruptsEnabled = 1;
388template<
class mesh_t,
class network_t,
class radio_t>
392 while (mesh.update()) {
393 if (!thisNodeAddress) {
399 while (network.update()) {
404 while (network.external_queue.size() > 0) {
405 f = network.external_queue.front();
409 unsigned int bytesRead = f.message_size;
412 memcpy(&msg.message, &f.message_buffer, bytesRead);
413 msg.size = bytesRead;
415#if (DEBUG_LEVEL >= 1)
416 std::cout <<
"Radio: Received " << bytesRead <<
" bytes ... " << std::endl;
418#if (DEBUG_LEVEL >= 3)
420 std::cout <<
"TunRead: " << std::endl;
421 for (
size_t i = 0; i < msg.size; i++) {
423 printf(
":%0x :", msg.message[i]);
425 std::cout << std::endl;
434 network.external_queue.pop();
440template<
class mesh_t,
class network_t,
class radio_t>
441struct in_addr
ESBGateway<mesh_t, network_t, radio_t>::getLocalIP()
443 struct ifaddrs *ifap, *ifa;
445 char host[NI_MAXHOST];
446 struct in_addr myNet;
449 for (ifa = ifap, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
450 if (std::string(
"tun_nrf24").compare(ifa->ifa_name) != 0 || ifa->ifa_addr == NULL) {
451 if (ifa->ifa_next == NULL) {
459 family = ifa->ifa_addr->sa_family;
462 if (family == AF_INET) {
463 s = getnameinfo(ifa->ifa_addr,
sizeof(
struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
465 myNet.s_addr = ntohl(inet_network(host));
477template<
class mesh_t,
class network_t,
class radio_t>
482 while (!txQueue.empty() && network.external_queue.size() == 0) {
484 msgStruct* msgTx = &txQueue.front();
486#if (DEBUG_LEVEL >= 1)
487 std::cout <<
"Radio: Sending " << msgTx->size <<
" bytes ... ";
488 std::cout << std::endl;
490#if (DEBUG_LEVEL >= 3)
496 std::uint8_t* tmp = msgTx->message;
500 uint32_t RF24_STR = 0x34324652;
501 uint32_t ARP_BC = 0xFFFFFFFF;
504 uint32_t rf24_Verification;
509 memcpy(&macData.rf24_Addr, tmp + 4, 2);
510 memcpy(&macData.rf24_Verification, tmp, 4);
512 if (macData.rf24_Verification == RF24_STR) {
513 const uint16_t other_node = macData.rf24_Addr;
514 RF24NetworkHeader header( other_node, EXTERNAL_DATA_TYPE);
515 ok = network.write(header, &msgTx->message, msgTx->size);
517 else if (macData.rf24_Verification == ARP_BC) {
518 RF24NetworkHeader header( 00, EXTERNAL_DATA_TYPE);
519 if (msgTx->size <= 42) {
520 if (thisNodeAddress == 00) {
522 uint32_t arp_timeout = millis();
524 ok = network.multicast(header, &msgTx->message, msgTx->size, 1);
525 while (millis() - arp_timeout < 5) {
528 network.multicast(header, &msgTx->message, msgTx->size, 1);
529 arp_timeout = millis();
530 while (millis() - arp_timeout < 15) {
533 network.multicast(header, &msgTx->message, msgTx->size, 1);
536 ok = network.write(header, &msgTx->message, msgTx->size);
543 uint8_t lastOctet = tmp[19];
546 RF24NetworkHeader header(00, EXTERNAL_DATA_TYPE);
547 bool sendData =
false;
549 struct in_addr ipDestination;
550 memcpy(&ipDestination.s_addr, &tmp[16], 4);
552 if ((getLocalIP().s_addr & 0x00FFFFFF) == (ipDestination.s_addr & 0x00FFFFFF)) {
553 if ((meshAddr = mesh.getAddress(lastOctet)) > 0) {
554 header.to_node = meshAddr;
558 if (thisNodeID > 0) {
564 else if (thisNodeID > 0) {
567 else if (routingTableSize > 0) {
568 for (
int i = 0; i < routingTableSize; i++) {
569 struct in_addr network;
570 network.s_addr = routingStruct[i].ip.s_addr & routingStruct[i].mask.s_addr;
571 struct in_addr destNet;
572 destNet.s_addr = ipDestination.s_addr & routingStruct[i].mask.s_addr;
574 if (destNet.s_addr == network.s_addr) {
575 uint8_t toNode = routingStruct[i].gw.s_addr >> 24;
577 if ((netAddr = mesh.getAddress(toNode)) > 0) {
578 header.to_node = netAddr;
587 ok = network.write(header, msgTx->message, msgTx->size);
608template<
class mesh_t,
class network_t,
class radio_t>
612 struct timeval selectTimeout;
613 uint8_t buffer[MAX_PAYLOAD_SIZE];
617 FD_SET(tunFd, &socketSet);
619 selectTimeout.tv_sec = 0;
620 selectTimeout.tv_usec = waitDelay * 1000;
622 if (select(tunFd + 1, &socketSet, NULL, NULL, &selectTimeout) != 0) {
623 if (FD_ISSET(tunFd, &socketSet)) {
624 if ((nread = read(tunFd, buffer, MAX_PAYLOAD_SIZE)) >= 0) {
626#if (DEBUG_LEVEL >= 1)
627 std::cout <<
"Tun: Successfully read " << nread <<
" bytes from tun device" << std::endl;
629#if (DEBUG_LEVEL >= 3)
630 std::cout <<
"TunRead: " << std::endl;
631 for (
int i = 0; i < nread; i++)
633 printf(
":%0x :", buffer[i]);
635 std::cout << std::endl;
638 memcpy(&msg.message, &buffer, nread);
640 if (txQueue.size() < 2) {
648#if (DEBUG_LEVEL >= 1)
649 std::cerr <<
"Tun: Error while reading from tun/tap interface." << std::endl;
658template<
class mesh_t,
class network_t,
class radio_t>
662 if (rxQueue.size() < 1)
666 msgStruct* msg = &rxQueue.front();
668 if (msg->size > MAX_PAYLOAD_SIZE)
678 size_t writtenBytes = write(tunFd, &msg->message, msg->size);
679 if (writtenBytes != msg->size)
683 printf(
"Tun: Less bytes written %d to tun/tap device then requested %d.", writtenBytes, msg->size);
688#if (DEBUG_LEVEL >= 1)
689 std::cout <<
"Tun: Successfully wrote " << writtenBytes <<
" bytes to tun device" << std::endl;
693#if (DEBUG_LEVEL >= 3)
695 std::cout <<
"TunRead: " << std::endl;
696 for (
size_t i = 0; i < msg->size; i++) {
699 std::cout << std::endl;
722template<
class mesh_t,
class network_t,
class radio_t>
726 const char* myAddr =
"127.0.0.1";
728 addr.sin_family = AF_INET;
729 ret = inet_aton(myAddr, &addr.sin_addr);
734 addr.sin_port = htons(32001);
736 s = socket(PF_INET, SOCK_DGRAM, 0);
745template<
class mesh_t,
class network_t,
class radio_t>
749 uint8_t buffer[MAX_PAYLOAD_SIZE + 11];
751 memcpy(&buffer[0], &nodeID, 1);
752 memcpy(&buffer[1], &frame.header, 8);
753 memcpy(&buffer[9], &frame.message_size, 2);
754 memcpy(&buffer[11], &frame.message_buffer, frame.message_size);
756 int ret = sendto(s, &buffer, frame.message_size + 11, 0, (
struct sockaddr*)&addr,
sizeof(addr));
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)
void sendUDP(uint8_t nodeID, RF24NetworkFrame frame)