Skip to content

Commit

Permalink
Testing some RPi changes/additions
Browse files Browse the repository at this point in the history
- Modify fragmented payload writing
- Add network_poll and address request handling
  • Loading branch information
TMRh20 committed Sep 27, 2014
1 parent 48de499 commit e3d0100
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 34 deletions.
119 changes: 88 additions & 31 deletions RPi/RF24Network/RF24Network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ uint32_t nFails = 0, nOK=0;

/******************************************************************/

RF24Network::RF24Network( RF24& _radio ): radio(_radio), frame_size(MAX_FRAME_SIZE), lastMultiMessageID(0), noListen(1), lastWriteTime(0)
RF24Network::RF24Network( RF24& _radio ): radio(_radio), frame_size(MAX_FRAME_SIZE)
{}

/******************************************************************/
Expand All @@ -48,7 +48,7 @@ void RF24Network::begin(uint8_t _channel, uint16_t _node_address ) {
if ( ! radio.isValid() ) {
return;
}

radio.stopListening();
// Set up the radio the way we want it to look
radio.setChannel(_channel);
radio.setDataRate(RF24_1MBPS);
Expand Down Expand Up @@ -138,6 +138,28 @@ uint8_t RF24Network::update(void) {
returnVal = NETWORK_ACK;
continue;
}
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);
//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;
memcpy(frame_buffer,&header,sizeof(RF24NetworkHeader));
write(header.to_node,TX_NORMAL);
//printf("fwd addr req\n");
continue;
}

enqueue(frame);

Expand All @@ -155,10 +177,18 @@ uint8_t RF24Network::update(void) {
IF_SERIAL_DEBUG_ROUTING(printf_P(PSTR("RT: FWD multicast frame from 0%o to level %d\n"),header.from_node,multicast_level+1););
write(levelToAddress(multicast_level)<<3,4);
}

if(header.type == NETWORK_POLL ){
header.to_node = header.from_node;
header.from_node = node_address;
memcpy(frame_buffer,&header,sizeof(RF24NetworkHeader));
delay(2);
write(header.to_node,USER_TX_TO_PHYSICAL_ADDRESS);
//printf("send poll\n");
continue;
}

