Skip to content

Commit

Permalink
Fix: Corrupt payloads Add: Address Confirm
Browse files Browse the repository at this point in the history
- Modify dynamic payload handling on AVR to prevent corrupt payloads in
certain cases
- Add address confirmation type NETWORK_ADDR_CONFIRM
- Move frame_buffer to public to allow system type messages to be passed
directly via the frame buffer
  • Loading branch information
TMRh20 committed Oct 6, 2014
1 parent e7fd5a7 commit c73eabc
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 68 deletions.
83 changes: 35 additions & 48 deletions RF24Network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ uint8_t RF24Network::update(void)
while ( radio.isValid() && radio.available())//&pipe_num) )
{


dynLen = radio.getDynamicPayloadSize();
if(!dynLen){delay(5);continue;}

// Dump the payloads until we've gotten everything
// Fetch the payload, and see if this was the last one.
radio.read( frame_buffer, sizeof(frame_buffer) );
Expand All @@ -124,51 +128,35 @@ uint8_t RF24Network::update(void)
uint8_t res = header.type;
// Is this for us?
if ( header.to_node == node_address ){
if(res == NETWORK_ACK){ // If received a routing payload, (Network ACK) discard it, and indicate what it was.
IF_SERIAL_DEBUG_ROUTING( printf_P(PSTR("MAC: Network ACK Rcvd \n")); );
returnVal = NETWORK_ACK;
return NETWORK_ACK;
} // Add it to the buffer of frames for us
if(header.type == NETWORK_ADDR_RESPONSE ){
uint16_t requester = frame_buffer[8];// | frame_buffer[9] << 8;
requester |= frame_buffer[9] << 8;

if(requester != node_address){
header.to_node = requester;
//header.from_node = node_address;
write(header.to_node,USER_TX_TO_PHYSICAL_ADDRESS);
write(header.to_node,USER_TX_TO_PHYSICAL_ADDRESS);
write(header.to_node,USER_TX_TO_PHYSICAL_ADDRESS);
//write(header.to_node,USER_TX_TO_PHYSICAL_ADDRESS);
//printf("fwd addr resp to 0%o , this node: 0%o \n", requester,node_address);
continue;
}
}
if(header.type == NETWORK_REQ_ADDRESS && node_address){
//RF24NetworkHeader reqHeader = header;
header.from_node = node_address;
header.to_node = 0;
write(header.to_node,TX_NORMAL);
//printf("fwd addr req\n");

if(res == NETWORK_ACK || (res == NETWORK_REQ_ADDRESS && !node_address) || res == NETWORK_ADDR_CONFIRM ){
IF_SERIAL_DEBUG_ROUTING( printf_P(PSTR("MAC: System payload rcvd %d\n"),res); );
return res;
}
if(header.type == NETWORK_ADDR_RESPONSE ){
uint16_t requester = frame_buffer[8];// | frame_buffer[9] << 8;
requester |= frame_buffer[9] << 8;
if(requester != node_address){
header.to_node = requester;
write(header.to_node,USER_TX_TO_PHYSICAL_ADDRESS);
delay(50);
write(header.to_node,USER_TX_TO_PHYSICAL_ADDRESS);
//printf("Fwd add response to 0%o\n",requester);
continue;
}

// This ensures that all address requests are only placed at the front of the queue
if( header.type == NETWORK_REQ_ADDRESS ){

if(available()){
//printf("Dropped address request\n");
return returnVal;
}else{
enqueue();
return NETWORK_REQ_ADDRESS;
}
}
if(header.type == NETWORK_REQ_ADDRESS && node_address){
//printf("Fwd add req to 0\n");
header.from_node = node_address;
header.to_node = 0;
write(header.to_node,TX_NORMAL);
continue;
}

enqueue();

}else{
dynLen = radio.getDynamicPayloadSize();
if(!dynLen){continue;}

#if defined (RF24NetworkMulticast)
if( header.to_node == 0100){
if(header.id != lastMultiMessageID){
Expand All @@ -178,13 +166,11 @@ uint8_t RF24Network::update(void)
}

if(header.type == NETWORK_POLL ){
//Serial.println("Send poll");
header.to_node = header.from_node;
header.from_node = node_address;

delay(node_address%5);
header.from_node = node_address;
delay((node_address%5)*5);
write(header.to_node,USER_TX_TO_PHYSICAL_ADDRESS);
//write(header.to_node,USER_TX_TO_PHYSICAL_ADDRESS);
//Serial.println("send poll");
continue;
}

Expand All @@ -194,7 +180,7 @@ uint8_t RF24Network::update(void)
else{
IF_SERIAL_DEBUG_ROUTING( printf_P(PSTR("MAC: Drop duplicate multicast frame %d from 0%o\n"),header.id,header.from_node); );
}
}else{
}else{
write(header.to_node,1); //Send it on, indicate it is a routed payload
}
#else
Expand Down Expand Up @@ -495,14 +481,14 @@ bool RF24Network::write(uint16_t to_node, uint8_t directTo) // Direct To: 0 = F
RF24NetworkHeader& header = * reinterpret_cast<RF24NetworkHeader*>(frame_buffer);
header.type = NETWORK_ACK; // Set the payload type to NETWORK_ACK
header.to_node = header.from_node; // Change the 'to' address to the 'from' address
dynLen=8;
//dynLen=8;
conversion = { header.from_node,TX_ROUTED,0};
logicalToPhysicalAddress(&conversion);

//Write the data using the resulting physical address
write_to_pipe(conversion.send_node, conversion.send_pipe, conversion.multicast);

dynLen=0;
//dynLen=0;
IF_SERIAL_DEBUG_ROUTING( printf_P(PSTR("%lu MAC: Route OK to 0%o ACK sent to 0%o\n"),millis(),to_node,header.to_node); );
}

Expand Down Expand Up @@ -597,7 +583,8 @@ bool RF24Network::write_to_pipe( uint16_t node, uint8_t pipe, bool multicast )
radio.stopListening();
radio.openWritingPipe(out_pipe);
size_t wLen = dynLen ? dynLen: frame_size;
radio.writeFast(frame_buffer, wLen,multicast);
radio.writeFast(&frame_buffer, wLen,multicast);
dynLen=0;
ok = radio.txStandBy(txTimeout);


Expand Down
10 changes: 8 additions & 2 deletions RF24Network.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#define NETWORK_ACK 129
#define NETWORK_REQ_ADDRESS 151
#define NETWORK_ADDR_RESPONSE 152
#define NETWORK_ADDR_CONFIRM 153

/**System-Sub Types (0-255)*/
//#define NETWORK_REQ_STREAM 11;
Expand Down Expand Up @@ -390,6 +391,7 @@ class RF24Network
#endif
uint16_t addressOfPipe( uint16_t node,uint8_t pipeNo );
bool is_valid_address( uint16_t node );

private:

bool write(uint16_t, uint8_t directTo);
Expand Down Expand Up @@ -423,18 +425,22 @@ class RF24Network
uint16_t node_address; /**< Logical node address of this unit, 1 .. UINT_MAX */
const static int frame_size = 32; /**< How large is each frame over the air */
const static unsigned int max_frame_payload_size = MAX_FRAME_SIZE-sizeof(RF24NetworkHeader);
uint8_t frame_buffer[frame_size]; /**< Space to put the frame that will be sent/received over the air */


#if defined RF24TINY
uint8_t frame_queue[3*frame_size]; /**< Space for a small set of frames that need to be delivered to the app layer */
#else
uint8_t frame_queue[5*frame_size]; /**< Space for a small set of frames that need to be delivered to the app layer */
#endif
uint8_t* next_frame; /**< Pointer into the @p frame_queue where we should place the next received frame */


uint16_t parent_node; /**< Our parent's node address */
uint8_t parent_pipe; /**< The pipe our parent uses to listen to us */
uint16_t node_mask; /**< The bits which contain signfificant node address information */


public:
uint8_t frame_buffer[frame_size]; /**< Space to put the frame that will be sent/received over the air */

};

Expand Down
25 changes: 8 additions & 17 deletions RPi/RF24Network/RF24Network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,43 +132,34 @@ uint8_t RF24Network::update(void) {

// Is this for us?
if ( header.to_node == node_address ) {
if (header.type == NETWORK_ACK) {
IF_SERIAL_DEBUG_ROUTING(printf_P(PSTR("RT: Network ACK Rcvd\n")););
returnVal = NETWORK_ACK;
continue;

if (header.type == NETWORK_ACK || (header.type == NETWORK_REQ_ADDRESS && !node_address) || header.type == NETWORK_ADDR_CONFIRM ) {
IF_SERIAL_DEBUG_ROUTING(printf_P(PSTR("RT: System payload rcvd %d\n"),res););
return header.type;
}
if(header.type == NETWORK_ADDR_RESPONSE ){
uint16_t requester = frame_buffer[8];// | frame_buffer[9] << 8;
requester |= frame_buffer[9] << 8;

if(requester != node_address){
header.to_node = requester;
//header.from_node = node_address;
memcpy(frame_buffer,&header,sizeof(RF24NetworkHeader));
write(header.to_node,USER_TX_TO_PHYSICAL_ADDRESS);
delay(50);
write(header.to_node,USER_TX_TO_PHYSICAL_ADDRESS);
//printf("fwd addr resp to 0%o , this node: 0%o\n", requester,node_address);
continue;
}
}
if(header.type == NETWORK_REQ_ADDRESS && node_address){
//RF24NetworkHeader reqHeader = header;
// printf("Fwd add req to 0\n");
header.from_node = node_address;
header.to_node = 0;
memcpy(frame_buffer,&header,sizeof(RF24NetworkHeader));
write(header.to_node,TX_NORMAL);
//printf("fwd addr req\n");
continue;
}
// This ensures that all address requests are only placed at the front of the queue
if( header.type == NETWORK_REQ_ADDRESS ){
if(available()){
printf("Dropped address request\n");
return returnVal;
}else{
enqueue(frame);
return returnVal;
}
}

enqueue(frame);

if (radio.rxFifoFull()) {
Expand Down
6 changes: 5 additions & 1 deletion RPi/RF24Network/RF24Network.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
/* System retained - response messages */
#define NETWORK_REQ_ADDRESS 151
#define NETWORK_ADDR_RESPONSE 152
#define NETWORK_ADDR_CONFIRM 153

/** Defines for handling written payloads */
#define TX_NORMAL 0
Expand Down Expand Up @@ -345,6 +346,7 @@ class RF24Network {
bool is_valid_address( uint16_t node );
uint16_t addressOfPipe( uint16_t node,uint8_t pipeNo );


protected:
//void open_pipes(void);
//uint16_t find_node( uint16_t current_node, uint16_t target_node );
Expand Down Expand Up @@ -377,7 +379,6 @@ uint16_t addressOfPipe( uint16_t node,uint8_t pipeNo );
uint16_t node_address; /**< Logical node address of this unit, 1 .. UINT_MAX */
uint8_t frame_size; /**< How large is each frame over the air */
const static unsigned int max_frame_payload_size = MAX_FRAME_SIZE-sizeof(RF24NetworkHeader);
uint8_t frame_buffer[MAX_FRAME_SIZE]; /**< Space to put the frame that will be sent/received over the air */
std::queue<RF24NetworkFrame> frame_queue;
std::map<std::pair<uint16_t, uint16_t>, RF24NetworkFrame> frameFragmentsCache;

Expand All @@ -388,6 +389,9 @@ uint16_t addressOfPipe( uint16_t node,uint8_t pipeNo );
bool noListen; //FIXME
uint32_t lastWriteTime; //FIXME

public:
uint8_t frame_buffer[MAX_FRAME_SIZE]; /**< Space to put the frame that will be sent/received over the air */

};

/**
Expand Down

0 comments on commit c73eabc

Please sign in to comment.