From d8f055104c2799131503741204ad528c2a5a2282 Mon Sep 17 00:00:00 2001 From: Henrik Ekblad Date: Fri, 31 Jan 2014 00:29:38 +0100 Subject: [PATCH] Fixed bug in routing for messages sent out from gateway. --- libraries/MySensors/Gateway.cpp | 5 +++ libraries/MySensors/Gateway.h | 4 ++- libraries/MySensors/Relay.cpp | 61 ++++++++++++++++++++++++++++++--- libraries/MySensors/Relay.h | 4 ++- libraries/MySensors/Sensor.cpp | 34 ++++++++++++------ libraries/MySensors/Sensor.h | 4 +-- 6 files changed, 94 insertions(+), 18 deletions(-) diff --git a/libraries/MySensors/Gateway.cpp b/libraries/MySensors/Gateway.cpp index 75bf5b9..01e9185 100644 --- a/libraries/MySensors/Gateway.cpp +++ b/libraries/MySensors/Gateway.cpp @@ -85,6 +85,11 @@ void Gateway::checkButtonTriggeredInclusion() { serial(PSTR("0;0;%d;%d;Inclusion started by button.\n"), M_INTERNAL, I_LOG_MESSAGE); buttonTriggeredInclusion = false; setInclusionMode(true); + +#ifdef DEBUG + sendChildren(); +#endif + } } diff --git a/libraries/MySensors/Gateway.h b/libraries/MySensors/Gateway.h index a195524..88bd3df 100644 --- a/libraries/MySensors/Gateway.h +++ b/libraries/MySensors/Gateway.h @@ -48,6 +48,8 @@ class Gateway : public Relay void ledTimersInterrupt(); void startInclusionInterrupt(); + + private: char commandBuffer[MAX_RECEIVE_LENGTH]; char serialBuffer[MAX_SEND_LENGTH]; // Buffer for building string when sending data to vera @@ -64,12 +66,12 @@ class Gateway : public Relay uint8_t pinTx; uint8_t pinEr; + void serial(const char *fmt, ... ); uint8_t validate(); void serial(message_s msg); void interruptStartInclusion(); void checkButtonTriggeredInclusion(); void setInclusionMode(boolean newMode); - void serial(const char *fmt, ... ); void checkInclusionFinished(); void ledTimers(); void rxBlink(uint8_t cnt); diff --git a/libraries/MySensors/Relay.cpp b/libraries/MySensors/Relay.cpp index c4144ea..98c0aca 100644 --- a/libraries/MySensors/Relay.cpp +++ b/libraries/MySensors/Relay.cpp @@ -29,20 +29,56 @@ void Relay::begin(uint8_t _radioId) { } +boolean Relay::sendData(uint8_t from, uint8_t to, uint8_t childId, uint8_t messageType, uint8_t type, const char *data, uint8_t length, boolean binary) { + bool ok = false; + if (length < sizeof(msg.data)) { + uint8_t route = getChildRoute(to); + if (route>0) { + debug(PSTR("Found child in routing table. Sending to %d\n"),route); + buildMsg(from, to, childId, messageType, type, data, length, binary); + // Found node in route table + ok = sendWrite(route, msg, length); + } if (radioId == GATEWAY_ADDRESS) { + // If we're GW (no parent...). As a last resort try sending message directly to node. + debug(PSTR("Target not found in routing table. \n")); + buildMsg(from, to, childId, messageType, type, data, length, binary); + // Found node in route table + ok = sendWrite(to, msg, length); + + } else { + debug(PSTR("Route message back to relay\n")); + // We are probably a repeater node which should send message back to relay + ok = Sensor::sendData(from, to, childId, messageType, type, data, length, binary); + } + } else { + debug(PSTR("Message too large\n")); + } + return ok; +} + + + boolean Relay::send(message_s message, int length) { bool ok = true; uint8_t route = getChildRoute(msg.header.to); if (route>0 && route<255 && message.header.to != GATEWAY_ADDRESS) { - debug(PSTR("Routing message.\n")); + debug(PSTR("Routing message to %d.\n"), route); // Message destination is not gateway and is in routing table for this node. // Send it downstream - sendWrite(route, message, length); + ok = sendWrite(route, message, length); + + } else if (radioId != GATEWAY_ADDRESS) { debug(PSTR("Sending message back towards gw.\n")); // Should be routed back to gateway. Sensor code knows how to do this. ok = Sensor::send(message, length); } + + if (!ok) { + debug(PSTR("No ack received.\n")); + } + return ok; } @@ -50,6 +86,11 @@ boolean Relay::send(message_s message, int length) { boolean Relay::messageAvailable() { uint8_t pipe; boolean available = RF24::available(&pipe); + + if (available) { + debug(PSTR("Message available on pipe %d\n"),pipe); + } + if (available) { uint8_t len = RF24::getDynamicPayloadSize()-sizeof(msg.header); readMessage(); @@ -91,6 +132,9 @@ boolean Relay::messageAvailable() { return false; } // Return rest of internal messages back to sketch... + if (msg.header.last != GATEWAY_ADDRESS) + addChildRoute(msg.header.from, msg.header.last); + return true; } else { // If this is variable message from sensor net gateway. Send ack back. @@ -101,6 +145,9 @@ boolean Relay::messageAvailable() { sendVariableAck(); } // Return message to waiting sketch... + if (msg.header.last != GATEWAY_ADDRESS) + addChildRoute(msg.header.from, msg.header.last); + return true; } } else { @@ -204,9 +251,15 @@ void Relay::clearChildRoutes() { void Relay::sendChildren() { // Send in which children that is using this node as an relay. - debug(PSTR("Send child info to sensor gateway.\n")); - sendInternal(I_CHILDREN, "not implemented"); // TODO: Fix this + debug(PSTR("Send child info to sensor gateway.\n")); + + for (int i=0;i< 10; i++) { +// Serial.println(childNodeTable[i]); + debug(PSTR("rt:%d, %d\n"), i, getChildRoute(i) ); + } + + //sendInternal(I_CHILDREN, "not implemented"); } diff --git a/libraries/MySensors/Relay.h b/libraries/MySensors/Relay.h index 2a38cb8..4d5e6c9 100644 --- a/libraries/MySensors/Relay.h +++ b/libraries/MySensors/Relay.h @@ -43,7 +43,10 @@ class Relay : public Sensor boolean messageAvailable(); boolean send(message_s message, int length); + boolean sendData(uint8_t from, uint8_t to, uint8_t childId, uint8_t messageType, uint8_t type, const char *data, uint8_t length, boolean binary); + protected: + void sendChildren(); private: uint8_t childNodeTable[256]; // Buffer to store child node information. Store this in EEPROM @@ -52,7 +55,6 @@ class Relay : public Sensor void addChildRoute(uint8_t childId, uint8_t route); void removeChildRoute(uint8_t childId); void clearChildRoutes(); - void sendChildren(); void relayMessage(uint8_t length, uint8_t pipe); }; diff --git a/libraries/MySensors/Sensor.cpp b/libraries/MySensors/Sensor.cpp index 4c93977..321445d 100644 --- a/libraries/MySensors/Sensor.cpp +++ b/libraries/MySensors/Sensor.cpp @@ -113,6 +113,7 @@ void Sensor::findRelay() { // Open a reading pipe for current radioId (if it differs from broadcast) if (radioId != BROADCAST_PIPE) { RF24::openReadingPipe(CURRENT_NODE_PIPE, BASE_RADIO_ID+radioId); + debug(PSTR("Open ping reading pipe: %d\n"), radioId); } distance = 255; uint8_t oldRelayId = relayId; @@ -123,6 +124,7 @@ void Sensor::findRelay() { // Wait for replies for max 10 seconds (or when buffer for all relay nodes have been filled up) unsigned long enter = millis(); uint8_t neighborDistanceToGW; + // Wait for ack responses 5 seconds while (millis() - enter < 5000) { if (messageAvailable()) { @@ -218,18 +220,19 @@ boolean Sensor::sendWrite(uint8_t dest, message_s message, int length) { // Add current radioId to last-field and calculate crc message.header.last = radioId; message.header.crc = crc8Message(message); - debug(PSTR("Sending: from=%d, to=%d, childId=%d, mtype=%d, type=%d, crc=%d, '%s', sent via %d\n"), - message.header.from,message.header.to, message.header.childId, message.header.messageType, message.header.type, message.header.crc, message.data, dest); + debug(PSTR("Tx: f=%d,t=%d,p=%d,n=%d,c=%d,mt=%d,t=%d,x=%d: %s\n"), + message.header.from,message.header.to, message.header.last, dest, message.header.childId, message.header.messageType, message.header.type, message.header.crc, message.data); RF24::stopListening(); bool ok = false; - RF24::openWritingPipe(BASE_RADIO_ID + dest); + RF24::openWritingPipe(BASE_RADIO_ID+ dest); int retry = 5; do { ok = RF24::write(&message, min(MAX_MESSAGE_LENGTH, sizeof(message.header) + length)); } while ( !ok && --retry ); RF24::startListening(); +// RF24::openReadingPipe(CURRENT_NODE_PIPE, BASE_RADIO_ID+radioId); if (ok) { debug(PSTR("Sent successfully\n")); @@ -369,7 +372,15 @@ void Sensor::requestIsMetricSystem() { boolean Sensor::messageAvailable() { - if (RF24::available()) { + uint8_t pipe; + boolean available = RF24::available(&pipe); + + if (available) { + debug(PSTR("Message available on pipe %d\n"),pipe); + } + + + if (available) { readMessage(); boolean ok = validate() == VALIDATE_OK; debug(PSTR("Mess crc %s.\n"),ok?"ok":"error"); @@ -408,8 +419,8 @@ message_s Sensor::readMessage() { bool done = RF24::read(&msg, len); // Make sure string gets terminated ok. msg.data[len - sizeof(header_s) ] = '\0'; - debug(PSTR("Received: from=%d, to=%d, childId=%d, mtype=%d, type=%d, crc=%d, '%s'\n"), - msg.header.from,msg.header.to, msg.header.childId, msg.header.messageType, msg.header.type,msg.header.crc, msg.data); + debug(PSTR("Rx: f=%d,t=%d,l=%d,c=%d,mt=%d,t=%d,x=%d: %s\n"), + msg.header.from,msg.header.to, msg.header.last, msg.header.childId, msg.header.messageType, msg.header.type,msg.header.crc, msg.data); return msg; } @@ -518,15 +529,18 @@ void Sensor::debugPrint(const char *fmt, ... ) { vsnprintf_P(fmtBuffer, 300, fmt, args); va_end (args); if (radioId == GATEWAY_ADDRESS) { - // Truncte message if this is gateway node - vsnprintf_P(fmtBuffer, 97, fmt, args); - fmtBuffer[96] = '\n'; - fmtBuffer[97] = '\0'; + // Truncate message if this is gateway node + vsnprintf_P(fmtBuffer, 60, fmt, args); + fmtBuffer[59] = '\n'; + fmtBuffer[60] = '\0'; } else { vsnprintf_P(fmtBuffer, 299, fmt, args); } va_end (args); Serial.print(fmtBuffer); + + + //Serial.print("0;0;4;11;Mem free:"); //Serial.println(freeRam()); } #endif diff --git a/libraries/MySensors/Sensor.h b/libraries/MySensors/Sensor.h index bf2b1fd..13e23a1 100644 --- a/libraries/MySensors/Sensor.h +++ b/libraries/MySensors/Sensor.h @@ -22,7 +22,7 @@ #include #include -#define DEBUG // Turn on/off debug mode by having/removing this define +#define DEBUG #ifdef DEBUG #define debug(x,...) debugPrint(x, ##__VA_ARGS__) @@ -42,7 +42,7 @@ // This is the radioId for sensor net gateway receiver sketch (where all sensors should send their data). // This is also act as base value for sensor radioId -#define BASE_RADIO_ID 0xABCDABC000LL +#define BASE_RADIO_ID ((uint64_t)0xABCDABC000LL) #define GATEWAY_ADDRESS ((uint8_t)0) #define BROADCAST_ADDRESS ((uint8_t)0xFF)