Merge branch 'development' of https://github.com/mysensors/Arduino.git into development

This commit is contained in:
Henrik Ekblad
2015-02-17 14:32:08 +01:00
2 changed files with 96 additions and 72 deletions
+63 -64
View File
@@ -125,7 +125,8 @@ ControllerConfig MySensor::getConfig() {
void MySensor::requestNodeId() { void MySensor::requestNodeId() {
debug(PSTR("req node id\n")); debug(PSTR("req node id\n"));
radio->setAddress(nc.nodeId); radio->setAddress(nc.nodeId);
sendRoute(build(msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_ID_REQUEST, false).set("")); build(msg, nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_ID_REQUEST, false).set("");
sendWrite(nc.parentNodeId, msg);
wait(2000); wait(2000);
} }
@@ -160,49 +161,82 @@ void MySensor::findParentNode() {
} }
boolean MySensor::sendRoute(MyMessage &message) { boolean MySensor::sendRoute(MyMessage &message) {
// Make sure to process any incoming messages before sending (could this end up in recursive loop?) uint8_t sender = message.sender;
// process(); uint8_t dest = message.destination;
bool isInternal = mGetCommand(message) == C_INTERNAL; uint8_t last = message.last;
bool ok;
// If we still don't have any parent id, re-request and skip this message.
if (nc.parentNodeId == AUTO) {
findParentNode();
return false;
}
// If we still don't have any node id, re-request and skip this message. // If we still don't have any node id, re-request and skip this message.
if (nc.nodeId == AUTO && !(isInternal && message.type == I_ID_REQUEST)) { if (nc.nodeId == AUTO) {
requestNodeId(); requestNodeId();
return false; return false;
} }
if (repeaterMode) { if (dest == GATEWAY_ADDRESS || !repeaterMode) {
uint8_t dest = message.destination; // If destination is the gateway or if we aren't a repeater, let
// our parent take care of the message
ok = sendWrite(nc.parentNodeId, message);
} else {
// Relay the message
uint8_t route = getChildRoute(dest); uint8_t route = getChildRoute(dest);
if (route>GATEWAY_ADDRESS && route<BROADCAST_ADDRESS && dest != GATEWAY_ADDRESS) { if (route > GATEWAY_ADDRESS && route < BROADCAST_ADDRESS) {
// --- debug(PSTR("route %d.\n"), route); // This message should be forwarded to a child node. If we send message
// to this nodes pipe then all children will receive it because the are
// all listening to this nodes pipe.
//
// +----B
// -A
// +----C------D
//
// We're node C, Message comes from A and has destination D
//
// 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
return sendWrite(route, message); return sendWrite(route, message);
} else if (isInternal && message.type == I_ID_RESPONSE && dest==BROADCAST_ADDRESS) { } else if (sender == GATEWAY_ADDRESS && dest == BROADCAST_ADDRESS) {
// Node has not yet received any id. We need to send it // Node has not yet received any id. We need to send it
// by doing a broadcast sending, // by doing a broadcast sending,
return sendWrite(BROADCAST_ADDRESS, message); return sendWrite(BROADCAST_ADDRESS, message);
} else if (isGateway) {
// Destination isn't in our routing table and isn't a broadcast address
// Nothing to do here
return false;
} else {
// A message comes from a child node and we have no
// route for it.
//
// +----B
// -A
// +----C------D <-- Message comes from D
//
// We're node C
//
// Message should be passed to node A (this nodes relay)
// This message should be routed back towards sensor net gateway
ok = sendWrite(nc.parentNodeId, message);
// Add this child to our "routing table" if it not already exist
addChildRoute(sender, last);
} }
} }
if (!isGateway) { if (!ok) {
// Should be routed back to gateway. // Failure when sending to parent node. The parent node might be down and we
bool ok = sendWrite(nc.parentNodeId, message); // need to find another route to gateway.
failedTransmissions++;
if (!ok) { if (autoFindParent && failedTransmissions > SEARCH_FAILURES) {
// Failure when sending to parent node. The parent node might be down and we findParentNode();
// need to find another route to gateway.
if (autoFindParent && failedTransmissions > SEARCH_FAILURES) {
findParentNode();
} else {
failedTransmissions++;
}
} else {
failedTransmissions = 0;
} }
return ok; } else {
failedTransmissions = 0;
} }
return false; return ok;
} }
boolean MySensor::sendWrite(uint8_t to, MyMessage &message) { boolean MySensor::sendWrite(uint8_t to, MyMessage &message) {
@@ -369,10 +403,10 @@ boolean MySensor::process() {
// Return true if message was addressed for this node... // Return true if message was addressed for this node...
return true; return true;
} else if (repeaterMode && nc.nodeId != AUTO) { } else if (repeaterMode && nc.nodeId != AUTO) {
// Relaying nodes should answer only after set an id // If this node have an id, relay the message
if (command == C_INTERNAL && type == I_FIND_PARENT) { if (command == C_INTERNAL && type == I_FIND_PARENT) {
if (nc.distance == 255) { if (nc.distance == DISTANCE_INVALID) {
findParentNode(); findParentNode();
} else if (sender != nc.parentNodeId) { } else if (sender != nc.parentNodeId) {
// Relaying nodes should always answer ping messages // Relaying nodes should always answer ping messages
@@ -383,42 +417,7 @@ boolean MySensor::process() {
} }
} else if (to == nc.nodeId) { } else if (to == nc.nodeId) {
// We should try to relay this message to another node // We should try to relay this message to another node
sendRoute(msg);
uint8_t route = getChildRoute(msg.destination);
if (route>0 && route<255) {
// This message should be forwarded to a child node. If we send message
// to this nodes pipe then all children will receive it because the are
// all listening to this nodes pipe.
//
// +----B
// -A
// +----C------D
//
// We're node C, Message comes from A and has destination D
//
// lookup route in table and send message there
sendWrite(route, msg);
} else if (sender == GATEWAY_ADDRESS && destination == BROADCAST_ADDRESS) {
// A net gateway reply to a message previously sent by us from a 255 node
// We should broadcast this back to the node
sendWrite(BROADCAST_ADDRESS, msg);
} else {
// A message comes from a child node and we have no
// route for it.
//
// +----B
// -A
// +----C------D <-- Message comes from D
//
// We're node C
//
// Message should be passed to node A (this nodes relay)
// This message should be routed back towards sensor net gateway
sendWrite(nc.parentNodeId, msg);
// Add this child to our "routing table" if it not already exist
addChildRoute(sender, last);
}
} }
} }
return false; return false;
@@ -15,14 +15,15 @@
By default, no locking is performed. User have to manually enable the flags that By default, no locking is performed. User have to manually enable the flags that
turn on the locking. Furthermore, user have to send a SPACE character on serial turn on the locking. Furthermore, user have to send a SPACE character on serial
console when prompted to do any locking. console when prompted to do any locking. On boards that does not provide UART
Default settings use ATSHA204 on pin 7. input it is possible to configure the sketch to skip this confirmation.
Default settings use ATSHA204 on pin 17 (A3).
*/ */
#include <sha204_library.h> #include <sha204_library.h>
#include <sha204_lib_return_codes.h> #include <sha204_lib_return_codes.h>
// The pin the ATSHA204 is connected on // The pin the ATSHA204 is connected on
#define ATSHA204_PIN 7 #define ATSHA204_PIN 17 // A3
// Uncomment this to enable locking the configuration zone. // Uncomment this to enable locking the configuration zone.
// *** BE AWARE THAT THIS PREVENTS ANY FUTURE CONFIGURATION CHANGE TO THE CHIP *** // *** BE AWARE THAT THIS PREVENTS ANY FUTURE CONFIGURATION CHANGE TO THE CHIP ***
@@ -44,11 +45,24 @@
// Uncomment this to skip key generation and use 'user_key_data' as key instead. // Uncomment this to skip key generation and use 'user_key_data' as key instead.
//#define USER_KEY_DATA //#define USER_KEY_DATA
// Uncomment this for boards that lack UART
// IMPORTANT: No confirmation will be required for locking any zones with this
// configuration!
// Also, key generation is not permitted in this mode as there is no way of
// presenting the generated key.
//#define SKIP_UART_CONFIRMATION
#if defined(SKIP_UART_CONFIRMATION) && !defined(USER_KEY_DATA)
#error You have to define USER_KEY_DATA for boards that does not have UART
#endif
#ifdef USER_KEY_DATA #ifdef USER_KEY_DATA
const uint8_t user_key_data[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, const uint8_t user_key_data[32] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
#endif #endif
const int sha204Pin = ATSHA204_PIN; const int sha204Pin = ATSHA204_PIN;
@@ -727,6 +741,7 @@ void setup()
#ifdef LOCK_CONFIGURATION #ifdef LOCK_CONFIGURATION
// Purge serial input buffer // Purge serial input buffer
#ifndef SKIP_UART_CONFIRMATION
while (Serial.available()) while (Serial.available())
{ {
Serial.read(); Serial.read();
@@ -735,6 +750,7 @@ void setup()
while (Serial.available() == 0); while (Serial.available() == 0);
if (Serial.read() == ' ') if (Serial.read() == ' ')
#endif //not SKIP_UART_CONFIRMATION
{ {
Serial.println(F("Locking configuration...")); Serial.println(F("Locking configuration..."));
@@ -773,10 +789,12 @@ void setup()
} }
} }
} }
#ifndef SKIP_UART_CONFIRMATION
else else
{ {
Serial.println(F("Unexpected answer. Skipping lock.")); Serial.println(F("Unexpected answer. Skipping lock."));
} }
#endif //not SKIP_UART_CONFIRMATION
#else //LOCK_CONFIGURATION #else //LOCK_CONFIGURATION
Serial.println(F("Dry-run. Configuration not locked. Define LOCK_CONFIGURATION to lock for real.")); Serial.println(F("Dry-run. Configuration not locked. Define LOCK_CONFIGURATION to lock for real."));
#endif #endif
@@ -793,7 +811,7 @@ void setup()
#else #else
#ifdef USER_KEY_DATA #ifdef USER_KEY_DATA
memcpy(key, user_key_data, 32); memcpy(key, user_key_data, 32);
Serial.print(F("Using this user supplied key: ")); Serial.println(F("Using this user supplied key:"));
#else #else
// Retrieve random value to use as key // Retrieve random value to use as key
ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE); ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
@@ -817,11 +835,14 @@ void setup()
#endif #endif
for (int i=0; i<32; i++) for (int i=0; i<32; i++)
{ {
Serial.print("0x");
if (key[i] < 0x10) if (key[i] < 0x10)
{ {
Serial.print('0'); // Because Serial.print does not 0-pad HEX Serial.print('0'); // Because Serial.print does not 0-pad HEX
} }
Serial.print(key[i], HEX); Serial.print(key[i], HEX);
if (i < 31) Serial.print(',');
if (!((i+1) % 8)) Serial.println();
} }
Serial.println(); Serial.println();
@@ -842,6 +863,7 @@ void setup()
if (lockValue != 0x00) if (lockValue != 0x00)
{ {
#ifdef LOCK_DATA #ifdef LOCK_DATA
#ifndef SKIP_UART_CONFIRMATION
while (Serial.available()) while (Serial.available())
{ {
Serial.read(); Serial.read();
@@ -849,6 +871,7 @@ void setup()
Serial.println(F("Send SPACE character to lock data...")); Serial.println(F("Send SPACE character to lock data..."));
while (Serial.available() == 0); while (Serial.available() == 0);
if (Serial.read() == ' ') if (Serial.read() == ' ')
#endif //not SKIP_UART_CONFIRMATION
{ {
// Correct sequence, resync chip // Correct sequence, resync chip
ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer); ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
@@ -907,10 +930,12 @@ void setup()
} }
} }
} }
#ifndef SKIP_UART_CONFIRMATION
else else
{ {
Serial.println(F("Unexpected answer. Skipping lock.")); Serial.println(F("Unexpected answer. Skipping lock."));
} }
#endif //not SKIP_UART_CONFIRMATION
#else //LOCK_DATA #else //LOCK_DATA
Serial.println(F("Dry-run. Data not locked. Define LOCK_DATA to lock for real.")); Serial.println(F("Dry-run. Data not locked. Define LOCK_DATA to lock for real."));
#endif #endif