RF24Gateway - TCP/IP over RF24Network  0.1b
TMRh20 - Pushing the practical limits of RF24 modules
RF24Gateway.h
1 
2 
3 #ifndef __RF24GATEWAY_H__
4 #define __RF24GATEWAY_H__
5 
6 
7 /**
8  * @file RF24Gateway.h
9  *
10  * Class declaration for RF24Gateway
11  */
12  #include "net/if_arp.h"
13  #include <cstdlib>
14  #include <cstdint>
15  #include <iostream>
16  #include <string>
17  #include <sys/socket.h>
18  #include <linux/if.h>
19  #include <linux/if_tun.h>
20  #include <arpa/inet.h>
21  #include <fcntl.h>
22  #include <unistd.h>
23  #include <sys/ioctl.h>
24 
25  #include <RF24/RF24.h>
26  #include <RF24Network/RF24Network.h>
27  #include <RF24Mesh/RF24Mesh.h>
28 
29 #ifndef IFF_MULTI_QUEUE
30  #define IFF_MULTI_QUEUE 0x0100
31 #endif
32 
33 #define DEBUG 0
34 
35  class RF24;
36  class RF24Network;
37  class RF24Mesh;
38 
39 class RF24Gateway {
40 
41  /**@}*/
42  /**
43  * @name RF24Gateway (RPi/Linux)
44  *
45  * RF24Gateway library for devices with an IP stack
46  */
47  /**@{*/
48 
49 public:
50 
51  /**
52  * RF24Gateway constructor.
53  */
54  RF24Gateway(RF24& _radio,RF24Network& _network, RF24Mesh& _mesh);
55 
56  /**
57  * Begin function for use with RF24Mesh (TUN interface)
58  *
59  * @param nodeID The RF24Mesh nodeID to use
60  * @param channel The radio channel to use (1-127)
61  * @param data_rate The RF24 datarate to use (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS)
62  *
63  * @code gw.begin(); //Start the gateway using RF24Mesh, with nodeID 0 (Master) @endcode
64  * @code uint8_t nodeID; gw.begin(nodeID); //Start the gateway using RF24Mesh, with nodeID 1 (Child node) @endcode
65  */
66  void begin(uint8_t nodeID=0, uint8_t channel=97,rf24_datarate_e data_rate=RF24_1MBPS);
67 
68  /**
69  * Begin function for use with a TAP (Ethernet) interface. RF24Mesh can be used for address assignment, but
70  * ARP will be used to perform the lookups.
71  *
72  * @param address The RF24Network address to use
73  * @param channel The radio channel (0-127) to use
74  * @param data_rate The RF24 datarate to use (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS)
75  * @param meshEnable Whether to use RF24Mesh for address assignment
76  * @param nodeID The RF24Mesh nodeID to use **if** meshEnable has been set to true
77  *
78  * @code uint16_t address=00; gw.begin(address); //Start the gateway without using RF24Mesh, with RF24Network address 00 (Master) @endcode
79  * @code uint16_t address=01; gw.begin(address); //Start the gateway without using RF24Mesh, with RF24Network address 01 (Child) @endcode
80  */
81  void begin(uint16_t address, uint8_t channel=97, rf24_datarate_e data_rate=RF24_1MBPS, bool meshEnable=0, uint8_t nodeID=0 );
82 
83  /**
84  * Once the Gateway has been started via begin() , call setIP to configure the IP and
85  * subnet mask.
86  *
87  * @param ip A character array containing the numeric IP address ie: 192.168.1.1
88  * @param mask A character array containing the subnet mask ie: 255.255.255.0
89  * @return -1 if failed, 0 on success
90  */
91  int setIP( char *ip_addr, char *mask);
92 
93  /**
94  * Calling update() keeps the network and mesh layers active and processing data. This needs to be called regularly.
95  * @code
96  * gw.update();
97  * if(network.available()){
98  * ...do something
99  * }
100  * @endcode
101  */
102  void update();
103 
104  uint16_t thisNodeAddress; /**< Address of our node in Octal format (01,021, etc) */
105  uint8_t thisNodeID; /**< NodeID (0-255) */
106 
107 
108  bool meshEnabled(); /**< Is RF24Mesh enabled? */
109  bool config_TUN; /**< Using a TAP(false) or TUN(true) interface */
110 
111  uint32_t ifDropped(){
112  return droppedIncoming;
113  }
114 
115 private:
116  RF24& radio;
117  RF24Network& network;
118  RF24Mesh& mesh;
119 
120  bool begin(bool configTUN, bool meshEnable, uint16_t address, uint8_t mesh_nodeID, rf24_datarate_e data_rate, uint8_t _channel);
121  bool mesh_enabled;
122 
123  uint32_t droppedIncoming;
124 
125  uint8_t channel;
126  rf24_datarate_e dataRate;
127  char tunName[IFNAMSIZ];
128  int tunFd;
129 
130  unsigned long packets_sent; /**< How many have we sent already */
131  uint32_t interfaceInTimer;
132 
133  void handleRadio();
134  void handleRX();
135  void handleTX();
136 
137  int configDevice(uint16_t address);
138  int allocateTunDevice(char *dev, int flags, uint16_t address);
139 
140  struct msgStruct{
141  std::uint8_t message[MAX_PAYLOAD_SIZE];
142  std::size_t size;
143  };
144 
145  std::queue<msgStruct>rxQueue;
146  std::queue<msgStruct>txQueue;
147 
148  void printPayload(std::string buffer, std::string debugMsg = "");
149  void printPayload(char *buffer, int nread, std::string debugMsg = "");
150 };
151 
152 
153 
154 
155 /**
156  * @example RF24GatewayNode.cpp
157  *
158  * A simple example of using RF24Gateway node to forward IP traffic automatically to a network interface, while
159  * managing standard RF24Network user payloads independently.
160  */
161 
162  /**
163  * @example RF24Gateway_ncurses.cpp
164  *
165  * RF24Gateway NCurses interface - TMRh20 2015 <br>
166  * This is a generic tool for nodes supporting or combining with RF24Ethernet and/or RF24Network.
167  *
168  * The tool provides a simple interface for monitoring information and activity regarding the RF24Gateway: <br>
169  * a: Interface statistics from /proc/net/dev <br>
170  * b: RF24Mesh address/id assignments <br>
171  * c: RF24Network/Radio information <br>
172  * d: Active IP connections (optional) <br>
173  *
174  * **Requirements: NCurses** <br>
175  * Install NCurses: apt-get install libncurses5-dev
176  * Optional: Enable nf_conntrack: @code modprobe nf_conntrack_ipv4 @endcode
177  *
178  * @image html ncurses.JPG
179  */
180 
181  /** @example bClient.sh
182  *
183  * Once RF24Gateway and RF24Ethernet are configured, standard tools can be used to interact with
184  * the sensor nodes. <br>Example of on demand LED/Lighting control using a Bash script.
185  */
186 
187  /** @example nodeClient.js
188  *
189  * Once RF24Gateway and RF24Ethernet are configured, standard tools can be used to interact with
190  * the sensor nodes. <br> Example of on demand LED/Lighting control using a NodeJS script.
191  */
192 
193  /** @example pyClient.py
194  *
195  * Once RF24Gateway and RF24Ethernet are configured, standard tools can be used to interact with
196  * the sensor nodes. <br> Example of scheduled LED/Lighting control using a Python script.
197  */
198 
199 /**
200  * @mainpage RF24Gateway
201  *
202  * RF24Gateway is a library style replacement for the standalone RF24toTUN application, used with RF24Ethernet.
203  *
204  * In addition to passing TCP/IP payloads to a network interface, RF24Gateway also allows users to send and receive
205  * standard RF24Network payloads.
206  *
207  * This allows users to deploy and manage hybrid networks, consisting of nodes communicating via TCP/IP and RF24Network Messages
208  *
209  * @section Installation Installation
210  *
211  * See http://tmrh20.github.io/RF24 for installation instructions using the installer, or clone the RF24 libs and run 'make install' for each one.
212  *
213  * After running the installer, RF24Gateway will be installed at rf24libs/RF24Gateway. <b><a href="examples.html">Examples</a></b> are included for operating the gateway
214  * as well as client scripts & programs to control nodes via http requests.
215  *
216  * Note: RF24Gateway is tested with and defaults to using RF24Mesh. Sensor nodes must also use RF24Mesh or be statically assigned within RF24Mesh.
217  *
218  * See http://tmrh20.github.io/RF24Ethernet/ for related documentation for use with RF24Gateway.
219  *
220  * @section HowItWorks How It Works
221  *
222  * RF24Gateway is relatively simple in design, and uses the <a href="https://www.kernel.org/doc/Documentation/networking/tuntap.txt">Universal TUN/TAP driver for Linux</a> <br>
223  * Data incoming from the RF24 communication stack (designated as external data) is passed to the interface without modification. Conversely, incoming TCP/IP or other data
224  * received on the TUN/TAP interface is passed directly into the radio network and designated as external data.
225  *
226  * Linux devices running RF24Gateway can establish network links using the built-in TCP/IP stack, and users can include Arduino/AVR devices or additional RPi devices to automatically
227  * extend the wireless range.<br>
228  * Arduino/AVR devices, etc must utilize a software IP stack such as uIP.
229  *
230  */
231 
232 
233  #endif
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
uint32_t ifDropped()
Definition: RF24Gateway.h:111
bool meshEnabled()
Definition: RF24Gateway.cpp:89
int setIP(char *ip_addr, char *mask)