Optimized RF24Network Layer v2.0.4
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
161#define NETWORK_ACK 193
162
170#define NETWORK_POLL 194
171
178#define NETWORK_REQ_ADDRESS 195
179
180// The following 2 atrifacts now exist in RF24Mesh as their significance was specific to RF24Mesh.
181//#define NETWORK_ADDR_LOOKUP 196
182//#define NETWORK_ADDR_RELEASE 197
185/* This isn't actually used anywhere. */
186#define NETWORK_MORE_FRAGMENTS_NACK 200
187
188/* Internal defines for handling written payloads */
189#define TX_NORMAL 0
190#define TX_ROUTED 1
191#define USER_TX_TO_PHYSICAL_ADDRESS 2 // no network ACK
192#define USER_TX_TO_LOGICAL_ADDRESS 3 // network ACK
193#define USER_TX_MULTICAST 4
194
195#if defined NRF52_RADIO_LIBRARY
196 #define MAX_FRAME_SIZE 123 // Size of individual radio frames is larger with NRF52
197#else
198 #define MAX_FRAME_SIZE 32 // Size of individual radio frames
199#endif
200
201#define FRAME_HEADER_SIZE 10 // Size of RF24Network frames - data
202
207#define USE_CURRENT_CHANNEL 255
208
213#define FLAG_FAST_FRAG 4
219#define FLAG_NO_POLL 8
220
221class RF24;
222#if defined(ARDUINO_ARCH_NRF52) || defined(ARDUINO_ARCH_NRF52840) || defined(ARDUINO_ARCH_NRF52833)
223class nrf_to_nrf;
224#endif
225
234{
236 uint16_t from_node;
237
239 uint16_t to_node;
240
242 uint16_t id;
243
251 unsigned char type;
252
259 unsigned char reserved;
260
262 static uint16_t next_id;
263
270
292 RF24NetworkHeader(uint16_t _to, unsigned char _type = 0) : to_node(_to), id(next_id++), type(_type) {}
293
303 const char* toString(void) const;
304};
305
317{
320
322 uint16_t message_size;
323
328#if defined(RF24_LINUX)
329 uint8_t message_buffer[MAX_PAYLOAD_SIZE]; // Array to store the message
330#else
331 uint8_t* message_buffer; // Pointer to the buffer storing the actual message
332#endif
333
340
351#if defined(RF24_LINUX) || defined(DOXYGEN_FORCED)
352 RF24NetworkFrame(RF24NetworkHeader& _header, const void* _message = NULL, uint16_t _len = 0) : header(_header), message_size(_len)
353 {
354 if (_message && _len) {
355 memcpy(message_buffer, _message, _len);
356 }
357 }
358#endif
359#if defined(DOXYGEN_FORCED) || !defined(RF24_LINUX)
370 RF24NetworkFrame(RF24NetworkHeader& _header, uint16_t _message_size) : header(_header), message_size(_message_size)
371 {
372 }
373#endif
374};
375
387template<class radio_t = RF24>
389{
390
398public:
416 ESBNetwork(radio_t& _radio);
417
438 inline void begin(uint16_t _node_address)
439 {
440 begin(USE_CURRENT_CHANNEL, _node_address);
441 }
442
451 uint8_t update(void);
452
458 bool available(void);
459
470 uint16_t peek(RF24NetworkHeader& header);
471
485 void peek(RF24NetworkHeader& header, void* message, uint16_t maxlen = MAX_PAYLOAD_SIZE);
486
509 uint16_t read(RF24NetworkHeader& header, void* message, uint16_t maxlen = MAX_PAYLOAD_SIZE);
510
530 bool write(RF24NetworkHeader& header, const void* message, uint16_t len);
531
560 void multicastLevel(uint8_t level);
561
570
579 void setup_watchdog(uint8_t prescalar);
580
590 uint32_t txTimeout;
591
600 uint16_t routeTimeout;
601
610#if defined(ENABLE_NETWORK_STATS) || defined(DOXYGEN_FORCED)
611
621 void failures(uint32_t* _fails, uint32_t* _ok);
622
623#endif // defined (ENABLE_NETWORK_STATS)
624#if defined(RF24NetworkMulticast)
625
642 bool multicast(RF24NetworkHeader& header, const void* message, uint16_t len, uint8_t level = 7);
643
644#endif
645
651 bool write(RF24NetworkHeader& header, const void* message, uint16_t len, uint16_t writeDirect);
652
685 bool sleepNode(unsigned int cycles, int interruptPin, uint8_t INTERRUPT_MODE = 0); //added interrupt mode support (default 0=LOW)
686
692 uint16_t parent() const;
693
697 uint16_t addressOfPipe(uint16_t node, uint8_t pipeNo);
698
708 bool is_valid_address(uint16_t node);
709
739 void begin(uint8_t _channel, uint16_t _node_address);
740
759
778#if defined(RF24_LINUX) || defined(DOXYGEN_FORCED)
779 std::queue<RF24NetworkFrame> external_queue;
780#endif
781
782#if (!defined(DISABLE_FRAGMENTATION) && !defined(RF24_LINUX)) || defined(DOXYGEN_FORCED)
802#endif
803
821
837
838protected:
839#if defined(RF24NetworkMulticast)
845#endif
852 uint16_t node_address;
853
854private:
872 bool write(uint16_t to_node, uint8_t sendType);
873
881 bool write_to_pipe(uint16_t node, uint8_t pipe, bool multicast);
882
891 uint8_t enqueue(RF24NetworkHeader* header);
892
893 /*
894 * Called from begin(), this sets up the radio to act accordingly per the
895 * logical `_node_address` parameter passed to `begin()`.
896 *
897 * Based on the value of the private member `node_address`, the resulting confiuration affects
898 * private members `node_mask`, `parent_node`, `parent_pipe`, and `_multicast_level`.
899 */
900 void setup_address(void);
901
902 /*
903 * This (non-overloaded) function copies the outgoing frame into the `frame_buffer` and detirmines
904 * the initial values passed into `logicalToPhysicalAddress()` (based on the value passed
905 * to the `writeDirect` parameter). This is always called from either of the overloaded public
906 * `write()` functions.
907 */
908 bool _write(RF24NetworkHeader& header, const void* message, uint16_t len, uint16_t writeDirect);
909
910 /*
911 * The main write function where fragmentation and processing of the payload is initiated
912 */
913 inline bool main_write(RF24NetworkHeader& header, const void* message, uint16_t len, uint16_t writeDirect);
914
915 struct logicalToPhysicalStruct
916 {
918 uint16_t send_node;
920 uint8_t send_pipe;
922 bool multicast;
923 };
924
925 /*
926 * Translates an outgoing frame's header information into the current node's
927 * required information (`logicalToPhysicalStruct`) for making the transmission.
928 *
929 * This returns void because the translated results are stored in the
930 * `logicalToPhysicalStruct` passed by reference.
931 */
932 void logicalToPhysicalAddress(logicalToPhysicalStruct* conversionInfo);
933
934 /********* only called from `logicalToPhysicalAddress()` ***************/
935
936 /* Returns true if the given logical address (`node` parameter) is a direct child of the current node; otherwise returns false. */
937 bool is_direct_child(uint16_t node);
938 /* Returns true if the given logical address (`node` parameter) is a descendent of the current node; otherwise returns false. */
939 bool is_descendant(uint16_t node);
940 /* Returns a logical address for the first child en route to a child node */
941 uint16_t direct_child_route_to(uint16_t node);
942
943 /***********************************************************************/
944
945 radio_t& radio;
947 uint8_t frame_size; /* The outgoing frame's total size including the header info. Ranges [8, MAX_PAYLOAD_SIZE] */
948
949 unsigned int max_frame_payload_size = MAX_FRAME_SIZE - sizeof(RF24NetworkHeader); /* always 24 bytes to compensate for the frame's header */
950
951#if defined(RF24_LINUX)
952 std::queue<RF24NetworkFrame> frame_queue;
953 std::map<uint16_t, RF24NetworkFrame> frameFragmentsCache;
954 bool appendFragmentToFrame(RF24NetworkFrame frame);
955#else // Not Linux:
956
957 #if defined(DISABLE_USER_PAYLOADS)
958 uint8_t frame_queue[1];
959 #else
960 uint8_t frame_queue[MAIN_BUFFER_SIZE];
961 #endif
962
963 uint8_t* next_frame;
965 #if !defined(DISABLE_FRAGMENTATION)
966 RF24NetworkFrame frag_queue; /* a cache for re-assembling incoming message fragments */
967 uint8_t frag_queue_message_buffer[MAX_PAYLOAD_SIZE]; //frame size + 1
968 #endif
969
970#endif // Linux/Not Linux
971
972 uint16_t parent_node;
973 uint8_t parent_pipe;
974 uint16_t node_mask;
976 /* Given the Logical node address & a pipe number, this returns the Physical address assigned to the radio's pipes. */
977 uint64_t pipe_address(uint16_t node, uint8_t pipe);
978
979#if defined ENABLE_NETWORK_STATS
980 uint32_t nFails;
981 uint32_t nOK;
982#endif
983
984#if defined(RF24NetworkMulticast)
985 /* translates network level number (0-3) to a Logical address (used for TX multicasting) */
986 uint16_t levelToAddress(uint8_t level);
987#endif
988
990};
991
1004#if defined(ARDUINO_ARCH_NRF52) || defined(ARDUINO_ARCH_NRF52840) || defined(ARDUINO_ARCH_NRF52833)
1005typedef ESBNetwork<nrf_to_nrf> RF52Network;
1006#endif
1007
1109#endif // __RF24NETWORK_H__
ESBNetwork< RF24 > RF24Network
Definition RF24Network.h:1003
#define USE_CURRENT_CHANNEL
Definition RF24Network.h:207
#define MAX_FRAME_SIZE
Definition RF24Network.h:198
#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:389
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:779
bool sleepNode(unsigned int cycles, int interruptPin, uint8_t INTERRUPT_MODE=0)
bool returnSysMsgs
Definition RF24Network.h:820
void multicastLevel(uint8_t level)
Definition RF24Network.cpp:1189
uint16_t node_address
Definition RF24Network.h:852
bool multicast(RF24NetworkHeader &header, const void *message, uint16_t len, uint8_t level=7)
Definition RF24Network.cpp:680
bool available(void)
Definition RF24Network.cpp:554
void begin(uint16_t _node_address)
Definition RF24Network.h:438
uint16_t routeTimeout
Timeout for routed payloads.
Definition RF24Network.h:600
void setup_watchdog(uint8_t prescalar)
void failures(uint32_t *_fails, uint32_t *_ok)
uint8_t update(void)
Definition RF24Network.cpp:130
uint32_t txTimeout
Network timeout value.
Definition RF24Network.h:590
uint8_t networkFlags
Definition RF24Network.h:836
RF24NetworkFrame * frag_ptr
Definition RF24Network.h:801
uint16_t peek(RF24NetworkHeader &header)
Definition RF24Network.cpp:578
uint8_t _multicast_level
Definition RF24Network.h:844
uint16_t addressOfPipe(uint16_t node, uint8_t pipeNo)
Definition RF24Network.cpp:1129
bool is_valid_address(uint16_t node)
Definition RF24Network.cpp:1157
uint8_t frame_buffer[MAX_FRAME_SIZE]
The raw system frame buffer.
Definition RF24Network.h:758
uint16_t read(RF24NetworkHeader &header, void *message, uint16_t maxlen=MAX_PAYLOAD_SIZE)
Definition RF24Network.cpp:624
bool multicastRelay
Definition RF24Network.h:569
uint16_t parent() const
Definition RF24Network.cpp:567
bool write(RF24NetworkHeader &header, const void *message, uint16_t len)
Definition RF24Network.cpp:692
Definition RF24Network.h:317
RF24NetworkFrame(RF24NetworkHeader &_header, uint16_t _message_size)
Definition RF24Network.h:370
RF24NetworkFrame(RF24NetworkHeader &_header, const void *_message=NULL, uint16_t _len=0)
Definition RF24Network.h:352
uint8_t * message_buffer
Definition RF24Network.h:331
RF24NetworkHeader header
Definition RF24Network.h:319
uint16_t message_size
Definition RF24Network.h:322
RF24NetworkFrame()
Definition RF24Network.h:339
Definition RF24Network.h:234
const char * toString(void) const
Definition RF24Network.cpp:1049
unsigned char reserved
Definition RF24Network.h:259
RF24NetworkHeader(uint16_t _to, unsigned char _type=0)
Definition RF24Network.h:292
RF24NetworkHeader()
Definition RF24Network.h:269
unsigned char type
Definition RF24Network.h:251
uint16_t id
Definition RF24Network.h:242
uint16_t to_node
Definition RF24Network.h:239
static uint16_t next_id
Definition RF24Network.h:262
uint16_t from_node
Definition RF24Network.h:236