From fcb92436d9abd3a86c9b74d6732a3c26c620e856 Mon Sep 17 00:00:00 2001 From: Marcelo Aquino Date: Thu, 9 Jul 2015 14:19:57 -0300 Subject: [PATCH 1/2] fix repeater loop for I_FIND_PARENT A repeater calls findParentNode() inside process() when receives a I_FIND_PARENT and nc.distance is invalid, this could cause a loop --- libraries/MySensors/MySensor.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libraries/MySensors/MySensor.cpp b/libraries/MySensors/MySensor.cpp index 2e2d70e..099a927 100644 --- a/libraries/MySensors/MySensor.cpp +++ b/libraries/MySensors/MySensor.cpp @@ -302,6 +302,12 @@ void MySensor::setupNode() { } void MySensor::findParentNode() { + static boolean findingParentNode = false; + + if (findingParentNode) + return; + findingParentNode = true; + failedTransmissions = 0; // Set distance to max @@ -316,6 +322,7 @@ void MySensor::findParentNode() { // Wait for ping response. wait(2000); + findingParentNode = false; } boolean MySensor::sendRoute(MyMessage &message) { From a22f712d60fd2cb404c5ab509dcb7405ec7332b1 Mon Sep 17 00:00:00 2001 From: Marcelo Aquino Date: Tue, 28 Jul 2015 11:32:52 -0300 Subject: [PATCH 2/2] respond to a I_FIND_PARENT after findParentNode() When a repeater receives a I_FIND_PARENT, it first update the nc.distance if is invalid and then respond the request --- libraries/MySensors/MySensor.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/libraries/MySensors/MySensor.cpp b/libraries/MySensors/MySensor.cpp index 099a927..19b03c4 100644 --- a/libraries/MySensors/MySensor.cpp +++ b/libraries/MySensors/MySensor.cpp @@ -781,14 +781,17 @@ boolean MySensor::process() { // If this node have an id, relay the message if (command == C_INTERNAL && type == I_FIND_PARENT) { - if (nc.distance == DISTANCE_INVALID) { - findParentNode(); - } else if (sender != nc.parentNodeId) { - // Relaying nodes should always answer ping messages - // Wait a random delay of 0-2 seconds to minimize collision - // between ping ack messages from other relaying nodes - wait(hw_millis() & 0x3ff); - sendWrite(sender, build(msg, nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_RESPONSE, false).set(nc.distance)); + if (sender != nc.parentNodeId) { + if (nc.distance == DISTANCE_INVALID) + findParentNode(); + + if (nc.distance != DISTANCE_INVALID) { + // Relaying nodes should always answer ping messages + // Wait a random delay of 0-2 seconds to minimize collision + // between ping ack messages from other relaying nodes + wait(hw_millis() & 0x3ff); + sendWrite(sender, build(msg, nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_RESPONSE, false).set(nc.distance)); + } } } else if (to == nc.nodeId) { // We should try to relay this message to another node