Various MyTransport optimisations

This commit is contained in:
tekka007
2016-09-25 12:46:58 +02:00
parent b7ae549a04
commit efc71165c7
11 changed files with 612 additions and 347 deletions
+53 -14
View File
@@ -2,7 +2,7 @@
* The MySensors Arduino library handles the wireless radio link and protocol * The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice. * between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each * 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 * repeater and gateway builds a routing tables in RAM or EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes. * network topology allowing messages to be routed to nodes.
* *
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
@@ -81,18 +81,54 @@
//#define MY_RADIO_RFM69 //#define MY_RADIO_RFM69
//#define MY_RS485 //#define MY_RS485
/**
* @def MY_RAM_ROUTING_TABLE_FEATURE
* @brief If enabled, the routing table is kept in RAM (if memory allows) and saved in regular intervals.
* note: AVR has limited memory, use with care
*/
#define MY_RAM_ROUTING_TABLE_FEATURE
/**
* @def MY_ROUTING_TABLE_SAVE_INTERVAL_MS
* @brief Interval to dump content of routing table to eeprom
*/
#ifndef MY_ROUTING_TABLE_SAVE_INTERVAL_MS
#define MY_ROUTING_TABLE_SAVE_INTERVAL_MS (10*60*1000ul)
#endif
/** /**
* @def MY_TRANSPORT_SANITY_CHECK * @def MY_TRANSPORT_SANITY_CHECK
* @brief If enabled, node will check transport in regular intervals to detect HW issues and re-initialize in case of failure. This feature is enabled for all repeater nodes (incl. GW) * @brief If enabled, node will check transport in regular intervals to detect HW issues and re-initialize in case of failure.
* This feature is enabled for all repeater nodes (incl. GW)
*/ */
//#define MY_TRANSPORT_SANITY_CHECK //#define MY_TRANSPORT_SANITY_CHECK
/** /**
* @def MY_TRANSPORT_SANITY_CHECK_INTERVAL * @def MY_TRANSPORT_SANITY_CHECK_INTERVAL_MS
* @brief Interval (in ms) of transport sanity checks * @brief Interval (in ms) of transport sanity checks
*/ */
#ifndef MY_TRANSPORT_SANITY_CHECK_INTERVAL #ifndef MY_TRANSPORT_SANITY_CHECK_INTERVAL_MS
#define MY_TRANSPORT_SANITY_CHECK_INTERVAL ((uint32_t)60000) #define MY_TRANSPORT_SANITY_CHECK_INTERVAL_MS (60*1000ul)
#endif #endif
/**
* @def MY_TRANSPORT_DISCOVERY_INTERVAL_MS
* @brief This is a gateway-only feature: Interval (in ms) to issue network discovery checks
*/
#ifndef MY_TRANSPORT_DISCOVERY_INTERVAL_MS
#define MY_TRANSPORT_DISCOVERY_INTERVAL_MS (10*60*1000ul)
#endif
/**
*@def MY_TRANSPORT_UPLINK_CHECK_DISABLED
*@brief If set, uplink check to GW is disabled during transport initialisation
*/
//#define MY_TRANSPORT_UPLINK_CHECK_DISABLED
/**
*@def MY_TRANSPORT_MAX_TX_FAILURES
*@brief Set to override max. consecutive TX failures until SNP is initiated
*/
//#define MY_TRANSPORT_MAX_TX_FAILURES (10u)
/** /**
* @def MY_REGISTRATION_FEATURE * @def MY_REGISTRATION_FEATURE
* @brief If enabled, node has to register to gateway/controller before allowed to send sensor data. * @brief If enabled, node has to register to gateway/controller before allowed to send sensor data.
@@ -105,14 +141,13 @@
*/ */
#ifndef MY_REGISTRATION_RETRIES #ifndef MY_REGISTRATION_RETRIES
#define MY_REGISTRATION_RETRIES 3 #define MY_REGISTRATION_RETRIES (3u)
#endif #endif
/** /**
* @def MY_REGISTRATION_DEFAULT * @def MY_REGISTRATION_DEFAULT
* @brief Node registration default - this applies if no registration response is recieved from controller * @brief Node registration default - this applies if no registration response is received from controller
*/ */
#define MY_REGISTRATION_DEFAULT true #define MY_REGISTRATION_DEFAULT true
/** /**
@@ -149,8 +184,11 @@
*/ */
//#define MY_PARENT_NODE_IS_STATIC //#define MY_PARENT_NODE_IS_STATIC
// Enables repeater functionality (relays messages from other nodes) /**
// #define MY_REPEATER_FEATURE * @def MY_REPEATER_FEATURE
* @brief Enables repeater functionality (relays messages from other nodes)
*/
//#define MY_REPEATER_FEATURE
/** /**
* @def MY_SMART_SLEEP_WAIT_DURATION * @def MY_SMART_SLEEP_WAIT_DURATION
@@ -160,7 +198,7 @@
* potential buffered messages. * potential buffered messages.
*/ */
#ifndef MY_SMART_SLEEP_WAIT_DURATION #ifndef MY_SMART_SLEEP_WAIT_DURATION
#define MY_SMART_SLEEP_WAIT_DURATION 500 #define MY_SMART_SLEEP_WAIT_DURATION (500ul)
#endif #endif
/********************************** /**********************************
@@ -199,7 +237,7 @@
* @brief Max buffersize needed for messages coming from controller. * @brief Max buffersize needed for messages coming from controller.
*/ */
#ifndef MY_GATEWAY_MAX_RECEIVE_LENGTH #ifndef MY_GATEWAY_MAX_RECEIVE_LENGTH
#define MY_GATEWAY_MAX_RECEIVE_LENGTH 100 #define MY_GATEWAY_MAX_RECEIVE_LENGTH (100u)
#endif #endif
/** /**
@@ -207,7 +245,7 @@
* @brief Max buffer size when sending messages. * @brief Max buffer size when sending messages.
*/ */
#ifndef MY_GATEWAY_MAX_SEND_LENGTH #ifndef MY_GATEWAY_MAX_SEND_LENGTH
#define MY_GATEWAY_MAX_SEND_LENGTH 120 #define MY_GATEWAY_MAX_SEND_LENGTH (120u)
#endif #endif
/** /**
@@ -215,7 +253,7 @@
* @brief Max number of parallel clients (sever mode). * @brief Max number of parallel clients (sever mode).
*/ */
#ifndef MY_GATEWAY_MAX_CLIENTS #ifndef MY_GATEWAY_MAX_CLIENTS
#define MY_GATEWAY_MAX_CLIENTS 1 #define MY_GATEWAY_MAX_CLIENTS (1u)
#endif #endif
@@ -716,4 +754,5 @@
#define MY_RX_MESSAGE_BUFFER_FEATURE #define MY_RX_MESSAGE_BUFFER_FEATURE
#define MY_RX_MESSAGE_BUFFER_SIZE #define MY_RX_MESSAGE_BUFFER_SIZE
#define MY_NODE_LOCK_FEATURE #define MY_NODE_LOCK_FEATURE
#define MY_REPEATER_FEATURE
#endif #endif
+10
View File
@@ -239,6 +239,16 @@
#endif #endif
#endif #endif
// RAM ROUTING TABLE
#if defined(MY_RAM_ROUTING_TABLE_FEATURE) && defined(MY_REPEATER_FEATURE)
// activate feature based on architecture
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_SAMD) || defined(LINUX_ARCH_RASPBERRYPI)
#define MY_RAM_ROUTING_TABLE_ENABLED
#elif defined(ARDUINO_ARCH_AVR)
// memory limited, enable with care
// #define MY_RAM_ROUTING_TABLE_ENABLED
#endif
#endif
// RADIO // RADIO
#if defined(MY_RADIO_NRF24) || defined(MY_RADIO_RFM69) || defined(MY_RS485) #if defined(MY_RADIO_NRF24) || defined(MY_RADIO_RFM69) || defined(MY_RS485)
+2 -2
View File
@@ -70,7 +70,7 @@
#define MY_CAP_SIGN "-" #define MY_CAP_SIGN "-"
#endif #endif
#if defined(MY_RX_MESSAGE_BUFFER_SIZE) #if defined(MY_RX_MESSAGE_BUFFER_FEATURE)
#define MY_CAP_RXBUF "Q" #define MY_CAP_RXBUF "Q"
#else #else
#define MY_CAP_RXBUF "-" #define MY_CAP_RXBUF "-"
@@ -79,4 +79,4 @@
#define MY_CAPABILITIES MY_CAP_RESET MY_CAP_RADIO MY_CAP_OTA_FW MY_CAP_TYPE MY_CAP_ARCH MY_CAP_SIGN MY_CAP_RXBUF #define MY_CAPABILITIES MY_CAP_RESET MY_CAP_RADIO MY_CAP_OTA_FW MY_CAP_TYPE MY_CAP_ARCH MY_CAP_SIGN MY_CAP_RXBUF
#endif /* MyGatewayTransportEthernet_h */ #endif /* MyCapabilities_h */
+1 -1
View File
@@ -28,7 +28,7 @@
extern MyMessage _msgTmp; extern MyMessage _msgTmp;
char _serialInputString[MY_GATEWAY_MAX_RECEIVE_LENGTH]; // A buffer for incoming commands from serial interface char _serialInputString[MY_GATEWAY_MAX_RECEIVE_LENGTH]; // A buffer for incoming commands from serial interface
int _serialInputPos; uint8_t _serialInputPos;
MyMessage _serialMsg; MyMessage _serialMsg;
+4
View File
@@ -203,6 +203,10 @@ void hwDebugPrint(const char *fmt, ... ) {
// prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE) // prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE)
snprintf_P(fmtBuffer, sizeof(fmtBuffer), PSTR("0;255;%d;0;%d;"), C_INTERNAL, I_LOG_MESSAGE); snprintf_P(fmtBuffer, sizeof(fmtBuffer), PSTR("0;255;%d;0;%d;"), C_INTERNAL, I_LOG_MESSAGE);
MY_SERIALDEVICE.print(fmtBuffer); MY_SERIALDEVICE.print(fmtBuffer);
#else
// prepend timestamp (AVR nodes)
MY_SERIALDEVICE.print(hwMillis());
MY_SERIALDEVICE.print(" ");
#endif #endif
va_list args; va_list args;
va_start (args, fmt ); va_start (args, fmt );
+4 -1
View File
@@ -34,11 +34,12 @@ typedef enum {
INDICATION_GOT_PARENT, //!< Found parent node. INDICATION_GOT_PARENT, //!< Found parent node.
INDICATION_REQ_NODEID, //!< Request node ID. INDICATION_REQ_NODEID, //!< Request node ID.
INDICATION_GOT_NODEID, //!< Got a node ID. INDICATION_GOT_NODEID, //!< Got a node ID.
INDICATION_CHECK_UPLINK, //!< Check uplink
INDICATION_REQ_REGISTRATION, //!< Request node registration. INDICATION_REQ_REGISTRATION, //!< Request node registration.
INDICATION_GOT_REGISTRATION, //!< Got registration reponse. INDICATION_GOT_REGISTRATION, //!< Got registration reponse.
INDICATION_REBOOT, //!< Rebooting node. INDICATION_REBOOT, //!< Rebooting node.
INDICATION_PRESENT, //!< Presenting node to gateway. INDICATION_PRESENT, //!< Presenting node to gateway.
INDICATION_CLEAR_ROUTING, //!< Clear rrouting table requested. INDICATION_CLEAR_ROUTING, //!< Clear routing table requested.
INDICATION_SLEEP, //!< Node goes to sleep. INDICATION_SLEEP, //!< Node goes to sleep.
INDICATION_WAKEUP, //!< Node just woke from sleep. INDICATION_WAKEUP, //!< Node just woke from sleep.
INDICATION_FW_UPDATE_START, //!< Start of OTA firmware update process. INDICATION_FW_UPDATE_START, //!< Start of OTA firmware update process.
@@ -50,7 +51,9 @@ typedef enum {
INDICATION_ERR_INIT_TRANSPORT, //!< MySensors transport hardware (radio) init failure. INDICATION_ERR_INIT_TRANSPORT, //!< MySensors transport hardware (radio) init failure.
INDICATION_ERR_FIND_PARENT, //!< Failed to find parent node. INDICATION_ERR_FIND_PARENT, //!< Failed to find parent node.
INDICATION_ERR_GET_NODEID, //!< Failed to receive node ID. INDICATION_ERR_GET_NODEID, //!< Failed to receive node ID.
INDICATION_ERR_CHECK_UPLINK, //!< Failed to check uplink
INDICATION_ERR_SIGN, //!< Error signing. INDICATION_ERR_SIGN, //!< Error signing.
INDICATION_ERR_LENGTH, //!< Invalid message length.
INDICATION_ERR_VERSION, //!< Protocol version mismatch. INDICATION_ERR_VERSION, //!< Protocol version mismatch.
INDICATION_ERR_NET_FULL, //!< Network full. All node ID's are taken. INDICATION_ERR_NET_FULL, //!< Network full. All node ID's are taken.
INDICATION_ERR_INIT_GWTRANSPORT, //!< Gateway transport hardware init failure. INDICATION_ERR_INIT_GWTRANSPORT, //!< Gateway transport hardware init failure.
+3 -3
View File
@@ -36,9 +36,9 @@
#include <stdint.h> #include <stdint.h>
#endif #endif
#define PROTOCOL_VERSION 2 //!< The version of the protocol #define PROTOCOL_VERSION (2u) //!< The version of the protocol
#define MAX_MESSAGE_LENGTH 32 //!< The maximum size of a message (including header) #define MAX_MESSAGE_LENGTH (32u) //!< The maximum size of a message (including header)
#define HEADER_SIZE 7 //!< The size of the header #define HEADER_SIZE (7u) //!< The size of the header
#define MAX_PAYLOAD (MAX_MESSAGE_LENGTH - HEADER_SIZE) //!< The maximum size of a payload depends on #MAX_MESSAGE_LENGTH and #HEADER_SIZE #define MAX_PAYLOAD (MAX_MESSAGE_LENGTH - HEADER_SIZE) //!< The maximum size of a payload depends on #MAX_MESSAGE_LENGTH and #HEADER_SIZE
/// @brief The command field (message-type) defines the overall properties of a message /// @brief The command field (message-type) defines the overall properties of a message
+9 -9
View File
@@ -99,7 +99,7 @@ void _begin() {
#if defined(MY_RADIO_FEATURE) #if defined(MY_RADIO_FEATURE)
// Save static parent id in eeprom (used by bootloader) // Save static parent id in eeprom (used by bootloader)
hwWriteConfig(EEPROM_PARENT_NODE_ID_ADDRESS, MY_PARENT_NODE_ID); hwWriteConfig(EEPROM_PARENT_NODE_ID_ADDRESS, MY_PARENT_NODE_ID);
transportInitialize(); transportInitialise();
while (!isTransportReady()) { while (!isTransportReady()) {
hwWatchdogReset(); hwWatchdogReset();
transportProcess(); transportProcess();
@@ -142,7 +142,7 @@ void _begin() {
inclusionInit(); inclusionInit();
#endif #endif
// initialize the transport driver // initialise the transport driver
if (!gatewayTransportInit()) { if (!gatewayTransportInit()) {
setIndication(INDICATION_ERR_INIT_GWTRANSPORT); setIndication(INDICATION_ERR_INIT_GWTRANSPORT);
debug(PSTR("!MCO:BGN:TSP FAIL\n")); debug(PSTR("!MCO:BGN:TSP FAIL\n"));
@@ -353,15 +353,15 @@ bool _processInternalMessages() {
} }
else if (type == I_DEBUG) { else if (type == I_DEBUG) {
#if defined(MY_DEBUG) || defined(MY_SPECIAL_DEBUG) #if defined(MY_DEBUG) || defined(MY_SPECIAL_DEBUG)
char debug_msg = _msg.data[0]; const char debug_msg = _msg.data[0];
if (debug_msg == 'R') { // routing table if (debug_msg == 'R') { // routing table
#if defined(MY_REPEATER_FEATURE) #if defined(MY_REPEATER_FEATURE)
for (uint8_t cnt = 0; cnt != 255; cnt++) { for (uint8_t cnt = 0; cnt != 255; cnt++) {
uint8_t route = hwReadConfig(EEPROM_ROUTES_ADDRESS + cnt); const uint8_t route = transportGetRoute(cnt);
if (route != BROADCAST_ADDRESS) { if (route != BROADCAST_ADDRESS) {
debug(PSTR("MCO:PIM:ROUTE N=%d,R=%d\n"), cnt, route); debug(PSTR("MCO:PIM:ROUTE N=%d,R=%d\n"), cnt, route);
uint8_t OutBuf[2] = { cnt,route }; uint8_t outBuf[2] = { cnt,route };
_sendRoute(build(_msgTmp, _nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_DEBUG, false).set(OutBuf, 2)); _sendRoute(build(_msgTmp, _nc.nodeId, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_DEBUG, false).set(outBuf, 2));
wait(200); wait(200);
} }
} }
@@ -390,15 +390,15 @@ bool _processInternalMessages() {
// sender is a node // sender is a node
if (type == I_REGISTRATION_REQUEST) { if (type == I_REGISTRATION_REQUEST) {
#if defined(MY_GATEWAY_FEATURE) #if defined(MY_GATEWAY_FEATURE)
// register request are exclusively handled by GW/Controller // registeration requests are exclusively handled by GW/Controller
// !!! eventually define if AUTO ACK or register request forwarded to controller
#if !defined(MY_REGISTRATION_CONTROLLER) #if !defined(MY_REGISTRATION_CONTROLLER)
// auto register if version compatible // auto registration if version compatible
bool approveRegistration = true; bool approveRegistration = true;
#if defined(MY_CORE_COMPATIBILITY_CHECK) #if defined(MY_CORE_COMPATIBILITY_CHECK)
approveRegistration = (_msg.getByte() >= MY_CORE_MIN_VERSION); approveRegistration = (_msg.getByte() >= MY_CORE_MIN_VERSION);
#endif #endif
// delay for slow nodes *****************************
_sendRoute(build(_msgTmp, _nc.nodeId, _msg.sender, NODE_SENSOR_ID, C_INTERNAL, I_REGISTRATION_RESPONSE, false).set(approveRegistration)); _sendRoute(build(_msgTmp, _nc.nodeId, _msg.sender, NODE_SENSOR_ID, C_INTERNAL, I_REGISTRATION_RESPONSE, false).set(approveRegistration));
#else #else
return false; // processing of this request via controller return false; // processing of this request via controller
+2 -2
View File
@@ -25,7 +25,7 @@
* @{ * @{
* *
* MySensorsCore-related log messages, format: [!]SYSTEM:[SUB SYSTEM:]MESSAGE * MySensorsCore-related log messages, format: [!]SYSTEM:[SUB SYSTEM:]MESSAGE
* - [!] Exclamation mark is prepended in case of error * - [!] Exclamation mark is prepended in case of error or warning
* - SYSTEM: * - SYSTEM:
* - <b>MCO</b> messages emitted by MySensorsCore * - <b>MCO</b> messages emitted by MySensorsCore
* - SUB SYSTEMS: * - SUB SYSTEMS:
@@ -44,7 +44,7 @@
* | | MCO | BGN | STP | Callback setup() * | | MCO | BGN | STP | Callback setup()
* | | MCO | BGN | INIT OK,ID=%%d,PAR=%%d,DIS=%%d,REG=%%d | Core initialized, parent ID (PAR), distance to GW (DIS), registration (REG) * | | MCO | BGN | INIT OK,ID=%%d,PAR=%%d,DIS=%%d,REG=%%d | Core initialized, parent ID (PAR), distance to GW (DIS), registration (REG)
* | | MCO | BGN | NODE UNLOCKED | Node successfully unlocked (see signing chapter) * | | MCO | BGN | NODE UNLOCKED | Node successfully unlocked (see signing chapter)
* |!| MCO | BGN | TSP FAIL | Transport initialization failed * |!| MCO | BGN | TSP FAIL | Transport initialisation failed
* | | MCO | REG | REQ | Registration request * | | MCO | REG | REQ | Registration request
* | | MCO | REG | NOT NEEDED | No registration needed (i.e. GW) * | | MCO | REG | NOT NEEDED | No registration needed (i.e. GW)
* |!| MCO | SND | NODE NOT REG | Node is not registered, cannot send message * |!| MCO | SND | NODE NOT REG | Node is not registered, cannot send message
+396 -255
View File
File diff suppressed because it is too large Load Diff
+128 -60
View File
@@ -6,7 +6,7 @@
* network topology allowing messages to be routed to nodes. * network topology allowing messages to be routed to nodes.
* *
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB * Copyright (C) 2013-2016 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
* *
* Documentation: http://www.mysensors.org * Documentation: http://www.mysensors.org
@@ -36,7 +36,7 @@
* - TSM:ID from <b>stID</b> Check/request node ID, if dynamic node ID set * - TSM:ID from <b>stID</b> Check/request node ID, if dynamic node ID set
* - TSM:UPL from <b>stUplink</b> Verify uplink connection by pinging GW * - TSM:UPL from <b>stUplink</b> Verify uplink connection by pinging GW
* - TSM:READY from <b>stReady</b> Transport is ready and fully operational * - TSM:READY from <b>stReady</b> Transport is ready and fully operational
* - TSM:FAILURE from <b>stFailure</b> Failure in transport link or transport HW * - TSM:FAIL from <b>stFailure</b> Failure in transport link or transport HW
* - Transport support function (<b>TSF</b>) * - Transport support function (<b>TSF</b>)
* - TSF:CHKUPL from @ref transportCheckUplink(), checks connection to GW * - TSF:CHKUPL from @ref transportCheckUplink(), checks connection to GW
* - TSF:ASID from @ref transportAssignNodeID(), assigns node ID * - TSF:ASID from @ref transportAssignNodeID(), assigns node ID
@@ -52,7 +52,7 @@
* |E| SYS | SUB | Message | Comment * |E| SYS | SUB | Message | Comment
* |-|------|-----------|-----------------------|--------------------------------------------------------------------- * |-|------|-----------|-----------------------|---------------------------------------------------------------------
* | | TSM | INIT | | <b>Transition to stInit state</b> * | | TSM | INIT | | <b>Transition to stInit state</b>
* | | TSM | INIT | STATID,ID=%%d | Node ID is static * | | TSM | INIT | STATID=%%d | Node ID is static
* | | TSM | INIT | TSP OK | Transport device configured and fully operational * | | TSM | INIT | TSP OK | Transport device configured and fully operational
* | | TSM | INIT | GW MODE | Node is set up as GW, thus omitting ID and findParent states * | | TSM | INIT | GW MODE | Node is set up as GW, thus omitting ID and findParent states
* |!| TSM | INIT | TSP FAIL | Transport device initialization failed * |!| TSM | INIT | TSP FAIL | Transport device initialization failed
@@ -67,13 +67,14 @@
* |!| TSM | ID | FAIL,ID=%%d | ID verification failed, ID invalid * |!| TSM | ID | FAIL,ID=%%d | ID verification failed, ID invalid
* | | TSM | UPL | | <b>Transition to stUplink state</b> * | | TSM | UPL | | <b>Transition to stUplink state</b>
* | | TSM | UPL | OK | Uplink OK, GW returned ping * | | TSM | UPL | OK | Uplink OK, GW returned ping
* | | TSF | UPL | DGWC,O=%%d,N=%%d | Uplink check revealed changed network topology, old distance (O), new distance (N)
* |!| TSM | UPL | FAIL | Uplink check failed, i.e. GW could not be pinged * |!| TSM | UPL | FAIL | Uplink check failed, i.e. GW could not be pinged
* | | TSM | READY | | <b>Transition to stReady</b>, i.e. transport is ready and fully operational * | | TSM | READY | | <b>Transition to stReady</b>, i.e. transport is ready and fully operational
* |!| TSM | READY | UPL FAIL,SNP | Too many failed uplink transmissions, search new parent * |!| TSM | READY | UPL FAIL,SNP | Too many failed uplink transmissions, search new parent
* |!| TSM | READY | FAIL,STATP | Too many failed uplink transmissions, static parent enforced * |!| TSM | READY | FAIL,STATP | Too many failed uplink transmissions, static parent enforced
* | | TSM | FAILURE | | <b>Transition to stFailure state</b> * | | TSM | FAIL | CNT=%%d | <b>Transition to stFailure state</b>, consecutive failure counter (CNT)
* | | TSM | FAILURE | PDT | Power-down transport * | | TSM | FAIL | PDT | Power-down transport
* | | TSM | FAILURE | RE-INIT | Attempt to re-initialize transport * | | TSM | FAIL | RE-INIT | Attempt to re-initialize transport
* | | TSF | CHKUPL | OK | Uplink OK * | | TSF | CHKUPL | OK | Uplink OK
* | | TSF | CHKUPL | OK,FCTRL | Uplink OK, flood control prevents pinging GW in too short intervals * | | TSF | CHKUPL | OK,FCTRL | Uplink OK, flood control prevents pinging GW in too short intervals
* | | TSF | CHKUPL | DGWC,O=%%d,N=%%d | Uplink check revealed changed network topology, old distance (O), new distance (N) * | | TSF | CHKUPL | DGWC,O=%%d,N=%%d | Uplink check revealed changed network topology, old distance (O), new distance (N)
@@ -95,7 +96,8 @@
* | | TSF | MSG | FWD BC MSG | Controlled broadcast message forwarding * | | TSF | MSG | FWD BC MSG | Controlled broadcast message forwarding
* | | TSF | MSG | REL MSG | Relay message * | | TSF | MSG | REL MSG | Relay message
* | | TSF | MSG | REL PxNG,HP=%%d | Relay PING/PONG message, increment hop counter (HP) * | | TSF | MSG | REL PxNG,HP=%%d | Relay PING/PONG message, increment hop counter (HP)
* |!| TSF | MSG | PVER,%%d!=%%d | Message protocol version mismatch * |!| TSF | MSG | LEN,%%d!=%%d | Invalid message length, (actual!=expected)
* |!| TSF | MSG | PVER,%%d!=%%d | Message protocol version mismatch (actual!=expected)
* |!| TSF | MSG | SIGN VERIFY FAIL | Signing verification failed * |!| TSF | MSG | SIGN VERIFY FAIL | Signing verification failed
* |!| TSF | MSG | REL MSG,NORP | Node received a message for relaying, but node is not a repeater, message skipped * |!| TSF | MSG | REL MSG,NORP | Node received a message for relaying, but node is not a repeater, message skipped
* |!| TSF | MSG | SIGN FAIL | Signing message failed * |!| TSF | MSG | SIGN FAIL | Signing message failed
@@ -123,8 +125,9 @@
* - <b>t</b>=msg type * - <b>t</b>=msg type
* - <b>pt</b>=payload type * - <b>pt</b>=payload type
* - <b>l</b>=length * - <b>l</b>=length
* - <b>ft</b>=failed uplink transmission counter
* - <b>sg</b>=signing flag * - <b>sg</b>=signing flag
* - <b>ft</b>=failed uplink transmission counter
* - <b>st</b>=send status, OK=success, NACK=no radio ACK received
* *
* @brief API declaration for MyTransport * @brief API declaration for MyTransport
* *
@@ -139,15 +142,50 @@
#if defined(MY_DEBUG) #if defined(MY_DEBUG)
#define TRANSPORT_DEBUG(x,...) debug(x, ##__VA_ARGS__) //!< debug #define TRANSPORT_DEBUG(x,...) debug(x, ##__VA_ARGS__) //!< debug
#else #else
#define TRANSPORT_DEBUG(x,...) //!< debug NULL #define TRANSPORT_DEBUG(x,...) //!< debug NULL
#endif #endif
#if defined(MY_REPEATER_FEATURE) #if defined(MY_REPEATER_FEATURE)
#define TRANSMISSION_FAILURES 10 //!< search for a new parent node after this many transmission failures, higher threshold for repeating nodes #define MY_TRANSPORT_MAX_TX_FAILURES (10u) //!< search for a new parent node after this many transmission failures, higher threshold for repeating nodes
#else #else
#define TRANSMISSION_FAILURES 5 //!< search for a new parent node after this many transmission failures, lower threshold for non-repeating nodes #define MY_TRANSPORT_MAX_TX_FAILURES (5u) //!< search for a new parent node after this many transmission failures, lower threshold for non-repeating nodes
#endif #endif
#define MY_TRANSPORT_MAX_TSM_FAILURES (15u) //!< Max. number of consecutive TSM failure state entries (4bit)
#ifndef MY_TRANSPORT_TIMEOUT_FAILURE_STATE
#define MY_TRANSPORT_TIMEOUT_FAILURE_STATE (10*1000ul) //!< Duration failure state (in ms)
#endif
#ifndef MY_TRANSPORT_TIMEOUT_EXT_FAILURE_STATE
#define MY_TRANSPORT_TIMEOUT_EXT_FAILURE_STATE (60*1000ul) //!< Duration extended failure state (in ms)
#endif
#ifndef MY_TRANSPORT_STATE_TIMEOUT_MS
#define MY_TRANSPORT_STATE_TIMEOUT_MS (2*1000ul) //!< general state timeout (in ms)
#endif
#ifndef MY_TRANSPORT_CHKUPL_INTERVAL_MS
#define MY_TRANSPORT_CHKUPL_INTERVAL_MS (10*1000ul) //!< Interval to re-check uplink (in ms)
#endif
#ifndef MY_TRANSPORT_STATE_RETRIES
#define MY_TRANSPORT_STATE_RETRIES (3u) //!< retries before switching to FAILURE
#endif
#define AUTO (255u) //!< ID 255 is reserved
#define BROADCAST_ADDRESS (255u) //!< broadcasts are addressed to ID 255
#define DISTANCE_INVALID (255u) //!< invalid distance when searching for parent
#define MAX_HOPS (254u) //!< maximal mumber of hops for ping/pong
#define INVALID_HOPS (255u) //!< invalid hops
#define MAX_SUBSEQ_MSGS (5u) //!< Maximum number of subsequentially processed messages in FIFO (to prevent transport deadlock if HW issue)
// parent node check
#if defined(MY_PARENT_NODE_IS_STATIC) && !defined(MY_PARENT_NODE_ID)
#error MY_PARENT_NODE_IS_STATIC but no MY_PARENT_NODE_ID defined!
#endif
#define _autoFindParent (bool)(MY_PARENT_NODE_ID == AUTO) //!< returns true if static parent id is undefined
#define isValidDistance(distance) (bool)(distance!=DISTANCE_INVALID) //!< returns true if distance is valid
#define isValidParent(parent) (bool)(parent != AUTO) //!< returns true if parent is valid
// RX queue
#if defined(MY_RX_MESSAGE_BUFFER_FEATURE) #if defined(MY_RX_MESSAGE_BUFFER_FEATURE)
#if defined(MY_RADIO_RFM69) #if defined(MY_RADIO_RFM69)
#error Receive message buffering not supported for RFM69! #error Receive message buffering not supported for RFM69!
@@ -159,20 +197,6 @@
#error Receive message buffering requires message buffering feature enabled! #error Receive message buffering requires message buffering feature enabled!
#endif #endif
#define TIMEOUT_FAILURE_STATE 10000 //!< duration failure state
#define STATE_TIMEOUT 2000 //!< general state timeout
#define STATE_RETRIES 3 //!< retries before switching to FAILURE
#define AUTO 255 //!< ID 255 is reserved for auto initialization of nodeId.
#define BROADCAST_ADDRESS ((uint8_t)255) //!< broadcasts are addressed to ID 255
#define DISTANCE_INVALID ((uint8_t)255) //!< invalid distance when searching for parent
#define MAX_HOPS ((uint8_t)254) //!< maximal mumber of hops for ping/pong
#define INVALID_HOPS ((uint8_t)255) //!< invalid hops
#define MAX_SUBSEQ_MSGS 5 //!< Maximum number of subsequentially processed messages in FIFO (to prevent transport deadlock if HW issue)
#define CHKUPL_INTERVAL ((uint32_t)10000) //!< Minimum time interval to re-check uplink
#define _autoFindParent (bool)(MY_PARENT_NODE_ID == AUTO) //!< returns true if static parent id is undefined
#define isValidDistance(distance) (bool)(distance!=DISTANCE_INVALID) //!< returns true if distance is valid
#define isValidParent(parent) (bool)(parent != AUTO) //!< returns true if parent is valid
/** /**
* @brief SM state * @brief SM state
@@ -190,67 +214,82 @@ struct transportState {
* This structure stores transport status and SM variables * This structure stores transport status and SM variables
*/ */
typedef struct { typedef struct {
// SM variables
transportState* currentState; //!< pointer to current fsm state transportState* currentState; //!< pointer to current fsm state
uint32_t stateEnter; //!< state enter timepoint uint32_t stateEnter; //!< state enter timepoint
// general transport variables
uint32_t lastUplinkCheck; //!< last uplink check, required to prevent GW flooding uint32_t lastUplinkCheck; //!< last uplink check, required to prevent GW flooding
uint32_t lastSanityCheck; //!< last sanity check
// 8 bits // 8 bits
bool findingParentNode : 1; //!< flag finding parent node is active bool findingParentNode : 1; //!< flag finding parent node is active
bool preferredParentFound : 1; //!< flag preferred parent found bool preferredParentFound : 1; //!< flag preferred parent found
bool uplinkOk : 1; //!< flag uplink ok bool uplinkOk : 1; //!< flag uplink ok
bool pingActive : 1; //!< flag ping active bool pingActive : 1; //!< flag ping active
bool transportActive : 1; //!< flag transport active bool transportActive : 1; //!< flag transport active
uint8_t reserved : 3; //!< reserved uint8_t stateRetries : 3; //!< retries / state re-enter (max 7)
// 8 bits // 8 bits
uint8_t retries : 4; //!< retries / state re-enter uint8_t failedUplinkTransmissions : 4; //!< counter failed uplink transmissions (max 15)
uint8_t failedUplinkTransmissions : 4; //!< counter failed uplink transmissions uint8_t failureCounter : 4; //!< counter for TSM failures (max 15)
// 8 bits // 8 bits
uint8_t pingResponse; //!< stores hops received in I_PONG uint8_t pingResponse; //!< stores I_PONG hops
} __attribute__((packed)) transportSM; } transportSM;
/**
* @brief RAM routing table
*/
typedef struct {
uint8_t route[256]; //!< route for node
} routingTable;
// PRIVATE functions // PRIVATE functions
/** /**
* @brief Initialize SM variables and transport HW * @brief Initialise SM variables and transport HW
*/ */
void stInitTransition(); void stInitTransition(void);
/**
* @brief Initialise transport
*/
void stInitUpdate(void);
/** /**
* @brief Find parent * @brief Find parent
*/ */
void stParentTransition(); void stParentTransition(void);
/** /**
* @brief Verify find parent responses * @brief Verify find parent responses
*/ */
void stParentUpdate(); void stParentUpdate(void);
/** /**
* @brief Send ID request * @brief Send ID request
*/ */
void stIDTransition(); void stIDTransition(void);
/** /**
* @brief Verify ID response and GW link * @brief Verify ID response and GW link
*/ */
void stIDUpdate(); void stIDUpdate(void);
/** /**
* @brief Send uplink ping request * @brief Send uplink ping request
*/ */
void stUplinkTransition(); void stUplinkTransition(void);
/**
* @brief Verify uplink response
*/
void stUplinkUpdate(void);
/** /**
* @brief Set transport OK * @brief Set transport OK
*/ */
void stReadyTransition(); void stReadyTransition(void);
/** /**
* @brief Monitor transport link * @brief Monitor transport link
*/ */
void stReadyUpdate(); void stReadyUpdate(void);
/** /**
* @brief Transport failure and power down radio * @brief Transport failure and power down radio
*/ */
void stFailureTransition(); void stFailureTransition(void);
/** /**
* @brief Re-initialize transport after timeout * @brief Re-initialize transport after timeout
*/ */
void stFailureUpdate(); void stFailureUpdate(void);
/** /**
* @brief Switch SM state * @brief Switch SM state
* @param newState New state to switch SM to * @param newState New state to switch SM to
@@ -259,30 +298,30 @@ void transportSwitchSM(transportState& newState);
/** /**
* @brief Update SM state * @brief Update SM state
*/ */
void transportUpdateSM(); void transportUpdateSM(void);
/** /**
* @brief Request time in current SM state * @brief Request time in current SM state
* @return ms in current state * @return ms in current state
*/ */
uint32_t transportTimeInState(); uint32_t transportTimeInState(void);
/** /**
* @brief Call transport driver sanity check * @brief Call transport driver sanity check
*/ */
void transportInvokeSanityCheck(); void transportInvokeSanityCheck(void);
/** /**
* @brief Process all pending messages in RX FIFO * @brief Process all pending messages in RX FIFO
*/ */
void transportProcessFIFO(); void transportProcessFIFO(void);
/** /**
* @brief Receive message from RX FIFO and process * @brief Receive message from RX FIFO and process
*/ */
void transportProcessMessage(); void transportProcessMessage(void);
/** /**
* @brief Assign node ID * @brief Assign node ID
* @param newNodeId New node ID * @param newNodeId New node ID
* @return true if node ID valid and successfully assigned * @return true if node ID valid and successfully assigned
*/ */
bool transportAssignNodeID(uint8_t newNodeId); bool transportAssignNodeID(const uint8_t newNodeId);
/** /**
* @brief Wait and process messages for a defined amount of time until specified message received * @brief Wait and process messages for a defined amount of time until specified message received
* @param ms Time to wait and process incoming messages in ms * @param ms Time to wait and process incoming messages in ms
@@ -290,13 +329,13 @@ bool transportAssignNodeID(uint8_t newNodeId);
* @param msgtype Specific message type * @param msgtype Specific message type
* @return true if specified command received within waiting time * @return true if specified command received within waiting time
*/ */
bool transportWait(uint32_t ms, uint8_t cmd, uint8_t msgtype); bool transportWait(const uint32_t ms, const uint8_t cmd, const uint8_t msgtype);
/** /**
* @brief Ping node * @brief Ping node
* @param targetId Node to be pinged * @param targetId Node to be pinged
* @return hops from pinged node or 255 if no answer received within 2000ms * @return hops from pinged node or 255 if no answer received within 2000ms
*/ */
uint8_t transportPingNode(uint8_t targetId); uint8_t transportPingNode(const uint8_t targetId);
/** /**
* @brief Send and route message according to destination * @brief Send and route message according to destination
* *
@@ -318,44 +357,73 @@ bool transportSendRoute(MyMessage &message);
* @param message * @param message
* @return true if message sent successfully * @return true if message sent successfully
*/ */
bool transportSendWrite(uint8_t to, MyMessage &message); bool transportSendWrite(const uint8_t to, MyMessage &message);
/** /**
* @brief Check uplink to GW, includes flooding control * @brief Check uplink to GW, includes flooding control
* @param force to override flood control timer * @param force to override flood control timer
* @return true if uplink ok * @return true if uplink ok
*/ */
bool transportCheckUplink(bool force); bool transportCheckUplink(bool force=false);
// PUBLIC functions // PUBLIC functions
/** /**
* @brief Initialize transport and SM * @brief Initialize transport and SM
*/ */
void transportInitialize(); void transportInitialize(void);
/** /**
* @brief Process FIFO msg and update SM * @brief Process FIFO msg and update SM
*/ */
void transportProcess(); void transportProcess(void);
/** /**
* @brief Flag transport ready * @brief Flag transport ready
* @return true if transport is initialize and ready * @return true if transport is initialize and ready
*/ */
bool isTransportReady(); bool isTransportReady(void);
/** /**
* @brief Flag searching parent ongoing * @brief Flag searching parent ongoing
* @return true if transport is searching for parent * @return true if transport is searching for parent
*/ */
bool isTransportSearchingParent(); bool isTransportSearchingParent(void);
/**
* @brief Flag TSM extended failure
* @return true if TSM had too many consecutive failure state entries
*/
bool isTransportExtendedFailure(void);
/** /**
* @brief Clear routing table * @brief Clear routing table
*/ */
void transportClearRoutingTable(); void transportClearRoutingTable(void);
/** /**
* @brief Return heart beat, i.e. ms in current state * @brief Return heart beat
* @return MS in current state
*/ */
uint32_t transportGetHeartbeat(); uint32_t transportGetHeartbeat(void);
/**
* @brief Load routing table from EEPROM to RAM.
* Only for GW devices with enough RAM, i.e. ESP8266, RPI Sensebender GW, etc.
* Atmega328 has only limited amount of RAM
*/
void transportLoadRoutingTable(void);
/**
* @brief Save routing table to EEPROM.
*/
void transportSaveRoutingTable(void);
/**
* @brief Update routing table
* @param node
* @param route
*/
void transportSetRoute(const uint8_t node, const uint8_t route);
/**
* @brief Load route to node
* @param node
* @return route to node
*/
uint8_t transportGetRoute(const uint8_t node);
// interface functions for radio driver
// interface functions for radio driver ************************************************
/** /**
* @brief Initialize transport HW * @brief Initialize transport HW