Fixed bug in routing for messages sent out from gateway.

This commit is contained in:
Henrik Ekblad
2014-01-31 00:29:38 +01:00
parent 609d9e5be9
commit d8f055104c
6 changed files with 94 additions and 18 deletions
+5
View File
@@ -85,6 +85,11 @@ void Gateway::checkButtonTriggeredInclusion() {
serial(PSTR("0;0;%d;%d;Inclusion started by button.\n"), M_INTERNAL, I_LOG_MESSAGE); serial(PSTR("0;0;%d;%d;Inclusion started by button.\n"), M_INTERNAL, I_LOG_MESSAGE);
buttonTriggeredInclusion = false; buttonTriggeredInclusion = false;
setInclusionMode(true); setInclusionMode(true);
#ifdef DEBUG
sendChildren();
#endif
} }
} }
+3 -1
View File
@@ -48,6 +48,8 @@ class Gateway : public Relay
void ledTimersInterrupt(); void ledTimersInterrupt();
void startInclusionInterrupt(); void startInclusionInterrupt();
private: private:
char commandBuffer[MAX_RECEIVE_LENGTH]; char commandBuffer[MAX_RECEIVE_LENGTH];
char serialBuffer[MAX_SEND_LENGTH]; // Buffer for building string when sending data to vera 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 pinTx;
uint8_t pinEr; uint8_t pinEr;
void serial(const char *fmt, ... );
uint8_t validate(); uint8_t validate();
void serial(message_s msg); void serial(message_s msg);
void interruptStartInclusion(); void interruptStartInclusion();
void checkButtonTriggeredInclusion(); void checkButtonTriggeredInclusion();
void setInclusionMode(boolean newMode); void setInclusionMode(boolean newMode);
void serial(const char *fmt, ... );
void checkInclusionFinished(); void checkInclusionFinished();
void ledTimers(); void ledTimers();
void rxBlink(uint8_t cnt); void rxBlink(uint8_t cnt);
+57 -4
View File
@@ -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) { boolean Relay::send(message_s message, int length) {
bool ok = true; bool ok = true;
uint8_t route = getChildRoute(msg.header.to); uint8_t route = getChildRoute(msg.header.to);
if (route>0 && route<255 && message.header.to != GATEWAY_ADDRESS) { 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. // Message destination is not gateway and is in routing table for this node.
// Send it downstream // Send it downstream
sendWrite(route, message, length); ok = sendWrite(route, message, length);
} else if (radioId != GATEWAY_ADDRESS) { } else if (radioId != GATEWAY_ADDRESS) {
debug(PSTR("Sending message back towards gw.\n")); debug(PSTR("Sending message back towards gw.\n"));
// Should be routed back to gateway. Sensor code knows how to do this. // Should be routed back to gateway. Sensor code knows how to do this.
ok = Sensor::send(message, length); 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() { boolean Relay::messageAvailable() {
uint8_t pipe; uint8_t pipe;
boolean available = RF24::available(&pipe); boolean available = RF24::available(&pipe);
if (available) {
debug(PSTR("Message available on pipe %d\n"),pipe);
}
if (available) { if (available) {
uint8_t len = RF24::getDynamicPayloadSize()-sizeof(msg.header); uint8_t len = RF24::getDynamicPayloadSize()-sizeof(msg.header);
readMessage(); readMessage();
@@ -91,6 +132,9 @@ boolean Relay::messageAvailable() {
return false; return false;
} }
// Return rest of internal messages back to sketch... // Return rest of internal messages back to sketch...
if (msg.header.last != GATEWAY_ADDRESS)
addChildRoute(msg.header.from, msg.header.last);
return true; return true;
} else { } else {
// If this is variable message from sensor net gateway. Send ack back. // If this is variable message from sensor net gateway. Send ack back.
@@ -101,6 +145,9 @@ boolean Relay::messageAvailable() {
sendVariableAck(); sendVariableAck();
} }
// Return message to waiting sketch... // Return message to waiting sketch...
if (msg.header.last != GATEWAY_ADDRESS)
addChildRoute(msg.header.from, msg.header.last);
return true; return true;
} }
} else { } else {
@@ -204,9 +251,15 @@ void Relay::clearChildRoutes() {
void Relay::sendChildren() { void Relay::sendChildren() {
// Send in which children that is using this node as an relay. // 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 // 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");
} }
+3 -1
View File
@@ -43,7 +43,10 @@ class Relay : public Sensor
boolean messageAvailable(); boolean messageAvailable();
boolean send(message_s message, int length); 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: protected:
void sendChildren();
private: private:
uint8_t childNodeTable[256]; // Buffer to store child node information. Store this in EEPROM 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 addChildRoute(uint8_t childId, uint8_t route);
void removeChildRoute(uint8_t childId); void removeChildRoute(uint8_t childId);
void clearChildRoutes(); void clearChildRoutes();
void sendChildren();
void relayMessage(uint8_t length, uint8_t pipe); void relayMessage(uint8_t length, uint8_t pipe);
}; };
+23 -9
View File
@@ -113,6 +113,7 @@ void Sensor::findRelay() {
// Open a reading pipe for current radioId (if it differs from broadcast) // Open a reading pipe for current radioId (if it differs from broadcast)
if (radioId != BROADCAST_PIPE) { if (radioId != BROADCAST_PIPE) {
RF24::openReadingPipe(CURRENT_NODE_PIPE, BASE_RADIO_ID+radioId); RF24::openReadingPipe(CURRENT_NODE_PIPE, BASE_RADIO_ID+radioId);
debug(PSTR("Open ping reading pipe: %d\n"), radioId);
} }
distance = 255; distance = 255;
uint8_t oldRelayId = relayId; 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) // Wait for replies for max 10 seconds (or when buffer for all relay nodes have been filled up)
unsigned long enter = millis(); unsigned long enter = millis();
uint8_t neighborDistanceToGW; uint8_t neighborDistanceToGW;
// Wait for ack responses 5 seconds // Wait for ack responses 5 seconds
while (millis() - enter < 5000) { while (millis() - enter < 5000) {
if (messageAvailable()) { if (messageAvailable()) {
@@ -218,8 +220,8 @@ boolean Sensor::sendWrite(uint8_t dest, message_s message, int length) {
// Add current radioId to last-field and calculate crc // Add current radioId to last-field and calculate crc
message.header.last = radioId; message.header.last = radioId;
message.header.crc = crc8Message(message); 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"), 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.childId, message.header.messageType, message.header.type, message.header.crc, message.data, dest); 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(); RF24::stopListening();
bool ok = false; bool ok = false;
@@ -230,6 +232,7 @@ boolean Sensor::sendWrite(uint8_t dest, message_s message, int length) {
} }
while ( !ok && --retry ); while ( !ok && --retry );
RF24::startListening(); RF24::startListening();
// RF24::openReadingPipe(CURRENT_NODE_PIPE, BASE_RADIO_ID+radioId);
if (ok) { if (ok) {
debug(PSTR("Sent successfully\n")); debug(PSTR("Sent successfully\n"));
@@ -369,7 +372,15 @@ void Sensor::requestIsMetricSystem() {
boolean Sensor::messageAvailable() { 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(); readMessage();
boolean ok = validate() == VALIDATE_OK; boolean ok = validate() == VALIDATE_OK;
debug(PSTR("Mess crc %s.\n"),ok?"ok":"error"); debug(PSTR("Mess crc %s.\n"),ok?"ok":"error");
@@ -408,8 +419,8 @@ message_s Sensor::readMessage() {
bool done = RF24::read(&msg, len); bool done = RF24::read(&msg, len);
// Make sure string gets terminated ok. // Make sure string gets terminated ok.
msg.data[len - sizeof(header_s) ] = '\0'; msg.data[len - sizeof(header_s) ] = '\0';
debug(PSTR("Received: from=%d, to=%d, childId=%d, mtype=%d, type=%d, crc=%d, '%s'\n"), 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.childId, msg.header.messageType, msg.header.type,msg.header.crc, msg.data); 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; return msg;
} }
@@ -518,15 +529,18 @@ void Sensor::debugPrint(const char *fmt, ... ) {
vsnprintf_P(fmtBuffer, 300, fmt, args); vsnprintf_P(fmtBuffer, 300, fmt, args);
va_end (args); va_end (args);
if (radioId == GATEWAY_ADDRESS) { if (radioId == GATEWAY_ADDRESS) {
// Truncte message if this is gateway node // Truncate message if this is gateway node
vsnprintf_P(fmtBuffer, 97, fmt, args); vsnprintf_P(fmtBuffer, 60, fmt, args);
fmtBuffer[96] = '\n'; fmtBuffer[59] = '\n';
fmtBuffer[97] = '\0'; fmtBuffer[60] = '\0';
} else { } else {
vsnprintf_P(fmtBuffer, 299, fmt, args); vsnprintf_P(fmtBuffer, 299, fmt, args);
} }
va_end (args); va_end (args);
Serial.print(fmtBuffer); Serial.print(fmtBuffer);
//Serial.print("0;0;4;11;Mem free:");
//Serial.println(freeRam()); //Serial.println(freeRam());
} }
#endif #endif
+2 -2
View File
@@ -22,7 +22,7 @@
#include <avr/progmem.h> #include <avr/progmem.h>
#include <stdarg.h> #include <stdarg.h>
#define DEBUG // Turn on/off debug mode by having/removing this define #define DEBUG
#ifdef DEBUG #ifdef DEBUG
#define debug(x,...) debugPrint(x, ##__VA_ARGS__) #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 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 // 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 GATEWAY_ADDRESS ((uint8_t)0)
#define BROADCAST_ADDRESS ((uint8_t)0xFF) #define BROADCAST_ADDRESS ((uint8_t)0xFF)