lastMultiMessageID = header.id;
enqueue(frame);

} else {
//Duplicate received
IF_SERIAL_DEBUG_ROUTING(printf_P(PSTR("RT: Drop duplicate multicast frame %u from 0%o\n"),header.id,header.from_node););
Expand Down Expand Up @@ -225,20 +255,20 @@ bool RF24Network::enqueue(RF24NetworkFrame frame) {

result = true;

} else if (frame.header.type <= MAX_USER_DEFINED_HEADER_TYPE) {
} else{// if (frame.header.type <= MAX_USER_DEFINED_HEADER_TYPE) {
//This is not a fragmented payload but a whole frame.

IF_SERIAL_DEBUG(printf_P(PSTR("%u: NET Enqueue @%x "),millis(),frame_queue.size()));
// Copy the current frame into the frame queue
frame_queue.push(frame);
result = true;

} else {
}/* else {
//Undefined/Unknown header.type received. Drop frame!
IF_SERIAL_DEBUG_MINIMAL( printf("%u: FRG Received unknown or system header type %d with fragment id %d\n",millis(),frame.header.type, frame.header.fragment_id); );
//The frame is not explicitly dropped, but the given object is ignored.
//FIXME: does this causes problems with memory management?
}
}*/

if (result) {
IF_SERIAL_DEBUG(printf("ok\n\r"));
Expand All @@ -253,6 +283,8 @@ bool RF24Network::enqueue(RF24NetworkFrame frame) {

void RF24Network::appendFragmentToFrame(RF24NetworkFrame frame) {


if(frameFragmentsCache.size() >= 7){ frameFragmentsCache.erase(frameFragmentsCache.begin()); }
if (frameFragmentsCache.count(std::make_pair(frame.header.from_node,frame.header.id)) == 0 ) {
// This is the first of many fragments.

Expand Down Expand Up @@ -281,7 +313,7 @@ void RF24Network::appendFragmentToFrame(RF24NetworkFrame frame) {
if (frame.header.fragment_id != f->header.fragment_id) {
if (frame.header.fragment_id > f->header.fragment_id) {
IF_SERIAL_DEBUG_MINIMAL(printf("%u: FRG Duplicate or out of sequence frame %d, expected %d. Cleared.\n",millis(),frame.header.fragment_id,f->header.fragment_id););
frameFragmentsCache.erase( std::make_pair(frame.header.from_node,frame.header.id) );
//frameFragmentsCache.erase( std::make_pair(frame.header.from_node,frame.header.id) );
} else {
frameFragmentsCache.erase( std::make_pair(frame.header.from_node,frame.header.id) );
IF_SERIAL_DEBUG_MINIMAL(printf("%u: FRG Out of sequence frame %d, expected %d. Cleared.\n",millis(),frame.header.fragment_id,f->header.fragment_id););
Expand Down Expand Up @@ -371,7 +403,7 @@ bool RF24Network::multicast(RF24NetworkHeader& header,const void* message, size_
header.from_node = node_address;

// Build the full frame to send
RF24NetworkFrame frame = RF24NetworkFrame(header,message,std::min(sizeof(message),len));
//RF24NetworkFrame frame = RF24NetworkFrame(header,message,std::min(sizeof(message),len));

IF_SERIAL_DEBUG(printf_P(PSTR("%u: NET Sending %s\n\r"),millis(),header.toString()));
if (len) {
Expand Down Expand Up @@ -415,18 +447,18 @@ bool RF24Network::write(RF24NetworkHeader& header,const void* message, size_t le
// --> We cann transmit the message.

// First, stop listening so we can talk.
radio.stopListening();
//radio.stopListening();

//Normal Write (Un-Fragmented)
//The len of the payload if less or equal than the max_frame_payload_size,
//therefore we send this payload in a single frame. Fragmentation not needed.
if (len <= max_frame_payload_size) {
txSuccess = _write(header,message,len,writeDirect);
radio.startListening();
//radio.startListening();
return txSuccess;
}

noListen = 1;
//noListen = 1;

//Fragmented Write
//The len payload is definitely bigger than the max_frame_payload_size,
Expand Down Expand Up @@ -466,13 +498,18 @@ bool RF24Network::write(RF24NetworkHeader& header,const void* message, size_t le

IF_SERIAL_DEBUG_FRAGMENTATION(printf("%u: FRG try to transmit fragmented payload of size %i Bytes with fragmentID '%i'\n\r",millis(),fragmentLen,fragment_id););

//uint8_t msg[32];

//Try to send the payload chunk with the copied header
bool ok = _write(fragmentHeader,message+offset,fragmentLen,writeDirect);
bool ok = _write(fragmentHeader,((char *)message)+offset,fragmentLen,writeDirect);

if (!noListen) {
//Hack to allow the radio to be able to process the tx bytes
if(!ok){ delay(100); ok = _write(fragmentHeader,((char *)message)+offset,fragmentLen,writeDirect);
if(!ok){ delay(150); ok = _write(fragmentHeader,((char *)message)+offset,fragmentLen,writeDirect);
}
}
//if (!noListen) {
delayMicroseconds(50);
}
//}

if (!ok) {
IF_SERIAL_DEBUG_FRAGMENTATION(printf("%u: FRG message transmission with fragmentID '%i' failed. Abort.\n\r",millis(),fragment_id););
Expand All @@ -488,10 +525,10 @@ bool RF24Network::write(RF24NetworkHeader& header,const void* message, size_t le
msgCount++;
}

noListen = 0;
//noListen = 0;

// Now, continue listening
radio.startListening();
//radio.startListening();

int frag_delay = uint8_t(len/48);
delay( std::min(frag_delay,20));
Expand Down Expand Up @@ -561,9 +598,9 @@ bool RF24Network::write(uint16_t to_node, uint8_t directTo) {
return false;
}

if (to_node != parent_node && !is_direct_child(to_node) ) {
noListen=0;
}
//if (to_node != parent_node && !is_direct_child(to_node) ) {
// noListen=0;
//}
//Load info into our conversion structure, and get the converted address info
conversion.send_node = to_node;
conversion.send_pipe = directTo;
Expand All @@ -582,11 +619,13 @@ bool RF24Network::write(uint16_t to_node, uint8_t directTo) {

if ( directTo == 1 && ok && conversion.send_node == to_node && frame_buffer[6] != NETWORK_ACK ) {

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

conversion.send_node=header.from_node;
//RF24NetworkHeader& header = * reinterpret_cast<RF24NetworkHeader*>(frame_buffer);
frame_buffer[6] = NETWORK_ACK; // Set the payload type to NETWORK_ACK
//header.to_node = header.from_node; // Change the 'to' address to the 'from' address
frame_buffer[2] = frame_buffer[0];
frame_buffer[3] = frame_buffer[1];

conversion.send_node = (frame_buffer[0] | frame_buffer[1] << 8);//header.from_node;
conversion.send_pipe = TX_ROUTED;
logicalToPhysicalAddress(&conversion);

Expand All @@ -596,9 +635,9 @@ bool RF24Network::write(uint16_t to_node, uint8_t directTo) {
IF_SERIAL_DEBUG_ROUTING(printf("RT Route OK to 0%o ACK sent to 0%o\n",to_node,header.to_node););
}

if (!noListen ) {
//if (!noListen ) {
radio.startListening();
}
//}

if ( ok && (conversion.send_node != to_node) && (directTo==0 || directTo == 3 )) {

Expand All @@ -611,7 +650,7 @@ bool RF24Network::write(uint16_t to_node, uint8_t directTo) {
break;
}
}
if (!noListen) { radio.stopListening(); }
//if (!noListen) { radio.stopListening(); }
}

//Increment the number of correctly trasmitted frames or the number of fail transmissions
Expand Down Expand Up @@ -682,9 +721,9 @@ bool RF24Network::write_to_pipe( uint16_t node, uint8_t pipe, bool multicast ) {

uint64_t out_pipe = pipe_address( node, pipe );

if (!noListen) {
//if (!noListen) {
radio.stopListening();
}
//}

// Open the correct pipe for writing.
radio.openWritingPipe(out_pipe);
Expand Down Expand Up @@ -769,6 +808,24 @@ void RF24Network::setup_address(void) {

/******************************************************************/

uint16_t RF24Network::addressOfPipe( uint16_t node, uint8_t pipeNo )
{
//Say this node is 013 (1011), mask is 077 or (00111111)
//Say we want to use pipe 3 (11)
//6 bits in node mask, so shift pipeNo 6 times left and | into address
uint16_t m = node_mask >> 3;
uint8_t i=0;

while (m){ //While there are bits left in the node mask
m>>=1; //Shift to the right
i++; //Count the # of increments
}

return node | (pipeNo << i);
}

/******************************************************************/

uint16_t RF24Network::direct_child_route_to( uint16_t node ) {
// Presumes that this is in fact a child!!
uint16_t child_mask = ( node_mask << 3 ) | 0B111;
Expand Down
3 changes: 1 addition & 2 deletions RPi/RF24Network/RF24Network.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
/* System Discard Types */
#define NETWORK_ACK_REQUEST 128
#define NETWORK_ACK 129
#define NETWORK_POLL 130

/*System-Sub Types (0-255)*/
#define NETWORK_REQ_STREAM 11;
Expand Down Expand Up @@ -376,12 +377,10 @@ uint16_t addressOfPipe( uint16_t node,uint8_t pipeNo );
std::queue<RF24NetworkFrame> frame_queue;
std::map<std::pair<uint16_t, uint16_t>, RF24NetworkFrame> frameFragmentsCache;


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 */

uint16_t lastMultiMessageID; //FIXME
bool noListen; //FIXME
uint32_t lastWriteTime; //FIXME

Expand Down
2 changes: 1 addition & 1 deletion RPi/RF24Network/RF24Network_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

/********** USER CONFIG **************/

//#define RF24NetworkMulticast //Use multicast capabilities
#define RF24NetworkMulticast //Use multicast capabilities
//#define SERIAL_DEBUG //Set for full debug
#define SERIAL_DEBUG_MINIMAL //Enable minimal debugging
//#define SERIAL_DEBUG_ROUTING
Expand Down

0 comments on commit e3d0100

Please sign in to comment.