7#include "RF24Gateway.h"
8#include "RF24Mesh/RF24Mesh_config.h"
9#if defined(RF24NETWORK_CCM)
10 #include <RF24Network/RF24CCM.h>
15template<
class mesh_t,
class network_t,
class radio_t>
25template<
class mesh_t,
class network_t,
class radio_t>
29 begin(
true, mesh_enabled, 0, nodeID, data_rate, _channel);
34template<
class mesh_t,
class network_t,
class radio_t>
37 begin(0, mesh_enabled, address, nodeID, data_rate, _channel);
42template<
class mesh_t,
class network_t,
class radio_t>
45#if (RF24GATEWAY_DEBUG_LEVEL >= 1)
47 printf(
"Config Device address 0%o nodeID %d\n", address, mesh_nodeID);
49 config_TUN = configTUN;
57 if (configDevice(address) < 0) {
60 mesh_enabled = meshEnable;
61 thisNodeID = mesh_nodeID;
62 thisNodeAddress = address;
66 if (channel == 97 && MESH_DEFAULT_CHANNEL != 97) {
67 channel = MESH_DEFAULT_CHANNEL;
70 if (!thisNodeAddress && !mesh_nodeID) {
77 mesh.setNodeID(mesh_nodeID);
79 mesh.begin(channel, data_rate);
80 thisNodeAddress = mesh.mesh_address;
85 const uint16_t this_node = address;
86 radio.setDataRate(dataRate);
87 radio.setChannel(channel);
89 network.begin( this_node);
90 thisNodeAddress = this_node;
92 network.multicastRelay = 1;
106template<
class mesh_t,
class network_t,
class radio_t>
107void ESBGateway<mesh_t, network_t, radio_t>::loadRoutingTable()
109 std::ifstream infile(
"routing.txt", std::ifstream::in);
115 std::string ip, mask, gw;
117 std::string space =
" ";
119 while (std::getline(infile, str)) {
121 size_t subLen = str.find(space);
122 if (subLen != std::string::npos) {
123 ip = str.substr(0, subLen);
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);
137 startLen = startLen + subLen + 1;
138 subLen = str.length() - (startLen);
139 gw = str.substr(startLen, subLen);
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()));
150 routingTableSize = count;
159template<
class mesh_t,
class network_t,
class radio_t>
167template<
class mesh_t,
class network_t,
class radio_t>
168int ESBGateway<mesh_t, network_t, radio_t>::configDevice(uint16_t address)
170 std::string tunTapDevice =
"tun_nrf24";
171 strcpy(tunName, tunTapDevice.c_str());
175 flags = IFF_TUN | IFF_NO_PI | IFF_MULTI_QUEUE;
178 flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
180 tunFd = allocateTunDevice(tunName, flags, address);
182 std::cerr <<
"RF24Gw: Error allocating tun/tap interface: " << tunFd << std::endl;
185#if RF24GATEWAY_DEBUG_LEVEL >= 1
186 std::cout <<
"RF24Gw: Successfully attached to tun/tap device " << tunTapDevice << std::endl;
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)
200 if ((fd = open(
"/dev/net/tun", O_RDWR)) < 0) {
204 memset(&ifr, 0,
sizeof(ifr));
206 ifr.ifr_flags = flags;
209 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
213 if (ioctl(fd, TUNSETIFF, (
void*)&ifr) < 0) {
215 std::cerr <<
"RF24Gw: Error: enabling TUNSETIFF" << std::endl;
216 uint32_t UID = getuid();
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;
227 if (ioctl(fd, TUNSETPERSIST, 1) < 0) {
229 std::cerr <<
"RF24Gw: Error: enabling TUNSETPERSIST" << std::endl;
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;
244 memcpy((
char*)&ifr.ifr_hwaddr, (
char*)&sap,
sizeof(
struct sockaddr));
246 if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) {
247#if RF24GATEWAY_DEBUG_LEVEL >= 1
248 fprintf(stderr,
"RF24Gw: Failed to set MAC address\n");
253 strcpy(dev, ifr.ifr_name);
259template<
class mesh_t,
class network_t,
class radio_t>
263 struct sockaddr_in sin;
264 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
266 fprintf(stderr,
"Could not get socket.\n");
270 sin.sin_family = AF_INET;
272 inet_aton(ip_addr, &sin.sin_addr);
273 strncpy(ifr.ifr_name, tunName, IFNAMSIZ);
275 if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
276 fprintf(stderr,
"ifdown: shutdown ");
277 perror(ifr.ifr_name);
282 #define IRFFLAGS ifr_flags
284 #define IRFFLAGS ifr_flagshigh
287 if (!(ifr.IRFFLAGS & IFF_UP)) {
289 ifr.IRFFLAGS |= IFF_UP;
290 if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
291 fprintf(stderr,
"ifup: failed ");
292 perror(ifr.ifr_name);
297 memcpy(&ifr.ifr_addr, &sin,
sizeof(
struct sockaddr));
300 if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
301 fprintf(stderr,
"Cannot set IP address. ");
302 perror(ifr.ifr_name);
306 inet_aton(mask, &sin.sin_addr);
307 memcpy(&ifr.ifr_addr, &sin,
sizeof(
struct sockaddr));
309 if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) {
310 fprintf(stderr,
"Cannot define subnet mask for this device");
311 perror(ifr.ifr_name);
321template<
class mesh_t,
class network_t,
class radio_t>
329template<
class mesh_t,
class network_t,
class radio_t>
346template<
class mesh_t,
class network_t,
class radio_t>
349 if (!gotInterrupt && radio.available()) {
357 gotInterrupt =
false;
366template<
class mesh_t,
class network_t,
class radio_t>
367void ESBGateway<mesh_t, network_t, radio_t>::handleRadioIn()
370 uint8_t returnVal = 0;
373 while ((returnVal = mesh.update())) {
374 if (returnVal == NETWORK_OVERRUN) {
377 else if (returnVal == NETWORK_CORRUPTION) {
380 if (!thisNodeAddress) {
386 while ((returnVal = network.update())) {
387 if (returnVal == NETWORK_OVERRUN) {
390 else if (returnVal == NETWORK_CORRUPTION) {
397 while (network.external_queue.size() > 0) {
398 f = network.external_queue.front();
402 if (f.message_size > 0 && f.message_size <= MAX_PAYLOAD_SIZE) {
403 if (!validSource(f)) {
405 network.external_queue.pop();
408 memcpy(&msg.message, &f.message_buffer, f.message_size);
409 msg.size = f.message_size;
411#if (RF24GATEWAY_DEBUG_LEVEL >= 1)
412 std::cout <<
"Radio: Received " << f.message_size <<
" bytes ... " << std::endl;
414#if (RF24GATEWAY_DEBUG_LEVEL >= 3)
416 std::cout <<
"TunRead: " << std::endl;
417 for (
size_t i = 0; i < msg.size; i++) {
419 printf(
":%0x :", msg.message[i]);
421 std::cout << std::endl;
430 network.external_queue.pop();
436template<
class mesh_t,
class network_t,
class radio_t>
437bool ESBGateway<mesh_t, network_t, radio_t>::validSource(RF24NetworkFrame& frame)
441 if (!config_TUN || !mesh_enabled || thisNodeID > 0) {
446 if (frame.message_size < 20 || (frame.message_buffer[0] >> 4) != 4) {
450 int16_t senderID = mesh.getNodeID(frame.header.from_node);
455 struct in_addr ipSource;
456 memcpy(&ipSource.s_addr, &frame.message_buffer[12], 4);
459 if ((getLocalIP().s_addr & 0x00FFFFFF) == (ipSource.s_addr & 0x00FFFFFF)) {
460 return frame.message_buffer[15] == (uint8_t)senderID;
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) {
475template<
class mesh_t,
class network_t,
class radio_t>
476struct in_addr
ESBGateway<mesh_t, network_t, radio_t>::getLocalIP()
478 struct ifaddrs *ifap, *ifa;
480 char host[NI_MAXHOST];
481 struct in_addr myNet;
482 memset(&myNet, 0,
sizeof(myNet));
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) {
495 family = ifa->ifa_addr->sa_family;
498 if (family == AF_INET) {
499 s = getnameinfo(ifa->ifa_addr,
sizeof(
struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
501 myNet.s_addr = ntohl(inet_network(host));
513template<
class mesh_t,
class network_t,
class radio_t>
514void ESBGateway<mesh_t, network_t, radio_t>::handleRadioOut()
518 uint32_t txQueueTimer = millis();
520 while (!txQueue.empty() && network.external_queue.size() == 0) {
522 uint32_t queueSize = txQueue.size();
523 if (millis() - txQueueTimer > 750 && queueSize >= 10) {
524 for (uint32_t i = 0; i < queueSize; i++) {
530 msgStruct* msgTx = &txQueue.front();
532#if (RF24GATEWAY_DEBUG_LEVEL >= 1)
533 std::cout <<
"Radio: Sending " << msgTx->size <<
" bytes ... ";
534 std::cout << std::endl;
536#if (RF24GATEWAY_DEBUG_LEVEL >= 3)
542 std::uint8_t* tmp = msgTx->message;
545 if (msgTx->size < 6) {
552 uint32_t RF24_STR = 0x34324652;
553 uint32_t ARP_BC = 0xFFFFFFFF;
556 uint32_t rf24_Verification;
561 memcpy(&macData.rf24_Addr, tmp + 4, 2);
562 memcpy(&macData.rf24_Verification, tmp, 4);
564 if (macData.rf24_Verification == RF24_STR) {
565 const uint16_t other_node = macData.rf24_Addr;
566 RF24NetworkHeader header( other_node, EXTERNAL_DATA_TYPE);
567 ok = network.write(header, &msgTx->message, msgTx->size);
569 else if (macData.rf24_Verification == ARP_BC) {
570 RF24NetworkHeader header( 00, EXTERNAL_DATA_TYPE);
571 if (msgTx->size <= 42) {
572 if (thisNodeAddress == 00) {
574 uint32_t arp_timeout = millis();
576 ok = network.multicast(header, &msgTx->message, msgTx->size, 1);
577 while (millis() - arp_timeout < 5) {
578 uint8_t returnVal = network.update();
579 if (returnVal == NETWORK_OVERRUN) {
582 else if (returnVal == NETWORK_CORRUPTION) {
586 network.multicast(header, &msgTx->message, msgTx->size, 1);
587 arp_timeout = millis();
588 while (millis() - arp_timeout < 15) {
589 uint8_t returnVal = network.update();
590 if (returnVal == NETWORK_OVERRUN) {
593 else if (returnVal == NETWORK_CORRUPTION) {
597 network.multicast(header, &msgTx->message, msgTx->size, 1);
600 ok = network.write(header, &msgTx->message, msgTx->size);
608 if (msgTx->size < 20) {
613 uint8_t lastOctet = tmp[19];
616 RF24NetworkHeader header(00, EXTERNAL_DATA_TYPE);
617 bool sendData =
false;
619 struct in_addr ipDestination;
620 memcpy(&ipDestination.s_addr, &tmp[16], 4);
622 if ((getLocalIP().s_addr & 0x00FFFFFF) == (ipDestination.s_addr & 0x00FFFFFF)) {
623 if ((meshAddr = mesh.getAddress(lastOctet)) > 0) {
624 header.to_node = meshAddr;
628 if (thisNodeID > 0) {
634 else if (thisNodeID > 0) {
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;
644 if (destNet.s_addr == network.s_addr) {
645 uint8_t toNode = routingStruct[i].gw.s_addr >> 24;
647 if ((netAddr = mesh.getAddress(toNode)) > 0) {
648 header.to_node = netAddr;
657 ok = network.write(header, msgTx->message, msgTx->size);
678template<
class mesh_t,
class network_t,
class radio_t>
679void ESBGateway<mesh_t, network_t, radio_t>::handleRX(uint32_t waitDelay)
682 struct timeval selectTimeout;
683 uint8_t buffer[MAX_PAYLOAD_SIZE];
690 uint32_t tunTimeout = millis();
695 FD_SET(tunFd, &socketSet);
696 selectTimeout.tv_sec = 0;
697 selectTimeout.tv_usec = waitDelay * 1000;
699 int ready = select(tunFd + 1, &socketSet, NULL, NULL, &selectTimeout);
704 if (errno == EINTR && millis() - tunTimeout <= 750) {
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;
714#if (RF24GATEWAY_DEBUG_LEVEL >= 3)
715 std::cout <<
"TunRead: " << std::endl;
716 for (
int i = 0; i < nread; i++)
718 printf(
":%0x :", buffer[i]);
720 std::cout << std::endl;
723 memcpy(&msg.message, &buffer, nread);
728#if (RF24GATEWAY_DEBUG_LEVEL >= 1)
729 std::cerr <<
"Tun: Error while reading from tun/tap interface." << std::endl;
733 if (millis() - tunTimeout > 750) {
741template<
class mesh_t,
class network_t,
class radio_t>
742void ESBGateway<mesh_t, network_t, radio_t>::handleTX()
745 if (rxQueue.size() < 1 || tunFd < 0)
749 msgStruct* msg = &rxQueue.front();
751 if (msg->size > MAX_PAYLOAD_SIZE)
761 size_t writtenBytes = write(tunFd, &msg->message, msg->size);
762 if (writtenBytes != msg->size)
765#if RF24GATEWAY_DEBUG_LEVEL >= 1
766 printf(
"Tun: Less bytes written %d to tun/tap device then requested %d.", writtenBytes, msg->size);
771#if (RF24GATEWAY_DEBUG_LEVEL >= 1)
772 std::cout <<
"Tun: Successfully wrote " << writtenBytes <<
" bytes to tun device" << std::endl;
776#if (RF24GATEWAY_DEBUG_LEVEL >= 3)
778 std::cout <<
"TunRead: " << std::endl;
779 for (
size_t i = 0; i < msg->size; i++) {
782 std::cout << std::endl;
805template<
class mesh_t,
class network_t,
class radio_t>
806void ESBGateway<mesh_t, network_t, radio_t>::setupSocket()
809 const char* myAddr =
"127.0.0.1";
811 addr.sin_family = AF_INET;
812 ret = inet_aton(myAddr, &addr.sin_addr);
817 addr.sin_port = htons(32001);
819 s = socket(PF_INET, SOCK_DGRAM, 0);
828template<
class mesh_t,
class network_t,
class radio_t>
832 uint8_t buffer[MAX_PAYLOAD_SIZE + 11];
834 if (frame.message_size > MAX_PAYLOAD_SIZE) {
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);
842 int ret = sendto(s, &buffer, frame.message_size + 11, 0, (
struct sockaddr*)&addr,
sizeof(addr));
852#if defined(RF24NETWORK_CCM)
int setIP(char *ip_addr, char *mask)
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)
void sendUDP(uint8_t nodeID, RF24NetworkFrame frame)