Optimized RF24Network Layer v2.0.5
2024 - Optimized RF24 Network Layer for NRF24L01 & NRF52x radios
Loading...
Searching...
No Matches
RF24Network.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 version 2 as published by the Free Software Foundation.
7 */
8
9#ifndef __RF24NETWORK_H__
10#define __RF24NETWORK_H__
11
18#include <stddef.h>
19#include <stdint.h>
20#include "RF24Network_config.h"
21
22#if (defined(__linux) || defined(linux)) && !defined(__ARDUINO_X86__)
23 #include <stdint.h>
24 #include <stdio.h>
25 #include <time.h>
26 #include <string.h>
27 #include <sys/time.h>
28 #include <stddef.h>
29 #include <assert.h>
30 #include <map>
31 #include <utility> // std::pair
32 #include <queue>
33
34//ATXMega
35#elif defined(XMEGA_D3)
36 #include "../../rf24lib/rf24lib/RF24.h"
37#endif
38
39/* Header types range */
40#define MIN_USER_DEFINED_HEADER_TYPE 0
41#define MAX_USER_DEFINED_HEADER_TYPE 127
42
43// ACK Response Types
72#define NETWORK_ADDR_RESPONSE 128
73
79#define NETWORK_PING 130
80
103#define EXTERNAL_DATA_TYPE 131
104
108#define NETWORK_FIRST_FRAGMENT 148
109
113#define NETWORK_MORE_FRAGMENTS 149
114
119#define NETWORK_LAST_FRAGMENT 150
120//#define NETWORK_LAST_FRAGMENT 201
121
122// NO ACK Response Types
123//#define NETWORK_ACK_REQUEST 192
124
128#define NETWORK_OVERRUN 160
129
133#define NETWORK_CORRUPTION 161
134
171#define NETWORK_ACK 193
172
180#define NETWORK_POLL 194
181
188#define NETWORK_REQ_ADDRESS 195
189
190// The following 2 atrifacts now exist in RF24Mesh as their significance was specific to RF24Mesh.
191//#define NETWORK_ADDR_LOOKUP 196
192//#define NETWORK_ADDR_RELEASE 197
195/* This isn't actually used anywhere. */
196#define NETWORK_MORE_FRAGMENTS_NACK 200
197
198/* Internal defines for handling written payloads */
199#define TX_NORMAL 0
200#define TX_ROUTED 1
201#define USER_TX_TO_PHYSICAL_ADDRESS 2 // no network ACK
202#define USER_TX_TO_LOGICAL_ADDRESS 3 // network ACK
203#define USER_TX_MULTICAST 4
204
205#if defined NRF52_RADIO_LIBRARY
206 #define MAX_FRAME_SIZE 123 // Size of individual radio frames is larger with NRF52
207#else
208 #define MAX_FRAME_SIZE 32 // Size of individual radio frames
209#endif
210
211#define FRAME_HEADER_SIZE 10 // Size of RF24Network frames - data
212
217#define USE_CURRENT_CHANNEL 255
218
223#define FLAG_FAST_FRAG 4
229#define FLAG_NO_POLL 8
230
231class RF24;
232#if defined(ARDUINO_ARCH_NRF52) || defined(ARDUINO_ARCH_NRF52840) || defined(ARDUINO_ARCH_NRF52833)
233class nrf_to_nrf;
234#endif
235
244{
246 uint16_t from_node;
247
249 uint16_t to_node;
250
252 uint16_t id;
253
261 unsigned char type;
262
269 unsigned char reserved;
270
272 static uint16_t next_id;
273
280
302 RF24NetworkHeader(uint16_t _to, unsigned char _type = 0) : to_node(_to), id(next_id++), type(_type) {}
303
313 const char* toString(void) const;
314};
315
327{
330
332 uint16_t message_size;
333
338#if defined(RF24_LINUX)
339 uint8_t message_buffer[MAX_PAYLOAD_SIZE]; // Array to store the message
340#else
341 uint8_t* message_buffer; // Pointer to the buffer storing the actual message
342#endif
343
350
361#if defined(RF24_LINUX) || defined(DOXYGEN_FORCED)
362 RF24NetworkFrame(RF24NetworkHeader& _header, const void* _message = NULL, uint16_t _len = 0) : header(_header), message_size(_len)
363 {
364 if (_message && _len) {
365 memcpy(message_buffer, _message, _len);
366 }
367 }
368#endif
369#if defined(DOXYGEN_FORCED) || !defined(RF24_LINUX)
380 RF24NetworkFrame(RF24NetworkHeader& _header, uint16_t _message_size) : header(_header), message_size(_message_size)
381 {
382 }
383#endif
384};
385
397template<class radio_t = RF24>
399{
400
408public:
426 ESBNetwork(radio_t& _radio);
427
448 inline void begin(uint16_t _node_address)
449 {
450 begin(USE_CURRENT_CHANNEL, _node_address);
451 }
452
461 uint8_t update(void);
462
468 bool available(void);
469
480 uint16_t peek(RF24NetworkHeader& header);
481
495 void peek(RF24NetworkHeader& header, void* message, uint16_t maxlen = MAX_PAYLOAD_SIZE);
496
519 uint16_t read(RF24NetworkHeader& header, void* message, uint16_t maxlen = MAX_PAYLOAD_SIZE);
520
540 bool write(RF24NetworkHeader& header, const void* message, uint16_t len);
541
570 void multicastLevel(uint8_t level);
571
580
589 void setup_watchdog(uint8_t prescalar);
590
600 uint32_t txTimeout;
601
610 uint16_t routeTimeout;
611
620#if defined(ENABLE_NETWORK_STATS) || defined(DOXYGEN_FORCED)
621
631 void failures(uint32_t* _fails, uint32_t* _ok);
632
633#endif // defined (ENABLE_NETWORK_STATS)
634#if defined(RF24NetworkMulticast)
635
652 bool multicast(RF24NetworkHeader& header, const void* message, uint16_t len, uint8_t level = 7);
653
654#endif
655
661 bool write(RF24NetworkHeader& header, const void* message, uint16_t len, uint16_t writeDirect);
662
695 bool sleepNode(unsigned int cycles, int interruptPin, uint8_t INTERRUPT_MODE = 0); //added interrupt mode support (default 0=LOW)
696
702 uint16_t parent() const;
703
707 uint16_t addressOfPipe(uint16_t node, uint8_t pipeNo);
708
718 bool is_valid_address(uint16_t node);
719
749 void begin(uint8_t _channel, uint16_t _node_address);
750
769
788#if defined(RF24_LINUX) || defined(DOXYGEN_FORCED)
789 std::queue<RF24NetworkFrame> external_queue;
790#endif
791
792#if (!defined(DISABLE_FRAGMENTATION) && !defined(RF24_LINUX)) || defined(DOXYGEN_FORCED)
812#endif
813
831
847
848protected:
849#if defined(RF24NetworkMulticast)
855#endif
862 uint16_t node_address;
863
864private:
882 bool write(uint16_t to_node, uint8_t sendType);
883
891 bool write_to_pipe(uint16_t node, uint8_t pipe, bool multicast);
892
901 uint8_t enqueue(RF24NetworkHeader* header);
902
903 /*
904 * Called from begin(), this sets up the radio to act accordingly per the
905 * logical `_node_address` parameter passed to `begin()`.
906 *
907 * Based on the value of the private member `node_address`, the resulting confiuration affects
908 * private members `node_mask`, `parent_node`, `parent_pipe`, and `_multicast_level`.
909 */
910 void setup_address(void);
911
912 /*
913 * This (non-overloaded) function copies the outgoing frame into the `frame_buffer` and detirmines
914 * the initial values passed into `logicalToPhysicalAddress()` (based on the value passed
915 * to the `writeDirect` parameter). This is always called from either of the overloaded public
916 * `write()` functions.
917 */
918 bool _write(RF24NetworkHeader& header, const void* message, uint16_t len, uint16_t writeDirect);
919
920 /*
921 * The main write function where fragmentation and processing of the payload is initiated
922 */
923 inline bool main_write(RF24NetworkHeader& header, const void* message, uint16_t len, uint16_t writeDirect);
924
925 struct logicalToPhysicalStruct
926 {
928 uint16_t send_node;
930 uint8_t send_pipe;
932 bool multicast;
933 };
934
935 /*
936 * Translates an outgoing frame's header information into the current node's
937 * required information (`logicalToPhysicalStruct`) for making the transmission.
938 *
939 * This returns void because the translated results are stored in the
940 * `logicalToPhysicalStruct` passed by reference.
941 */
942 void logicalToPhysicalAddress(logicalToPhysicalStruct* conversionInfo);
943
944 /********* only called from `logicalToPhysicalAddress()` ***************/
945
946 /* Returns true if the given logical address (`node` parameter) is a direct child of the current node; otherwise returns false. */
947 bool is_direct_child(uint16_t node);
948 /* Returns true if the given logical address (`node` parameter) is a descendent of the current node; otherwise returns false. */
949 bool is_descendant(uint16_t node);
950 /* Returns a logical address for the first child en route to a child node */
951 uint16_t direct_child_route_to(uint16_t node);
952
953 /***********************************************************************/
954
955 radio_t& radio;
957 uint8_t frame_size; /* The outgoing frame's total size including the header info. Ranges [8, MAX_PAYLOAD_SIZE] */
958
959 unsigned int max_frame_payload_size = MAX_FRAME_SIZE - sizeof(RF24NetworkHeader); /* always 24 bytes to compensate for the frame's header */
960
961#if defined(RF24_LINUX)
962 std::queue<RF24NetworkFrame> frame_queue;
963 std::map<uint16_t, RF24NetworkFrame> frameFragmentsCache;
964 bool appendFragmentToFrame(RF24NetworkFrame frame);
965#else // Not Linux:
966
967 #if defined(DISABLE_USER_PAYLOADS)
968 uint8_t frame_queue[1];
969 #else
970 uint8_t frame_queue[MAIN_BUFFER_SIZE];
971 #endif
972
973 uint8_t* next_frame;
975 #if !defined(DISABLE_FRAGMENTATION)
976 RF24NetworkFrame frag_queue; /* a cache for re-assembling incoming message fragments */
977 uint8_t frag_queue_message_buffer[MAX_PAYLOAD_SIZE]; //frame size + 1
978 #endif
979
980#endif // Linux/Not Linux
981
982 uint16_t parent_node;
983 uint8_t parent_pipe;
984 uint16_t node_mask;
986 /* Given the Logical node address & a pipe number, this returns the Physical address assigned to the radio's pipes. */
987 void pipe_address(uint16_t node, uint8_t pipe, uint8_t* address);
988
989#if defined ENABLE_NETWORK_STATS
990 uint32_t nFails;
991 uint32_t nOK;
992#endif
993
994#if defined(RF24NetworkMulticast)
995 /* translates network level number (0-3) to a Logical address (used for TX multicasting) */
996 uint16_t levelToAddress(uint8_t level);
997#endif
998
1000};
1001
1014#if defined(ARDUINO_ARCH_NRF52) || defined(ARDUINO_ARCH_NRF52840) || defined(ARDUINO_ARCH_NRF52833)
1015typedef ESBNetwork<nrf_to_nrf> RF52Network;
1016#endif
1017
1119#endif // __RF24NETWORK_H__
ESBNetwork< RF24 > RF24Network
Definition RF24Network.h:1013
#define USE_CURRENT_CHANNEL
Definition RF24Network.h:217
#define MAX_FRAME_SIZE
Definition RF24Network.h:208
#define MAX_PAYLOAD_SIZE
Maximum size of fragmented network frames and fragmentation cache.
Definition RF24Network_config.h:67
#define MAIN_BUFFER_SIZE
The allocated size of the incoming frame buffer.
Definition RF24Network_config.h:78
Definition RF24Network.h:399
ESBNetwork(radio_t &_radio)
Definition RF24Network.cpp:63
bool write(RF24NetworkHeader &header, const void *message, uint16_t len, uint16_t writeDirect)
std::queue< RF24NetworkFrame > external_queue
Definition RF24Network.h:789
bool sleepNode(unsigned int cycles, int interruptPin, uint8_t INTERRUPT_MODE=0)
bool returnSysMsgs
Definition RF24Network.h:830
void multicastLevel(uint8_t level)
Definition RF24Network.cpp:1187
uint16_t node_address
Definition RF24Network.h:862
bool multicast(RF24NetworkHeader &header, const void *message, uint16_t len, uint8_t level=7)
Definition RF24Network.cpp:682
bool available(void)
Definition RF24Network.cpp:556
void begin(uint16_t _node_address)
Definition RF24Network.h:448
uint16_t routeTimeout
Timeout for routed payloads.
Definition RF24Network.h:610
void setup_watchdog(uint8_t prescalar)
void failures(uint32_t *_fails, uint32_t *_ok)
uint8_t update(void)
Definition RF24Network.cpp:133
uint32_t txTimeout
Network timeout value.
Definition RF24Network.h:600
uint8_t networkFlags
Definition RF24Network.h:846
RF24NetworkFrame * frag_ptr
Definition RF24Network.h:811
uint16_t peek(RF24NetworkHeader &header)
Definition RF24Network.cpp:580
uint8_t _multicast_level
Definition RF24Network.h:854
uint16_t addressOfPipe(uint16_t node, uint8_t pipeNo)
Definition RF24Network.cpp:1127
bool is_valid_address(uint16_t node)
Definition RF24Network.cpp:1155
uint8_t frame_buffer[MAX_FRAME_SIZE]
The raw system frame buffer.
Definition RF24Network.h:768
uint16_t read(RF24NetworkHeader &header, void *message, uint16_t maxlen=MAX_PAYLOAD_SIZE)
Definition RF24Network.cpp:626
bool multicastRelay
Definition RF24Network.h:579
uint16_t parent() const
Definition RF24Network.cpp:569
bool write(RF24NetworkHeader &header, const void *message, uint16_t len)
Definition RF24Network.cpp:694
Definition RF24Network.h:327
RF24NetworkFrame(RF24NetworkHeader &_header, uint16_t _message_size)
Definition RF24Network.h:380
RF24NetworkFrame(RF24NetworkHeader &_header, const void *_message=NULL, uint16_t _len=0)
Definition RF24Network.h:362
uint8_t * message_buffer
Definition RF24Network.h:341
RF24NetworkHeader header
Definition RF24Network.h:329
uint16_t message_size
Definition RF24Network.h:332
RF24NetworkFrame()
Definition RF24Network.h:349
Definition RF24Network.h:244
const char * toString(void) const
Definition RF24Network.cpp:1047
unsigned char reserved
Definition RF24Network.h:269
RF24NetworkHeader(uint16_t _to, unsigned char _type=0)
Definition RF24Network.h:302
RF24NetworkHeader()
Definition RF24Network.h:279
unsigned char type
Definition RF24Network.h:261
uint16_t id
Definition RF24Network.h:252
uint16_t to_node
Definition RF24Network.h:249
static uint16_t next_id
Definition RF24Network.h:272
uint16_t from_node
Definition RF24Network.h:246