RF24Gateway - TCP/IP over RF24Network  0.1b
TMRh20 - Pushing the practical limits of RF24 modules
RF24Gateway.cpp
1 
2 
3 
4 #include "RF24Gateway.h"
5 #include "RF24Mesh/RF24Mesh_config.h"
6 
7 /***************************************************************************************/
8 
9 RF24Gateway::RF24Gateway(RF24& _radio,RF24Network& _network, RF24Mesh& _mesh):
10  radio(_radio),network(_network),mesh(_mesh)
11 {
12 }
13 
14 /***************************************************************************************/
15 
16 void RF24Gateway::begin(uint8_t nodeID, uint8_t _channel, rf24_datarate_e data_rate) {
17 
18  mesh_enabled = true;
19  begin(true, mesh_enabled, 0, nodeID, data_rate, _channel);
20 }
21 
22 /***************************************************************************************/
23 
24 void RF24Gateway::begin(uint16_t address, uint8_t _channel, rf24_datarate_e data_rate, bool meshEnable, uint8_t nodeID) {
25 
26  begin(0, mesh_enabled, address, nodeID, data_rate, _channel);
27 }
28 
29 /***************************************************************************************/
30 
31 bool RF24Gateway::begin(bool configTUN, bool meshEnable, uint16_t address, uint8_t mesh_nodeID, rf24_datarate_e data_rate, uint8_t _channel) {
32 
33  #if(DEBUG>=1)
34  printf("GW Begin\n");
35  printf("Config Device address 0%o nodeID %d\n",address,mesh_nodeID);
36  #endif
37  config_TUN = configTUN;
38 
39  ///FIX
40 
41  channel = _channel;//97;
42 
43  dataRate = data_rate;
44 
45  configDevice(address);
46  mesh_enabled = meshEnable;
47  thisNodeID = mesh_nodeID;
48  thisNodeAddress = address;
49 
50  if(meshEnable){
51  // GW radio channel setting takes precedence over mesh_default_channel
52  if(channel == 97 && MESH_DEFAULT_CHANNEL != 97){
53  channel = MESH_DEFAULT_CHANNEL;
54  }
55 
56  if(!thisNodeAddress && !mesh_nodeID){
57  mesh.setNodeID(0);
58  }else{
59  if(!mesh_nodeID){
60  mesh_nodeID = 253;
61  }
62  mesh.setNodeID(mesh_nodeID); //Try not to conflict with any low-numbered node-ids
63  }
64  mesh.begin(channel,data_rate);
65  thisNodeAddress = mesh.mesh_address;
66  }else{
67  radio.begin();
68  delay(5);
69  const uint16_t this_node = address;
70  radio.setDataRate(dataRate);
71  radio.setChannel(channel);
72 
73  network.begin(/*node address*/ this_node);
74  thisNodeAddress = this_node;
75 
76  }
77  network.multicastRelay=1;
78 
79 
80  //#if (DEBUG >= 1)
81  radio.printDetails();
82  //#endif
83 
84  return true;
85 }
86 
87 /***************************************************************************************/
88 
90  return mesh_enabled;
91 }
92 
93 /***************************************************************************************/
94 
95 int RF24Gateway::configDevice(uint16_t address){
96 
97  std::string tunTapDevice = "tun_nrf24";
98  strcpy(tunName, tunTapDevice.c_str());
99 
100  int flags;
101  if(config_TUN){
102  flags = IFF_TUN | IFF_NO_PI | IFF_MULTI_QUEUE;
103  }else{
104  flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
105  }
106  tunFd = allocateTunDevice(tunName, flags, address);
107  #if DEBUG >= 1
108  if (tunFd >= 0) {
109  std::cout << "RF24Gw: Successfully attached to tun/tap device " << tunTapDevice << std::endl;
110  } else {
111  std::cerr << "RF24Gw: Error allocating tun/tap interface: " << tunFd << std::endl;
112  exit(1);
113  }
114  #endif
115  return tunFd;
116 }
117 
118 /***************************************************************************************/
119 
120 int RF24Gateway::allocateTunDevice(char *dev, int flags, uint16_t address) {
121  struct ifreq ifr;
122  int fd;
123 
124  //open the device
125  if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ) {
126  return fd;
127  }
128 
129  memset(&ifr, 0, sizeof(ifr));
130 
131  ifr.ifr_flags = flags; // IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI
132 
133  if (*dev) {
134  strncpy(ifr.ifr_name, dev, IFNAMSIZ);
135  }
136 
137  // Create device
138  if(ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
139  //close(fd);
140  //#if (DEBUG >= 1)
141  std::cerr << "RF24Gw: Error: enabling TUNSETIFF" << std::endl;
142  std::cerr << "RF24Gw: If changing from TAP/TUN, run 'sudo ip link delete tun_nrf24' to remove the interface" << std::endl;
143  return -1;
144  //#endif
145  }
146 
147  //Make persistent
148  if(ioctl(fd, TUNSETPERSIST, 1) < 0){
149  #if (DEBUG >= 1)
150  std::cerr << "RF24Gw: Error: enabling TUNSETPERSIST" << std::endl;
151  #endif
152  return -1;
153  }
154 
155  if(!config_TUN){
156  struct sockaddr sap;
157  sap.sa_family = ARPHRD_ETHER;
158  ((char*)sap.sa_data)[4]=address;
159  ((char*)sap.sa_data)[5]=address>>8;
160  ((char*)sap.sa_data)[0]=0x52;
161  ((char*)sap.sa_data)[1]=0x46;
162  ((char*)sap.sa_data)[2]=0x32;
163  ((char*)sap.sa_data)[3]=0x34;
164 
165  //printf("Address 0%o first %u last %u\n",address,sap.sa_data[0],sap.sa_data[1]);
166  memcpy((char *) &ifr.ifr_hwaddr, (char *) &sap, sizeof(struct sockaddr));
167 
168  if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) {
169  #if DEBUG >= 1
170  fprintf(stderr, "RF24Gw: Failed to set MAC address\n");
171  #endif
172  }
173  }
174 
175  strcpy(dev, ifr.ifr_name);
176  return fd;
177 }
178 
179 /***************************************************************************************/
180 
181 int RF24Gateway::setIP( char *ip_addr, char *mask) {
182 
183  struct ifreq ifr;
184  struct sockaddr_in sin;
185  int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
186  if(sockfd == -1){
187  fprintf(stderr, "Could not get socket.\n");
188  return -1;
189  }
190 
191 
192  sin.sin_family = AF_INET;
193  //inet_aton(ip_addr,&sin.sin_addr.s_addr);
194  inet_aton(ip_addr,&sin.sin_addr);
195  strncpy(ifr.ifr_name, tunName, IFNAMSIZ);
196 
197  if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
198  fprintf(stderr, "ifdown: shutdown ");
199  perror(ifr.ifr_name);
200  return -1;
201  }
202 
203  #ifdef ifr_flags
204  # define IRFFLAGS ifr_flags
205  #else /* Present on kFreeBSD */
206  # define IRFFLAGS ifr_flagshigh
207  #endif
208 
209  if (!(ifr.IRFFLAGS & IFF_UP)) {
210  //fprintf(stdout, "Device is currently down..setting up.-- %u\n",ifr.IRFFLAGS);
211  ifr.IRFFLAGS |= IFF_UP;
212  if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
213  fprintf(stderr, "ifup: failed ");
214  perror(ifr.ifr_name);
215  return -1;
216  }
217  }
218 
219  memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
220 
221  // Set interface address
222  if (ioctl(sockfd, SIOCSIFADDR, &ifr) < 0) {
223  fprintf(stderr, "Cannot set IP address. ");
224  perror(ifr.ifr_name);
225  return -1;
226  }
227 
228 
229  inet_aton(mask, &sin.sin_addr);
230  memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr));
231 
232  if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0)
233  {
234  fprintf(stderr,"Cannot define subnet mask for this device");
235  perror(ifr.ifr_name);
236  return -1;
237  }
238 
239 
240  #undef IRFFLAGS
241  return 0;
242 }
243 
244 /***************************************************************************************/
245 
247  handleRadio();
248  //handleTX();
249  //handleRX();
250 }
251 
252 /***************************************************************************************/
253 
254 void RF24Gateway::handleRadio(){
255 
256 
257 
258  if(mesh_enabled){
259 
260  while(mesh.update());
261 
262  if(!thisNodeAddress){
263  mesh.DHCP();
264  }
265  }else{
266  while(network.update());
267  }
268 
269  RF24NetworkFrame f;
270  while(network.external_queue.size() > 0 ){
271  f = network.external_queue.front();
272 
273  msgStruct msg;
274 
275  unsigned int bytesRead = f.message_size;
276 
277  if (bytesRead > 0) {
278  memcpy(&msg.message,&f.message_buffer,bytesRead);
279  msg.size=bytesRead;
280 
281  #if (DEBUG >= 1)
282  std::cout << "Radio: Received "<< bytesRead << " bytes ... " << std::endl;
283  #endif
284  #if (DEBUG >= 3)
285  //printPayload(msg.getPayloadStr(),"radio RX");
286  std::cout << "TunRead: " << std::endl;
287  for(size_t i=0; i<msg.size;i++){
288  //std::cout << std::hex << buffer[i];
289  printf(":%0x :",msg.message[i]);
290  }
291  std::cout << std::endl;
292 
293  #endif
294 
295  rxQueue.push(msg);
296 
297  } else {
298  //std::cerr << "Radio: Error reading data from radio. Read '" << bytesRead << "' Bytes." << std::endl;
299  }
300  network.external_queue.pop();
301 
302  }
303  handleTX();
304  if(mesh_enabled){
305 
306  while(mesh.update());
307 
308  if(!thisNodeAddress){
309  mesh.DHCP();
310  }
311  }else{
312  while(network.update());
313  }
314  handleRX();
315 
316  if(network.external_queue.size() == 0 || txQueue.empty()){
317  //sched_yield();
318  if(dataRate == RF24_2MBPS){
319  delayMicroseconds(850);
320  }else
321  if(dataRate == RF24_1MBPS){
322  delayMicroseconds(1000);
323  }else
324  if(dataRate == RF24_250KBPS){
325  delayMicroseconds(4500);
326  }
327  }
328  // TX section
329  bool ok = 0;
330 
331  while(!txQueue.empty() && !radio.available() && network.external_queue.size() == 0) {
332  if(dataRate == RF24_2MBPS){
333  delayMicroseconds(850);
334  }else
335  if(dataRate == RF24_1MBPS){
336  delayMicroseconds(1500);
337  }else
338  if(dataRate == RF24_250KBPS){
339  delayMicroseconds(4500);
340  }
341  msgStruct *msgTx = &txQueue.front();
342 
343  #if (DEBUG >= 1)
344  std::cout << "Radio: Sending " << msgTx->size << " bytes ... ";
345  std::cout << std::endl;
346  #endif
347  #if (DEBUG >= 3)
348  //PrintDebug == 1 does not have an endline.
349  //printPayload(msg.getPayloadStr(),"radio TX");
350  #endif
351 
352  std::uint8_t *tmp = msgTx->message;
353 
354 
355  if(!config_TUN ){ //TAP can use RF24Mesh for address assignment, but will still use ARP for address resolution
356 
357  uint32_t RF24_STR = 0x34324652; //Identifies the mac as an RF24 mac
358  uint32_t ARP_BC = 0xFFFFFFFF; //Broadcast address
359  struct macStruct{
360  uint32_t rf24_Verification;
361  uint16_t rf24_Addr;
362  };
363 
364 
365  macStruct macData;
366  memcpy(&macData.rf24_Addr,tmp+4,2);
367  memcpy(&macData.rf24_Verification,tmp,4);
368 
369 
370  if(macData.rf24_Verification == RF24_STR){
371  const uint16_t other_node = macData.rf24_Addr;
372  RF24NetworkHeader header(/*to node*/ other_node, EXTERNAL_DATA_TYPE);
373  ok = network.write(header,&msgTx->message,msgTx->size);
374 
375  }else
376  if(macData.rf24_Verification == ARP_BC){
377  RF24NetworkHeader header(/*to node*/ 00, EXTERNAL_DATA_TYPE); //Set to master node, will be modified by RF24Network if multi-casting
378  if(msgTx->size <= 42){
379  if(thisNodeAddress == 00){ //Master Node
380 
381  uint32_t arp_timeout = millis();
382 
383  ok=network.multicast(header,&msgTx->message,msgTx->size,1 ); //Send to Level 1
384  while(millis() - arp_timeout < 5){network.update();}
385  network.multicast(header,&msgTx->message,msgTx->size,1 ); //Send to Level 1
386  arp_timeout=millis();
387  while(millis()- arp_timeout < 15){network.update();}
388  network.multicast(header,&msgTx->message,msgTx->size,1 ); //Send to Level 1
389 
390  }else{
391 
392  ok = network.write(header,&msgTx->message,msgTx->size);
393  }
394  }
395  }
396  }else{ // TUN always needs to use RF24Mesh for address assignment AND resolution
397 
398  uint8_t lastOctet = tmp[19];
399  uint16_t meshAddr;
400 
401  if ( (meshAddr = mesh.getAddress(lastOctet)) > 0 || thisNodeID) {
402  RF24NetworkHeader header(meshAddr, EXTERNAL_DATA_TYPE);
403  if(thisNodeID){ //If not the master node, send to master (00)
404  header.to_node = 00;
405  }
406  ok = network.write(header, msgTx->message, msgTx->size);
407  }else{
408  //printf("Could not find matching mesh nodeID for IP ending in %d\n",lastOctet);
409  }
410 
411  }
412  txQueue.pop();
413 
414 
415  //printf("Addr: 0%#x\n",macData.rf24_Addr);
416  //printf("Verif: 0%#x\n",macData.rf24_Verification);
417  if (ok) {
418  // std::cout << "ok." << std::endl;
419  } else {
420  // std::cerr << "failed." << std::endl;
421  }
422 
423 
424 
425  } //End Tx
426 
427 }
428 
429 /***************************************************************************************/
430 
431 void RF24Gateway::handleRX(){
432 
433  fd_set socketSet;
434  struct timeval selectTimeout;
435  uint8_t buffer[MAX_PAYLOAD_SIZE];
436  int nread;
437 
438  FD_ZERO(&socketSet);
439  FD_SET(tunFd, &socketSet);
440 
441  selectTimeout.tv_sec = 0;
442  selectTimeout.tv_usec = 0;
443 
444  if (select(tunFd + 1, &socketSet, NULL, NULL,&selectTimeout) != 0) {
445  if (FD_ISSET(tunFd, &socketSet)) {
446  if ((nread = read(tunFd, buffer, MAX_PAYLOAD_SIZE)) >= 0) {
447 
448  #if (DEBUG >= 1)
449  std::cout << "Tun: Successfully read " << nread << " bytes from tun device" << std::endl;
450  #endif
451  #if (DEBUG >= 3)
452  std::cout << "TunRead: " << std::endl;
453  for(int i=0; i<nread;i++){
454  printf(":%0x :",buffer[i]);
455  }
456  std::cout << std::endl;
457  #endif
458 
459  msgStruct msg;
460  memcpy(&msg.message,&buffer,nread);
461  msg.size = nread;
462 
463  if(txQueue.size() < 2){
464  txQueue.push(msg);
465  }else{
466  droppedIncoming++;
467  }
468 
469  } else{
470  #if (DEBUG >= 1)
471  std::cerr << "Tun: Error while reading from tun/tap interface." << std::endl;
472  #endif
473 
474  }
475  }
476  }
477 }
478 
479 /***************************************************************************************/
480 
481  void RF24Gateway::handleTX(){
482 
483  if(rxQueue.size() < 1){
484  return;
485  }
486  msgStruct *msg = &rxQueue.front();
487 
488  if(msg->size > MAX_PAYLOAD_SIZE){
489  //printf("*****WTF OVER *****");
490  rxQueue.pop();
491  return;
492  }
493 
494  if (msg->size > 0 ) {
495 
496  size_t writtenBytes = write(tunFd, &msg->message, msg->size);
497  if (writtenBytes != msg->size) {
498  //std::cerr << "Tun: Less bytes written to tun/tap device then requested." << std::endl;
499  #if DEBUG >= 1
500  printf("Tun: Less bytes written %d to tun/tap device then requested %d.",writtenBytes,msg->size);
501  #endif
502 
503  } else {
504  #if (DEBUG >= 1)
505  std::cout << "Tun: Successfully wrote " << writtenBytes << " bytes to tun device" << std::endl;
506  #endif
507  }
508 
509  #if (DEBUG >= 3)
510  //printPayload(msg.message,"tun write");
511  std::cout << "TunRead: " << std::endl;
512  for(size_t i=0; i<msg->size;i++){
513  //printf(":%0x :",msg->message[i]);
514  }
515  std::cout << std::endl;
516  #endif
517  rxQueue.pop();
518  }
519 
520 }
521 
522 /***************************************************************************************/
523 
524 void printPayload(std::string buffer, std::string debugMsg = "") {
525 
526 }
527 
528 /***************************************************************************************/
529 
530 void printPayload(char *buffer, int nread, std::string debugMsg = "") {
531 
532 
533 }
534 
535 /***************************************************************************************/
void begin(uint8_t nodeID=0, uint8_t channel=97, rf24_datarate_e data_rate=RF24_1MBPS)
Definition: RF24Gateway.cpp:16
uint16_t thisNodeAddress
Definition: RF24Gateway.h:104
uint8_t thisNodeID
Definition: RF24Gateway.h:105
bool config_TUN
Definition: RF24Gateway.h:109
RF24Gateway(RF24 &_radio, RF24Network &_network, RF24Mesh &_mesh)
Definition: RF24Gateway.cpp:9
bool meshEnabled()
Definition: RF24Gateway.cpp:89
int setIP(char *ip_addr, char *mask)