TOSAs OTA bootloader, test nodejs gateway and other misc changes.

Merge commit '5968ddf21964dff4043e70df8bd65286c90b5127' into development

* commit '5968ddf21964dff4043e70df8bd65286c90b5127':
  Send reboot msg after message retrieval to deal with sensors going to sleep
  Node JS controller
  OTA Bootloader
  Binary message payload handling
  Remote reboot capability
  Misc fixes

Conflicts:
	EthernetGateway/EthernetGateway.ino
	libraries/MySensors/MyGateway.cpp
	libraries/MySensors/MyMessage.h
This commit is contained in:
Henrik Ekblad
2014-07-27 20:08:55 +02:00
45 changed files with 3004 additions and 6901 deletions
+28 -1
View File
@@ -105,10 +105,22 @@ void MyGateway::checkInclusionFinished() {
}
}
uint8_t MyGateway::h2i(char c) {
uint8_t i = 0;
if (c <= '9')
i += c - '0';
else if (c >= 'a')
i += c - 'a' + 10;
else
i += c - 'A' + 10;
return i;
}
void MyGateway::parseAndSend(char *commandBuffer) {
boolean ok = false;
char *str, *p, *value=NULL;
uint8_t bvalue[MAX_PAYLOAD];
uint8_t blen = 0;
int i = 0;
uint16_t destination = 0;
uint8_t sensor = 0;
@@ -138,7 +150,18 @@ void MyGateway::parseAndSend(char *commandBuffer) {
type = atoi(str);
break;
case 5: // Variable value
value = str;
if (command == C_STREAM) {
blen = 0;
uint8_t val;
while (*str) {
val = h2i(*str++) << 4;
val += h2i(*str++);
bvalue[blen] = val;
blen++;
}
} else {
value = str;
}
break;
}
i++;
@@ -163,6 +186,10 @@ void MyGateway::parseAndSend(char *commandBuffer) {
mSetRequestAck(msg,ack?1:0);
mSetAck(msg,false);
msg.set(value);
if (command == C_STREAM)
msg.set(bvalue, blen);
else
msg.set(value);
ok = sendRoute(msg);
if (!ok) {
errBlink(1);
+2
View File
@@ -68,6 +68,8 @@ class MyGateway : public MySensor
uint8_t pinTx;
uint8_t pinEr;
uint8_t h2i(char c);
void serial(const char *fmt, ... );
void serial(MyMessage &msg);
void interruptStartInclusion();
+25 -4
View File
@@ -33,6 +33,30 @@ const char* MyMessage::getString() const {
}
}
// handles single character hex (0 - 15)
char MyMessage::i2h(uint8_t i) const {
uint8_t k = i & 0x0F;
if (k <= 9)
return '0' + k;
else
return 'A' + k - 10;
}
char* MyMessage::getStream(char *buffer) const {
uint8_t cmd = miGetCommand();
if ((cmd == C_STREAM) && (buffer != NULL)) {
for (uint8_t i = 0; i < miGetLength(); i++)
{
buffer[i * 2] = i2h(data[i] >> 4);
buffer[(i * 2) + 1] = i2h(data[i]);
}
buffer[miGetLength() * 2] = '\0';
return buffer;
} else {
return NULL;
}
}
char* MyMessage::getString(char *buffer) const {
uint8_t payloadType = miGetPayloadType();
if (payloadType == P_STRING) {
@@ -57,10 +81,7 @@ char* MyMessage::getString(char *buffer) const {
ultoa(ulValue, buffer, 10);
break;
case P_CUSTOM:
// TODO: Ok, what do we do here? We should probably convert this to hex
// Mostly gateway interested in this so we do the special handling of this
// over there.
return getStream(buffer);
break;
}
return buffer;
+29 -5
View File
@@ -12,11 +12,15 @@
#ifndef MyMessage_h
#define MyMessage_h
#include <SPI.h>
#ifdef __cplusplus
#include <Arduino.h>
#include <string.h>
#include <stdint.h>
#endif
#define PROTOCOL_VERSION 2
#define MAX_MESSAGE_LENGTH 32
#define HEADER_SIZE 8
#define HEADER_SIZE 7
#define MAX_PAYLOAD (MAX_MESSAGE_LENGTH - HEADER_SIZE)
// Message types
@@ -41,7 +45,8 @@ typedef enum {
typedef enum {
I_BATTERY_LEVEL, I_TIME, I_VERSION, I_ID_REQUEST, I_ID_RESPONSE,
I_INCLUSION_MODE, I_CONFIG, I_PING, I_PING_ACK,
I_LOG_MESSAGE, I_CHILDREN, I_SKETCH_NAME, I_SKETCH_VERSION
I_LOG_MESSAGE, I_CHILDREN, I_SKETCH_NAME, I_SKETCH_VERSION,
I_REBOOT
} internal;
// Type of sensor (for presentation message)
@@ -53,7 +58,8 @@ typedef enum {
// Type of data stream (for streamed message)
typedef enum {
ST_FIRMWARE, ST_SOUND, ST_IMAGE
ST_FIRMWARE_CONFIG_REQUEST, ST_FIRMWARE_CONFIG_RESPONSE, ST_FIRMWARE_REQUEST, ST_FIRMWARE_RESPONSE,
ST_SOUND, ST_IMAGE
} stream;
typedef enum {
@@ -96,6 +102,8 @@ typedef enum {
// internal access for special fields
#define miGetCommand() BF_GET(command_ack_payload, 0, 3)
#define miSetLength(_length) BF_SET(version_length, _length, 3, 5)
#define miGetLength() BF_GET(version_length, 3, 5)
@@ -109,7 +117,7 @@ typedef enum {
#define miGetPayloadType() BF_GET(command_ack_payload, 5, 3)
#ifdef __cplusplus
class MyMessage
{
public:
@@ -118,11 +126,14 @@ public:
MyMessage(uint8_t sensor, uint8_t type);
char i2h(uint8_t i) const;
/**
* If payload is something else than P_STRING you can have the payload value converted
* into string representation by supplying a buffer with the minimum size of
* 2*MAX_PAYLOAD+1. This is to be able to fit hex-conversion of a full binary payload.
*/
char* getStream(char *buffer) const;
char* getString(char *buffer) const;
const char* getString() const;
void* getCustom() const;
@@ -152,6 +163,13 @@ public:
MyMessage& set(unsigned int value);
MyMessage& set(int value);
#else
typedef union {
struct
{
#endif
uint8_t version_length; // 3 bit - Protocol version
// 5 bit - Length of payload
@@ -176,6 +194,12 @@ public:
int iValue;
char data[MAX_PAYLOAD + 1];
} __attribute__((packed));
#ifdef __cplusplus
} __attribute__((packed));
#else
};
uint8_t array[HEADER_SIZE + MAX_PAYLOAD + 1];
} __attribute__((packed)) MyMessage;
#endif
#endif
+4
View File
@@ -328,6 +328,10 @@ boolean MySensor::process() {
bool isMetric;
switch (type) {
case I_REBOOT:
wdt_enable(WDTO_15MS);
for (;;);
break;
case I_ID_RESPONSE:
if (nc.nodeId == AUTO) {
nc.nodeId = msg.getByte();
+13 -5
View File
@@ -15,15 +15,19 @@
#include "Version.h" // Auto generated by bot
#include "MyConfig.h"
#include "MyMessage.h"
#include <Arduino.h>
#include <stddef.h>
#include <SPI.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <stdarg.h>
#ifdef __cplusplus
#include <Arduino.h>
#include <SPI.h>
#include "utility/LowPower.h"
#include "utility/RF24.h"
#include "utility/RF24_config.h"
#endif
#ifdef DEBUG
#define debug(x,...) debugPrint(x, ##__VA_ARGS__)
@@ -46,7 +50,11 @@
#define EEPROM_DISTANCE_ADDRESS (EEPROM_PARENT_NODE_ID_ADDRESS+1)
#define EEPROM_ROUTES_ADDRESS (EEPROM_DISTANCE_ADDRESS+1) // Where to start storing routing information in EEPROM. Will allocate 256 bytes.
#define EEPROM_CONTROLLER_CONFIG_ADDRESS (EEPROM_ROUTES_ADDRESS+256) // Location of controller sent configuration (we allow one payload of config data from controller)
#define EEPROM_LOCAL_CONFIG_ADDRESS (EEPROM_CONTROLLER_CONFIG_ADDRESS+24) // First free address for sketch static configuration
#define EEPROM_FIRMWARE_TYPE_ADDRESS (EEPROM_CONTROLLER_CONFIG_ADDRESS+24)
#define EEPROM_FIRMWARE_VERSION_ADDRESS (EEPROM_FIRMWARE_TYPE_ADDRESS+2)
#define EEPROM_FIRMWARE_BLOCKS_ADDRESS (EEPROM_FIRMWARE_VERSION_ADDRESS+2)
#define EEPROM_FIRMWARE_CRC_ADDRESS (EEPROM_FIRMWARE_BLOCKS_ADDRESS+2)
#define EEPROM_LOCAL_CONFIG_ADDRESS (EEPROM_FIRMWARE_CRC_ADDRESS+2) // First free address for sketch static configuration
// This is the nodeId for sensor net gateway receiver sketch (where all sensors should send their data).
// This is also act as base value for sensor nodeId
@@ -73,8 +81,7 @@ struct ControllerConfig {
uint8_t isMetric;
};
#ifdef __cplusplus
class MySensor : public RF24
{
public:
@@ -266,5 +273,6 @@ class MySensor : public RF24
void removeChildRoute(uint8_t childId);
void internalSleep(unsigned long ms);
};
#endif
#endif