Fix: ATSHA204, serial gw, ethernet warnings

This commit is contained in:
Henrik Ekblad
2015-09-17 07:24:12 +02:00
parent ada872f30f
commit 6cf6255e50
28 changed files with 206 additions and 254 deletions
+18 -8
View File
@@ -19,15 +19,14 @@
#ifndef MySensor_h
#define MySensor_h
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
// #pragma message(VAR_NAME_VALUE(MY_GATEWAY_FEATURE))
/* { dg-warning "import is a deprecated GCC extension" "deprecated" {target *-*-* } 0 } */
#include "MyConfig.h"
#include "core/MySensorCore.h"
#if defined(MY_GATEWAY_SERIAL) || defined(MY_GATEWAY_W5100) || defined(MY_GATEWAY_ENC28J60)
#if defined(MY_GATEWAY_SERIAL) || defined(MY_GATEWAY_W5100) || defined(MY_GATEWAY_ENC28J60) || defined(ARDUINO_ARCH_ESP8266)
#define MY_GATEWAY_FEATURE
#define MY_NODE_TYPE "gateway"
#elif defined(MY_REPEATER_FEATURE)
@@ -41,6 +40,8 @@
#if defined(ARDUINO_ARCH_ESP8266)
#include "drivers/ESP8266/SPI/SPI.cpp"
#include "core/MyHwESP8266.cpp"
// For ESP8266, we always enable gateway feature
#define MY_GATEWAY_ESP8266
#elif defined(ARDUINO_ARCH_AVR)
#include "drivers/AVR/SPI/SPI.cpp"
#include "core/MyHwATMega328.cpp"
@@ -84,9 +85,14 @@
// GATEWAY - COMMON FUNCTIONS
#include "core/MyGatewayTransport.cpp"
// We currently only support one protocol, enable it.
#if !defined(MY_GATEWAY_PROTOCOL_DEFAULT)
#define MY_GATEWAY_PROTOCOL_DEFAULT
#endif
// GATEWAY - PROTOCOL
#if defined(MY_GATEWAY_PROTOCOL_DEFAULT)
#include "core/MyProtocolDefault.cpp"
#include "core/MyProtocolMySensors.cpp"
#else
#error No gateway protocol specified!
#endif
@@ -102,8 +108,10 @@
#if !defined(MY_PORT)
#error You must define MY_PORT (cotroller or gatway port to open)
#endif
#if defined(MY_GATEWAY_ESP8266)
// GATEWAY - ESP8266
#if defined(MY_GATEWAY_W5100)
#elif defined(MY_GATEWAY_W5100)
// GATEWAY - W5100
#include "drivers/AVR/Ethernet_W5100/utility/socket.cpp"
#include "drivers/AVR/Ethernet_W5100/utility/w5100.cpp"
@@ -192,7 +200,9 @@
#undef MY_INCLUSION_BUTTON_FEATURE
#endif
#if !defined(MY_GATEWAY_FEATURE) && !defined(MY_RADIO_FEATURE)
#error No radio or gateway feature activated. This means nowhere to send messages! Pretty pointless.
#endif
#include "core/MyMessage.cpp"
@@ -43,7 +43,7 @@ inline void gatewayTransportProcess() {
inclusionModeSet(atoi(_msg.data) == 1);
#endif
} else {
processInternalMessages();
_processInternalMessages();
}
} else {
// Call incoming message callback if available
@@ -23,7 +23,7 @@
#include "MyConfig.h"
#include "MyMessage.h"
#include "MyProtocol.h"
#include "MyProtocolDefault.h"
#include "MyProtocolMySensors.h"
#include "MyGatewayTransport.h"
@@ -23,7 +23,7 @@
#include "MyMessage.h"
#include "MyGatewayTransport.h"
#include "MyProtocol.h"
#include "MyProtocolDefault.h"
#include "MyProtocolMySensors.h"
#define MAX_RECEIVE_LENGTH 100 // Maximum message length for messages coming from controller
@@ -18,7 +18,7 @@
*/
#include "MyProtocol.h"
#include "MyProtocolDefault.h"
#include "MyProtocolMySensors.h"
#include "MyTransport.h"
char _fmtBuffer[MAX_FORMAT_BUFFER_LENGTH];
+17 -14
View File
@@ -54,21 +54,32 @@ void _process() {
#endif
}
#if defined(MY_RADIO_FEATURE)
static inline bool isValidParent( const uint8_t parent ) {
return parent != AUTO;
}
#endif
void setIncomingCallback(void (*msgCallback)(const MyMessage &)) {
_msgCallback = msgCallback;
}
void _begin() {
#if defined(MY_DISABLED_SERIAL)
#if !defined(MY_DISABLED_SERIAL)
hwInit();
#endif
#if defined(MY_RADIO_FEATURE)
_failedTransmissions = 0;
// Setup radio
if (!transportInit()) {
debug(PSTR("radio init fail\n"));
while(1); // Nothing more we can do
}
#endif
#if defined(MY_GATEWAY_FEATURE)
#if defined(MY_INCLUSION_BUTTON_FEATURE)
inclusionInit();
@@ -83,15 +94,6 @@ void _begin() {
gatewayTransportSend(buildGw(_msg, I_GATEWAY_READY).set("Gateway startup complete."));
#endif
#if defined(MY_RADIO_FEATURE)
_failedTransmissions = 0;
// Setup radio
if (!transportInit()) {
debug(PSTR("radio init fail\n"));
while(1); // Nothing more we can do
}
#endif
#if defined(MY_SIGNING_FEATURE)
// Read out the signing requirements from EEPROM
@@ -114,7 +116,7 @@ void _begin() {
_nc.parentNodeId = GATEWAY_ADDRESS;
_nc.distance = 0;
_nc.nodeId = GATEWAY_ADDRESS;
#else
#elif defined(MY_RADIO_FEATURE)
// Read settings from eeprom
hwReadConfigBlock((void*)&_nc, (void*)EEPROM_NODE_ID_ADDRESS, sizeof(NodeConfig));
// Read latest received controller configuration from EEPROM
@@ -151,6 +153,7 @@ void _begin() {
#if defined(MY_RADIO_FEATURE)
transportSetupNode();
#endif
debug(PSTR("%s started, id=%d, parent=%d, distance=%d\n"), MY_NODE_TYPE, _nc.nodeId, _nc.parentNodeId, _nc.distance);
}
@@ -176,7 +179,7 @@ boolean _sendRoute(MyMessage &message) {
}
#endif
#if defined(MY_RADIO_FEATURE)
transportSendRoute(message);
return transportSendRoute(message);
#else
return false;
#endif
+2
View File
@@ -60,6 +60,8 @@
// This is the nodeId for sensor net gateway receiver sketch (where all sensors should send their data).
#define GATEWAY_ADDRESS ((uint8_t)0)
// Node child is always created/presented when a node is started
#define NODE_SENSOR_ID 0xFF
struct NodeConfig
+75 -96
View File
@@ -34,25 +34,20 @@
// Uncomment this to get some useful serial debug info (Serial.print and Serial.println expected)
//#define DEBUG_SIGNING
uint8_t atshaPin=MY_ATSHA204_PIN);
ATSHA204Class atsha204;
unsigned long timestamp;
bool verification_ongoing;
uint8_t current_nonce[NONCE_NUMIN_SIZE_PASSTHROUGH+SHA204_SERIAL_SZ+1];
uint8_t temp_message[SHA_MSG_SIZE];
uint8_t rx_buffer[SHA204_RSP_SIZE_MAX];
uint8_t tx_buffer[SHA204_CMD_SIZE_MAX];
void calculateSignature(MyMessage &msg);
uint8_t* sha256(const uint8_t* data, size_t sz);
ATSHA204Class atsha204(MY_SIGNING_ATSHA204_PIN);
unsigned long _signing_timestamp;
bool _signing_verification_ongoing = false;
uint8_t _signing_current_nonce[NONCE_NUMIN_SIZE_PASSTHROUGH+SHA204_SERIAL_SZ+1];
uint8_t _signing_temp_message[SHA_MSG_SIZE];
uint8_t _singning_rx_buffer[SHA204_RSP_SIZE_MAX];
uint8_t _singning_tx_buffer[SHA204_CMD_SIZE_MAX];
#ifdef MY_SIGNING_NODE_WHITELISTING
uint8_t nof_whitelist_entries=0;
const uint8_t whitelist_entry_t* the_whitelist=NULL,
uint8_t whitlist_sz;
const whitelist_entry_t* whitelist;
const whitelist_entry_t _signing_whitelist[] = MY_SIGNING_NODE_WHITELISTING;
#endif
#ifdef DEBUG_SIGNING
#define DEBUG_SIGNING_PRINTLN(args) Serial.println(args)
#else
@@ -78,79 +73,63 @@ static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf,
#endif
MySigningAtsha204::MySigningAtsha204(bool requestSignatures,
#ifdef MY_SIGNING_NODE_WHITELISTING
uint8_t nof_whitelist_entries, const whitelist_entry_t* the_whitelist,
#endif
uint8_t atshaPin)
:
MySigning(requestSignatures),
atsha204(atshaPin),
#ifdef MY_SIGNING_NODE_WHITELISTING
whitelist(the_whitelist),
whitlist_sz(nof_whitelist_entries),
#endif
verification_ongoing(false)
{
}
bool MySigningAtsha204::getNonce(MyMessage &msg) {
bool signerGetNonce(MyMessage &msg) {
// Generate random number for use as nonce
// We used a basic whitening technique that takes the first byte of a new random value and builds up a 32-byte random value
// This 32-byte random value is then hashed (SHA256) to produce the resulting nonce
for (int i = 0; i < 32; i++) {
if (atsha204.sha204m_execute(SHA204_RANDOM, RANDOM_NO_SEED_UPDATE, 0, 0, NULL,
RANDOM_COUNT, tx_buffer, RANDOM_RSP_SIZE, rx_buffer) != SHA204_SUCCESS) {
RANDOM_COUNT, _singning_tx_buffer, RANDOM_RSP_SIZE, _singning_rx_buffer) != SHA204_SUCCESS) {
DEBUG_SIGNING_PRINTLN(F("FTGN")); // FTGN = Failed to generate nonce
return false;
}
current_nonce[i] = rx_buffer[SHA204_BUFFER_POS_DATA];
_signing_current_nonce[i] = _singning_rx_buffer[SHA204_BUFFER_POS_DATA];
}
memcpy(current_nonce, sha256(current_nonce, 32), MAX_PAYLOAD);
memcpy(_signing_current_nonce, signerSha256(_signing_current_nonce, 32), MAX_PAYLOAD);
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(&current_nonce[MAX_PAYLOAD], 0xAA, sizeof(current_nonce)-MAX_PAYLOAD);
memset(&_signing_current_nonce[MAX_PAYLOAD], 0xAA, sizeof(_signing_current_nonce)-MAX_PAYLOAD);
// Replace the first byte in the nonce with our signing identifier
current_nonce[0] = SIGNING_IDENTIFIER;
_signing_current_nonce[0] = SIGNING_IDENTIFIER;
// Transfer the first part of the nonce to the message
msg.set(current_nonce, MAX_PAYLOAD);
verification_ongoing = true;
timestamp = millis(); // Set timestamp to determine when to purge nonce
msg.set(_signing_current_nonce, MAX_PAYLOAD);
_signing_verification_ongoing = true;
_signing_timestamp = millis(); // Set timestamp to determine when to purge nonce
// 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 + MY_VERIFICATION_TIMEOUT_MS < millis()) timestamp = 0;
if (_signing_timestamp + MY_VERIFICATION_TIMEOUT_MS < millis()) _signing_timestamp = 0;
return true;
}
bool MySigningAtsha204::checkTimer() {
if (verification_ongoing) {
if (millis() < timestamp || millis() > timestamp + MY_VERIFICATION_TIMEOUT_MS) {
bool signerCheckTimer() {
if (_signing_verification_ongoing) {
if (millis() < _signing_timestamp || millis() > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) {
DEBUG_SIGNING_PRINTLN(F("VT")); // VT = Verification timeout
// Purge nonce
memset(current_nonce, 0x00, NONCE_NUMIN_SIZE_PASSTHROUGH);
verification_ongoing = false;
memset(_signing_current_nonce, 0x00, NONCE_NUMIN_SIZE_PASSTHROUGH);
_signing_verification_ongoing = false;
return false;
}
}
return true;
}
bool MySigningAtsha204::putNonce(MyMessage &msg) {
bool signerPutNonce(MyMessage &msg) {
if (((uint8_t*)msg.getCustom())[0] != SIGNING_IDENTIFIER) {
DEBUG_SIGNING_PRINTLN(F("ISI")); // ISI = Incorrect signing identifier
return false;
}
memcpy(current_nonce, (uint8_t*)msg.getCustom(), MAX_PAYLOAD);
memcpy(_signing_current_nonce, (uint8_t*)msg.getCustom(), MAX_PAYLOAD);
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(&current_nonce[MAX_PAYLOAD], 0xAA, sizeof(current_nonce)-MAX_PAYLOAD);
memset(&_signing_current_nonce[MAX_PAYLOAD], 0xAA, sizeof(_signing_current_nonce)-MAX_PAYLOAD);
return true;
}
bool MySigningAtsha204::signMsg(MyMessage &msg) {
bool signerSignMsg(MyMessage &msg) {
// If we cannot fit any signature in the message, refuse to sign it
if (mGetLength(msg) > MAX_PAYLOAD-2) {
DEBUG_SIGNING_PRINTLN(F("MTOL")); // Message too large for signature to fit
@@ -159,37 +138,37 @@ bool MySigningAtsha204::signMsg(MyMessage &msg) {
// Calculate signature of message
mSetSigned(msg, 1); // make sure signing flag is set before signature is calculated
calculateSignature(msg);
signerCalculateSignature(msg);
#ifdef MY_SIGNING_NODE_WHITELISTING
// Salt the signature with the senders nodeId and the unique serial of the ATSHA device
memcpy(current_nonce, &rx_buffer[SHA204_BUFFER_POS_DATA], 32); // We can reuse the nonce buffer now since it is no longer needed
current_nonce[32] = msg.sender;
atsha204.getSerialNumber(&current_nonce[33]);
(void)sha256(current_nonce, 32+1+SHA204_SERIAL_SZ); // we can 'void' sha256 because the hash is already put in the correct place
memcpy(_signing_current_nonce, &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], 32); // We can reuse the nonce buffer now since it is no longer needed
_signing_current_nonce[32] = msg.sender;
atsha204.getSerialNumber(&_signing_current_nonce[33]);
(void)signerSha256(_signing_current_nonce, 32+1+SHA204_SERIAL_SZ); // we can 'void' sha256 because the hash is already put in the correct place
DEBUG_SIGNING_PRINTLN(F("SWS")); // SWS = Signature whitelist salted
#endif
// Overwrite the first byte in the signature with the signing identifier
rx_buffer[SHA204_BUFFER_POS_DATA] = SIGNING_IDENTIFIER;
_singning_rx_buffer[SHA204_BUFFER_POS_DATA] = SIGNING_IDENTIFIER;
// Transfer as much signature data as the remaining space in the message permits
memcpy(&msg.data[mGetLength(msg)], &rx_buffer[SHA204_BUFFER_POS_DATA], MAX_PAYLOAD-mGetLength(msg));
memcpy(&msg.data[mGetLength(msg)], &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], MAX_PAYLOAD-mGetLength(msg));
return true;
}
bool MySigningAtsha204::verifyMsg(MyMessage &msg) {
if (!verification_ongoing) {
bool signerVerifyMsg(MyMessage &msg) {
if (!_signing_verification_ongoing) {
DEBUG_SIGNING_PRINTLN(F("NAVS")); // NAVS = No active verification session
return false;
} else {
// Make sure we have not expired
if (!checkTimer()) {
if (!signerCheckTimer()) {
return false;
}
verification_ongoing = false;
_signing_verification_ongoing = false;
if (msg.data[mGetLength(msg)] != SIGNING_IDENTIFIER) {
DEBUG_SIGNING_PRINTLN(F("ISI")); // ISI = Incorrect signing identifier
@@ -197,28 +176,28 @@ bool MySigningAtsha204::verifyMsg(MyMessage &msg) {
}
DEBUG_SIGNING_PRINTBUF(F("SIM:"), (uint8_t*)&msg.data[mGetLength(msg)], MAX_PAYLOAD-mGetLength(msg)); // SIM = Signature in message
calculateSignature(msg); // Get signature of message
signerCalculateSignature(msg); // Get signature of message
#ifdef MY_SIGNING_NODE_WHITELISTING
// Look up the senders nodeId in our whitelist and salt the signature with that data
for (int j=0; j < whitlist_sz; j++) {
if (whitelist[j].nodeId == msg.sender) {
for (int j=0; j < NUM_OF(_signing_whitelist); j++) {
if (_signing_whitelist[j].nodeId == msg.sender) {
DEBUG_SIGNING_PRINTLN(F("SIW")); // SIW = Sender found in whitelist
memcpy(current_nonce, &rx_buffer[SHA204_BUFFER_POS_DATA], 32); // We can reuse the nonce buffer now since it is no longer needed
current_nonce[32] = msg.sender;
memcpy(&current_nonce[33], whitelist[j].serial, SHA204_SERIAL_SZ);
(void)sha256(current_nonce, 32+1+SHA204_SERIAL_SZ); // we can 'void' sha256 because the hash is already put in the correct place
memcpy(_signing_current_nonce, &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], 32); // We can reuse the nonce buffer now since it is no longer needed
_signing_current_nonce[32] = msg.sender;
memcpy(&_signing_current_nonce[33], _signing_whitelist[j].serial, SHA204_SERIAL_SZ);
(void)signerSha256(_signing_current_nonce, 32+1+SHA204_SERIAL_SZ); // we can 'void' sha256 because the hash is already put in the correct place
break;
}
}
#endif
// Overwrite the first byte in the signature with the signing identifier
rx_buffer[SHA204_BUFFER_POS_DATA] = SIGNING_IDENTIFIER;
_singning_rx_buffer[SHA204_BUFFER_POS_DATA] = SIGNING_IDENTIFIER;
// Compare the caluclated signature with the provided signature
if (memcmp(&msg.data[mGetLength(msg)], &rx_buffer[SHA204_BUFFER_POS_DATA], MAX_PAYLOAD-mGetLength(msg))) {
DEBUG_SIGNING_PRINTBUF(F("SNOK:"), &rx_buffer[SHA204_BUFFER_POS_DATA], MAX_PAYLOAD-mGetLength(msg)); // SNOK = Signature bad
if (memcmp(&msg.data[mGetLength(msg)], &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], MAX_PAYLOAD-mGetLength(msg))) {
DEBUG_SIGNING_PRINTBUF(F("SNOK:"), &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], MAX_PAYLOAD-mGetLength(msg)); // SNOK = Signature bad
#ifdef MY_SIGNING_NODE_WHITELISTING
DEBUG_SIGNING_PRINTLN(F("W?")); // W? = Is the sender whitelisted?
#endif
@@ -230,60 +209,60 @@ bool MySigningAtsha204::verifyMsg(MyMessage &msg) {
}
}
// Helper to calculate signature of msg (returned in rx_buffer[SHA204_BUFFER_POS_DATA])
void MySigningAtsha204::calculateSignature(MyMessage &msg) {
memset(temp_message, 0, 32);
memcpy(temp_message, (uint8_t*)&msg.data[1-HEADER_SIZE], MAX_MESSAGE_LENGTH-1-(MAX_PAYLOAD-mGetLength(msg)));
// Helper to calculate signature of msg (returned in _singning_rx_buffer[SHA204_BUFFER_POS_DATA])
void signerCalculateSignature(MyMessage &msg) {
memset(_signing_temp_message, 0, 32);
memcpy(_signing_temp_message, (uint8_t*)&msg.data[1-HEADER_SIZE], MAX_MESSAGE_LENGTH-1-(MAX_PAYLOAD-mGetLength(msg)));
// Program the data to sign into the ATSHA204
DEBUG_SIGNING_PRINTBUF(F("MSG:"), (uint8_t*)&msg.data[1-HEADER_SIZE], MAX_MESSAGE_LENGTH-1-(MAX_PAYLOAD-mGetLength(msg))); // MSG = Message to sign
DEBUG_SIGNING_PRINTBUF(F("CNC:"), current_nonce, 32); // CNC = Current nonce
(void)atsha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG, 8 << 3, 32, temp_message,
WRITE_COUNT_LONG, tx_buffer, WRITE_RSP_SIZE, rx_buffer);
DEBUG_SIGNING_PRINTBUF(F("CNC:"), _signing_current_nonce, 32); // CNC = Current nonce
(void)atsha204.sha204m_execute(SHA204_WRITE, SHA204_ZONE_DATA | SHA204_ZONE_COUNT_FLAG, 8 << 3, 32, _signing_temp_message,
WRITE_COUNT_LONG, _singning_tx_buffer, WRITE_RSP_SIZE, _singning_rx_buffer);
// Program the nonce to use for the signature (has to be done just before GENDIG due to chip limitations)
(void)atsha204.sha204m_execute(SHA204_NONCE, NONCE_MODE_PASSTHROUGH, 0, NONCE_NUMIN_SIZE_PASSTHROUGH, current_nonce,
NONCE_COUNT_LONG, tx_buffer, NONCE_RSP_SIZE_SHORT, rx_buffer);
(void)atsha204.sha204m_execute(SHA204_NONCE, NONCE_MODE_PASSTHROUGH, 0, NONCE_NUMIN_SIZE_PASSTHROUGH, _signing_current_nonce,
NONCE_COUNT_LONG, _singning_tx_buffer, NONCE_RSP_SIZE_SHORT, _singning_rx_buffer);
// Purge nonce when used
memset(current_nonce, 0x00, NONCE_NUMIN_SIZE_PASSTHROUGH);
memset(_signing_current_nonce, 0x00, NONCE_NUMIN_SIZE_PASSTHROUGH);
// Generate digest of data and nonce
(void)atsha204.sha204m_execute(SHA204_GENDIG, GENDIG_ZONE_DATA, 8, 0, NULL,
GENDIG_COUNT_DATA, tx_buffer, GENDIG_RSP_SIZE, rx_buffer);
GENDIG_COUNT_DATA, _singning_tx_buffer, GENDIG_RSP_SIZE, _singning_rx_buffer);
// Calculate HMAC of message+nonce digest and secret key
(void)atsha204.sha204m_execute(SHA204_HMAC, HMAC_MODE_SOURCE_FLAG_MATCH, 0, 0, NULL,
HMAC_COUNT, tx_buffer, HMAC_RSP_SIZE, rx_buffer);
HMAC_COUNT, _singning_tx_buffer, HMAC_RSP_SIZE, _singning_rx_buffer);
// Put device back to sleep
atsha204.sha204c_sleep();
DEBUG_SIGNING_PRINTBUF(F("HMAC:"), &rx_buffer[SHA204_BUFFER_POS_DATA], 32);
DEBUG_SIGNING_PRINTBUF(F("HMAC:"), &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], 32);
}
// Helper to calculate a generic SHA256 digest of provided buffer (only supports one block)
// The pointer to the hash is returned, but the hash is also stored in rx_buffer[SHA204_BUFFER_POS_DATA])
uint8_t* MySigningAtsha204::sha256(const uint8_t* data, size_t sz) {
// The pointer to the hash is returned, but the hash is also stored in _singning_rx_buffer[SHA204_BUFFER_POS_DATA])
uint8_t* signerSha256(const uint8_t* data, size_t sz) {
// Initiate SHA256 calculator
(void)atsha204.sha204m_execute(SHA204_SHA, SHA_INIT, 0, 0, NULL,
SHA_COUNT_SHORT, tx_buffer, SHA_RSP_SIZE_SHORT, rx_buffer);
SHA_COUNT_SHORT, _singning_tx_buffer, SHA_RSP_SIZE_SHORT, _singning_rx_buffer);
// Calculate a hash
memset(temp_message, 0x00, SHA_MSG_SIZE);
memcpy(temp_message, data, sz);
temp_message[sz] = 0x80;
memset(_signing_temp_message, 0x00, SHA_MSG_SIZE);
memcpy(_signing_temp_message, data, sz);
_signing_temp_message[sz] = 0x80;
// Write length data to the last bytes
temp_message[SHA_MSG_SIZE-2] = (sz >> 5);
temp_message[SHA_MSG_SIZE-1] = (sz << 3);
DEBUG_SIGNING_PRINTBUF(F("DTH:"), temp_message, SHA_MSG_SIZE); // DTH = Data to hash
(void)atsha204.sha204m_execute(SHA204_SHA, SHA_CALC, 0, SHA_MSG_SIZE, temp_message,
SHA_COUNT_LONG, tx_buffer, SHA_RSP_SIZE_LONG, rx_buffer);
_signing_temp_message[SHA_MSG_SIZE-2] = (sz >> 5);
_signing_temp_message[SHA_MSG_SIZE-1] = (sz << 3);
DEBUG_SIGNING_PRINTBUF(F("DTH:"), _signing_temp_message, SHA_MSG_SIZE); // DTH = Data to hash
(void)atsha204.sha204m_execute(SHA204_SHA, SHA_CALC, 0, SHA_MSG_SIZE, _signing_temp_message,
SHA_COUNT_LONG, _singning_tx_buffer, SHA_RSP_SIZE_LONG, _singning_rx_buffer);
// Put device back to sleep
atsha204.sha204c_sleep();
DEBUG_SIGNING_PRINTBUF(F("SHA:"), &rx_buffer[SHA204_BUFFER_POS_DATA], 32);
return &rx_buffer[SHA204_BUFFER_POS_DATA];
DEBUG_SIGNING_PRINTBUF(F("SHA:"), &_singning_rx_buffer[SHA204_BUFFER_POS_DATA], 32);
return &_singning_rx_buffer[SHA204_BUFFER_POS_DATA];
}
#endif // #if defined(ARDUINO_ARCH_AVR)
+4 -17
View File
@@ -33,27 +33,14 @@
#include "drivers/ATSHA204/ATSHA204.h"
#include <stdint.h>
#ifdef MY_SIGNING_NODE_WHITELISTING
typedef struct {
uint8_t nodeId;
uint8_t serial[SHA204_SERIAL_SZ];
} whitelist_entry_t;
#endif
// 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.
class MySigningAtsha204 : public MySigning
{
public:
MySigningAtsha204(bool requestSignatures=true,
bool getNonce(MyMessage &msg);
bool checkTimer(void);
bool putNonce(MyMessage &msg);
bool signMsg(MyMessage &msg);
bool verifyMsg(MyMessage &msg);
private:
};
void signerCalculateSignature(MyMessage &msg);
uint8_t* signerSha256(const uint8_t* data, size_t sz);
#endif
+5 -8
View File
@@ -59,24 +59,21 @@ static void DEBUG_NONE_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf, ui
#define DEBUG_NONE_PRINTBUF(str, buf, sz)
#endif
MySigningNone::MySigningNone() : MySigning() {
}
bool MySigningNone::getNonce(MyMessage &msg) {
bool signerGetNonce(MyMessage &msg) {
(void)msg;
return true;
}
bool MySigningNone::checkTimer() {
bool signerCheckTimer() {
return true;
}
bool MySigningNone::putNonce(MyMessage &msg) {
bool signerPutNonce(MyMessage &msg) {
(void)msg;
return true;
}
bool MySigningNone::signMsg(MyMessage &msg) {
bool signerSignMsg(MyMessage &msg) {
// If we cannot fit any signature in the message, refuse to sign it
if (mGetLength(msg) > MAX_PAYLOAD-2) {
DEBUG_SIGNING_PRINTLN(F("MTOL")); // Message too large for signature to fit
@@ -87,7 +84,7 @@ bool MySigningNone::signMsg(MyMessage &msg) {
return true;
}
bool MySigningNone::verifyMsg(MyMessage &msg) {
bool signerVerifyMsg(MyMessage &msg) {
if (msg.data[mGetLength(msg)] != SIGNING_IDENTIFIER)
return false;
else
-10
View File
@@ -37,15 +37,5 @@
// It does check SIGNING_IDENTIFIER byte to avoid illegal mixing of signing back-ends in
// the network (as seen by this node) and it does verify proper execution order on the API.
// The "none" driver rejects all other back-ends.
class MySigningNone : public MySigning
{
public:
MySigningNone();
bool getNonce(MyMessage &msg);
bool checkTimer(void);
bool putNonce(MyMessage &msg);
bool signMsg(MyMessage &msg);
bool verifyMsg(MyMessage &msg);
};
#endif
+1 -1
View File
@@ -300,7 +300,7 @@ inline void transportProcess() {
// Wait a random delay of 0-2 seconds to minimize collision
// between ping ack messages from other relaying nodes
wait(hwMillis() & 0x3ff);
sendWrite(sender, build(_msg, _nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_RESPONSE, false).set(_nc.distance));
transportSendWrite(sender, build(_msg, _nc.nodeId, sender, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_RESPONSE, false).set(_nc.distance));
}
}
} else if (to == _nc.nodeId) {
-1
View File
@@ -77,7 +77,6 @@ typedef struct {
#define AUTO 0xFF // 0-254. Id 255 is reserved for auto initialization of nodeId.
#define NODE_SENSOR_ID 0xFF // Node child id is always created for when a node
#define BROADCAST_ADDRESS ((uint8_t)0xFF)
@@ -24,7 +24,6 @@
#include "MyTransport.h"
#include <stdint.h>
#include "drivers/RFM69/RFM69.h"
#include "drivers/SPI/SPI.h"
#endif
+1 -1
View File
@@ -6,6 +6,6 @@
#ifndef Version_h
#define Version_h
#define LIBRARY_VERSION "1.5"
#define LIBRARY_VERSION "1.6"
#endif
@@ -19,10 +19,10 @@
extern "C"
{
#import "utility/uip-conf.h"
#import "utility/uip.h"
#import "utility/uip_arp.h"
#import "string.h"
#include "utility/uip-conf.h"
#include "utility/uip.h"
#include "utility/uip_arp.h"
#include "string.h"
}
#include "UIPEthernet.h"
#include "UIPClient.h"
@@ -22,11 +22,11 @@
#include "ethernet_comp.h"
#include "Print.h"
#import "Client.h"
#import "utility/mempool.h"
#include "Client.h"
#include "utility/mempool.h"
extern "C" {
#import "utility/uip.h"
#include "utility/uip.h"
}
#define UIP_SOCKET_DATALEN UIP_TCP_MSS
@@ -58,6 +58,7 @@ extern "C"
uip_ethaddr.addr[4] = eaddr[4];\
uip_ethaddr.addr[5] = eaddr[5];} while(0)
#undef BUF
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
class UIPEthernetClass
@@ -20,8 +20,8 @@
#define UIPSERVER_H
#include "ethernet_comp.h"
#import "Server.h"
#import "UIPClient.h"
#include "Server.h"
#include "UIPClient.h"
class UIPServer : public Server {
@@ -223,6 +223,7 @@ static u16_t tmp16;
/* Macros. */
#undef BUF
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
@@ -113,6 +113,7 @@ static u8_t i, c;
static u8_t arptime;
static u8_t tmpage;
#undef BUF
#define BUF ((struct arp_hdr *)&uip_buf[0])
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
/*-----------------------------------------------------------------------------------*/
+1 -1
View File
@@ -31,7 +31,7 @@
// **********************************************************************************
#include "RFM69.h"
#include "RFM69registers.h"
#include "drivers/SPI/SPI.h"
#include "drivers/AVR/SPI/SPI.h"
volatile byte RFM69::DATA[RF69_MAX_DATA_LEN];
volatile byte RFM69::_mode; // current transceiver state
@@ -34,9 +34,14 @@
*
*/
#include <SPI.h>
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
#include <MySensor.h>
#include <Wire.h>
#define CHILD_ID_MQ 0
/************************Hardware Related Macros************************************/
@@ -76,19 +81,16 @@ float SmokeCurve[3] ={2.3,0.53,-0.44}; //two points are taken from
//data format:{ x, y, slope}; point1: (lg200, 0.53), point2:(lg10000,-0.22)
MySensor gw;
MyMessage msg(CHILD_ID_MQ, V_LEVEL);
void setup()
{
gw.begin();
// Send the sketch version information to the gateway and Controller
gw.sendSketchInfo("Air Quality Sensor", "1.0");
sendSketchInfo("Air Quality Sensor", "1.0");
// Register all sensors to gateway (they will be created as child devices)
gw.present(CHILD_ID_MQ, S_AIR_QUALITY);
present(CHILD_ID_MQ, S_AIR_QUALITY);
Ro = MQCalibration(MQ_SENSOR_ANALOG_PIN); //Calibrating the sensor. Please make sure the sensor is in clean air
//when you perform the calibration
@@ -113,11 +115,11 @@ void loop()
Serial.print("\n");
if (valMQ != lastMQ) {
gw.send(msg.set((int)ceil(valMQ)));
send(msg.set((int)ceil(valMQ)));
lastMQ = ceil(valMQ);
}
gw.sleep(SLEEP_TIME); //sleep for: sleepTime
sleep(SLEEP_TIME); //sleep for: sleepTime
}
/****************** MQResistanceCalculation ****************************************
@@ -56,19 +56,16 @@
*
*/
// Enable debug prints to console
// Enable debug prints to serial monitor
#define MY_DEBUG
// This node has a NR24L01+ radio attached
#define MY_RADIO_NRF24
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
// Enable gateway type
// Enable gateway transportation type
#define MY_GATEWAY_W5100
//#define MY_GATEWAY_W5100
// Set default gateway protocol (http://www.mysensors.org/download/serial_api_15)
#define MY_GATEWAY_PROTOCOL_DEFAULT
//#define MY_GATEWAY_ENC28J60
// Enable Soft SPI for radio (note different radio wiring required)
// Useful for W5100 which sometimes have hard time co-operate with radio on the same spi bus.
@@ -27,51 +27,46 @@
* http://www.mysensors.org/build/relay
*/
#include <MySigningNone.h>
#include <MyTransportNRF24.h>
#include <MyTransportRFM69.h>
#include <MyHwATMega328.h>
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
// Enable repeater functionality for this node
#define MY_REPEATER_FEATURE
#include <MySensor.h>
#include <SPI.h>
#define RELAY_1 3 // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
#define NUMBER_OF_RELAYS 1 // Total number of attached relays
#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
// NRFRF24L01 radio driver (set low transmit power by default)
MyTransportNRF24 radio(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW);
//MyTransportRFM69 radio;
// Message signing driver (none default)
//MySigningNone signer;
// Select AtMega328 hardware profile
MyHwATMega328 hw;
// Construct MySensors library
MySensor gw(radio, hw);
void setup()
{
// Initialize library and add callback for incoming messages
gw.begin(incomingMessage, AUTO, true);
setIncomingCallback(incomingMessage);
// Send the sketch version information to the gateway and Controller
gw.sendSketchInfo("Relay", "1.0");
sendSketchInfo("Relay", "1.0");
// Fetch relay status
for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS;sensor++, pin++) {
// Register all sensors to gw (they will be created as child devices)
gw.present(sensor, S_LIGHT);
present(sensor, S_LIGHT);
// Then set relay pins in output mode
pinMode(pin, OUTPUT);
// Set relay to last known state (using eeprom storage)
digitalWrite(pin, gw.loadState(sensor)?RELAY_ON:RELAY_OFF);
digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
}
}
void loop()
{
// Alway process incoming messages whenever possible
gw.process();
}
void incomingMessage(const MyMessage &message) {
@@ -80,7 +75,7 @@ void incomingMessage(const MyMessage &message) {
// Change relay state
digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
// Store state in eeprom
gw.saveState(message.sensor, message.getBool());
saveState(message.sensor, message.getBool());
// Write some debug info
Serial.print("Incoming change for sensor:");
Serial.print(message.sensor);
@@ -26,7 +26,10 @@
* This example will remember lock state even after power failure.
*/
// Enable and select radio type
// Enable debug prints to serial monitor
#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
@@ -35,9 +38,9 @@
//#define MY_SIGNING_ATSHA204 // Hardware signing using ATSHA204A
// Enable node whitelisting
#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}}}
//#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}}}
// Enable this if you want destination node to sign all messages sent to this node. Default is not to require signing.
#define MY_SIGNING_REQUEST_SIGNATURES
//#define MY_SIGNING_REQUEST_SIGNATURES
// SETTINGS FOR MY_SIGNING_SOFT
@@ -51,7 +54,6 @@
// SETTINGS FOR MY_SIGNING_ATSHA204
#define MY_SIGNING_ATSHA204_PIN 17 // A3 - pin where ATSHA204 is attached
#include <MySensor.h>
@@ -1,4 +1,4 @@
/**
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
@@ -36,57 +36,44 @@
*
*/
#include <MySigningNone.h>
#include <MyTransportRFM69.h>
#include <MyTransportNRF24.h>
#include <MyHwATMega328.h>
#include <MySigningAtsha204Soft.h>
#include <MySigningAtsha204.h>
// Enable debug prints to serial monitor
#define MY_DEBUG
#include <SPI.h>
#include <MyGatewayTransportSerial.h>
#include <MyProtocolDefault.h>
#include <MyGateway.h>
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
#define INCLUSION_MODE_TIME 60 // Number of seconds inclusion mode is enabled
#define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button
#define RADIO_ERROR_LED_PIN 4 // Error led pin
#define RADIO_RX_LED_PIN 6 // Receive led pin
#define RADIO_TX_LED_PIN 5 // the PCB, on board LED
// Enable serial gateway
#define MY_GATEWAY_SERIAL
// NRFRF24L01 radio driver (set low transmit power by default)
MyTransportNRF24 transport(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW);
//MyTransportRFM69 transport;
// Flash leds on rx/tx/err
#define MY_LEDS_BLINKING_FEATURE
// Set blinking period
#define MY_DEFAULT_LED_BLINK_PERIOD 300
// Message signing driver (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h)
//MySigningNone signer;
//MySigningAtsha204Soft signer;
//MySigningAtsha204 signer;
// Enable inclusion mode
#define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
#define MY_INCLUSION_BUTTON_FEATURE
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
#define MY_INCLUSION_MODE_BUTTON_PIN 3
// Hardware profile
MyHwATMega328 hw;
#define MY_DEFAULT_ERR_LED_PIN 7 // Error led pin
#define MY_DEFAULT_RX_LED_PIN 8 // Receive led pin
#define MY_DEFAULT_TX_LED_PIN 9 // the PCB, on board LED
// Controller Transport profile
MyProtocolDefault protocol;
MyGatewayTransportSerial ctrlTransport(protocol);
// Construct MySensors library (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h)
// To use LEDs blinking, uncomment MY_LEDS_BLINKING_FEATURE in MyConfig.h
#ifdef MY_LEDS_BLINKING_FEATURE
MyGateway gw(ctrlTransport, transport, hw /*, signer*/, RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN);
#else
MyGateway gw(ctrlTransport, transport, hw /*, signer*/);
#endif
#include <MySensor.h>
void setup()
{
gw.begin(NULL);
// Nothing to do here
}
void loop()
{
gw.process();
// Nothing to do here
}