Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. [security] Introducing signing support to MySensors

[security] Introducing signing support to MySensors

Scheduled Pinned Locked Moved Development
security
491 Posts 48 Posters 333.9k Views 30 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    tomkxy
    wrote on last edited by
    #141

    Yep, it is

    `#define MY_ATSHA204_PIN 17 // A3 - pin where ATSHA204 is attached
    ``
    I am just irritate by the 17. So this does map to A3 even on ProMini?
    AnticimexA 1 Reply Last reply
    0
    • T tomkxy

      Yep, it is

      `#define MY_ATSHA204_PIN 17 // A3 - pin where ATSHA204 is attached
      ``
      I am just irritate by the 17. So this does map to A3 even on ProMini?
      AnticimexA Offline
      AnticimexA Offline
      Anticimex
      Contest Winner
      wrote on last edited by
      #142

      @tomkxy yes it does.

      Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

      1 Reply Last reply
      0
      • T Offline
        T Offline
        tomkxy
        wrote on last edited by
        #143

        @Anticimex Unfortunately, I am now in a total state of mess. It seems that nothing works anymore the moment I turn on any signing. For sure, I have a problem with ATSHA204 and the ProMini which I need to sort out separately. I tried them all with my Uno (reading out the config) which worked. When I try to just read the config with my ProMini I get the error cannot wake up device.

        But now, even soft signing did not work any longer (it worked first, than I made changes and afte. I just receive nonce transmission errors from the sensor to the gateway although both radios are side by side and transmission without signing works perfectly.

        Btw, what is stored in the EPROM and under what circumstances do I have to clear EPROM first. I changed between the various signing feature (soft signing, HW signing, signing required etc.) back and forth and it seems that this info is stored in EPROM and somehow not cleared?? How does the sensor know that the gateway requires signing? Will it get the info out of EPROM? Will this information be updated during presentation?

        I think you did a great job on that implementation, the more frustrating it is that I cannot get it to work reliably. I am out for today. May be I find some time tomorrow getting anot ProMini prepared to checkout the issue with the chips.

        AnticimexA 1 Reply Last reply
        0
        • T tomkxy

          @Anticimex Unfortunately, I am now in a total state of mess. It seems that nothing works anymore the moment I turn on any signing. For sure, I have a problem with ATSHA204 and the ProMini which I need to sort out separately. I tried them all with my Uno (reading out the config) which worked. When I try to just read the config with my ProMini I get the error cannot wake up device.

          But now, even soft signing did not work any longer (it worked first, than I made changes and afte. I just receive nonce transmission errors from the sensor to the gateway although both radios are side by side and transmission without signing works perfectly.

          Btw, what is stored in the EPROM and under what circumstances do I have to clear EPROM first. I changed between the various signing feature (soft signing, HW signing, signing required etc.) back and forth and it seems that this info is stored in EPROM and somehow not cleared?? How does the sensor know that the gateway requires signing? Will it get the info out of EPROM? Will this information be updated during presentation?

          I think you did a great job on that implementation, the more frustrating it is that I cannot get it to work reliably. I am out for today. May be I find some time tomorrow getting anot ProMini prepared to checkout the issue with the chips.

          AnticimexA Offline
          AnticimexA Offline
          Anticimex
          Contest Winner
          wrote on last edited by Anticimex
          #144

          @tomkxy The information stored in EEPROM is not specific to any backend. It just informs the node what other nodes require signed messages. At startup, a node broadcasts it's preference to the gateway which then updates it's EEPROM table and replies with its own preference back so the node knows if the gateway wants signed messages as well. If the preferences differ from what is stored in EEPROM already, it is the updated preferences that will replace the stored preferences.
          The usecases for this is if you were to deploy a new sensor which require signing, it would inform gateway of this at startup. But if you restart your gateway it would loose this unless it was stored in EEPROM (the same goes the other way around) so the EEPROM is used so that the signing rules in the network gets preserved even if nodes dissappear or restart.
          If you suspect the EEPROM to contain corrupt data, you can clear it with the cleareeorom sketch/example.
          The typical circumstance you need to clear EEPROM under is when you switch library version, and the reserved region of EEPROM in the library change (and you also use EEPROM in your sketch). Then the library might take some of your sketch data for "it's own" and that can/will lead to unpredictable results.

          Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

          1 Reply Last reply
          0
          • scalzS Offline
            scalzS Offline
            scalz
            Hardware Contributor
            wrote on last edited by scalz
            #145

            Just to say, that I tried some weeks ago ATSHA204A with pro mini and had no problem too. Maybe you should try clear eeprom and retry. Or try with another pro mini. But it should work I think.
            And for those who want to test excellent work of @Anticimex and @Tekka, I have posted a simple/basic not expensive, 1.8$ for 3 breakouts here : https://oshpark.com/shared_projects/lvvxsHSW . It can be useful for existing nodes too.

            See you soon

            TD22057T 1 Reply Last reply
            1
            • scalzS scalz

              Just to say, that I tried some weeks ago ATSHA204A with pro mini and had no problem too. Maybe you should try clear eeprom and retry. Or try with another pro mini. But it should work I think.
              And for those who want to test excellent work of @Anticimex and @Tekka, I have posted a simple/basic not expensive, 1.8$ for 3 breakouts here : https://oshpark.com/shared_projects/lvvxsHSW . It can be useful for existing nodes too.

              See you soon

              TD22057T Offline
              TD22057T Offline
              TD22057
              Hardware Contributor
              wrote on last edited by
              #146

              @scalz said:

              Just to say, that I tried some weeks ago ATSHA204A with pro mini and had no problem too. Maybe you should try clear eeprom and retry. Or try with another pro mini. But it should work I think.
              And for those who want to test excellent work of @Anticimex and @Tekka, I have posted a simple/basic not expensive, 1.8$ for 3 breakouts here : https://oshpark.com/shared_projects/lvvxsHSW . It can be useful for existing nodes too.

              Good idea - I'm finding soldering the ATSHA chips to be a real pain and a small breakout board would help with that. Is the eeprom pads on your board for people who are just using a mega328 chip? Doesn't a pro-mini already have enough eeprom on board?

              1 Reply Last reply
              0
              • scalzS Offline
                scalzS Offline
                scalz
                Hardware Contributor
                wrote on last edited by
                #147

                @TDD22057: eeprom on the breakout is for the new ota in Mysensors (over the air upload sketch) . It is not related to authentication.
                I made this cheap breakout firstly because I wanted to test the new Mysensors features easily. and I thought it could be useful in some specific case where you don't need to make a pcb for one specific usercase so you use a veroboard and so you can easily add these new features with less pain...
                Happy it can help some people :smile:

                1 Reply Last reply
                0
                • T Offline
                  T Offline
                  tomkxy
                  wrote on last edited by
                  #148

                  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:

                  1. Breakout wired to the ProMini without breadboard use
                  2. Breakout wired to a breadboard where the ProMini was plugged
                  3. 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?

                  1 Reply Last reply
                  0
                  • scalzS Offline
                    scalzS Offline
                    scalz
                    Hardware Contributor
                    wrote on last edited by
                    #149

                    @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...

                    1 Reply Last reply
                    0
                    • T Offline
                      T Offline
                      tomkxy
                      wrote on last edited by
                      #150

                      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.

                      AnticimexA 1 Reply Last reply
                      0
                      • T tomkxy

                        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.

                        AnticimexA Offline
                        AnticimexA Offline
                        Anticimex
                        Contest Winner
                        wrote on last edited by
                        #151

                        @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.

                        Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

                        1 Reply Last reply
                        0
                        • O Offline
                          O Offline
                          otto001
                          wrote on last edited by
                          #152

                          Hi,

                          I seem to be too stupid (or drunk ;-) ) to get this working with MySigningAtsha204Soft :-(
                          Is anyone willing to provide a working MyConfig.h and EthernetGateway.ino for this?
                          There seemed to be some changes and I am sure, I am just too dumb... :-(

                          1 Reply Last reply
                          0
                          • T Offline
                            T Offline
                            tomkxy
                            wrote on last edited by
                            #153

                            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;
                              }
                            }
                            
                            
                            O 1 Reply Last reply
                            0
                            • T tomkxy

                              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;
                                }
                              }
                              
                              
                              O Offline
                              O Offline
                              otto001
                              wrote on last edited by
                              #154

                              @tomkxy Thanks, that helped! I seemed to have two problems:

                              1. 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

                              AnticimexA 1 Reply Last reply
                              0
                              • O otto001

                                @tomkxy Thanks, that helped! I seemed to have two problems:

                                1. 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

                                AnticimexA Offline
                                AnticimexA Offline
                                Anticimex
                                Contest Winner
                                wrote on last edited by
                                #155

                                @otto001 Great! And thanks @tomkxy for helping out. MySensors teamwork at it's best. This is what it's all about :D

                                Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

                                1 Reply Last reply
                                0
                                • O Offline
                                  O Offline
                                  otto001
                                  wrote on last edited by otto001
                                  #156

                                  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 select
                                  

                                  And 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

                                  TD22057T 1 Reply Last reply
                                  0
                                  • O otto001

                                    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 select
                                    

                                    And 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

                                    TD22057T Offline
                                    TD22057T Offline
                                    TD22057
                                    Hardware Contributor
                                    wrote on last edited by
                                    #157

                                    @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.

                                    1 Reply Last reply
                                    0
                                    • TD22057T Offline
                                      TD22057T Offline
                                      TD22057
                                      Hardware Contributor
                                      wrote on last edited by
                                      #158

                                      @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#msg1607035

                                      FYI 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.

                                      1 Reply Last reply
                                      0
                                      • F Offline
                                        F Offline
                                        fleinze
                                        wrote on last edited by
                                        #159

                                        @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 used MySigningAtsha204Soft 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?

                                        AnticimexA 2 Replies Last reply
                                        0
                                        • F fleinze

                                          @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 used MySigningAtsha204Soft 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?

                                          AnticimexA Offline
                                          AnticimexA Offline
                                          Anticimex
                                          Contest Winner
                                          wrote on last edited by
                                          #160

                                          @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".

                                          Do you feel secure today? No? Start requiring some signatures and feel better tomorrow ;)

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          14

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.0k

                                          Posts


                                          Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular