From bf8102ecadd53772e7887c75248c61194e9dd182 Mon Sep 17 00:00:00 2001 From: Henrik Ekblad Date: Thu, 26 Feb 2015 23:53:37 +0100 Subject: [PATCH] For discussion --- libraries/MySensors/MyConfig.h | 103 ++++-------------- libraries/MySensors/MyParserSerial.cpp | 1 + libraries/MySensors/MyRFDriverNRF24.cpp | 58 +++++----- libraries/MySensors/MyRFDriverNRF24.h | 25 +---- libraries/MySensors/MySensor.cpp | 6 +- libraries/MySensors/MySensor.h | 7 +- .../MySensors/MySigningDriverAtsha204.cpp | 16 +-- libraries/MySensors/MySigningDriverAtsha204.h | 3 + .../MySensors/MySigningDriverAtsha204Soft.cpp | 14 +-- .../MySensors/MySigningDriverAtsha204Soft.h | 3 + libraries/MySensors/MySigningDriverNone.cpp | 2 - libraries/MySensors/MySigningDriverNone.h | 2 + .../examples/RelayActuator/RelayActuator.ino | 6 +- 13 files changed, 90 insertions(+), 156 deletions(-) diff --git a/libraries/MySensors/MyConfig.h b/libraries/MySensors/MyConfig.h index c574b58..168a5fc 100644 --- a/libraries/MySensors/MyConfig.h +++ b/libraries/MySensors/MyConfig.h @@ -1,99 +1,36 @@ #ifndef MyConfig_h #define MyConfig_h -/*** - * Configure Sensor Network - */ - -// pick ONE of these - other board layouts can be easily added this way -#define MYSENSORS_SENSOR -//#define MYSENSORS_SERIAL_GATEWAY -//#define MYSENSORS_ETHERNET_GATEWAY -//#define MYSENSORS_MQTT_GATEWAY +/********************************** +* Enable/Disable debug logging +***********************************/ +#define DEBUG -// Choose radio type by enabling one of the following -#define MYSENSORS_RF_NRF24 -//#define MYSENSORS_RF_RF69 - -// Choose signing backend by enabling one of the following -#define MYSENSORS_SIGNING_NONE -//#define MYSENSORS_SIGNING_ATSHA204 -//#define MYSENSORS_SIGNING_ATSHA204SOFT +/********************************** +* Message Signing Settings +***********************************/ // Define a suitable timeout for a signature verification session // Consider the turnaround from a nonce being generated to a signed message being received // which might vary, especially in networks with many hops. 5s ought to be enough for anyone. -#define VERIFICATION_TIMEOUT_MS 5000 +#define MY_VERIFICATION_TIMEOUT_MS 5000 -#ifdef MYSENSORS_RF_NRF24 -#include "MyRFDriverNRF24.h" -typedef class MyRFDriverNRF24 MyRFDriverClass; -#endif +// MySigningDriverAtsha204 settinga +#define MY_ATSHA204_PIN 17 // A3 - pin where ATSHA204 is attached -#ifdef MYSENSORS_RF_RF69 -#include "MyRFDriverRF69.h" -typedef class MyRFDriverRF69 MyRFDriverClass; -#endif +// MySigningDriverAtsha204Soft settings +#define MY_RANDOMSEED_PIN 7 // A7 - Pin used for random generation (do not connect anything to this) +// Key to use for HMAC calculation in MySigningDriverAtsha204Soft (32 bytes) +#define MY_HMAC_KEY 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 -#if defined(MYSENSORS_SERIAL_GATEWAY) || defined(MYSENSORS_ETHERNET_GATEWAY) -#include "MyParserSerial.h" -typedef class MyParserSerial MyParserClass; -#endif -#ifdef MYSENSORS_SIGNING_NONE -#include "MySigningDriverNone.h" -#define SIGNING_IDENTIFIER (0) // Reserved for dummy implementation, will not work with other backends -typedef class MySigningDriverNone MySigningDriverClass; -#endif +/********************************** +* NRF24L01 Driver Defaults +***********************************/ +#define RF24_CE_PIN 9 +#define RF24_CS_PIN 10 +#define RF24_PA_LEVEL RF24_PA_MAX -#ifdef MYSENSORS_SIGNING_ATSHA204 -#ifdef MYSENSORS_SENSOR -#define ATSHA204_PIN 17 //A3 -#endif -#ifdef MYSENSORS_SERIAL_GATEWAY -#define ATSHA204_PIN 17 //A3 -#endif - -#if defined(MYSENSORS_ETHERNET_GATEWAY) || defined(MYSENSORS_MQTT_GATEWAY) -#define ATSHA204_PIN 17 //A3 -#endif - -#include "MySigningDriverAtsha204.h" -#define SIGNING_IDENTIFIER (1) // SHA256-based HMAC (ATSHA204 specific) -typedef class MySigningDriverAtsha204 MySigningDriverClass; -#endif - -#ifdef MYSENSORS_SIGNING_ATSHA204SOFT -// Key to use for HMAC calculation -static uint8_t hmacKey[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 -}; - -// Pick an unconnected analog pin for RANDOMSEED_PIN -#ifdef MYSENSORS_SENSOR -#define RANDOMSEED_PIN 7 //A7 -#endif - -#ifdef MYSENSORS_SERIAL_GATEWAY -#define RANDOMSEED_PIN 7 //A7 -#endif - -#if defined(MYSENSORS_ETHERNET_GATEWAY) || defined(MYSENSORS_MQTT_GATEWAY) -#define RANDOMSEED_PIN 7 //A7 -#endif - -#include "MySigningDriverAtsha204Soft.h" -#define SIGNING_IDENTIFIER (1) // SHA256-based HMAC (ATSHA204 specific) -typedef class MySigningDriverAtsha204Soft MySigningDriverClass; -#endif - -/*** - * Enable/Disable debug logging - */ -#define DEBUG #endif diff --git a/libraries/MySensors/MyParserSerial.cpp b/libraries/MySensors/MyParserSerial.cpp index dc233c0..8c020b5 100644 --- a/libraries/MySensors/MyParserSerial.cpp +++ b/libraries/MySensors/MyParserSerial.cpp @@ -1,5 +1,6 @@ #include "MyParser.h" #include "MyParserSerial.h" +#include "MyRFDriver.h" MyParserSerial::MyParserSerial() : MyParser() {} diff --git a/libraries/MySensors/MyRFDriverNRF24.cpp b/libraries/MySensors/MyRFDriverNRF24.cpp index 1667fc6..9b4fe45 100644 --- a/libraries/MySensors/MyRFDriverNRF24.cpp +++ b/libraries/MySensors/MyRFDriverNRF24.cpp @@ -1,37 +1,41 @@ #include "MyRFDriver.h" #include "MyRFDriverNRF24.h" -MyRFDriverNRF24::MyRFDriverNRF24() : MyRFDriver() { - rf24 = new RF24(RF24_CE_PIN, RF24_CS_PIN); +MyRFDriverNRF24::MyRFDriverNRF24(uint8_t ce, uint8_t cs, uint8_t paLevel) + : + MyRFDriver(), + rf24(ce, cs), + _paLevel(paLevel) +{ } void MyRFDriverNRF24::init() { // Start up the radio library - rf24->begin(); + rf24.begin(); - if (!rf24->isPVariant()) { + if (!rf24.isPVariant()) { debug(PSTR("check wires\n")); while(1); } - rf24->setAutoAck(1); - rf24->setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast - rf24->enableAckPayload(); - rf24->setChannel(RF24_CHANNEL); - rf24->setPALevel(RF24_PA_LEVEL); - rf24->setDataRate(RF24_DATARATE); - rf24->setRetries(5,15); - rf24->setCRCLength(RF24_CRC_16); - rf24->enableDynamicPayloads(); + rf24.setAutoAck(1); + rf24.setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast + rf24.enableAckPayload(); + rf24.setChannel(RF24_CHANNEL); + rf24.setPALevel(_paLevel); + rf24.setDataRate(RF24_DATARATE); + rf24.setRetries(5,15); + rf24.setCRCLength(RF24_CRC_16); + rf24.enableDynamicPayloads(); // All nodes listen to broadcast pipe (for FIND_PARENT_RESPONSE messages) - rf24->openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS)); + rf24.openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS)); } void MyRFDriverNRF24::setAddress(uint8_t address) { _address = address; - rf24->openReadingPipe(WRITE_PIPE, TO_ADDR(address)); - rf24->openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(address)); - rf24->startListening(); + rf24.openReadingPipe(WRITE_PIPE, TO_ADDR(address)); + rf24.openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(address)); + rf24.startListening(); } uint8_t MyRFDriverNRF24::getAddress() { @@ -40,30 +44,30 @@ uint8_t MyRFDriverNRF24::getAddress() { bool MyRFDriverNRF24::send(uint8_t to, const void* data, uint8_t len) { // Make sure radio has powered up - rf24->powerUp(); - rf24->stopListening(); - rf24->openWritingPipe(TO_ADDR(to)); - bool ok = rf24->write(data, len, to == BROADCAST_ADDRESS); - rf24->startListening(); + rf24.powerUp(); + rf24.stopListening(); + rf24.openWritingPipe(TO_ADDR(to)); + bool ok = rf24.write(data, len, to == BROADCAST_ADDRESS); + rf24.startListening(); return ok; } bool MyRFDriverNRF24::available(uint8_t *to) { uint8_t pipe = 255; - boolean avail = rf24->available(&pipe); + boolean avail = rf24.available(&pipe); if (pipe == CURRENT_NODE_PIPE) *to = _address; else if (pipe == BROADCAST_PIPE) *to = BROADCAST_ADDRESS; - return (rf24->available() && pipe < 6); + return (rf24.available() && pipe < 6); } uint8_t MyRFDriverNRF24::receive(void* data) { - uint8_t len = rf24->getDynamicPayloadSize(); - rf24->read(data, len); + uint8_t len = rf24.getDynamicPayloadSize(); + rf24.read(data, len); return len; } void MyRFDriverNRF24::powerDown() { - rf24->powerDown(); + rf24.powerDown(); } diff --git a/libraries/MySensors/MyRFDriverNRF24.h b/libraries/MySensors/MyRFDriverNRF24.h index 267b19c..21607e2 100644 --- a/libraries/MySensors/MyRFDriverNRF24.h +++ b/libraries/MySensors/MyRFDriverNRF24.h @@ -7,26 +7,6 @@ #include "utility/RF24.h" #include "utility/RF24_config.h" - - -#ifdef MYSENSORS_SENSOR -#define RF24_CE_PIN 9 -#define RF24_CS_PIN 10 -#define RF24_PA_LEVEL RF24_PA_MAX -#endif - -#ifdef MYSENSORS_SERIAL_GATEWAY -#define RF24_CE_PIN 9 -#define RF24_CS_PIN 10 -#define RF24_PA_LEVEL RF24_PA_LOW -#endif - -#if defined(MYSENSORS_ETHERNET_GATEWAY) || defined(MYSENSORS_MQTT_GATEWAY) -#define RF24_CE_PIN 5 -#define RF24_CS_PIN 6 -#define RF24_PA_LEVEL RF24_PA_LOW -#endif - #define RF24_CHANNEL 76 //RF channel for the sensor net, 0-127 #define RF24_DATARATE RF24_250KBPS //RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps #define RF24_BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL) // This is also act as base value for sensor nodeId addresses. Change this (or channel) if you have more than one sensor network. @@ -40,7 +20,7 @@ class MyRFDriverNRF24 : public MyRFDriver { public: - MyRFDriverNRF24(); + MyRFDriverNRF24(uint8_t ce=RF24_CE_PIN, uint8_t cs=RF24_CS_PIN, uint8_t paLevel=RF24_PA_LEVEL); void init(); void setAddress(uint8_t address); uint8_t getAddress(); @@ -49,8 +29,9 @@ public: uint8_t receive(void* data); void powerDown(); private: - RF24 *rf24; + RF24 rf24; uint8_t _address; + uint8_t _paLevel; }; #endif diff --git a/libraries/MySensors/MySensor.cpp b/libraries/MySensors/MySensor.cpp index ce971f7..aab91ec 100755 --- a/libraries/MySensors/MySensor.cpp +++ b/libraries/MySensors/MySensor.cpp @@ -37,7 +37,11 @@ static inline bool isValidDistance( const uint8_t distance ) { return distance != DISTANCE_INVALID; } -MySensor::MySensor() { +MySensor::MySensor(MyRFDriver &_radio, MySigningDriver &_signer) + : + radio(_radio), + signer(_signer) +{ } diff --git a/libraries/MySensors/MySensor.h b/libraries/MySensors/MySensor.h index 747990a..01ca2b4 100644 --- a/libraries/MySensors/MySensor.h +++ b/libraries/MySensors/MySensor.h @@ -79,7 +79,7 @@ class MySensor * Creates a new instance of Sensor class. * */ - MySensor(); + MySensor(MyRFDriver &radio, MySigningDriver &signer); /** * Begin operation of the MySensors library @@ -249,9 +249,8 @@ class MySensor MyMessage tmpMsg ; // Buffer for temporary messages (acks and nonces among others). MyMessage msgSign; // Buffer for message to sign. - MyRFDriverClass radio; - - MySigningDriverClass signer; + MyRFDriver& radio; + MySigningDriver& signer; void setupRepeaterMode(); boolean sendWrite(uint8_t dest, MyMessage &message); diff --git a/libraries/MySensors/MySigningDriverAtsha204.cpp b/libraries/MySensors/MySigningDriverAtsha204.cpp index a71a30a..fab6942 100644 --- a/libraries/MySensors/MySigningDriverAtsha204.cpp +++ b/libraries/MySensors/MySigningDriverAtsha204.cpp @@ -7,7 +7,6 @@ #include "MySigningDriver.h" #include "MySigningDriverAtsha204.h" -#ifdef MYSENSORS_SIGNING_ATSHA204 // Uncomment this to get some useful serial debug info (Serial.print and Serial.println expected) //#define DEBUG_ATSHA_SIGNING @@ -36,11 +35,13 @@ static void DEBUG_ATSHA_PRINTBUF(char* str, uint8_t* buf, uint8_t sz) #define DEBUG_ATSHA_PRINTBUF(str, buf, sz) #endif -static atsha204Class atsha204(ATSHA204_PIN); - -MySigningDriverAtsha204::MySigningDriverAtsha204() : MySigningDriver() { - verification_ongoing = false; +MySigningDriverAtsha204::MySigningDriverAtsha204() + : + MySigningDriver(), + atsha204(MY_ATSHA204_PIN), + verification_ongoing(false) +{ // We set the part of the 32-byte nonce that does not fit into a message to 0xAA memset(current_nonce, 0xAA, sizeof(current_nonce)); } @@ -73,13 +74,13 @@ bool MySigningDriverAtsha204::getNonce(MyMessage &msg) { // Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover) // Note that if message is "too" quick, and arrives before turnover, it will be rejected // but this is consider such a rare case that it is accepted and rejects are 'safe' - if (timestamp + VERIFICATION_TIMEOUT_MS < millis()) timestamp = 0; + if (timestamp + MY_VERIFICATION_TIMEOUT_MS < millis()) timestamp = 0; return true; } bool MySigningDriverAtsha204::checkTimer() { if (verification_ongoing) { - if (millis() < timestamp || millis() > timestamp + VERIFICATION_TIMEOUT_MS) { + if (millis() < timestamp || millis() > timestamp + MY_VERIFICATION_TIMEOUT_MS) { DEBUG_ATSHA_PRINTLN("Verification timeout"); // Purge nonce memset(current_nonce, 0xAA, NONCE_NUMIN_SIZE_PASSTHROUGH); @@ -214,4 +215,3 @@ bool MySigningDriverAtsha204::calculateSignature(MyMessage &msg) { DEBUG_ATSHA_PRINTBUF("HMAC:", &rx_buffer[SHA204_BUFFER_POS_DATA], 32); return true; // We return with the signature in rx_buffer[SHA204_BUFFER_POS_DATA] } -#endif diff --git a/libraries/MySensors/MySigningDriverAtsha204.h b/libraries/MySensors/MySigningDriverAtsha204.h index a2f6b9d..57bb2f3 100644 --- a/libraries/MySensors/MySigningDriverAtsha204.h +++ b/libraries/MySensors/MySigningDriverAtsha204.h @@ -12,6 +12,8 @@ #include "utility/ATSHA204.h" #include +#define SIGNING_IDENTIFIER (1) + // The ATSHA204 is capable of generating proper random numbers for nonce // and can calculate HMAC-SHA256 signatures. This is enterprise- // level of security and ought to implement the signing needs for anybody. @@ -25,6 +27,7 @@ public: bool signMsg(MyMessage &msg); bool verifyMsg(MyMessage &msg); private: + atsha204Class atsha204; unsigned long timestamp; bool verification_ongoing; uint8_t current_nonce[NONCE_NUMIN_SIZE_PASSTHROUGH]; diff --git a/libraries/MySensors/MySigningDriverAtsha204Soft.cpp b/libraries/MySensors/MySigningDriverAtsha204Soft.cpp index aaff71f..47b57f3 100644 --- a/libraries/MySensors/MySigningDriverAtsha204Soft.cpp +++ b/libraries/MySensors/MySigningDriverAtsha204Soft.cpp @@ -7,11 +7,11 @@ Created by Patrick "Anticimex" Fallberg */ +#include "MyConfig.h" #include "MySigningDriver.h" #include "MySigningDriverAtsha204Soft.h" -#include "sha256.h" +#include "utility/sha256.h" -#ifdef MYSENSORS_SIGNING_ATSHA204SOFT // Uncomment this to get some useful serial debug info (Serial.print and Serial.println expected) //#define DEBUG_ATSHASOFT_SIGNING @@ -42,16 +42,15 @@ static void DEBUG_ATSHASOFT_PRINTBUF(char* str, uint8_t* buf, uint8_t sz) static Sha256Class Sha256; -MySigningDriverAtsha204Soft::MySigningDriverAtsha204Soft() : MySigningDriver() { +MySigningDriverAtsha204Soft::MySigningDriverAtsha204Soft() : MySigningDriver(), hmacKey({MY_HMAC_KEY}) { verification_ongoing = false; - // We set the part of the 32-byte nonce that does not fit into a message to 0xAA memset(current_nonce, 0xAA, sizeof(current_nonce)); } bool MySigningDriverAtsha204Soft::getNonce(MyMessage &msg) { // Set randomseed - randomSeed(analogRead(RANDOMSEED_PIN)); + randomSeed(analogRead(MY_RANDOMSEED_PIN)); for (int i = 0; i < MAX_PAYLOAD; i++) { current_nonce[i] = random(255); @@ -65,13 +64,13 @@ bool MySigningDriverAtsha204Soft::getNonce(MyMessage &msg) { // Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover) // Note that if message is "too" quick, and arrives before turnover, it will be rejected // but this is consider such a rare case that it is accepted and rejects are 'safe' - if (timestamp + VERIFICATION_TIMEOUT_MS < millis()) timestamp = 0; + if (timestamp + MY_VERIFICATION_TIMEOUT_MS < millis()) timestamp = 0; return true; } bool MySigningDriverAtsha204Soft::checkTimer() { if (verification_ongoing) { - if (millis() < timestamp || millis() > timestamp + VERIFICATION_TIMEOUT_MS) { + if (millis() < timestamp || millis() > timestamp + MY_VERIFICATION_TIMEOUT_MS) { DEBUG_ATSHASOFT_PRINTLN("Verification timeout"); // Purge nonce memset(current_nonce, 0xAA, 32); @@ -222,4 +221,3 @@ bool MySigningDriverAtsha204Soft::calculateSignature(MyMessage &msg) { DEBUG_ATSHASOFT_PRINTBUF("HMAC:", hmac, 32); return true; } -#endif diff --git a/libraries/MySensors/MySigningDriverAtsha204Soft.h b/libraries/MySensors/MySigningDriverAtsha204Soft.h index 16d8d3e..53d8426 100644 --- a/libraries/MySensors/MySigningDriverAtsha204Soft.h +++ b/libraries/MySensors/MySigningDriverAtsha204Soft.h @@ -15,6 +15,8 @@ #include "utility/ATSHA204.h" #include +#define SIGNING_IDENTIFIER (1) + // This implementation is the pure software variant of the ATSHA204. // It is designed to work fully compliant with nodes using ATSHA204 in the network // and therefore uses the same signing identifier as ATSHA204. @@ -36,6 +38,7 @@ private: bool verification_ongoing; uint8_t current_nonce[NONCE_NUMIN_SIZE_PASSTHROUGH]; uint8_t temp_message[32]; + uint8_t hmacKey[32]; uint8_t* hmac; bool calculateSignature(MyMessage &msg); }; diff --git a/libraries/MySensors/MySigningDriverNone.cpp b/libraries/MySensors/MySigningDriverNone.cpp index fed6e6c..a7ace62 100644 --- a/libraries/MySensors/MySigningDriverNone.cpp +++ b/libraries/MySensors/MySigningDriverNone.cpp @@ -6,7 +6,6 @@ #include "MySigningDriver.h" #include "MySigningDriverNone.h" -#ifdef MYSENSORS_SIGNING_NONE // Uncomment this to get some useful serial debug info (Serial.print and Serial.println expected) //#define DEBUG_NONE_SIGNING @@ -67,4 +66,3 @@ bool MySigningDriverNone::verifyMsg(MyMessage &msg) { else return true; } -#endif diff --git a/libraries/MySensors/MySigningDriverNone.h b/libraries/MySensors/MySigningDriverNone.h index 8c30367..9718a78 100644 --- a/libraries/MySensors/MySigningDriverNone.h +++ b/libraries/MySensors/MySigningDriverNone.h @@ -10,6 +10,8 @@ #include "MySigningDriver.h" #include +#define SIGNING_IDENTIFIER (0) + // The "none" signing driver that can be used for nodes // not requiring signing // It does check SIGNING_IDENTIFIER byte to avoid illegal mixing of signing back-ends in diff --git a/libraries/MySensors/examples/RelayActuator/RelayActuator.ino b/libraries/MySensors/examples/RelayActuator/RelayActuator.ino index 3f0e94f..c0e8a7c 100644 --- a/libraries/MySensors/examples/RelayActuator/RelayActuator.ino +++ b/libraries/MySensors/examples/RelayActuator/RelayActuator.ino @@ -1,6 +1,8 @@ // Example sketch showing how to control physical relays. // This example will remember relay state even after power failure. +#include +#include #include #include @@ -9,7 +11,9 @@ #define RELAY_ON 1 // GPIO value to write to turn on attached relay #define RELAY_OFF 0 // GPIO value to write to turn off attached relay -MySensor gw; +MyRFDriverNRF24 radio; // NRFRF24L01 radio driver +MySigningDriverNone signer; // Message signing disabled +MySensor gw(radio, signer); void setup() {