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() {
debug(PSTR("req node id\n"));
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);
}
@@ -160,49 +161,82 @@ void MySensor::findParentNode() {
}
boolean MySensor::sendRoute(MyMessage &message) {
// Make sure to process any incoming messages before sending (could this end up in recursive loop?)
// process();
bool isInternal = mGetCommand(message) == C_INTERNAL;
uint8_t sender = message.sender;
uint8_t dest = message.destination;
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 (nc.nodeId == AUTO && !(isInternal && message.type == I_ID_REQUEST)) {
if (nc.nodeId == AUTO) {
requestNodeId();
return false;
}
if (repeaterMode) {
uint8_t dest = message.destination;
if (dest == GATEWAY_ADDRESS || !repeaterMode) {
// 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);
if (route>GATEWAY_ADDRESS && route<BROADCAST_ADDRESS && dest != GATEWAY_ADDRESS) {
// --- debug(PSTR("route %d.\n"), route);
if (route > GATEWAY_ADDRESS && route < BROADCAST_ADDRESS) {
// 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.
// Send it downstream
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
// by doing a broadcast sending,
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) {
// Should be routed back to gateway.
bool ok = sendWrite(nc.parentNodeId, message);
if (!ok) {
// Failure when sending to parent node. The parent node might be down and we
// need to find another route to gateway.
if (autoFindParent && failedTransmissions > SEARCH_FAILURES) {
findParentNode();
} else {
failedTransmissions++;
}
} else {
failedTransmissions = 0;
if (!ok) {
// Failure when sending to parent node. The parent node might be down and we
// need to find another route to gateway.
failedTransmissions++;
if (autoFindParent && failedTransmissions > SEARCH_FAILURES) {
findParentNode();
}
return ok;
} else {
failedTransmissions = 0;
}
return false;
return ok;
}
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;
} 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 (nc.distance == 255) {
if (nc.distance == DISTANCE_INVALID) {
findParentNode();
} else if (sender != nc.parentNodeId) {
// Relaying nodes should always answer ping messages
@@ -383,42 +417,7 @@ boolean MySensor::process() {
}
} else if (to == nc.nodeId) {
// We should try to relay this message to another node
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);
}
sendRoute(msg);
}
}
return false;
@@ -15,14 +15,15 @@
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
console when prompted to do any locking.
Default settings use ATSHA204 on pin 7.
console when prompted to do any locking. On boards that does not provide UART
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_lib_return_codes.h>
// The pin the ATSHA204 is connected on
#define ATSHA204_PIN 7
#define ATSHA204_PIN 17 // A3
// Uncomment this to enable locking the configuration zone.
// *** 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.
//#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
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};
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
};
#endif
const int sha204Pin = ATSHA204_PIN;
@@ -727,6 +741,7 @@ void setup()
#ifdef LOCK_CONFIGURATION
// Purge serial input buffer
#ifndef SKIP_UART_CONFIRMATION
while (Serial.available())
{
Serial.read();
@@ -735,6 +750,7 @@ void setup()
while (Serial.available() == 0);
if (Serial.read() == ' ')
#endif //not SKIP_UART_CONFIRMATION
{
Serial.println(F("Locking configuration..."));
@@ -773,10 +789,12 @@ void setup()
}
}
}
#ifndef SKIP_UART_CONFIRMATION
else
{
Serial.println(F("Unexpected answer. Skipping lock."));
}
#endif //not SKIP_UART_CONFIRMATION
#else //LOCK_CONFIGURATION
Serial.println(F("Dry-run. Configuration not locked. Define LOCK_CONFIGURATION to lock for real."));
#endif
@@ -793,7 +811,7 @@ void setup()
#else
#ifdef USER_KEY_DATA
memcpy(key, user_key_data, 32);
Serial.print(F("Using this user supplied key: "));
Serial.println(F("Using this user supplied key:"));
#else
// Retrieve random value to use as key
ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE);
@@ -817,11 +835,14 @@ void setup()
#endif
for (int i=0; i<32; i++)
{
Serial.print("0x");
if (key[i] < 0x10)
{
Serial.print('0'); // Because Serial.print does not 0-pad HEX
}
Serial.print(key[i], HEX);
if (i < 31) Serial.print(',');
if (!((i+1) % 8)) Serial.println();
}
Serial.println();
@@ -842,6 +863,7 @@ void setup()
if (lockValue != 0x00)
{
#ifdef LOCK_DATA
#ifndef SKIP_UART_CONFIRMATION
while (Serial.available())
{
Serial.read();
@@ -849,6 +871,7 @@ void setup()
Serial.println(F("Send SPACE character to lock data..."));
while (Serial.available() == 0);
if (Serial.read() == ' ')
#endif //not SKIP_UART_CONFIRMATION
{
// Correct sequence, resync chip
ret_code = sha204.sha204c_resync(SHA204_RSP_SIZE_MAX, rx_buffer);
@@ -907,10 +930,12 @@ void setup()
}
}
}
#ifndef SKIP_UART_CONFIRMATION
else
{
Serial.println(F("Unexpected answer. Skipping lock."));
}
#endif //not SKIP_UART_CONFIRMATION
#else //LOCK_DATA
Serial.println(F("Dry-run. Data not locked. Define LOCK_DATA to lock for real."));
#endif