MySensors 2.3.0 release

This commit is contained in:
Patrick Fallberg
2018-06-18 16:15:50 +02:00
117 changed files with 10025 additions and 2405 deletions
+4 -2
View File
@@ -160,6 +160,8 @@
#define MY_CAP_ARCH "N"
#elif defined(ARDUINO_ARCH_ESP8266)
#define MY_CAP_ARCH "E"
#elif defined(ARDUINO_ARCH_ESP32)
#define MY_CAP_ARCH "F"
#elif defined(ARDUINO_ARCH_AVR)
#define MY_CAP_ARCH "A"
#elif defined(ARDUINO_ARCH_STM32F1)
@@ -216,14 +218,14 @@
* @def MY_CAP_ENCR
* @brief Indicate the encryption setting.
*
* @see MY_RF24_ENABLE_ENCRYPTION, MY_RFM69_ENABLE_ENCRYPTION, MY_NRF5_ESB_ENABLE_ENCRYPTION
* @see MY_ENCRYPTION_FEATURE
*
* | Setting | Indicator
* |------------|----------
* | Enabled | X
* | Disabled | -
*/
#if defined(MY_RF24_ENABLE_ENCRYPTION) || defined(MY_RFM69_ENABLE_ENCRYPTION) || defined (MY_NRF5_ESB_ENABLE_ENCRYPTION)
#if defined(MY_ENCRYPTION_FEATURE)
#define MY_CAP_ENCR "X"
#else
#define MY_CAP_ENCR "-"
+56 -25
View File
@@ -22,6 +22,35 @@
// global variables
extern MyMessage _msgTmp;
// housekeeping, remove for 3.0.0
#ifdef MY_ESP8266_SSID
#warning MY_ESP8266_SSID is deprecated, use MY_WIFI_SSID instead!
#define MY_WIFI_SSID MY_ESP8266_SSID
#undef MY_ESP8266_SSID // cleanup
#endif
#ifdef MY_ESP8266_PASSWORD
#warning MY_ESP8266_PASSWORD is deprecated, use MY_WIFI_PASSWORD instead!
#define MY_WIFI_PASSWORD MY_ESP8266_PASSWORD
#undef MY_ESP8266_PASSWORD // cleanup
#endif
#ifdef MY_ESP8266_BSSID
#warning MY_ESP8266_BSSID is deprecated, use MY_WIFI_BSSID instead!
#define MY_WIFI_BSSID MY_ESP8266_BSSID
#undef MY_ESP8266_BSSID // cleanup
#endif
#ifdef MY_ESP8266_HOSTNAME
#warning MY_ESP8266_HOSTNAME is deprecated, use MY_HOSTNAME instead!
#define MY_HOSTNAME MY_ESP8266_HOSTNAME
#undef MY_ESP8266_HOSTNAME // cleanup
#endif
#ifndef MY_WIFI_BSSID
#define MY_WIFI_BSSID NULL
#endif
#if defined(MY_CONTROLLER_IP_ADDRESS)
IPAddress _ethernetControllerIP(MY_CONTROLLER_IP_ADDRESS);
#endif
@@ -30,14 +59,14 @@ IPAddress _ethernetControllerIP(MY_CONTROLLER_IP_ADDRESS);
IPAddress _ethernetGatewayIP(MY_IP_ADDRESS);
#if defined(MY_IP_GATEWAY_ADDRESS)
IPAddress _gatewayIp(MY_IP_GATEWAY_ADDRESS);
#elif defined(MY_GATEWAY_ESP8266) /* Elif part of MY_IP_GATEWAY_ADDRESS */
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
// Assume the gateway will be the machine on the same network as the local IP
// but with last octet being '1'
IPAddress _gatewayIp(_ethernetGatewayIP[0], _ethernetGatewayIP[1], _ethernetGatewayIP[2], 1);
#endif /* End of MY_IP_GATEWAY_ADDRESS */
#if defined(MY_IP_SUBNET_ADDRESS)
IPAddress _subnetIp(MY_IP_SUBNET_ADDRESS);
#elif defined(MY_GATEWAY_ESP8266) /* Elif part of MY_IP_SUBNET_ADDRESS */
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
IPAddress _subnetIp(255, 255, 255, 0);
#endif /* End of MY_IP_SUBNET_ADDRESS */
#endif /* End of MY_IP_ADDRESS */
@@ -57,12 +86,12 @@ typedef struct {
uint8_t idx;
} inputBuffer;
#if defined(MY_GATEWAY_ESP8266)
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
// Some re-defines to make code more readable below
#define EthernetServer WiFiServer
#define EthernetClient WiFiClient
#define EthernetUDP WiFiUDP
#endif /* End of MY_GATEWAY_ESP8266 */
#endif
#if defined(MY_GATEWAY_CLIENT_MODE)
#if defined(MY_USE_UDP)
@@ -81,7 +110,7 @@ static inputBuffer inputString;
#else
static EthernetClient client = EthernetClient();
#endif /* End of MY_USE_UDP */
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX) /* Elif part of MY_GATEWAY_CLIENT_MODE */
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) || defined(MY_GATEWAY_LINUX)
static EthernetClient clients[MY_GATEWAY_MAX_CLIENTS];
static bool clientsConnected[MY_GATEWAY_MAX_CLIENTS];
static inputBuffer inputString[MY_GATEWAY_MAX_CLIENTS];
@@ -116,29 +145,31 @@ void _w5100_spi_en(bool enable)
bool gatewayTransportInit(void)
{
_w5100_spi_en(true);
#if defined(MY_GATEWAY_ESP8266)
#if defined(MY_ESP8266_SSID)
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
#if defined(MY_WIFI_SSID)
// Turn off access point
WiFi.mode(WIFI_STA);
#if defined(MY_ESP8266_HOSTNAME)
WiFi.hostname(MY_ESP8266_HOSTNAME);
#endif /* End of MY_ESP8266_HOSTNAME */
#if defined(MY_IP_ADDRESS)
WiFi.config(_ethernetGatewayIP, _gatewayIp, _subnetIp);
#endif /* End of MY_IP_ADDRESS */
#ifndef MY_ESP8266_BSSID
#define MY_ESP8266_BSSID NULL
#if defined(MY_HOSTNAME)
#if defined(MY_GATEWAY_ESP8266)
WiFi.hostname(MY_HOSTNAME);
#elif defined(MY_GATEWAY_ESP32)
WiFi.setHostname(MY_HOSTNAME);
#endif
(void)WiFi.begin(MY_ESP8266_SSID, MY_ESP8266_PASSWORD, 0, MY_ESP8266_BSSID);
#endif
#ifdef MY_IP_ADDRESS
WiFi.config(_ethernetGatewayIP, _gatewayIp, _subnetIp);
#endif
(void)WiFi.begin(MY_WIFI_SSID, MY_WIFI_PASSWORD, 0, MY_WIFI_BSSID);
while (WiFi.status() != WL_CONNECTED) {
wait(500);
GATEWAY_DEBUG(PSTR("GWT:TIN:CONNECTING...\n"));
}
GATEWAY_DEBUG(PSTR("GWT:TIN:IP=%s\n"), WiFi.localIP().toString().c_str());
#endif /* End of MY_ESP8266_SSID */
#elif defined(MY_GATEWAY_LINUX) /* Elif part of MY_GATEWAY_ESP8266 */
GATEWAY_DEBUG(PSTR("GWT:TIN:IP: %s\n"), WiFi.localIP().toString().c_str());
#endif
#elif defined(MY_GATEWAY_LINUX)
// Nothing to do here
#else /* Else part of MY_GATEWAY_ESP8266 */
#else
#if defined(MY_IP_GATEWAY_ADDRESS) && defined(MY_IP_SUBNET_ADDRESS)
// DNS server set to gateway ip
Ethernet.begin(_ethernetGatewayMAC, _ethernetGatewayIP, _gatewayIp, _gatewayIp, _subnetIp);
@@ -157,7 +188,7 @@ bool gatewayTransportInit(void)
Ethernet.localIP()[1], Ethernet.localIP()[2], Ethernet.localIP()[3]);
// give the Ethernet interface a second to initialize
delay(1000);
#endif /* End of MY_GATEWAY_ESP8266 */
#endif /* MY_GATEWAY_ESP8266 / MY_GATEWAY_ESP32 */
#if defined(MY_GATEWAY_CLIENT_MODE)
#if defined(MY_USE_UDP)
@@ -236,7 +267,7 @@ bool gatewayTransportSend(MyMessage &message)
#endif /* End of MY_USE_UDP */
#else /* Else part of MY_GATEWAY_CLIENT_MODE */
// Send message to connected clients
#if defined(MY_GATEWAY_ESP8266)
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) {
if (clients[i] && clients[i].connected()) {
nbytes += clients[i].write((uint8_t*)_ethernetMsg, strlen(_ethernetMsg));
@@ -253,7 +284,7 @@ bool gatewayTransportSend(MyMessage &message)
#if defined(MY_USE_UDP)
// Nothing to do here
#else
#if (defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX)) && !defined(MY_GATEWAY_CLIENT_MODE)
#if (defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) || defined(MY_GATEWAY_LINUX)) && !defined(MY_GATEWAY_CLIENT_MODE)
bool _readFromClient(uint8_t i)
{
while (clients[i].connected() && clients[i].available()) {
@@ -366,7 +397,7 @@ bool gatewayTransportAvailable(void)
}
#endif /* End of MY_USE_UDP */
#else /* Else part of MY_GATEWAY_CLIENT_MODE */
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX)
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) || defined(MY_GATEWAY_LINUX)
// ESP8266: Go over list of clients and stop any that are no longer connected.
// If the server has a new client connection it will be assigned to a free slot.
bool allSlotsOccupied = true;
@@ -443,7 +474,7 @@ MyMessage& gatewayTransportReceive(void)
return _ethernetMsg;
}
#if !defined(MY_IP_ADDRESS) && !defined(MY_GATEWAY_ESP8266) && !defined(MY_GATEWAY_LINUX)
#if !defined(MY_IP_ADDRESS) && !defined(MY_GATEWAY_ESP8266) && !defined(MY_GATEWAY_ESP32) && !defined(MY_GATEWAY_LINUX)
void gatewayTransportRenewIP(void)
{
/* renew/rebind IP address
+114 -13
View File
@@ -22,6 +22,35 @@
#include "MyGatewayTransport.h"
// housekeeping, remove for 3.0.0
#ifdef MY_ESP8266_SSID
#warning MY_ESP8266_SSID is deprecated, use MY_WIFI_SSID instead!
#define MY_WIFI_SSID MY_ESP8266_SSID
#undef MY_ESP8266_SSID // cleanup
#endif
#ifdef MY_ESP8266_PASSWORD
#warning MY_ESP8266_PASSWORD is deprecated, use MY_WIFI_PASSWORD instead!
#define MY_WIFI_PASSWORD MY_ESP8266_PASSWORD
#undef MY_ESP8266_PASSWORD // cleanup
#endif
#ifdef MY_ESP8266_BSSID
#warning MY_ESP8266_BSSID is deprecated, use MY_WIFI_BSSID instead!
#define MY_WIFI_BSSID MY_ESP8266_BSSID
#undef MY_ESP8266_BSSID // cleanup
#endif
#ifdef MY_ESP8266_HOSTNAME
#warning MY_ESP8266_HOSTNAME is deprecated, use MY_HOSTNAME instead!
#define MY_HOSTNAME MY_ESP8266_HOSTNAME
#undef MY_ESP8266_HOSTNAME // cleanup
#endif
#ifndef MY_WIFI_BSSID
#define MY_WIFI_BSSID NULL
#endif
#if defined MY_CONTROLLER_IP_ADDRESS
IPAddress _brokerIp(MY_CONTROLLER_IP_ADDRESS);
#endif
@@ -30,19 +59,20 @@ IPAddress _brokerIp(MY_CONTROLLER_IP_ADDRESS);
IPAddress _MQTT_clientIp(MY_IP_ADDRESS);
#if defined(MY_IP_GATEWAY_ADDRESS)
IPAddress _gatewayIp(MY_IP_GATEWAY_ADDRESS);
#elif defined(MY_GATEWAY_ESP8266) /* Elif part of MY_IP_GATEWAY_ADDRESS */
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
// Assume the gateway will be the machine on the same network as the local IP
// but with last octet being '1'
IPAddress _gatewayIp(_MQTT_clientIp[0], _MQTT_clientIp[1], _MQTT_clientIp[2], 1);
#endif /* End of MY_IP_GATEWAY_ADDRESS */
#if defined(MY_IP_SUBNET_ADDRESS)
IPAddress _subnetIp(MY_IP_SUBNET_ADDRESS);
#elif defined(MY_GATEWAY_ESP8266) /* Elif part of MY_IP_SUBNET_ADDRESS */
#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
IPAddress _subnetIp(255, 255, 255, 0);
#endif /* End of MY_IP_SUBNET_ADDRESS */
#endif /* End of MY_IP_ADDRESS */
#if defined(MY_GATEWAY_ESP8266)
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
#define EthernetClient WiFiClient
#elif defined(MY_GATEWAY_LINUX)
// Nothing to do here
@@ -50,8 +80,24 @@ IPAddress _subnetIp(255, 255, 255, 0);
uint8_t _MQTT_clientMAC[] = { MY_MAC_ADDRESS };
#endif /* End of MY_GATEWAY_ESP8266 */
#if defined(MY_GATEWAY_TINYGSM)
#if defined(MY_GSM_RX) && defined(MY_GSM_TX)
SoftwareSerial SerialAT(MY_GSM_RX, MY_GSM_TX);
#endif
static TinyGsm modem(SerialAT);
static TinyGsmClient _MQTT_gsmClient(modem);
static PubSubClient _MQTT_client(_MQTT_gsmClient);
#if defined(MY_GSM_BAUDRATE)
uint32_t rate = MY_GSM_BAUDRATE;
#else /* Else part of MY_GSM_BAUDRATE */
uint32_t rate = 0;
#endif /* End of MY_GSM_BAUDRATE */
#else /* Else part of MY_GATEWAY_TINYGSM */
static EthernetClient _MQTT_ethClient;
static PubSubClient _MQTT_client(_MQTT_ethClient);
#endif /* End of MY_GATEWAY_TINYGSM */
static bool _MQTT_connecting = true;
static bool _MQTT_available = false;
static MyMessage _MQTT_msg;
@@ -104,17 +150,19 @@ bool reconnectMQTT(void)
bool gatewayTransportConnect(void)
{
#if defined(MY_GATEWAY_ESP8266)
#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)
while (WiFi.status() != WL_CONNECTED) {
wait(500);
GATEWAY_DEBUG(PSTR("GWT:TPC:CONNECTING...\n"));
}
GATEWAY_DEBUG(PSTR("GWT:TPC:IP=%s\n"),WiFi.localIP().toString().c_str());
#elif defined(MY_GATEWAY_LINUX) /* Elif part of MY_GATEWAY_ESP8266 */
#elif defined(MY_GATEWAY_LINUX)
#if defined(MY_IP_ADDRESS)
_MQTT_ethClient.bind(_MQTT_clientIp);
#endif /* End of MY_IP_ADDRESS */
#else /* Else part of MY_GATEWAY_ESP8266 */
#elif defined(MY_GATEWAY_TINYGSM)
GATEWAY_DEBUG(PSTR("GWT:TPC:IP=%s\n"), modem.getLocalIP().c_str());
#else
#if defined(MY_IP_ADDRESS)
Ethernet.begin(_MQTT_clientMAC, _MQTT_clientIp);
#else /* Else part of MY_IP_ADDRESS */
@@ -130,13 +178,53 @@ bool gatewayTransportConnect(void)
Ethernet.localIP()[1], Ethernet.localIP()[2], Ethernet.localIP()[3]);
// give the Ethernet interface a second to initialize
delay(1000);
#endif /* End of MY_GATEWAY_ESP8266 */
#endif
return true;
}
bool gatewayTransportInit(void)
{
_MQTT_connecting = true;
#if defined(MY_GATEWAY_TINYGSM)
#if !defined(MY_GSM_BAUDRATE)
rate = TinyGsmAutoBaud(SerialAT);
#endif /* End of MY_GSM_BAUDRATE */
SerialAT.begin(rate);
delay(3000);
modem.restart();
#if defined(MY_GSM_PIN) && !defined(TINY_GSM_MODEM_ESP8266)
modem.simUnlock(MY_GSM_PIN);
#endif /* End of MY_GSM_PIN */
#ifndef TINY_GSM_MODEM_ESP8266
if (!modem.waitForNetwork()) {
GATEWAY_DEBUG(PSTR("!GWT:TIN:ETH FAIL\n"));
while (true);
}
GATEWAY_DEBUG(PSTR("GWT:TIN:ETH OK\n"));
if (!modem.gprsConnect(MY_GSM_APN, MY_GSM_USR, MY_GSM_PSW)) {
GATEWAY_DEBUG(PSTR("!GWT:TIN:ETH FAIL\n"));
while (true);
}
GATEWAY_DEBUG(PSTR("GWT:TIN:ETH OK\n"));
delay(1000);
#else /* Else part of TINY_GSM_MODEM_ESP8266 */
if (!modem.networkConnect(MY_GSM_SSID, MY_GSM_PSW)) {
GATEWAY_DEBUG(PSTR("!GWT:TIN:ETH FAIL\n"));
while (true);
}
GATEWAY_DEBUG(PSTR("GWT:TIN:ETH OK\n"));
delay(1000);
#endif /* End of TINY_GSM_MODEM_ESP8266 */
#endif /* End of MY_GATEWAY_TINYGSM */
#if defined(MY_CONTROLLER_IP_ADDRESS)
_MQTT_client.setServer(_brokerIp, MY_PORT);
#else
@@ -148,17 +236,30 @@ bool gatewayTransportInit(void)
#if defined(MY_GATEWAY_ESP8266)
// Turn off access point
WiFi.mode(WIFI_STA);
#if defined(MY_ESP8266_HOSTNAME)
WiFi.hostname(MY_ESP8266_HOSTNAME);
#if defined(MY_HOSTNAME)
WiFi.hostname(MY_HOSTNAME);
#endif /* End of MY_ESP8266_HOSTNAME */
#if defined(MY_IP_ADDRESS)
WiFi.config(_MQTT_clientIp, _gatewayIp, _subnetIp);
#endif /* End of MY_IP_ADDRESS */
#ifndef MY_ESP8266_BSSID
#define MY_ESP8266_BSSID NULL
#ifndef MY_WIFI_BSSID
#define MY_WIFI_BSSID NULL
#endif
(void)WiFi.begin(MY_WIFI_SSID, MY_WIFI_PASSWORD, 0, MY_WIFI_BSSID);
#elif defined(MY_GATEWAY_ESP32)
// Turn off access point
WiFi.mode(WIFI_STA);
#if defined(MY_HOSTNAME)
WiFi.setHostname(MY_HOSTNAME);
#endif /* End of MY_HOSTNAME */
#if defined(MY_IP_ADDRESS)
WiFi.config(_MQTT_clientIp, _gatewayIp, _subnetIp);
#endif /* End of MY_IP_ADDRESS */
#ifndef MY_WIFI_BSSID
#define MY_WIFI_BSSID NULL
#endif
(void)WiFi.begin(MY_WIFI_SSID, MY_WIFI_PASSWORD, 0, MY_WIFI_BSSID);
#endif
(void)WiFi.begin(MY_ESP8266_SSID, MY_ESP8266_PASSWORD, 0, MY_ESP8266_BSSID);
#endif /* End of MY_GATEWAY_ESP8266 */
gatewayTransportConnect();
-1
View File
@@ -76,7 +76,6 @@ const char* MyMessage::getString() const
}
}
// handles single character hex (0 - 15)
char MyMessage::i2h(uint8_t i) const
{
uint8_t k = i & 0x0F;
+182 -39
View File
@@ -50,6 +50,7 @@ typedef enum {
C_STREAM = 4 //!< For firmware and other larger chunks of data that need to be divided into pieces.
} mysensor_command;
#if !DOXYGEN // Hide until we migrate
/// @brief Type of sensor (used when presenting sensors)
typedef enum {
S_DOOR = 0, //!< Door sensor, V_TRIPPED, V_ARMED
@@ -158,6 +159,7 @@ typedef enum {
V_VA = 55, //!< S_POWER, Apparent power: volt-ampere (VA)
V_POWER_FACTOR = 56, //!< S_POWER, Ratio of real power to apparent power: floating point value in the range [-1,..,1]
} mysensor_data;
#endif
/// @brief Type of internal messages (for internal messages)
@@ -206,7 +208,9 @@ typedef enum {
ST_FIRMWARE_REQUEST = 2, //!< Request FW block
ST_FIRMWARE_RESPONSE = 3, //!< Response FW block
ST_SOUND = 4, //!< Sound
ST_IMAGE = 5 //!< Image
ST_IMAGE = 5, //!< Image
ST_FIRMWARE_CONFIRM = 6, //!< Mark running firmware as valid (MyOTAFirmwareUpdateNVM + mcuboot)
ST_FIRMWARE_RESPONSE_RLE = 7, //!< Response FW block with run length encoded data
} mysensor_stream;
/// @brief Type of payload
@@ -275,23 +279,37 @@ typedef enum {
#define miGetPayloadType() (uint8_t)BF_GET(command_ack_payload, 5, 3) //!< Internal getter for payload type field
#if !DOXYGEN
#ifdef __cplusplus
#if defined(__cplusplus) || defined(DOXYGEN)
/**
* @brief MyMessage is used to create, manipulate, send and read MySensors messages
*/
class MyMessage
{
private:
char* getCustomString(char *buffer) const;
public:
// Constructors
/**
* Default constructor
*/
MyMessage();
/**
* Constructor
* @param sensor id of the child sensor for this message
* @param type see http://korturl.nu/stupidurl
*/
MyMessage(uint8_t sensor, uint8_t type);
/**
* Single character hex (0 - 15) conversion
* @param i byte (only lower 4 bits will be considered)
* @return single char with the hex representation (0 to F) of the parameter
*/
char i2h(uint8_t i) const;
/**
* Clear message contents.
* @brief Clear message contents.
*/
void clear();
@@ -299,42 +317,158 @@ public:
* 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.
* @param buffer pointer to a buffer that's at least 2*MAX_PAYLOAD+1 bytes large
*/
char* getStream(char *buffer) const;
/**
* @brief Copy the payload into the supplied buffer
*/
char* getString(char *buffer) const;
/**
* @brief Get payload as string
* @return pointer to a char array storing the string
*/
const char* getString() const;
/**
* @brief Get custom payload
* @return pointer to the raw payload
*/
void* getCustom() const;
/**
* @brief Get bool payload
* @return a bool with the value of the payload (true/false)
*/
bool getBool() const;
/**
* @brief Get unsigned 8-bit integer payload
* @return the value of the payload, 0 to 255
*/
uint8_t getByte() const;
/**
* @brief Get float payload
* @return the floating-point value of the payload
*/
float getFloat() const;
/**
* @brief Get signed 16-bit integer payload
* @return the value of the payload, –32768 to 32767
*/
int16_t getInt() const;
/**
* @brief Get unsigned 16-bit integer payload
* @return the value of the payload, 0 to 65535
*/
uint16_t getUInt() const;
/**
* @brief Get signed 32-bit integer payload
* @return the value of the payload, –2147483648 to 2147483647
*/
int32_t getLong() const;
/**
* @brief Get unsigned 32-bit integer payload
* @return the value of the payload, 0 to 4294967295
*/
uint32_t getULong() const;
// Getter for command type
/**
* @brief Getter for command type
* @return #mysensor_command
*/
uint8_t getCommand() const;
// Getter for ack-flag. True if this is an ack message.
/**
* @brief Getter for ack-flag.
* @return true if this is an ack message
*/
bool isAck() const;
// Setters for building message "on the fly"
/**
* @brief Set message type
* @param type see http://korturl.nu/stupidurl
*/
MyMessage& setType(uint8_t type);
/**
* @brief Set which child sensor this message belongs to
*/
MyMessage& setSensor(uint8_t sensor);
/**
* @brief Set final destination node id for this message
*/
MyMessage& setDestination(uint8_t destination);
// Setters for payload
/**
* @brief Set entire payload
* @param payload pointer to the buffer where the payload is stored
* @param length of the payload
*/
MyMessage& set(void* payload, uint8_t length);
/**
* @brief Set payload to character array
* @param value pointer to the character array. The array must be null-terminated.
*/
MyMessage& set(const char* value);
#if !defined(__linux__)
/**
* @brief Set payload to character array from flash
* @param value pointer to the character array. The array must be null-terminated.
*/
MyMessage& set(const __FlashStringHelper* value);
#endif
/**
* @brief Set payload to decimal number
* @param value float
* @param decimals number of decimals to include
*/
MyMessage& set(float value, uint8_t decimals);
/**
* @brief Set payload to bool value
* @param value true or false
*/
MyMessage& set(bool value);
/**
* @brief Set payload to unsigned 8-bit integer value
* @param value (0 to 255)
*/
MyMessage& set(uint8_t value);
/**
* @brief Set payload to unsigned 32-bit integer value
* @param value (0 to 4294967295)
*/
MyMessage& set(uint32_t value);
/**
* @brief Set payload to signed 32-bit integer value
* @param value (–2147483648 to 2147483647)
*/
MyMessage& set(int32_t value);
/**
* @brief Set payload to unsigned 16-bit integer value
* @param value (0 to 65535)
*/
MyMessage& set(uint16_t value);
/**
* @brief Set payload to signed 16-bit integer value
* @param value (–32768 to 32767)
*/
MyMessage& set(int16_t value);
#else
@@ -343,47 +477,56 @@ typedef union {
struct {
#endif
uint8_t last; // 8 bit - Id of last node this message passed
uint8_t sender; // 8 bit - Id of sender node (origin)
uint8_t destination; // 8 bit - Id of destination node
uint8_t last; ///< 8 bit - Id of last node this message passed
uint8_t sender; ///< 8 bit - Id of sender node (origin)
uint8_t destination; ///< 8 bit - Id of destination node
uint8_t version_length; // 2 bit - Protocol version
// 1 bit - Signed flag
// 5 bit - Length of payload
uint8_t command_ack_payload; // 3 bit - Command type
// 1 bit - Request an ack - Indicator that receiver should send an ack back.
// 1 bit - Is ack message - Indicator that this is the actual ack message.
// 3 bit - Payload data type
uint8_t type; // 8 bit - Type varies depending on command
uint8_t sensor; // 8 bit - Id of sensor that this message concerns.
/**
* 2 bit - Protocol version<br>
* 1 bit - Signed flag<br>
* 5 bit - Length of payload
*/
uint8_t version_length;
// Each message can transfer a payload. We add one extra byte for string
// terminator \0 to be "printable" this is not transferred OTA
// This union is used to simplify the construction of the binary data types transferred.
/**
* 3 bit - Command type<br>
* 1 bit - Request an ack - Indicator that receiver should send an ack back<br>
* 1 bit - Is ack message - Indicator that this is the actual ack message<br>
* 3 bit - Payload data type
*/
uint8_t command_ack_payload;
uint8_t type; ///< 8 bit - Type varies depending on command
uint8_t sensor; ///< 8 bit - Id of sensor that this message concerns.
/*
* Each message can transfer a payload. We add one extra byte for string
* terminator \0 to be "printable" this is not transferred OTA
* This union is used to simplify the construction of the binary data types transferred.
*/
union {
uint8_t bValue;
uint16_t uiValue;
int16_t iValue;
uint32_t ulValue;
int32_t lValue;
struct { // Float messages
uint8_t bValue; ///< unsigned byte value (8-bit)
uint16_t uiValue; ///< unsigned integer value (16-bit)
int16_t iValue; ///< signed integer value (16-bit)
uint32_t ulValue; ///< unsigned long value (32-bit)
int32_t lValue; ///< signed long value (32-bit)
struct { //< Float messages
float fValue;
uint8_t fPrecision; // Number of decimals when serializing
uint8_t fPrecision; ///< Number of decimals when serializing
};
struct { // Presentation messages
uint8_t version; // Library version
uint8_t sensorType; // Sensor type hint for controller, see table above
struct { //< Presentation messages
uint8_t version; ///< Library version
uint8_t sensorType; ///< Sensor type hint for controller, see table above
};
char data[MAX_PAYLOAD + 1];
} __attribute__((packed));
#ifdef __cplusplus
char data[MAX_PAYLOAD + 1]; ///< Buffer for raw payload data
} __attribute__((packed)); ///< Doxygen will complain without this comment
#if defined(__cplusplus) || defined(DOXYGEN)
} __attribute__((packed));
#else
};
uint8_t array[HEADER_SIZE + MAX_PAYLOAD + 1];
uint8_t array[HEADER_SIZE + MAX_PAYLOAD + 1]; ///< buffer for entire message
} __attribute__((packed)) MyMessage;
#endif
#endif
#endif
/** @}*/
+144 -66
View File
@@ -26,15 +26,30 @@ extern MyMessage _msgTmp;
// local variables
#ifdef MY_OTA_USE_I2C_EEPROM
I2CEeprom _flash(MY_OTA_I2C_ADDR);
#else
#elif !defined(MCUBOOT_PRESENT)
SPIFlash _flash(MY_OTA_FLASH_SS, MY_OTA_FLASH_JDECID);
#endif
// Map flash functions
#ifndef MCUBOOT_PRESENT
#define _flash_initialize() _flash.initialize()
#define _flash_readByte(addr) _flash.readByte(addr)
#define _flash_writeBytes( dstaddr, data, size) _flash.writeBytes( dstaddr, data, size)
#define _flash_blockErase32K(num) _flash.blockErase32K(num)
#define _flash_busy() _flash.busy()
#else
#define _flash_initialize() true
#define _flash_readByte(addr) (*((uint8_t *)(addr)))
#define _flash_blockErase32K(num) Flash.erase((uint32_t *)FLASH_AREA_IMAGE_1_OFFSET_0, FLASH_AREA_IMAGE_1_SIZE_0)
#define _flash_busy() false
#endif
LOCAL nodeFirmwareConfig_t _nodeFirmwareConfig;
LOCAL bool _firmwareUpdateOngoing = false;
LOCAL uint32_t _firmwareLastRequest;
LOCAL uint16_t _firmwareBlock;
LOCAL uint8_t _firmwareRetry;
LOCAL bool _firmwareResponse(uint16_t block, uint8_t *data);
LOCAL void readFirmwareSettings(void)
{
@@ -83,15 +98,15 @@ LOCAL bool firmwareOTAUpdateProcess(void)
// copy new FW config
(void)memcpy(&_nodeFirmwareConfig, firmwareConfigResponse, sizeof(nodeFirmwareConfig_t));
// Init flash
if (!_flash.initialize()) {
if (!_flash_initialize()) {
setIndication(INDICATION_ERR_FW_FLASH_INIT);
OTA_DEBUG(PSTR("!OTA:FWP:FLASH INIT FAIL\n")); // failed to initialise flash
_firmwareUpdateOngoing = false;
} else {
// erase lower 32K -> max flash size for ATMEGA328
_flash.blockErase32K(0);
_flash_blockErase32K(0);
// wait until flash erased
while ( _flash.busy() ) {}
while ( _flash_busy() ) {}
_firmwareBlock = _nodeFirmwareConfig.blocks;
_firmwareUpdateOngoing = true;
// reset flags
@@ -102,68 +117,46 @@ LOCAL bool firmwareOTAUpdateProcess(void)
}
OTA_DEBUG(PSTR("OTA:FWP:UPDATE SKIPPED\n")); // FW update skipped, no newer version available
} else if (_msg.type == ST_FIRMWARE_RESPONSE) {
if (_firmwareUpdateOngoing) {
// extract FW block
replyFirmwareBlock_t *firmwareResponse = (replyFirmwareBlock_t *)_msg.data;
OTA_DEBUG(PSTR("OTA:FWP:RECV B=%04" PRIX16 "\n"), firmwareResponse->block); // received FW block
if (firmwareResponse->block != _firmwareBlock - 1) {
OTA_DEBUG(PSTR("!OTA:FWP:WRONG FWB\n")); // received FW block
// wrong firmware block received
setIndication(INDICATION_FW_UPDATE_RX_ERR);
// no further processing required
return true;
}
setIndication(INDICATION_FW_UPDATE_RX);
// Save block to flash
_flash.writeBytes( ((_firmwareBlock - 1) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET,
firmwareResponse->data, FIRMWARE_BLOCK_SIZE);
// wait until flash written
while (_flash.busy()) {}
#ifdef OTA_EXTRA_FLASH_DEBUG
{
char prbuf[8];
uint32_t addr = ((_firmwareBlock - 1) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET;
OTA_DEBUG(PSTR("OTA:FWP:FL DUMP "));
sprintf_P(prbuf,PSTR("%04" PRIX16 ":"), (uint16_t)addr);
MY_SERIALDEVICE.print(prbuf);
for(uint8_t i=0; i<FIRMWARE_BLOCK_SIZE; i++) {
uint8_t data = _flash.readByte(addr + i);
sprintf_P(prbuf,PSTR("%02" PRIX8 ""), (uint8_t)data);
MY_SERIALDEVICE.print(prbuf);
}
OTA_DEBUG(PSTR("\n"));
}
#endif
_firmwareBlock--;
if (!_firmwareBlock) {
// We're done! Do a checksum and reboot.
OTA_DEBUG(PSTR("OTA:FWP:FW END\n")); // received FW block
_firmwareUpdateOngoing = false;
if (transportIsValidFirmware()) {
OTA_DEBUG(PSTR("OTA:FWP:CRC OK\n")); // FW checksum ok
// Write the new firmware config to eeprom
hwWriteConfigBlock((void*)&_nodeFirmwareConfig, (void*)EEPROM_FIRMWARE_TYPE_ADDRESS,
sizeof(nodeFirmwareConfig_t));
// All seems ok, write size and signature to flash (DualOptiboot will pick this up and flash it)
const uint16_t firmwareSize = FIRMWARE_BLOCK_SIZE * _nodeFirmwareConfig.blocks;
const uint8_t OTAbuffer[FIRMWARE_START_OFFSET] = {'F','L','X','I','M','G',':', (uint8_t)(firmwareSize >> 8), (uint8_t)(firmwareSize & 0xff),':'};
_flash.writeBytes(0, OTAbuffer, FIRMWARE_START_OFFSET);
// wait until flash ready
while (_flash.busy()) {}
hwReboot();
} else {
setIndication(INDICATION_ERR_FW_CHECKSUM);
OTA_DEBUG(PSTR("!OTA:FWP:CRC FAIL\n"));
}
}
// reset flags
_firmwareRetry = MY_OTA_RETRY + 1;
_firmwareLastRequest = 0;
} else {
OTA_DEBUG(PSTR("!OTA:FWP:NO UPDATE\n"));
// extract FW block
replyFirmwareBlock_t *firmwareResponse = (replyFirmwareBlock_t *)_msg.data;
// Proceed firmware data
return _firmwareResponse(firmwareResponse->block, firmwareResponse->data);
#ifdef FIRMWARE_PROTOCOL_31
} else if (_msg.type == ST_FIRMWARE_RESPONSE_RLE) {
// RLE encoded block
// extract FW block
replyFirmwareBlockRLE_t *firmwareResponse = (replyFirmwareBlockRLE_t *)_msg.data;
uint8_t data[FIRMWARE_BLOCK_SIZE];
for (uint8_t i=0; i<FIRMWARE_BLOCK_SIZE; i++) {
data[i]=firmwareResponse->data;
}
while ((_firmwareBlock) && (firmwareResponse->number_of_blocks)) {
_firmwareResponse(firmwareResponse->block, data);
firmwareResponse->number_of_blocks--;
firmwareResponse->block--;
}
return true;
#endif
} else {
#ifdef MCUBOOT_PRESENT
if (_msg.type == ST_FIRMWARE_CONFIRM) {
if (*(uint16_t *)MCUBOOT_IMAGE_0_MAGIC_ADDR == ((uint16_t)MCUBOOT_IMAGE_MAGIC)) {
if (*(uint8_t*)(MCUBOOT_IMAGE_0_IMG_OK_ADDR)!=MCUBOOT_IMAGE_0_IMG_OK_BYTE) {
// Calculate data word to write
uint32_t *img_ok_base_addr = (uint32_t*)(MCUBOOT_IMAGE_0_IMG_OK_ADDR & ~3); // align word wise
uint32_t img_ok_data = *img_ok_base_addr;
// Set copy of MCUBOOT_IMAGE_0_IMG_OK_ADDR to MCUBOOT_IMAGE_0_IMG_OK_BYTE (0x01)
uint8_t * img_ok_array = (uint8_t*)(&img_ok_data);
img_ok_array[MCUBOOT_IMAGE_0_IMG_OK_ADDR % 4] = MCUBOOT_IMAGE_0_IMG_OK_BYTE;
// Write word back
Flash.write(img_ok_base_addr, img_ok_data);
}
OTA_DEBUG(PSTR("!OTA:FWP:IMAGE CONFIRMED\n"));
} else {
OTA_DEBUG(PSTR("!OTA:FWP:INVALID MCUBOOT MAGIC\n"));
}
}
#endif
}
return false;
}
@@ -178,6 +171,18 @@ LOCAL void presentBootloaderInformation(void)
(void)memcpy(requestFirmwareConfig, &_nodeFirmwareConfig, sizeof(nodeFirmwareConfig_t));
// add bootloader information
requestFirmwareConfig->BLVersion = MY_OTA_BOOTLOADER_VERSION;
#ifdef FIRMWARE_PROTOCOL_31
requestFirmwareConfig->blockSize = FIRMWARE_BLOCK_SIZE;
#ifndef MCUBOOT_PRESENT
requestFirmwareConfig->img_commited = 0x2;
requestFirmwareConfig->img_revision = 0x00;
requestFirmwareConfig->img_build_num = 0x00;
#else
requestFirmwareConfig->img_commited = *((uint8_t*)(MCUBOOT_IMAGE_0_IMG_OK_ADDR));
requestFirmwareConfig->img_revision = *((uint16_t*)(MCUBOOT_IMAGE_0_IMG_REVISION_ADDR));
requestFirmwareConfig->img_build_num = *((uint16_t*)(MCUBOOT_IMAGE_0_IMG_BUILD_NUM_ADDR));
#endif
#endif
_firmwareUpdateOngoing = false;
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_STREAM,
ST_FIRMWARE_CONFIG_REQUEST, false));
@@ -192,8 +197,8 @@ LOCAL bool transportIsValidFirmware(void)
{
// init crc
uint16_t crc = ~0;
for (uint16_t i = 0; i < _nodeFirmwareConfig.blocks * FIRMWARE_BLOCK_SIZE; ++i) {
crc ^= _flash.readByte(i + FIRMWARE_START_OFFSET);
for (uint32_t i = 0; i < _nodeFirmwareConfig.blocks * FIRMWARE_BLOCK_SIZE; ++i) {
crc ^= _flash_readByte(i + FIRMWARE_START_OFFSET);
for (int8_t j = 0; j < 8; ++j) {
if (crc & 1) {
crc = (crc >> 1) ^ 0xA001;
@@ -207,3 +212,76 @@ LOCAL bool transportIsValidFirmware(void)
_nodeFirmwareConfig.crc);
return crc == _nodeFirmwareConfig.crc;
}
LOCAL bool _firmwareResponse(uint16_t block, uint8_t *data)
{
if (_firmwareUpdateOngoing) {
OTA_DEBUG(PSTR("OTA:FWP:RECV B=%04" PRIX16 "\n"), block); // received FW block
if (block != _firmwareBlock - 1) {
OTA_DEBUG(PSTR("!OTA:FWP:WRONG FWB\n")); // received FW block
// wrong firmware block received
setIndication(INDICATION_FW_UPDATE_RX_ERR);
// no further processing required
return true;
}
setIndication(INDICATION_FW_UPDATE_RX);
// Save block to flash
#ifdef MCUBOOT_PRESENT
uint32_t addr = ((size_t)(((_firmwareBlock - 1) * FIRMWARE_BLOCK_SIZE)) + (size_t)(
FIRMWARE_START_OFFSET));
if (addr<FLASH_AREA_IMAGE_SCRATCH_OFFSET_0) {
Flash.write_block( (uint32_t *)addr, (uint32_t *)data, FIRMWARE_BLOCK_SIZE>>2);
}
#else
_flash_writeBytes( ((_firmwareBlock - 1) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET,
data, FIRMWARE_BLOCK_SIZE);
#endif
// wait until flash written
while (_flash_busy()) {}
#ifdef OTA_EXTRA_FLASH_DEBUG
{
char prbuf[8];
uint32_t addr = ((_firmwareBlock - 1) * FIRMWARE_BLOCK_SIZE) + FIRMWARE_START_OFFSET;
OTA_DEBUG(PSTR("OTA:FWP:FL DUMP "));
sprintf_P(prbuf,PSTR("%04" PRIX16 ":"), (uint16_t)addr);
MY_SERIALDEVICE.print(prbuf);
for(uint8_t i=0; i<FIRMWARE_BLOCK_SIZE; i++) {
uint8_t data = _flash_readByte(addr + i);
sprintf_P(prbuf,PSTR("%02" PRIX8 ""), (uint8_t)data);
MY_SERIALDEVICE.print(prbuf);
}
OTA_DEBUG(PSTR("\n"));
}
#endif
_firmwareBlock--;
if (!_firmwareBlock) {
// We're done! Do a checksum and reboot.
OTA_DEBUG(PSTR("OTA:FWP:FW END\n")); // received FW block
_firmwareUpdateOngoing = false;
if (transportIsValidFirmware()) {
OTA_DEBUG(PSTR("OTA:FWP:CRC OK\n")); // FW checksum ok
// Write the new firmware config to eeprom
hwWriteConfigBlock((void*)&_nodeFirmwareConfig, (void*)EEPROM_FIRMWARE_TYPE_ADDRESS,
sizeof(nodeFirmwareConfig_t));
#ifndef MCUBOOT_PRESENT
// All seems ok, write size and signature to flash (DualOptiboot will pick this up and flash it)
const uint16_t firmwareSize = FIRMWARE_BLOCK_SIZE * _nodeFirmwareConfig.blocks;
const uint8_t OTAbuffer[FIRMWARE_START_OFFSET] = {'F','L','X','I','M','G',':', (uint8_t)(firmwareSize >> 8), (uint8_t)(firmwareSize & 0xff),':'};
_flash_writeBytes(0, OTAbuffer, FIRMWARE_START_OFFSET);
// wait until flash ready
while (_flash_busy()) {}
#endif
hwReboot();
} else {
setIndication(INDICATION_ERR_FW_CHECKSUM);
OTA_DEBUG(PSTR("!OTA:FWP:CRC FAIL\n"));
}
}
// reset flags
_firmwareRetry = MY_OTA_RETRY + 1;
_firmwareLastRequest = 0;
} else {
OTA_DEBUG(PSTR("!OTA:FWP:NO UPDATE\n"));
}
return true;
}
+47
View File
@@ -58,17 +58,36 @@
#define MyOTAFirmwareUpdate_h
#include "MySensorsCore.h"
#ifdef MCUBOOT_PRESENT
#include "generated_dts_board.h"
#define FIRMWARE_PROTOCOL_31
#endif
#define LOCAL static //!< static
#if MAX_PAYLOAD >= 22
#define FIRMWARE_BLOCK_SIZE (16u) //!< Size of each firmware block
#else
#define FIRMWARE_BLOCK_SIZE (8u) //!< Size of each firmware block
#ifndef FIRMWARE_PROTOCOL_31
#define FIRMWARE_PROTOCOL_31
#endif
#endif
#define FIRMWARE_MAX_REQUESTS (5u) //!< Number of times a firmware block should be requested before giving up
#define MY_OTA_RETRY (5u) //!< Number of times to request a fw block before giving up
#define MY_OTA_RETRY_DELAY (500u) //!< Number of milliseconds before re-requesting a FW block
#ifndef MCUBOOT_PRESENT
#define FIRMWARE_START_OFFSET (10u) //!< Start offset for firmware in flash (DualOptiboot wants to keeps a signature first)
#else
#define FIRMWARE_START_OFFSET (FLASH_AREA_IMAGE_1_OFFSET_0) //!< Use offset from generated_dts_board.h (mcuboot)
#endif
#define MY_OTA_BOOTLOADER_MAJOR_VERSION (3u) //!< Bootloader version major
#ifdef FIRMWARE_PROTOCOL_31
#define MY_OTA_BOOTLOADER_MINOR_VERSION (1u) //!< Bootloader version minor
#else
#define MY_OTA_BOOTLOADER_MINOR_VERSION (0u) //!< Bootloader version minor
#endif
#define MY_OTA_BOOTLOADER_VERSION (MY_OTA_BOOTLOADER_MINOR_VERSION * 256 + MY_OTA_BOOTLOADER_MAJOR_VERSION) //!< Bootloader version
#if defined(MY_DEBUG_VERBOSE_OTA_UPDATE)
@@ -77,6 +96,18 @@
#else
#define OTA_DEBUG(x,...) //!< debug NULL
#endif
#if defined(DOXYGEN) && !defined(FIRMWARE_PROTOCOL_31)
/**
* @brief Enabled FOTA 3.1 protocol extensions
*
* Supports smaller FIRMWARE_BLOCK_SIZE, RLE and NVM for nRF5 with mcuboot. The
* extension is enabled per default when mcuboot is present or full FIRMWARE_BLOCK_SIZE
* exeeds MAX_PAYLOAD.
*/
#define FIRMWARE_PROTOCOL_31
#endif
/**
* @brief FW config structure, stored in eeprom
*/
@@ -96,6 +127,12 @@ typedef struct {
uint16_t blocks; //!< Number of blocks
uint16_t crc; //!< CRC of block data
uint16_t BLVersion; //!< Bootloader version
#ifdef FIRMWARE_PROTOCOL_31
uint8_t blockSize; //!< Blocksize, when protocol version >= 3.1 is reported. Otherwhise the blocksize is 16
uint8_t img_commited; //!< mcuboot image_ok attribute commited firmware=0x01(mcuboot)|0x02(DualOptiboot), when protocol version >= 3.1 is reported
uint16_t img_revision; //!< mcuboot revision attribute, when protocol version >= 3.1 is reported
uint32_t img_build_num; //!< mcuboot build_num attribute, when protocol version >= 3.1 is reported
#endif
} __attribute__((packed)) requestFirmwareConfig_t;
/**
@@ -117,6 +154,16 @@ typedef struct {
uint8_t data[FIRMWARE_BLOCK_SIZE]; //!< Block data
} __attribute__((packed)) replyFirmwareBlock_t;
/**
* @brief FW block reply structure (RLE)
*/
typedef struct {
uint16_t type; //!< Type of config
uint16_t version; //!< Version of config
uint16_t block; //!< Block index
uint16_t number_of_blocks; //!< Number of blocks to fill with data
uint8_t data; //!< Block data
} __attribute__((packed)) replyFirmwareBlockRLE_t;
/**
* @brief Read firmware settings from EEPROM
-9
View File
@@ -36,11 +36,7 @@ void OTALog(uint8_t logNode, bool enableAck, const char *fmt, ... )
// create message
va_start (args, fmt );
#ifdef vsnprintf_P
int n = vsnprintf_P(fmtBuffer, sizeof(fmtBuffer), fmt, args);
#else
int n = vsnprintf(fmtBuffer, sizeof(fmtBuffer), fmt, args);
#endif
va_end (args);
// Check number of chars
@@ -92,14 +88,9 @@ void OTALogPrintPrefix()
{
char prefix[37];
// prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE)
#ifdef snprintf_P
snprintf_P(prefix, sizeof(prefix),
PSTR("%" PRId8 ";%" PRId8 ";%" PRId8 ";0;%" PRId8 ";%" PRIu32 " "),
OTALogBufferNode, OTALogBufferSensor, C_INTERNAL, I_LOG_MESSAGE, hwMillis());
#else
snprintf(prefix, sizeof(prefix), PSTR("%" PRId8 ";%" PRId8 ";%" PRId8 ";0;%" PRId8 ";%" PRIu32 " "),
OTALogBufferNode, OTALogBufferSensor, C_INTERNAL, I_LOG_MESSAGE, hwMillis());
#endif
MY_SERIALDEVICE.print(prefix);
}
+11 -2
View File
@@ -32,6 +32,7 @@
#endif
// message buffers
MyMessage _msg; // Buffer for incoming messages
MyMessage _msgTmp; // Buffer for temporary messages (acks and nonces among others)
@@ -88,6 +89,14 @@ void _infiniteLoop(void)
void _begin(void)
{
#if defined(MY_CORE_ONLY)
// initialize HW and run setup if present
(void)hwInit();
if (setup) {
setup();
}
return;
#endif
// reset wdt
hwWatchdogReset();
@@ -168,7 +177,7 @@ void _begin(void)
setup();
}
#if defined(MY_SENSOR_NETWORK)
CORE_DEBUG(PSTR("MCO:BGN:INIT OK,TSP=%" PRIu8 "\n"), isTransportReady());
CORE_DEBUG(PSTR("MCO:BGN:INIT OK,TSP=%" PRIu8 "\n"), isTransportReady() && transportSanityCheck());
#else
// no sensor network defined, call presentation & registration
_callbackTransportReady();
@@ -585,7 +594,7 @@ int8_t _sleep(const uint32_t sleepingMS, const bool smartSleep, const uint8_t in
#endif // MY_OTA_FIRMWARE_FEATURE
if (smartSleep) {
// sleeping time left?
if (sleepingTimeMS < ((uint32_t)MY_SMART_SLEEP_WAIT_DURATION_MS)) {
if (sleepingTimeMS > 0 && sleepingTimeMS < ((uint32_t)MY_SMART_SLEEP_WAIT_DURATION_MS)) {
wait(sleepingMS);
CORE_DEBUG(PSTR("!MCO:SLP:NTL\n")); // sleeping not possible, no time left
return MY_SLEEP_NOT_POSSIBLE;
+11 -2
View File
@@ -177,6 +177,16 @@
* personalization has finished, you just program the sketch you plan to use (with the appropriate
* signing flags set).
*
* If you are using a Raspberry PI-based gateway, personalizaion is done slightly differently:
* 1. Generate keys, execute @c mysgw with arguments
* * To generate HMAC key @verbatim --gen-soft-hmac-key @endverbatim
* * To generate %AES key @verbatim --gen-aes-key @endverbatim
* * To generate a soft serial number @verbatim --gen-soft-serial @endverbatim
* 2. Update the gateway config file with the generated keys/valeus
* * For HMAC key @verbatim soft_hmac_key=<DATA> @endverbatim
* * For %AES key @verbatim aes_key=<DATA> @endverbatim
* * For soft serial number @verbatim soft_serial_key=<DATA> @endverbatim
*
* You are now set and ready to use message signing in your network.
* As of now, the following restrictions will be applied to your nodes:
* * If a node does require signing, any unsigned message sent to the node will be rejected.
@@ -393,8 +403,7 @@
* is to set your preferences in your sketch and personalize accordingly.
* That is enough to enable protection from both Eve and Mallory in your network
* although if you do not also enable encryption, Eve can eavesdrop, but not do anything about,
* your messages (except possibly preventing them from arriving). @ref MY_SIGNING_SIMPLE_PASSWD also
* enable encryption automatically.
* your messages (except possibly preventing them from arriving).
*
* How are the messages actually affected by the signing?<br>
* The following illustration shows what part of the message is signed, and where the signature is
+1 -1
View File
@@ -1,4 +1,4 @@
/*
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
+1 -1
View File
@@ -1,4 +1,4 @@
/*
/*
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
+2 -2
View File
@@ -47,9 +47,9 @@
#define STR(x) STR_HELPER(x) //!< Helper macro, STR()
#define MYSENSORS_LIBRARY_VERSION_MAJOR 2 //!< Major release version
#define MYSENSORS_LIBRARY_VERSION_MINOR 2 //!< Minor release version
#define MYSENSORS_LIBRARY_VERSION_MINOR 3 //!< Minor release version
#define MYSENSORS_LIBRARY_VERSION_PATCH 0 //!< Patch version
#define MYSENSORS_LIBRARY_VERSION_PRERELEASE "" //!< Pre-release suffix, i.e. alpha, beta, rc.1, etc
#define MYSENSORS_LIBRARY_VERSION_PRERELEASE "alpha" //!< Pre-release suffix, i.e. alpha, beta, rc.1, etc
#define MYSENSORS_LIBRARY_VERSION_PRERELEASE_NUMBER 0xFF //!< incremental counter, starting at 0x00. 0xFF for final release