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