[security] Introducing signing support to MySensors
-
Regarding my issue with the ATSHA204A, I did some testing with the following results. I soldered the ATSHA204A on a small breakout board and loaded the SHAPersonalizer sketch.
I tested three configurations:
- Breakout wired to the ProMini without breadboard use
- Breakout wired to a breadboard where the ProMini was plugged
- Breakout and ProMini both plugged to breadboard and connected by wires.
Config 3 does not work!!!
That means the breadboard significantly changes the electrical characteristics. Is anybody on the forum who is able to explain that? -
@tomkxy: it is strange. My first tests have been done in you config 3 (atsha breakout and promini both plugged to breadboard). And it worked well for me. Could it be your wire quality??? I had problems with some Dupont wire once...
-
Well , could be... I had to use different wires female - female, male - female, male - male (for config 3). For the male-male wire I have no other option at the moment.
However, I am glad it works now.
@tomkxy said:
Well , could be... I had to use different wires female - female, male - female, male - male (for config 3). For the male-male wire I have no other option at the moment.
However, I am glad it works now.
Good news! Regarding breadboard issues, it could be that you need an additional decoupling on the VCC line to the atsha204a. And also perhaps a pullup on the SDA signal. Breadboards usually put some more requirements on noise suppression.
-
-
Here you go....However, I do not have EthernetGateway but a MQTTClientGateway. May be it is of help.
What is your specific problem?myconfig.h (key changed)
/** * 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 * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Copyright (C) 2013-2015 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. */ #ifndef MyConfig_h #define MyConfig_h #include <stdint.h> // Enable debug flag for debug prints. This will add a lot to the size of the final sketch but good // to see what is actually is happening when developing #define DEBUG // Serial output baud rate (for debug prints and serial gateway) #define BAUD_RATE 115200 /********************************** * Over the air firmware updates ***********************************/ // The following define enables the safe over-the-air firmware update feature // which requires external flash and the DualOptiBoot bootloader. // Note: You can still have OTA FW updates without external flash but it // requires the MYSBootloader and disabled MY_OTA_FIRMWARE_FEATURE //#define MY_OTA_FIRMWARE_FEATURE // Slave select pin for external flash #define MY_OTA_FLASH_SS 8 // Flash jdecid #define MY_OTA_FLASH_JDECID 0x1F65 /********************************** * Information LEDs blinking ***********************************/ // This feature enables LEDs blinking on message receive, transmit // or if some error occured. This was commonly used only in gateways, // but now can be used in any sensor node. Also the LEDs can now be // disabled in the gateway. //#define WITH_LEDS_BLINKING // The following setting allows you to inverse the blinking feature WITH_LEDS_BLINKING // When WITH_LEDS_BLINKING_INVERSE is enabled LEDSs are normally turned on and switches // off when blinking //#define WITH_LEDS_BLINKING_INVERSE // default LEDs blinking period in milliseconds #define DEFAULT_LED_BLINK_PERIOD 300 // The RX LED default pin #define DEFAULT_RX_LED_PIN 6 // The TX LED default pin #define DEFAULT_TX_LED_PIN 5 // The Error LED default pin #define DEFAULT_ERR_LED_PIN 4 /********************************** * Message Signing Settings ***********************************/ // Disable to completly disable signing functionality in library #define MY_SIGNING_FEATURE // 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 MY_VERIFICATION_TIMEOUT_MS 5000 // Enable to turn on whitelisting // When enabled, a signing node will salt the signature with it's unique signature and nodeId. // The verifying node will look up the sender in a local table of trusted nodes and // do the corresponding salting in order to verify the signature. // For this reason, if whitelisting is enabled on one of the nodes in a sign-verify pair, both // nodes have to implement whitelisting for this to work. // Note that a node can still transmit a non-salted message (i.e. have whitelisting disabled) // to a node that has whitelisting enabled (assuming the receiver does not have a matching entry // for the sender in it's whitelist) //#define MY_SECURE_NODE_WHITELISTING // MySigningAtsha204 default setting #define MY_ATSHA204_PIN 17 // A3 - pin where ATSHA204 is attached // MySigningAtsha204Soft default 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 MySigningAtsha204Soft (32 bytes) #define MY_HMAC_KEY 0x10,0x23,0xBB,0x78,0x77,0x35,0xB0,0x01,0x70,0x47,0xF1,0xDE,0x21,0x94,0x54,0x67,0xEE,0x36,0x72,0x00,0x97,0x12,0xA0,0x0A,0x0F,0x09,0x03,0xE2,0x00,0x31,0xE4,0x41 /********************************** * NRF24L01 Driver Defaults ***********************************/ #define RF24_CE_PIN 9 #define RF24_CS_PIN 10 #define RF24_PA_LEVEL RF24_PA_MAX #define RF24_PA_LEVEL_GW RF24_PA_LOW // RF channel for the sensor net, 0-127 #define RF24_CHANNEL 76 //RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps #define RF24_DATARATE RF24_250KBPS // This is also act as base value for sensor nodeId addresses. Change this (or channel) if you have more than one sensor network. #define RF24_BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL) // Enable SOFTSPI for NRF24L01 when using the W5100 Ethernet module //#define SOFTSPI #ifdef SOFTSPI // Define the soft SPI pins used for NRF radio const uint8_t SOFT_SPI_MISO_PIN = 16; const uint8_t SOFT_SPI_MOSI_PIN = 15; const uint8_t SOFT_SPI_SCK_PIN = 14; #endif /********************************** * RFM69 Driver Defaults ***********************************/ // Default network id. Use the same for all nodes that will talk to each other #define RFM69_NETWORKID 100 // Default frequency to use. This must match the hardware version of the RFM69 radio (uncomment one): // #define RFM69_FREQUENCY RF69_433MHZ #define RFM69_FREQUENCY RF69_868MHZ //#define FREQUENCY RF69_915MHZ // Enable this for encryption of packets //#define RFM69_ENABLE_ENCRYPTION #define RFM69_ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes! #endif/* MyMQTT Client Gateway 0.1b Created by Norbert Truchsess <norbert.truchsess@t-online.de> Based on MyMQTT-broker gateway created by Daniel Wiegert <daniel.wiegert@gmail.com> Based on MySensors Ethernet Gateway by Henrik Ekblad <henrik.ekblad@gmail.com> http://www.mysensors.org Requires MySensors lib 1.4b * Change below; TCP_IP, TCP_PORT, TCP_MAC This will listen on your selected TCP_IP:TCP_PORT below, Please change TCP_MAC your liking also. *1 -> NOTE: Keep first byte at x2, x6, xA or xE (replace x with any hex value) for using Local Ranges. *2 You can use standard pin set-up as MySensors recommends or if you own a IBOARD you may change the radio-pins below if you hardware mod your iBoard. see [URL BELOW] for more details. http://forum.mysensors.org/topic/224/iboard-cheap-single-board-ethernet-arduino-with-radio/5 * Don't forget to look at the definitions in libraries\MySensors\MyMQTT.h! define TCPDUMP and connect serial interface if you have problems, please write on http://forum.mysensors.org/ and explain your problem, include serial output. Don't forget to turn on DEBUG in libraries\MySensors\MyConfig.h also. MQTT_FIRST_SENSORID is for 'DHCP' server in MyMQTT. You may limit the ID's with FIRST and LAST definition. If you want your manually configured below 20 set MQTT_FIRST_SENSORID to 20. To disable: set MQTT_FIRST_SENSORID to 255. MQTT_BROKER_PREFIX is the leading prefix for your nodes. This can be only one char if like. MQTT_SEND_SUBSCRIPTION is if you want the MyMQTT to send a empty payload message to your nodes. This can be useful if you want to send latest state back to the MQTT client. Just check if incoming message has any length or not. Example: if (msg.type==V_LIGHT && strlen(msg.getString())>0) otherwise the code might do strange things. * Address-layout is : [MQTT_BROKER_PREFIX]/[NodeID]/[SensorID]/V_[SensorType] NodeID and SensorID is uint8 (0-255) number. Last segment is translation of the sensor type, look inside MyMQTT.cpp for the definitions. User can change this to their needs. We have also left some space for custom types. Special: (sensor 255 reserved for special commands) You can receive a node sketch name with MyMQTT/20/255/V_Sketch_name (or version with _version) To-do: Special commands : clear or set EEPROM Values, Send REBOOT and Receive reboot for MyMQTT itself. Be able to send ACK so client returns the data being sent. ... Please come with ideas! What to do with publish messages. Test in more MQTT clients, So far tested in openhab and MyMQTT for Android (Not my creation) - http://www.openhab.org/ - https://play.google.com/store/apps/details?id=at.tripwire.mqtt.client&hl=en ... Please notify me if you use this broker with other software. * How to set-up Openhab and MQTTGateway: http://forum.mysensors.org/topic/303/mqtt-broker-gateway Changes by Thomas Krebs <thkrebs@gmx.de> - Add signing support from MySensors 1.5 and update for MySensors 1.5; - Restructured code back to a C like implementation following the existing MQTTGateway */ #include <SPI.h> #include <MySensor.h> #include "MyMQTTClient.h" #include "PubSubClient.h" #include <Ethernet.h> #include <DigitalIO.h> #include <MsTimer2.h> #include <Time.h> #ifdef MY_SIGNING_FEATURE #include <MySigningNone.h> #include <MySigningAtsha204Soft.h> #include <MySigningAtsha204.h> #endif //#define DSRTC #ifdef DSRTC #include <Wire.h> #include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t #endif /* * To configure MQTTClientGateway.ino to use an ENC28J60 based board include * 'UIPEthernet.h' (SPI.h required for MySensors anyway). The UIPEthernet-library can be downloaded * from: https://github.com/ntruchsess/arduino_uip */ //#include <UIPEthernet.h> /* * To execute MQTTClientGateway.ino on Yun uncomment Bridge.h and YunClient.h. * Do not include Ethernet.h or SPI.h in this case. * On Yun there's no need to configure local_ip and mac in the sketch * as this is configured on the linux-side of Yun. */ //#include <Bridge.h> //#include <YunClient.h> // * Use this for IBOARD modded to use standard MISO/MOSI/SCK, see note *1 above! /* #define RADIO_CE_PIN 3 // radio chip enable #define RADIO_SPI_SS_PIN 8 // radio SPI serial select #define RADIO_ERROR_LED_PIN A2 // Error led pin #define RADIO_RX_LED_PIN A1 // Receive led pin #define RADIO_TX_LED_PIN A0 // the PCB, on board LED*/ // * Use this for default configured pro mini / nano etc : // //#define RADIO_CE_PIN 5 // radio chip enable //#define RADIO_SPI_SS_PIN 6 // radio SPI serial select //#define RADIO_ERROR_LED_PIN 7 // Error led pin //#define RADIO_RX_LED_PIN 8 // Receive led pin //#define RADIO_TX_LED_PIN 9 // the PCB, on board LED*/ // CE_PIN and SPI_SS_PIN for Mega #define RADIO_CE_PIN 48 // radio chip enable #define RADIO_SPI_SS_PIN 49 // radio SPI serial select #define RADIO_ERROR_LED_PIN A2 // Error led pin #define RADIO_RX_LED_PIN A1 // Receive led pin #define RADIO_TX_LED_PIN A0 // the PCB, on board LED*/ //replace with ip of server you want to connect to, comment out if using 'remote_host' uint8_t remote_ip[] = { 192, 168, 178, 74 }; // Mosquitto broker //replace with hostname of server you want to connect to, comment out if using 'remote_ip' //char* remote_ip = "server.local"; //replace with the port that your server is listening on #define remote_port 1883 //replace with arduinos ip-address. Comment out if Ethernet-startup should use dhcp. Is ignored on Yun uint8_t local_ip[] = {192, 168, 178, 11}; //replace with ethernet shield mac. It's mandatory every device is assigned a unique mac. Is ignored on Yun uint8_t mac[] = { 0xA2, 0xAE, 0xAD, 0xA0, 0xA0, 0xA2 }; ////////////////////////////////////////////////////////////////// #if defined remote_ip && defined remote_host #error "cannot define both remote_ip and remote_host at the same time!" #endif #ifdef _YUN_CLIENT_H_ YunClient ethClient; #else EthernetClient ethClient; #endif //////////////////////////////////////////////////////////////// // NRFRF24L01 radio driver (set low transmit power by default) MyTransportNRF24 transport(RADIO_CE_PIN, RADIO_SPI_SS_PIN, RF24_PA_LEVEL_GW); //MyTransportRFM69 transport; // Message signing driver (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h) //MySigningNone signer; MySigningAtsha204Soft signer; //MySigningAtsha204 signer; // Hardware profile MyHwATMega328 hw; MyMessage msg; char convBuf[MAX_PAYLOAD * 2 + 1]; uint8_t buffsize; char buffer[MQTT_MAX_PACKET_SIZE]; //////////////////////////////////////////////////////////////// volatile uint8_t countRx; volatile uint8_t countTx; volatile uint8_t countErr; //////////////////////////////////////////////////////////////// void processMQTTMessages(char* topic, byte* payload, unsigned int length); PubSubClient client(remote_ip, remote_port, processMQTTMessages, ethClient); //////////////////////////////////////////////////////////////// // Declare and initialize MySensor instance // Construct MyMQTTClient (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h, if signing // feature not to be used, uncomment) // To use LEDs blinking, uncomment WITH_LEDS_BLINKING in MyConfig.h MySensor gw(transport, hw #ifdef MY_SIGNING_FEATURE , signer #endif #ifdef WITH_LEDS_BLINKING , RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN #endif ); /* * setup */ void setup() { countRx = 0; countTx = 0; countErr = 0; Ethernet.begin(mac, local_ip); //Bridge.begin(); delay(1000); // Wait for Ethernet to get configured. begin(); } /* * loop */ void loop() { if (!client.connected()) { client.connect("MySensor"); client.subscribe(MQTT_TOPIC_MASK); } client.loop(); gw.process(); } /* * processRadioMessage * * Receives radio message, parses it and forwards it to the MQTT broker */ void processRadioMessage(const MyMessage &message) { rxBlink(1); sendMQTT(message); } /* * sendMQTT * Handles processing of radio messages and eventually publishes it to the MQTT broker */ void sendMQTT(const MyMessage &inMsg) { MyMessage msg = inMsg; buffsize = 0; if (!client.connected()) return; //We have no connections - return if (msg.isAck()) { #ifdef DEBUG Serial.println("msg is ack!"); #endif if (msg.sender == 255 && mGetCommand(msg) == C_INTERNAL && msg.type == I_ID_REQUEST) { // TODO: sending ACK request on id_response fucks node up. doesn't work. // The idea was to confirm id and save to EEPROM_LATEST_NODE_ADDRESS. } } else { // we have to check every message if its a newly assigned id or not. // Ack on I_ID_RESPONSE does not work, and checking on C_PRESENTATION isn't reliable. uint8_t newNodeID = gw.loadState(EEPROM_LATEST_NODE_ADDRESS) + 1; if (newNodeID <= MQTT_FIRST_SENSORID) newNodeID = MQTT_FIRST_SENSORID; if (msg.sender == newNodeID) { gw.saveState(EEPROM_LATEST_NODE_ADDRESS, newNodeID); } if (mGetCommand(msg) == C_INTERNAL) { if (msg.type == I_CONFIG) { txBlink(1); if (!gw.sendRoute( build(msg, GATEWAY_ADDRESS, msg.sender, 255, C_INTERNAL, I_CONFIG, 0).set("M"))) errBlink(1); } else if (msg.type == I_TIME) { #ifdef DEBUG Serial.println("I_TIME requested!"); #endif txBlink(1); if (!gw.sendRoute( build(msg, GATEWAY_ADDRESS, msg.sender, 255, C_INTERNAL, I_TIME, 0).set(now()))) errBlink(1); } else if (msg.type == I_ID_REQUEST && msg.sender == 255) { uint8_t newNodeID = gw.loadState(EEPROM_LATEST_NODE_ADDRESS) + 1; if (newNodeID <= MQTT_FIRST_SENSORID) newNodeID = MQTT_FIRST_SENSORID; if (newNodeID >= MQTT_LAST_SENSORID) return; // Sorry no more id's left :( txBlink(1); if (!gw.sendRoute( build(msg, GATEWAY_ADDRESS, msg.sender, 255, C_INTERNAL, I_ID_RESPONSE, 0).set(newNodeID))) errBlink(1); } else if (msg.type == I_BATTERY_LEVEL) { strcpy_P(buffer, mqtt_prefix); buffsize += strlen_P(mqtt_prefix); buffsize += sprintf(&buffer[buffsize], "/%i/255/BATTERY_LEVEL\0", msg.sender ); msg.getString(convBuf); #ifdef DEBUG Serial.print("publish: "); Serial.print((char*) buffer); Serial.print(" "); Serial.println((char*) convBuf); #endif client.publish(buffer, convBuf); } else if (msg.type == I_SKETCH_NAME) { strcpy_P(buffer, mqtt_prefix); buffsize += strlen_P(mqtt_prefix); buffsize += sprintf(&buffer[buffsize], "/%i/255/SKETCH_NAME\0", msg.sender ); msg.getString(convBuf); #ifdef DEBUG Serial.print("publish: "); Serial.print((char*) buffer); Serial.print(" "); Serial.println((char*) convBuf); #endif client.publish(buffer, convBuf); } else if (msg.type == I_SKETCH_VERSION) { strcpy_P(buffer, mqtt_prefix); buffsize += strlen_P(mqtt_prefix); buffsize += sprintf(&buffer[buffsize], "/%i/255/SKETCH_VERSION\0", msg.sender ); msg.getString(convBuf); #ifdef DEBUG Serial.print("publish: "); Serial.print((char*) buffer); Serial.print(" "); Serial.println((char*) convBuf); #endif client.publish(buffer, convBuf); } } else if (mGetCommand(msg) != 0) { if (mGetCommand(msg) == 3) msg.type = msg.type + (S_FIRSTCUSTOM - 10); //Special message if (msg.type > VAR_TOTAL) msg.type = VAR_TOTAL; // If type > defined types set to unknown. strcpy_P(buffer, mqtt_prefix); buffsize += strlen_P(mqtt_prefix); buffsize += sprintf(&buffer[buffsize], "/%i/%i/V_%s\0", msg.sender, msg.sensor, getType(convBuf, &VAR_Type[msg.type])); msg.getString(convBuf); #ifdef DEBUG Serial.print("publish: "); Serial.print((char*) buffer); Serial.print(" "); Serial.println((char*) convBuf); #endif client.publish(buffer, convBuf); } } } /* * build * Constructs a radio message */ inline MyMessage& build(MyMessage &msg, uint8_t sender, uint8_t destination, uint8_t sensor, uint8_t command, uint8_t type, bool enableAck) { msg.destination = destination; msg.sender = sender; msg.sensor = sensor; msg.type = type; mSetCommand(msg, command); mSetRequestAck(msg, enableAck); mSetAck(msg, false); return msg; } /* * getType */ char *getType(char *b, const char **index) { char *q = b; char *p = (char *) pgm_read_word(index); while (*q++ = pgm_read_byte(p++)) ; *q = 0; return b; } /* * begin * wraps MySensors begin method; setup of RTC and led timers interrupt */ void begin() { #ifdef DEBUG Serial.begin(BAUD_RATE); #endif #ifdef DSRTC // Attach RTC setSyncProvider(RTC.get); // the function to get the time from the RTC setSyncInterval(60); #endif gw.begin(processRadioMessage, 0, true, 0); MsTimer2::set(200, ledTimersInterrupt); MsTimer2::start(); #ifdef DEBUG Serial.print(getType(convBuf, &VAR_Type[S_FIRSTCUSTOM])); #endif } /* * processMQTTMessages * message handler for the PubSubClient */ void processMQTTMessages(char* topic, byte* payload, unsigned int length) { processMQTTMessage(topic, payload, length); } /* * processMQTTMessage * processes MQTT messages, parses the topic, extracts radio address out of topic and sends them * to the respective radio */ void processMQTTMessage(char* topic, byte* payload, unsigned int length) { char *str, *p; uint8_t i = 0; buffer[0] = 0; buffsize = 0; uint8_t cmd = -1; for (str = strtok_r(topic, "/", &p); str && i < 5; str = strtok_r(NULL, "/", &p)) { switch (i) { case 0: { if (strcmp_P(str, mqtt_prefix) != 0) { //look for MQTT_PREFIX return; //Message not for us or malformatted! } break; } case 1: { msg.destination = atoi(str); //NodeID break; } case 2: { msg.sensor = atoi(str); //SensorID break; } case 3: { char match = 0; //SensorType //strcpy(str,(char*)&str[2]); //Strip VAR_ for (uint8_t j = 0; strcpy_P(convBuf, (char*) pgm_read_word(&(VAR_Type[j]))); j++) { if (strcmp((char*) &str[2], convBuf) == 0) { //Strip VAR_ and compare match = j; break; } if (j >= VAR_TOTAL) { // No match found! match = VAR_TOTAL; // last item. break; } } msg.type = match; break; } case 4: { // support the command get and set; get will be mapped to a C_REQ and set to C_SET if (strcmp(str,MQTT_CMD_SET) == 0) { cmd = C_SET; } else if (strcmp(str,MQTT_CMD_GET) == 0) { cmd = C_REQ; } else { #ifdef DEBUG Serial.print("Received unsupported command - ignore: "); Serial.println(str); #endif } } } i++; } //Check if packge has payload if (cmd != -1) { char* ca; ca = (char *)payload; ca += length; *ca = '\0'; msg.set((const char*)payload); //Payload txBlink(1); // inject time if ((msg.destination == 0) && (msg.sensor == 199)) { unsigned long epoch = atol((char*)payload); if (epoch > 10000) { #ifdef DSRTC RTC.set(epoch); // this sets the RTC to the time from controller - which we do want periodically #endif setTime(epoch); } #ifdef DEBUG Serial.print("Time recieved "); Serial.println(epoch); #endif } // if (!gw.sendRoute( build(msg, GATEWAY_ADDRESS, msg.destination, msg.sensor, C_SET, msg.type, 0))) errBlink(1); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Led handling ////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * ledTimersIntterupt */ void ledTimersInterrupt() { if (countRx && countRx != 255) { // switch led on digitalWrite(RADIO_RX_LED_PIN, LOW); } else if (!countRx) { // switching off digitalWrite(RADIO_RX_LED_PIN, HIGH); } if (countRx != 255) { countRx--; } if (countTx && countTx != 255) { // switch led on digitalWrite(RADIO_TX_LED_PIN, LOW); } else if (!countTx) { // switching off digitalWrite(RADIO_TX_LED_PIN, HIGH); } if (countTx != 255) { countTx--; } if (countErr && countErr != 255) { // switch led on digitalWrite(RADIO_ERROR_LED_PIN, LOW); } else if (!countErr) { // switching off digitalWrite(RADIO_ERROR_LED_PIN, HIGH); } if (countErr != 255) { countErr--; } } void rxBlink(uint8_t cnt) { if (countRx == 255) { countRx = cnt; } } void txBlink(uint8_t cnt) { if (countTx == 255) { countTx = cnt; } } void errBlink(uint8_t cnt) { if (countErr == 255) { countErr = cnt; } } -
Here you go....However, I do not have EthernetGateway but a MQTTClientGateway. May be it is of help.
What is your specific problem?myconfig.h (key changed)
/** * 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 * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Copyright (C) 2013-2015 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. */ #ifndef MyConfig_h #define MyConfig_h #include <stdint.h> // Enable debug flag for debug prints. This will add a lot to the size of the final sketch but good // to see what is actually is happening when developing #define DEBUG // Serial output baud rate (for debug prints and serial gateway) #define BAUD_RATE 115200 /********************************** * Over the air firmware updates ***********************************/ // The following define enables the safe over-the-air firmware update feature // which requires external flash and the DualOptiBoot bootloader. // Note: You can still have OTA FW updates without external flash but it // requires the MYSBootloader and disabled MY_OTA_FIRMWARE_FEATURE //#define MY_OTA_FIRMWARE_FEATURE // Slave select pin for external flash #define MY_OTA_FLASH_SS 8 // Flash jdecid #define MY_OTA_FLASH_JDECID 0x1F65 /********************************** * Information LEDs blinking ***********************************/ // This feature enables LEDs blinking on message receive, transmit // or if some error occured. This was commonly used only in gateways, // but now can be used in any sensor node. Also the LEDs can now be // disabled in the gateway. //#define WITH_LEDS_BLINKING // The following setting allows you to inverse the blinking feature WITH_LEDS_BLINKING // When WITH_LEDS_BLINKING_INVERSE is enabled LEDSs are normally turned on and switches // off when blinking //#define WITH_LEDS_BLINKING_INVERSE // default LEDs blinking period in milliseconds #define DEFAULT_LED_BLINK_PERIOD 300 // The RX LED default pin #define DEFAULT_RX_LED_PIN 6 // The TX LED default pin #define DEFAULT_TX_LED_PIN 5 // The Error LED default pin #define DEFAULT_ERR_LED_PIN 4 /********************************** * Message Signing Settings ***********************************/ // Disable to completly disable signing functionality in library #define MY_SIGNING_FEATURE // 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 MY_VERIFICATION_TIMEOUT_MS 5000 // Enable to turn on whitelisting // When enabled, a signing node will salt the signature with it's unique signature and nodeId. // The verifying node will look up the sender in a local table of trusted nodes and // do the corresponding salting in order to verify the signature. // For this reason, if whitelisting is enabled on one of the nodes in a sign-verify pair, both // nodes have to implement whitelisting for this to work. // Note that a node can still transmit a non-salted message (i.e. have whitelisting disabled) // to a node that has whitelisting enabled (assuming the receiver does not have a matching entry // for the sender in it's whitelist) //#define MY_SECURE_NODE_WHITELISTING // MySigningAtsha204 default setting #define MY_ATSHA204_PIN 17 // A3 - pin where ATSHA204 is attached // MySigningAtsha204Soft default 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 MySigningAtsha204Soft (32 bytes) #define MY_HMAC_KEY 0x10,0x23,0xBB,0x78,0x77,0x35,0xB0,0x01,0x70,0x47,0xF1,0xDE,0x21,0x94,0x54,0x67,0xEE,0x36,0x72,0x00,0x97,0x12,0xA0,0x0A,0x0F,0x09,0x03,0xE2,0x00,0x31,0xE4,0x41 /********************************** * NRF24L01 Driver Defaults ***********************************/ #define RF24_CE_PIN 9 #define RF24_CS_PIN 10 #define RF24_PA_LEVEL RF24_PA_MAX #define RF24_PA_LEVEL_GW RF24_PA_LOW // RF channel for the sensor net, 0-127 #define RF24_CHANNEL 76 //RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps #define RF24_DATARATE RF24_250KBPS // This is also act as base value for sensor nodeId addresses. Change this (or channel) if you have more than one sensor network. #define RF24_BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL) // Enable SOFTSPI for NRF24L01 when using the W5100 Ethernet module //#define SOFTSPI #ifdef SOFTSPI // Define the soft SPI pins used for NRF radio const uint8_t SOFT_SPI_MISO_PIN = 16; const uint8_t SOFT_SPI_MOSI_PIN = 15; const uint8_t SOFT_SPI_SCK_PIN = 14; #endif /********************************** * RFM69 Driver Defaults ***********************************/ // Default network id. Use the same for all nodes that will talk to each other #define RFM69_NETWORKID 100 // Default frequency to use. This must match the hardware version of the RFM69 radio (uncomment one): // #define RFM69_FREQUENCY RF69_433MHZ #define RFM69_FREQUENCY RF69_868MHZ //#define FREQUENCY RF69_915MHZ // Enable this for encryption of packets //#define RFM69_ENABLE_ENCRYPTION #define RFM69_ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes! #endif/* MyMQTT Client Gateway 0.1b Created by Norbert Truchsess <norbert.truchsess@t-online.de> Based on MyMQTT-broker gateway created by Daniel Wiegert <daniel.wiegert@gmail.com> Based on MySensors Ethernet Gateway by Henrik Ekblad <henrik.ekblad@gmail.com> http://www.mysensors.org Requires MySensors lib 1.4b * Change below; TCP_IP, TCP_PORT, TCP_MAC This will listen on your selected TCP_IP:TCP_PORT below, Please change TCP_MAC your liking also. *1 -> NOTE: Keep first byte at x2, x6, xA or xE (replace x with any hex value) for using Local Ranges. *2 You can use standard pin set-up as MySensors recommends or if you own a IBOARD you may change the radio-pins below if you hardware mod your iBoard. see [URL BELOW] for more details. http://forum.mysensors.org/topic/224/iboard-cheap-single-board-ethernet-arduino-with-radio/5 * Don't forget to look at the definitions in libraries\MySensors\MyMQTT.h! define TCPDUMP and connect serial interface if you have problems, please write on http://forum.mysensors.org/ and explain your problem, include serial output. Don't forget to turn on DEBUG in libraries\MySensors\MyConfig.h also. MQTT_FIRST_SENSORID is for 'DHCP' server in MyMQTT. You may limit the ID's with FIRST and LAST definition. If you want your manually configured below 20 set MQTT_FIRST_SENSORID to 20. To disable: set MQTT_FIRST_SENSORID to 255. MQTT_BROKER_PREFIX is the leading prefix for your nodes. This can be only one char if like. MQTT_SEND_SUBSCRIPTION is if you want the MyMQTT to send a empty payload message to your nodes. This can be useful if you want to send latest state back to the MQTT client. Just check if incoming message has any length or not. Example: if (msg.type==V_LIGHT && strlen(msg.getString())>0) otherwise the code might do strange things. * Address-layout is : [MQTT_BROKER_PREFIX]/[NodeID]/[SensorID]/V_[SensorType] NodeID and SensorID is uint8 (0-255) number. Last segment is translation of the sensor type, look inside MyMQTT.cpp for the definitions. User can change this to their needs. We have also left some space for custom types. Special: (sensor 255 reserved for special commands) You can receive a node sketch name with MyMQTT/20/255/V_Sketch_name (or version with _version) To-do: Special commands : clear or set EEPROM Values, Send REBOOT and Receive reboot for MyMQTT itself. Be able to send ACK so client returns the data being sent. ... Please come with ideas! What to do with publish messages. Test in more MQTT clients, So far tested in openhab and MyMQTT for Android (Not my creation) - http://www.openhab.org/ - https://play.google.com/store/apps/details?id=at.tripwire.mqtt.client&hl=en ... Please notify me if you use this broker with other software. * How to set-up Openhab and MQTTGateway: http://forum.mysensors.org/topic/303/mqtt-broker-gateway Changes by Thomas Krebs <thkrebs@gmx.de> - Add signing support from MySensors 1.5 and update for MySensors 1.5; - Restructured code back to a C like implementation following the existing MQTTGateway */ #include <SPI.h> #include <MySensor.h> #include "MyMQTTClient.h" #include "PubSubClient.h" #include <Ethernet.h> #include <DigitalIO.h> #include <MsTimer2.h> #include <Time.h> #ifdef MY_SIGNING_FEATURE #include <MySigningNone.h> #include <MySigningAtsha204Soft.h> #include <MySigningAtsha204.h> #endif //#define DSRTC #ifdef DSRTC #include <Wire.h> #include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t #endif /* * To configure MQTTClientGateway.ino to use an ENC28J60 based board include * 'UIPEthernet.h' (SPI.h required for MySensors anyway). The UIPEthernet-library can be downloaded * from: https://github.com/ntruchsess/arduino_uip */ //#include <UIPEthernet.h> /* * To execute MQTTClientGateway.ino on Yun uncomment Bridge.h and YunClient.h. * Do not include Ethernet.h or SPI.h in this case. * On Yun there's no need to configure local_ip and mac in the sketch * as this is configured on the linux-side of Yun. */ //#include <Bridge.h> //#include <YunClient.h> // * Use this for IBOARD modded to use standard MISO/MOSI/SCK, see note *1 above! /* #define RADIO_CE_PIN 3 // radio chip enable #define RADIO_SPI_SS_PIN 8 // radio SPI serial select #define RADIO_ERROR_LED_PIN A2 // Error led pin #define RADIO_RX_LED_PIN A1 // Receive led pin #define RADIO_TX_LED_PIN A0 // the PCB, on board LED*/ // * Use this for default configured pro mini / nano etc : // //#define RADIO_CE_PIN 5 // radio chip enable //#define RADIO_SPI_SS_PIN 6 // radio SPI serial select //#define RADIO_ERROR_LED_PIN 7 // Error led pin //#define RADIO_RX_LED_PIN 8 // Receive led pin //#define RADIO_TX_LED_PIN 9 // the PCB, on board LED*/ // CE_PIN and SPI_SS_PIN for Mega #define RADIO_CE_PIN 48 // radio chip enable #define RADIO_SPI_SS_PIN 49 // radio SPI serial select #define RADIO_ERROR_LED_PIN A2 // Error led pin #define RADIO_RX_LED_PIN A1 // Receive led pin #define RADIO_TX_LED_PIN A0 // the PCB, on board LED*/ //replace with ip of server you want to connect to, comment out if using 'remote_host' uint8_t remote_ip[] = { 192, 168, 178, 74 }; // Mosquitto broker //replace with hostname of server you want to connect to, comment out if using 'remote_ip' //char* remote_ip = "server.local"; //replace with the port that your server is listening on #define remote_port 1883 //replace with arduinos ip-address. Comment out if Ethernet-startup should use dhcp. Is ignored on Yun uint8_t local_ip[] = {192, 168, 178, 11}; //replace with ethernet shield mac. It's mandatory every device is assigned a unique mac. Is ignored on Yun uint8_t mac[] = { 0xA2, 0xAE, 0xAD, 0xA0, 0xA0, 0xA2 }; ////////////////////////////////////////////////////////////////// #if defined remote_ip && defined remote_host #error "cannot define both remote_ip and remote_host at the same time!" #endif #ifdef _YUN_CLIENT_H_ YunClient ethClient; #else EthernetClient ethClient; #endif //////////////////////////////////////////////////////////////// // NRFRF24L01 radio driver (set low transmit power by default) MyTransportNRF24 transport(RADIO_CE_PIN, RADIO_SPI_SS_PIN, RF24_PA_LEVEL_GW); //MyTransportRFM69 transport; // Message signing driver (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h) //MySigningNone signer; MySigningAtsha204Soft signer; //MySigningAtsha204 signer; // Hardware profile MyHwATMega328 hw; MyMessage msg; char convBuf[MAX_PAYLOAD * 2 + 1]; uint8_t buffsize; char buffer[MQTT_MAX_PACKET_SIZE]; //////////////////////////////////////////////////////////////// volatile uint8_t countRx; volatile uint8_t countTx; volatile uint8_t countErr; //////////////////////////////////////////////////////////////// void processMQTTMessages(char* topic, byte* payload, unsigned int length); PubSubClient client(remote_ip, remote_port, processMQTTMessages, ethClient); //////////////////////////////////////////////////////////////// // Declare and initialize MySensor instance // Construct MyMQTTClient (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h, if signing // feature not to be used, uncomment) // To use LEDs blinking, uncomment WITH_LEDS_BLINKING in MyConfig.h MySensor gw(transport, hw #ifdef MY_SIGNING_FEATURE , signer #endif #ifdef WITH_LEDS_BLINKING , RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN #endif ); /* * setup */ void setup() { countRx = 0; countTx = 0; countErr = 0; Ethernet.begin(mac, local_ip); //Bridge.begin(); delay(1000); // Wait for Ethernet to get configured. begin(); } /* * loop */ void loop() { if (!client.connected()) { client.connect("MySensor"); client.subscribe(MQTT_TOPIC_MASK); } client.loop(); gw.process(); } /* * processRadioMessage * * Receives radio message, parses it and forwards it to the MQTT broker */ void processRadioMessage(const MyMessage &message) { rxBlink(1); sendMQTT(message); } /* * sendMQTT * Handles processing of radio messages and eventually publishes it to the MQTT broker */ void sendMQTT(const MyMessage &inMsg) { MyMessage msg = inMsg; buffsize = 0; if (!client.connected()) return; //We have no connections - return if (msg.isAck()) { #ifdef DEBUG Serial.println("msg is ack!"); #endif if (msg.sender == 255 && mGetCommand(msg) == C_INTERNAL && msg.type == I_ID_REQUEST) { // TODO: sending ACK request on id_response fucks node up. doesn't work. // The idea was to confirm id and save to EEPROM_LATEST_NODE_ADDRESS. } } else { // we have to check every message if its a newly assigned id or not. // Ack on I_ID_RESPONSE does not work, and checking on C_PRESENTATION isn't reliable. uint8_t newNodeID = gw.loadState(EEPROM_LATEST_NODE_ADDRESS) + 1; if (newNodeID <= MQTT_FIRST_SENSORID) newNodeID = MQTT_FIRST_SENSORID; if (msg.sender == newNodeID) { gw.saveState(EEPROM_LATEST_NODE_ADDRESS, newNodeID); } if (mGetCommand(msg) == C_INTERNAL) { if (msg.type == I_CONFIG) { txBlink(1); if (!gw.sendRoute( build(msg, GATEWAY_ADDRESS, msg.sender, 255, C_INTERNAL, I_CONFIG, 0).set("M"))) errBlink(1); } else if (msg.type == I_TIME) { #ifdef DEBUG Serial.println("I_TIME requested!"); #endif txBlink(1); if (!gw.sendRoute( build(msg, GATEWAY_ADDRESS, msg.sender, 255, C_INTERNAL, I_TIME, 0).set(now()))) errBlink(1); } else if (msg.type == I_ID_REQUEST && msg.sender == 255) { uint8_t newNodeID = gw.loadState(EEPROM_LATEST_NODE_ADDRESS) + 1; if (newNodeID <= MQTT_FIRST_SENSORID) newNodeID = MQTT_FIRST_SENSORID; if (newNodeID >= MQTT_LAST_SENSORID) return; // Sorry no more id's left :( txBlink(1); if (!gw.sendRoute( build(msg, GATEWAY_ADDRESS, msg.sender, 255, C_INTERNAL, I_ID_RESPONSE, 0).set(newNodeID))) errBlink(1); } else if (msg.type == I_BATTERY_LEVEL) { strcpy_P(buffer, mqtt_prefix); buffsize += strlen_P(mqtt_prefix); buffsize += sprintf(&buffer[buffsize], "/%i/255/BATTERY_LEVEL\0", msg.sender ); msg.getString(convBuf); #ifdef DEBUG Serial.print("publish: "); Serial.print((char*) buffer); Serial.print(" "); Serial.println((char*) convBuf); #endif client.publish(buffer, convBuf); } else if (msg.type == I_SKETCH_NAME) { strcpy_P(buffer, mqtt_prefix); buffsize += strlen_P(mqtt_prefix); buffsize += sprintf(&buffer[buffsize], "/%i/255/SKETCH_NAME\0", msg.sender ); msg.getString(convBuf); #ifdef DEBUG Serial.print("publish: "); Serial.print((char*) buffer); Serial.print(" "); Serial.println((char*) convBuf); #endif client.publish(buffer, convBuf); } else if (msg.type == I_SKETCH_VERSION) { strcpy_P(buffer, mqtt_prefix); buffsize += strlen_P(mqtt_prefix); buffsize += sprintf(&buffer[buffsize], "/%i/255/SKETCH_VERSION\0", msg.sender ); msg.getString(convBuf); #ifdef DEBUG Serial.print("publish: "); Serial.print((char*) buffer); Serial.print(" "); Serial.println((char*) convBuf); #endif client.publish(buffer, convBuf); } } else if (mGetCommand(msg) != 0) { if (mGetCommand(msg) == 3) msg.type = msg.type + (S_FIRSTCUSTOM - 10); //Special message if (msg.type > VAR_TOTAL) msg.type = VAR_TOTAL; // If type > defined types set to unknown. strcpy_P(buffer, mqtt_prefix); buffsize += strlen_P(mqtt_prefix); buffsize += sprintf(&buffer[buffsize], "/%i/%i/V_%s\0", msg.sender, msg.sensor, getType(convBuf, &VAR_Type[msg.type])); msg.getString(convBuf); #ifdef DEBUG Serial.print("publish: "); Serial.print((char*) buffer); Serial.print(" "); Serial.println((char*) convBuf); #endif client.publish(buffer, convBuf); } } } /* * build * Constructs a radio message */ inline MyMessage& build(MyMessage &msg, uint8_t sender, uint8_t destination, uint8_t sensor, uint8_t command, uint8_t type, bool enableAck) { msg.destination = destination; msg.sender = sender; msg.sensor = sensor; msg.type = type; mSetCommand(msg, command); mSetRequestAck(msg, enableAck); mSetAck(msg, false); return msg; } /* * getType */ char *getType(char *b, const char **index) { char *q = b; char *p = (char *) pgm_read_word(index); while (*q++ = pgm_read_byte(p++)) ; *q = 0; return b; } /* * begin * wraps MySensors begin method; setup of RTC and led timers interrupt */ void begin() { #ifdef DEBUG Serial.begin(BAUD_RATE); #endif #ifdef DSRTC // Attach RTC setSyncProvider(RTC.get); // the function to get the time from the RTC setSyncInterval(60); #endif gw.begin(processRadioMessage, 0, true, 0); MsTimer2::set(200, ledTimersInterrupt); MsTimer2::start(); #ifdef DEBUG Serial.print(getType(convBuf, &VAR_Type[S_FIRSTCUSTOM])); #endif } /* * processMQTTMessages * message handler for the PubSubClient */ void processMQTTMessages(char* topic, byte* payload, unsigned int length) { processMQTTMessage(topic, payload, length); } /* * processMQTTMessage * processes MQTT messages, parses the topic, extracts radio address out of topic and sends them * to the respective radio */ void processMQTTMessage(char* topic, byte* payload, unsigned int length) { char *str, *p; uint8_t i = 0; buffer[0] = 0; buffsize = 0; uint8_t cmd = -1; for (str = strtok_r(topic, "/", &p); str && i < 5; str = strtok_r(NULL, "/", &p)) { switch (i) { case 0: { if (strcmp_P(str, mqtt_prefix) != 0) { //look for MQTT_PREFIX return; //Message not for us or malformatted! } break; } case 1: { msg.destination = atoi(str); //NodeID break; } case 2: { msg.sensor = atoi(str); //SensorID break; } case 3: { char match = 0; //SensorType //strcpy(str,(char*)&str[2]); //Strip VAR_ for (uint8_t j = 0; strcpy_P(convBuf, (char*) pgm_read_word(&(VAR_Type[j]))); j++) { if (strcmp((char*) &str[2], convBuf) == 0) { //Strip VAR_ and compare match = j; break; } if (j >= VAR_TOTAL) { // No match found! match = VAR_TOTAL; // last item. break; } } msg.type = match; break; } case 4: { // support the command get and set; get will be mapped to a C_REQ and set to C_SET if (strcmp(str,MQTT_CMD_SET) == 0) { cmd = C_SET; } else if (strcmp(str,MQTT_CMD_GET) == 0) { cmd = C_REQ; } else { #ifdef DEBUG Serial.print("Received unsupported command - ignore: "); Serial.println(str); #endif } } } i++; } //Check if packge has payload if (cmd != -1) { char* ca; ca = (char *)payload; ca += length; *ca = '\0'; msg.set((const char*)payload); //Payload txBlink(1); // inject time if ((msg.destination == 0) && (msg.sensor == 199)) { unsigned long epoch = atol((char*)payload); if (epoch > 10000) { #ifdef DSRTC RTC.set(epoch); // this sets the RTC to the time from controller - which we do want periodically #endif setTime(epoch); } #ifdef DEBUG Serial.print("Time recieved "); Serial.println(epoch); #endif } // if (!gw.sendRoute( build(msg, GATEWAY_ADDRESS, msg.destination, msg.sensor, C_SET, msg.type, 0))) errBlink(1); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Led handling ////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * ledTimersIntterupt */ void ledTimersInterrupt() { if (countRx && countRx != 255) { // switch led on digitalWrite(RADIO_RX_LED_PIN, LOW); } else if (!countRx) { // switching off digitalWrite(RADIO_RX_LED_PIN, HIGH); } if (countRx != 255) { countRx--; } if (countTx && countTx != 255) { // switch led on digitalWrite(RADIO_TX_LED_PIN, LOW); } else if (!countTx) { // switching off digitalWrite(RADIO_TX_LED_PIN, HIGH); } if (countTx != 255) { countTx--; } if (countErr && countErr != 255) { // switch led on digitalWrite(RADIO_ERROR_LED_PIN, LOW); } else if (!countErr) { // switching off digitalWrite(RADIO_ERROR_LED_PIN, HIGH); } if (countErr != 255) { countErr--; } } void rxBlink(uint8_t cnt) { if (countRx == 255) { countRx = cnt; } } void txBlink(uint8_t cnt) { if (countTx == 255) { countTx = cnt; } } void errBlink(uint8_t cnt) { if (countErr == 255) { countErr = cnt; } }@tomkxy Thanks, that helped! I seemed to have two problems:
- I did not know where to place the necessary includes! Thanks for the examples! Helped me a lot
2)Regarding my problems from above (error: 'DEFAULT_CE_PIN' was not declared in this scope): I removed the whole libraries/MySensors dir and copied it again from the recent devel branch - this helped, error is gone and everything is compiling fine now :-)
Thanks again and cheers,
Otto
-
@tomkxy Thanks, that helped! I seemed to have two problems:
- I did not know where to place the necessary includes! Thanks for the examples! Helped me a lot
2)Regarding my problems from above (error: 'DEFAULT_CE_PIN' was not declared in this scope): I removed the whole libraries/MySensors dir and copied it again from the recent devel branch - this helped, error is gone and everything is compiling fine now :-)
Thanks again and cheers,
Otto
-
Hi again,
and thanks again. signing seems to work now, unfortunately the sketch is too big for an UNO and I am right now struggling with the pinout and code adaptions to get it working with my W5100 shield and a mega...
/edit: got it working.MyConfig.h: #ifdef SOFTSPI // Define the soft SPI pins used for NRF radio //MEGA const uint8_t SOFT_SPI_MISO_PIN = 15; const uint8_t SOFT_SPI_MOSI_PIN = 14; const uint8_t SOFT_SPI_SCK_PIN = 16; #endif EthernetGateway.ino: #define RADIO_CE_PIN 35 // 5 // radio chip enable #define RADIO_SPI_SS_PIN 34 // 6 // radio SPI serial selectAnd exactly those pins I connected from radio to the mega... (just in case that anyone else is in need of this)
Might be a little OT, but maybe someone here knows a solution for a strange problem:
Whenever I am using an UNO or MEGA with my W5100 shield, I have to reset after every power-on to make the sketch run. Does anyone know this? Is there a solution? I am trying to adapt optiboot to wait additional 500ms when powering on, but no luck so far...Cheers,
Otto
-
Hi again,
and thanks again. signing seems to work now, unfortunately the sketch is too big for an UNO and I am right now struggling with the pinout and code adaptions to get it working with my W5100 shield and a mega...
/edit: got it working.MyConfig.h: #ifdef SOFTSPI // Define the soft SPI pins used for NRF radio //MEGA const uint8_t SOFT_SPI_MISO_PIN = 15; const uint8_t SOFT_SPI_MOSI_PIN = 14; const uint8_t SOFT_SPI_SCK_PIN = 16; #endif EthernetGateway.ino: #define RADIO_CE_PIN 35 // 5 // radio chip enable #define RADIO_SPI_SS_PIN 34 // 6 // radio SPI serial selectAnd exactly those pins I connected from radio to the mega... (just in case that anyone else is in need of this)
Might be a little OT, but maybe someone here knows a solution for a strange problem:
Whenever I am using an UNO or MEGA with my W5100 shield, I have to reset after every power-on to make the sketch run. Does anyone know this? Is there a solution? I am trying to adapt optiboot to wait additional 500ms when powering on, but no luck so far...Cheers,
Otto
@otto001 said:
Might be a little OT, but maybe someone here knows a solution for a strange problem:
Whenever I am using an UNO or MEGA with my W5100 shield, I have to reset after every power-on to make the sketch run. Does anyone know this? Is there a solution? I am trying to adapt optiboot to wait additional 500ms when powering on, but no luck so far...Check here: https://www.sparkfun.com/products/11166 Their "version 2" shield has some notes about fixing the power up reset problem with regular internet shields. Not sure what it is but maybe their notes and schematic can clue you in to a help you implement a fix on your current board.
-
@TD22057 said:
@otto001 said:
Might be a little OT, but maybe someone here knows a solution for a strange problem:
Whenever I am using an UNO or MEGA with my W5100 shield, I have to reset after every power-on to make the sketch run. Does anyone know this? Is there a solution? I am trying to adapt optiboot to wait additional 500ms when powering on, but no luck so far...Check here: https://www.sparkfun.com/products/11166 Their "version 2" shield has some notes about fixing the power up reset problem with regular internet shields. Not sure what it is but maybe their notes and schematic can clue you in to a help you implement a fix on your current board.
And is the explanation of the fix that needs to be made:
http://www.hobbyist.co.nz/?q=ethernet-shield-w5100
http://forum.arduino.cc/index.php?topic=215798.msg1607035#msg1607035FYI I just ordered a Mega myself for a gateway since I figured the $7 to get one is a better expenditure of my time/money than me trying to get the MqttClientGateway + signing + RF69 radio + debug print to all fit on an Uno so I'll be doing this mod as well.
-
@Anticimex
I think I may have found a bug in the code:
I wanted to build a gateway that accepts both signed and unsigned messages. For this I usedMySigningAtsha204Soft signer(false);.
Now the gateway did accept unsigned messages, but also all messages sent to the gateway by another node with signing where unsigned.
After changing this line in MySensor.cpp:if (signer.requestSignatures() && DO_SIGN(msg.sender))to
if (signer.requestSignatures() || DO_SIGN(msg.sender))it worked as I wanted it. The gateway accepts unsigned messages from nodes but if a node expects signed messages, the messages to the gateway are also signed.
This line means that the gateway requests signing from the node if he always requests signing or if the node requests signing.
What do you think? -
@Anticimex
I think I may have found a bug in the code:
I wanted to build a gateway that accepts both signed and unsigned messages. For this I usedMySigningAtsha204Soft signer(false);.
Now the gateway did accept unsigned messages, but also all messages sent to the gateway by another node with signing where unsigned.
After changing this line in MySensor.cpp:if (signer.requestSignatures() && DO_SIGN(msg.sender))to
if (signer.requestSignatures() || DO_SIGN(msg.sender))it worked as I wanted it. The gateway accepts unsigned messages from nodes but if a node expects signed messages, the messages to the gateway are also signed.
This line means that the gateway requests signing from the node if he always requests signing or if the node requests signing.
What do you think?@fleinze I am not sure I understand the basic problem. What do you mean by " but also all messages sent to the gateway by another node with signing where unsigned.". The signing is based on requirement. A node (or gateway) either require messages sent to it to be signed or not. You have told your gateway that it is not supposed to require signed messages so it will accept unsigned messages sent to it. It is up to the node to configure if the node require signed messages in return. The gateway configuration has nothing to do with the preferences of a node. If you tell your gateway that it does not require signing, no messages to it will be signed. The opposite also holds true. If you configure it to require signed messages, all messages have to be signed. That is "working as designed".
-
@Anticimex
I think I may have found a bug in the code:
I wanted to build a gateway that accepts both signed and unsigned messages. For this I usedMySigningAtsha204Soft signer(false);.
Now the gateway did accept unsigned messages, but also all messages sent to the gateway by another node with signing where unsigned.
After changing this line in MySensor.cpp:if (signer.requestSignatures() && DO_SIGN(msg.sender))to
if (signer.requestSignatures() || DO_SIGN(msg.sender))it worked as I wanted it. The gateway accepts unsigned messages from nodes but if a node expects signed messages, the messages to the gateway are also signed.
This line means that the gateway requests signing from the node if he always requests signing or if the node requests signing.
What do you think?@fleinze after reading the post a few times I think I understand better :) you want nodes who require signed messages from the gateway to send signed messages to the gateway as well even though the gateway is configured to not require it. I don't have a problem with that change as long as it is also portable to the nodes (the same code works equally well for both gateways and nodes usecases). You are welcome to put a pull request on the code so I can have a closer look. If approved I will update the head post to reflect this changed behaviour.
-
@fleinze I am quite stressed out for the moment so I forget my own design :)
What you actually should do is to configure the gateway to require signed messages. It will then do so, but only from nodes that in turn require signed messages. So you should not need to change anything, just set the GW to require signatures. -
@Anticimex If I do so, this is the output of the Gateway:
0;0;3;0;9;gateway started, id=0, parent=0, distance=0 0;0;3;0;14;Gateway startup complete. 0;0;3;0;9;no sign 0;0;3;0;9;no sign 0;0;3;0;9;no sign 0;0;3;0;9;no sign 0;0;3;0;9;read: 2-2-0 s=0,c=0,t=6,pt=0,l=0,sg=0: 2;0;0;0;6; 0;0;3;0;9;read: 2-2-0 s=1,c=0,t=30,pt=0,l=0,sg=0: 2;1;0;0;30; 0;0;3;0;9;no sign 0;0;3;0;9;no sign 0;0;3;0;9;no signI tried to compile the node with deactivated signing feature and also with
MySigningNone.
The messages get rejected because in MySensor.cpp line 570 (developement branch) it is not checked if the sender requires signing:if (signer.requestSignatures() && msg.destination == nc.nodeId && mGetLength(msg) && !mGetAck(msg) && (mGetCommand(msg) != C_INTERNAL || (msg.type != I_GET_NONCE_RESPONSE && msg.type != I_GET_NONCE && msg.type != I_REQUEST_SIGNING && msg.type != I_ID_REQUEST && msg.type != I_ID_RESPONSE && msg.type != I_FIND_PARENT && msg.type != I_FIND_PARENT_RESPONSE)))My thought is that if I have a mixed network (signing and non-signing nodes) for some sensors I do not need signing (i.e. temperature-sensors). But if I have a button sensor that can actually switch something on or off (via the controller), it would be a security benefit if the messages from the sensor to the gateway are signed.
-
@Anticimex If I do so, this is the output of the Gateway:
0;0;3;0;9;gateway started, id=0, parent=0, distance=0 0;0;3;0;14;Gateway startup complete. 0;0;3;0;9;no sign 0;0;3;0;9;no sign 0;0;3;0;9;no sign 0;0;3;0;9;no sign 0;0;3;0;9;read: 2-2-0 s=0,c=0,t=6,pt=0,l=0,sg=0: 2;0;0;0;6; 0;0;3;0;9;read: 2-2-0 s=1,c=0,t=30,pt=0,l=0,sg=0: 2;1;0;0;30; 0;0;3;0;9;no sign 0;0;3;0;9;no sign 0;0;3;0;9;no signI tried to compile the node with deactivated signing feature and also with
MySigningNone.
The messages get rejected because in MySensor.cpp line 570 (developement branch) it is not checked if the sender requires signing:if (signer.requestSignatures() && msg.destination == nc.nodeId && mGetLength(msg) && !mGetAck(msg) && (mGetCommand(msg) != C_INTERNAL || (msg.type != I_GET_NONCE_RESPONSE && msg.type != I_GET_NONCE && msg.type != I_REQUEST_SIGNING && msg.type != I_ID_REQUEST && msg.type != I_ID_RESPONSE && msg.type != I_FIND_PARENT && msg.type != I_FIND_PARENT_RESPONSE)))My thought is that if I have a mixed network (signing and non-signing nodes) for some sensors I do not need signing (i.e. temperature-sensors). But if I have a button sensor that can actually switch something on or off (via the controller), it would be a security benefit if the messages from the sensor to the gateway are signed.
@fleinze If you have upgraded the library version, the signing table might have shifted in EEPROM. You then need to run the clear EEPROM sketch to reset the stored state in order for the gw/nodes to re-learn the existing signing preferences of the network.
-
@Anticimex If I do so, this is the output of the Gateway:
0;0;3;0;9;gateway started, id=0, parent=0, distance=0 0;0;3;0;14;Gateway startup complete. 0;0;3;0;9;no sign 0;0;3;0;9;no sign 0;0;3;0;9;no sign 0;0;3;0;9;no sign 0;0;3;0;9;read: 2-2-0 s=0,c=0,t=6,pt=0,l=0,sg=0: 2;0;0;0;6; 0;0;3;0;9;read: 2-2-0 s=1,c=0,t=30,pt=0,l=0,sg=0: 2;1;0;0;30; 0;0;3;0;9;no sign 0;0;3;0;9;no sign 0;0;3;0;9;no signI tried to compile the node with deactivated signing feature and also with
MySigningNone.
The messages get rejected because in MySensor.cpp line 570 (developement branch) it is not checked if the sender requires signing:if (signer.requestSignatures() && msg.destination == nc.nodeId && mGetLength(msg) && !mGetAck(msg) && (mGetCommand(msg) != C_INTERNAL || (msg.type != I_GET_NONCE_RESPONSE && msg.type != I_GET_NONCE && msg.type != I_REQUEST_SIGNING && msg.type != I_ID_REQUEST && msg.type != I_ID_RESPONSE && msg.type != I_FIND_PARENT && msg.type != I_FIND_PARENT_RESPONSE)))My thought is that if I have a mixed network (signing and non-signing nodes) for some sensors I do not need signing (i.e. temperature-sensors). But if I have a button sensor that can actually switch something on or off (via the controller), it would be a security benefit if the messages from the sensor to the gateway are signed.
@fleinze said:
My thought is that if I have a mixed network (signing and non-signing nodes) for some sensors I do not need signing (i.e. temperature-sensors). But if I have a button sensor that can actually switch something on or off (via the controller), it would be a security benefit if the messages from the sensor to the gateway are signed.
This is the exact usecase for the gw default behavior to only require signing from nodes that require signing in return. But I also got "no sign" errors after I flashed development branch yesterday on node/gw and only after I wiped the GW EEPROM I got it back online. So please try that. If it still does not work, I have to look closer, and see why this has broken because it has been working like that when I submitted the signing behavior.