Skip to content

Commit

Permalink
Add timeouts per #23
Browse files Browse the repository at this point in the history
Per @Avamander  add timeout to address renewal.

- Add timeout for address renewals defaulting to 3 seconds
- Prevent any RF24Mesh functions from running when default address is
set (Note: RF24Network functions will still run, and may cause problems
if run after failed address renewal)
- Set mesh.begin() to return a boolean value indicating success or fail
of address request.
  • Loading branch information
TMRh20 committed Aug 8, 2015
1 parent fbceb85 commit 1a9b0c9
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 20 deletions.
55 changes: 38 additions & 17 deletions RF24Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@

RF24Mesh::RF24Mesh( RF24& _radio,RF24Network& _network ): radio(_radio),network(_network){}


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

void RF24Mesh::begin(uint8_t channel, rf24_datarate_e data_rate){
bool RF24Mesh::begin(uint8_t channel, rf24_datarate_e data_rate){
radio.begin();
if(getNodeID()){ //Not master node
mesh_address = MESH_DEFAULT_ADDRESS;
Expand All @@ -25,20 +26,27 @@ void RF24Mesh::begin(uint8_t channel, rf24_datarate_e data_rate){
}
radio_channel = channel;
radio.setChannel(radio_channel);
radio.setDataRate(data_rate);
network.begin(mesh_address);
radio.setDataRate(data_rate);
network.returnSysMsgs = 1;
if(getNodeID()){ //Not master node
renewAddress();
if(!renewAddress()){
return 0;
}
}else{
network.begin(mesh_address);
}
return 1;
}

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

uint8_t RF24Mesh::update(){



uint8_t type = network.update();

if(mesh_address == MESH_DEFAULT_ADDRESS){ return type; }

#if !defined (RF24_TINY) && !defined(MESH_NOMASTER)
if(type == NETWORK_REQ_ADDRESS){
doDHCP = 1;
Expand Down Expand Up @@ -71,14 +79,15 @@ uint8_t RF24Mesh::update(){
}

bool RF24Mesh::write(uint16_t to_node, const void* data, uint8_t msg_type, size_t size ){
if(mesh_address == MESH_DEFAULT_ADDRESS){ return 0; }
RF24NetworkHeader header(to_node,msg_type);
return network.write(header,data,size);
}

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

bool RF24Mesh::write(const void* data, uint8_t msg_type, size_t size, uint8_t nodeID){

if(mesh_address == MESH_DEFAULT_ADDRESS){ return 0; }
uint16_t toNode = 0;
if(nodeID){
toNode = getAddress(nodeID);
Expand All @@ -102,8 +111,8 @@ bool RF24Mesh::checkConnection(){

RF24NetworkHeader header(00,NETWORK_PING);
uint8_t count = 3;
bool ok;
while(count--){
bool ok = 0;
while(count-- && mesh_address != MESH_DEFAULT_ADDRESS){
update();
if(radio.rxFifoFull() || (network.networkFlags & 1)){
return 1;
Expand Down Expand Up @@ -134,7 +143,7 @@ uint16_t RF24Mesh::getAddress(uint8_t nodeID){
return 0;
}
#endif

if(mesh_address == MESH_DEFAULT_ADDRESS){ return 0; }
RF24NetworkHeader header( 00, MESH_ADDR_LOOKUP );
if(network.write(header,&nodeID,sizeof(nodeID)+1) ){
uint32_t timer=millis(), timeout = 500;
Expand All @@ -160,6 +169,7 @@ int RF24Mesh::getNodeID(uint16_t address){
}
}
}else{
if(mesh_address == MESH_DEFAULT_ADDRESS){ return -1; }
RF24NetworkHeader header( 00, MESH_ID_LOOKUP );
if(network.write(header,&address,sizeof(address)) ){
uint32_t timer=millis(), timeout = 500;
Expand All @@ -174,13 +184,17 @@ int RF24Mesh::getNodeID(uint16_t address){
/*****************************************************/

bool RF24Mesh::releaseAddress(){

if(mesh_address == MESH_DEFAULT_ADDRESS){ return 0; }
network.begin(MESH_DEFAULT_ADDRESS);
mesh_address=MESH_DEFAULT_ADDRESS;
RF24NetworkHeader header(00,MESH_ADDR_RELEASE);
return network.write(header,0,0);
}

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

uint16_t RF24Mesh::renewAddress(){
uint16_t RF24Mesh::renewAddress(uint32_t timeout){

if(radio.available()){ return 0; }
uint8_t reqCounter = 0;
Expand All @@ -192,11 +206,14 @@ uint16_t RF24Mesh::renewAddress(){

network.begin(MESH_DEFAULT_ADDRESS);
mesh_address = MESH_DEFAULT_ADDRESS;


uint32_t start = millis();
while(!requestAddress(reqCounter)){
delay(10 + ( (totalReqs+1)*(reqCounter+1)) * 2);
if(millis()-start > timeout){ return 0; }
delay(50 + ( (totalReqs+1)*(reqCounter+1)) * 2);
(++reqCounter) = reqCounter%4;
(++totalReqs) = totalReqs%10;

}
network.networkFlags &= ~2;
return mesh_address;
Expand Down Expand Up @@ -264,8 +281,9 @@ bool RF24Mesh::requestAddress(uint8_t level){
header.reserved = getNodeID();
header.to_node = *contactNode;

uint16_t addr = MESH_DEFAULT_ADDRESS;
// Do a direct write (no ack) to the contact node. Include the nodeId and address.
network.write(header,&mesh_address,sizeof(addrResponse),*contactNode);
network.write(header,&addr,sizeof(addrResponse),*contactNode);
#ifdef MESH_DEBUG_SERIAL
Serial.print( millis() ); Serial.println(F(" MSH: Request address "));
#elif defined MESH_DEBUG_PRINTF
Expand All @@ -291,7 +309,7 @@ bool RF24Mesh::requestAddress(uint8_t level){
uint8_t registerAddrCount = 0;

memcpy(&addrResponse,network.frame_buffer+sizeof(RF24NetworkHeader),sizeof(addrResponse));

if(!addrResponse.new_address || network.frame_buffer[7] != getNodeID() ){
#ifdef MESH_DEBUG_SERIAL
Serial.print(millis()); Serial.println(F(" MSH: Response discarded, wrong node"));
Expand Down Expand Up @@ -326,6 +344,7 @@ bool RF24Mesh::requestAddress(uint8_t level){
//printf("Retry register address...\n");
if(registerAddrCount++ >= 6 ){ return 0; }
}

return 1;
}

Expand Down Expand Up @@ -492,12 +511,13 @@ void RF24Mesh::DHCP(){
break;
}
}
if(!found){

header.type = NETWORK_ADDR_RESPONSE;
header.to_node = header.from_node;
//This is a routed request to 00
//printf("Send resp %d\n",sizeof(addrResponse));
//This is a routed request to 00
if(header.from_node != addrResponse.requester){ //Is NOT node 01 to 05
delay(2);
if( network.write(header,&addrResponse,sizeof(addrResponse)) ){
Expand All @@ -508,6 +528,7 @@ void RF24Mesh::DHCP(){
}else{
delay(2);
network.write(header,&addrResponse,sizeof(addrResponse),header.to_node);

//addrMap[from_id] = addrResponse.new_address;
}
uint32_t timer=millis();
Expand Down
7 changes: 4 additions & 3 deletions RF24Mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#if defined (__linux) && !defined(__ARDUINO_X86__)
#include <RF24/RF24.h>
#include <RF24Network/RF24Network.h>
#define RF24_LINUX
#else
#include <RF24.h>
#include <RF24Network.h>
Expand Down Expand Up @@ -87,7 +88,7 @@ class RF24Mesh
* This may take a few moments to complete.
* The radio channel and data-rate can be specified optionally as well
*/
void begin(uint8_t channel = MESH_DEFAULT_CHANNEL, rf24_datarate_e data_rate = RF24_1MBPS );
bool begin(uint8_t channel = MESH_DEFAULT_CHANNEL, rf24_datarate_e data_rate = RF24_1MBPS );

/**
* Very similar to network.update(), it needs to be called regularly to keep the network
Expand Down Expand Up @@ -149,7 +150,7 @@ class RF24Mesh
* @note Currently blocks until a connection is established and an address is received.
* @return Returns the newly assigned RF24Network address
*/
uint16_t renewAddress();
uint16_t renewAddress(uint32_t timeout=3000);

/**
* Releases the currently assigned address lease. Useful for nodes that will be sleeping etc.
Expand Down Expand Up @@ -230,7 +231,7 @@ class RF24Mesh
uint32_t lastSaveTime;
uint32_t lastFileSave;
uint8_t radio_channel;

public:


Expand Down

0 comments on commit 1a9b0c9

Please sign in to comment.