From f3c60a068f06a913b8953c4d70210641d642788b Mon Sep 17 00:00:00 2001 From: Marcelo Aquino Date: Fri, 13 Feb 2015 02:01:18 -0200 Subject: [PATCH 1/2] process() uses sendRoute() for routing decisions To keep routing decisions in one place, and avoid rewriting the same code to add failedTransmissions count to process() --- libraries/MySensors/MySensor.cpp | 127 +++++++++++++++---------------- 1 file changed, 63 insertions(+), 64 deletions(-) diff --git a/libraries/MySensors/MySensor.cpp b/libraries/MySensors/MySensor.cpp index d34aa61..6636214 100755 --- a/libraries/MySensors/MySensor.cpp +++ b/libraries/MySensors/MySensor.cpp @@ -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 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; From 4d3fc96ebfdd25f40c48e18e52e2ac96b7afcf22 Mon Sep 17 00:00:00 2001 From: Patrick Fallberg Date: Mon, 16 Feb 2015 22:21:22 +0100 Subject: [PATCH 2/2] ATSHA204 personalization sketch updated New default pin is A3. New option to skip UART confirmation: SKIP_UART_CONFIRMATION This option prohibits the possibility to auto-generate key as there will probably not be a way to show the generated key to the user. More copy+paste friendly serial output of the generated key for insertion into personalization sketch. --- .../sha204_personalizer.ino | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/libraries/sha204/examples/sha204_personalizer/sha204_personalizer.ino b/libraries/sha204/examples/sha204_personalizer/sha204_personalizer.ino index 771d024..a39ceeb 100644 --- a/libraries/sha204/examples/sha204_personalizer/sha204_personalizer.ino +++ b/libraries/sha204/examples/sha204_personalizer/sha204_personalizer.ino @@ -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 #include // 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