Core optimizations

This commit is contained in:
tekka007
2016-11-14 22:53:30 +01:00
committed by Olivier
parent 58e9d5864f
commit ba80a7e7b1
5 changed files with 98 additions and 105 deletions
+3 -3
View File
@@ -172,10 +172,10 @@
#define MY_CORE_COMPATIBILITY_CHECK #define MY_CORE_COMPATIBILITY_CHECK
/** /**
* @def MY_TRANSPORT_RELAX * @def MY_TRANSPORT_RELAXED
* @brief If enabled, node enters main loop() even if transport / connection to GW is not established * @brief If enabled, node enters main loop() even if transport / connection to GW is not established
*/ */
//#define MY_TRANSPORT_RELAX //#define MY_TRANSPORT_RELAXED
/** /**
* @def MY_NODE_ID * @def MY_NODE_ID
@@ -865,7 +865,7 @@
#define MY_PARENT_NODE_IS_STATIC #define MY_PARENT_NODE_IS_STATIC
#define MY_REGISTRATION_CONTROLLER #define MY_REGISTRATION_CONTROLLER
#define MY_TRANSPORT_UPLINK_CHECK_DISABLED #define MY_TRANSPORT_UPLINK_CHECK_DISABLED
#define MY_TRANSPORT_RELAX #define MY_TRANSPORT_RELAXED
#define MY_DEBUG_VERBOSE_RF24 #define MY_DEBUG_VERBOSE_RF24
#define MY_TRANSPORT_SANITY_CHECK #define MY_TRANSPORT_SANITY_CHECK
#define MY_RF24_IRQ_PIN #define MY_RF24_IRQ_PIN
+21 -26
View File
@@ -29,7 +29,7 @@ MyMessage _msg; // Buffer for incoming messages
MyMessage _msgTmp; // Buffer for temporary messages (acks and nonces among others) MyMessage _msgTmp; // Buffer for temporary messages (acks and nonces among others)
// core configuration // core configuration
coreConfig_t coreConfig; static coreConfig_t _coreConfig;
#if defined(MY_DEBUG) #if defined(MY_DEBUG)
char _convBuf[MAX_PAYLOAD*2+1]; char _convBuf[MAX_PAYLOAD*2+1];
@@ -41,16 +41,13 @@ void (*_timeCallback)(unsigned long);
// Callback for transport=ok transition // Callback for transport=ok transition
void _callbackTransportOk() void _callbackTransportOk()
{ {
if (!coreConfig.presentationSent) { if (!_coreConfig.presentationSent) {
presentNode(); presentNode();
coreConfig.presentationSent = true;
}
#if !defined(MY_GATEWAY_FEATURE) #if !defined(MY_GATEWAY_FEATURE)
if (!coreConfig.registrationRequested) {
_registerNode(); _registerNode();
coreConfig.registrationRequested = true;
}
#endif #endif
_coreConfig.presentationSent = true;
}
} }
void _process(void) { void _process(void) {
@@ -96,8 +93,7 @@ void _begin(void) {
CORE_DEBUG(PSTR("MCO:BGN:INIT " MY_NODE_TYPE ",CP=" MY_CAPABILITIES ",VER=" MYSENSORS_LIBRARY_VERSION "\n")); CORE_DEBUG(PSTR("MCO:BGN:INIT " MY_NODE_TYPE ",CP=" MY_CAPABILITIES ",VER=" MYSENSORS_LIBRARY_VERSION "\n"));
// set defaults // set defaults
coreConfig.presentationSent = false; _coreConfig.presentationSent = false;
coreConfig.registrationRequested = false;
// Call before() in sketch (if it exists) // Call before() in sketch (if it exists)
if (before) { if (before) {
@@ -112,8 +108,8 @@ void _begin(void) {
signerInit(); signerInit();
// Read latest received controller configuration from EEPROM // Read latest received controller configuration from EEPROM
// Note: _cc.isMetric is bool, hence empty EEPROM (=0xFF) evaluates to true (default) // Note: _coreConfig.isMetric is bool, hence empty EEPROM (=0xFF) evaluates to true (default)
hwReadConfigBlock((void*)&coreConfig.controllerConfig, (void*)EEPROM_CONTROLLER_CONFIG_ADDRESS, sizeof(controllerConfig_t)); hwReadConfigBlock((void*)&_coreConfig.controllerConfig, (void*)EEPROM_CONTROLLER_CONFIG_ADDRESS, sizeof(controllerConfig_t));
#if defined(MY_OTA_FIRMWARE_FEATURE) #if defined(MY_OTA_FIRMWARE_FEATURE)
// Read firmware config from EEPROM, i.e. type, version, CRC, blocks // Read firmware config from EEPROM, i.e. type, version, CRC, blocks
@@ -123,13 +119,12 @@ void _begin(void) {
#if defined(MY_SENSOR_NETWORK) #if defined(MY_SENSOR_NETWORK)
// 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);
// Register for transport layer // Register transport=OK callback
transportRegisterTransportOkCallback(_callbackTransportOk); transportRegisterOkCallback(_callbackTransportOk);
// Initialise transport layer // Initialise transport layer
transportInitialise(); transportInitialise();
#if !defined(MY_TRANSPORT_RELAX) #if !defined(MY_TRANSPORT_RELAXED)
// check if transport ready // check if transport ready
while (!isTransportReady()) { while (!isTransportReady()) {
transportProcess(); transportProcess();
@@ -174,14 +169,14 @@ void _registerNode(void)
#if defined (MY_REGISTRATION_FEATURE) && !defined(MY_GATEWAY_FEATURE) #if defined (MY_REGISTRATION_FEATURE) && !defined(MY_GATEWAY_FEATURE)
CORE_DEBUG(PSTR("MCO:REG:REQ\n")); // registration request CORE_DEBUG(PSTR("MCO:REG:REQ\n")); // registration request
setIndication(INDICATION_REQ_REGISTRATION); setIndication(INDICATION_REQ_REGISTRATION);
coreConfig.registered = MY_REGISTRATION_DEFAULT; _coreConfig.nodeRegistered = MY_REGISTRATION_DEFAULT;
uint8_t counter = MY_REGISTRATION_RETRIES; uint8_t counter = MY_REGISTRATION_RETRIES;
// only proceed if register response received or retries exceeded // only proceed if register response received or retries exceeded
do { do {
(void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_REGISTRATION_REQUEST).set(MY_CORE_VERSION)); (void)_sendRoute(build(_msgTmp, GATEWAY_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_REGISTRATION_REQUEST).set(MY_CORE_VERSION));
} while (!wait(2000, C_INTERNAL, I_REGISTRATION_RESPONSE) && counter--); } while (!wait(2000, C_INTERNAL, I_REGISTRATION_RESPONSE) && counter--);
#else #else
coreConfig.registered = true; _coreConfig.registered = true;
CORE_DEBUG(PSTR("MCO:REG:NOT NEEDED\n")); CORE_DEBUG(PSTR("MCO:REG:NOT NEEDED\n"));
#endif #endif
} }
@@ -255,7 +250,7 @@ uint8_t getDistanceGW(void)
} }
controllerConfig_t getConfig(void) { controllerConfig_t getConfig(void) {
return coreConfig.controllerConfig; return _coreConfig.controllerConfig;
} }
@@ -283,7 +278,7 @@ bool send(MyMessage &message, const bool enableAck) {
mSetRequestAck(message, enableAck); mSetRequestAck(message, enableAck);
#if defined(MY_REGISTRATION_FEATURE) && !defined(MY_GATEWAY_FEATURE) #if defined(MY_REGISTRATION_FEATURE) && !defined(MY_GATEWAY_FEATURE)
if (coreConfig.registered) { if (_coreConfig.nodeRegistered) {
return _sendRoute(message); return _sendRoute(message);
} }
else { else {
@@ -346,15 +341,15 @@ bool _processInternalMessages(void) {
} }
else if (type == I_REGISTRATION_RESPONSE) { else if (type == I_REGISTRATION_RESPONSE) {
#if defined (MY_REGISTRATION_FEATURE) && !defined(MY_GATEWAY_FEATURE) #if defined (MY_REGISTRATION_FEATURE) && !defined(MY_GATEWAY_FEATURE)
coreConfig.registered = _msg.getBool(); _coreConfig.nodeRegistered = _msg.getBool();
setIndication(INDICATION_GOT_REGISTRATION); setIndication(INDICATION_GOT_REGISTRATION);
CORE_DEBUG(PSTR("MCO:PIM:NODE REG=%d\n"), coreConfig.registered); // node registration CORE_DEBUG(PSTR("MCO:PIM:NODE REG=%d\n"), _coreConfig.nodeRegistered); // node registration
#endif #endif
} }
else if (type == I_CONFIG) { else if (type == I_CONFIG) {
// Pick up configuration from controller (currently only metric/imperial) and store it in eeprom if changed // Pick up configuration from controller (currently only metric/imperial) and store it in eeprom if changed
coreConfig.controllerConfig.isMetric = _msg.data[0] == 0x00 || _msg.data[0] == 'M'; // metric if null terminated or M _coreConfig.controllerConfig.isMetric = _msg.data[0] == 0x00 || _msg.data[0] == 'M'; // metric if null terminated or M
hwWriteConfigBlock((void*)&coreConfig.controllerConfig, (void*)EEPROM_CONTROLLER_CONFIG_ADDRESS, sizeof(controllerConfig_t)); hwWriteConfigBlock((void*)&_coreConfig.controllerConfig, (void*)EEPROM_CONTROLLER_CONFIG_ADDRESS, sizeof(controllerConfig_t));
} }
else if (type == I_PRESENTATION) { else if (type == I_PRESENTATION) {
// Re-send node presentation to controller // Re-send node presentation to controller
@@ -460,14 +455,14 @@ void wait(const uint32_t waitingMS) {
} }
} }
bool wait(const uint32_t waitingMS, const uint8_t cmd, const uint8_t msgtype) { bool wait(const uint32_t waitingMS, const uint8_t cmd, const uint8_t msgType) {
const uint32_t enteringMS = hwMillis(); const uint32_t enteringMS = hwMillis();
// invalidate msg type // invalidate msg type
_msg.type = !msgtype; _msg.type = !msgType;
bool expectedResponse = false; bool expectedResponse = false;
while ( (hwMillis() - enteringMS < waitingMS) && !expectedResponse ) { while ( (hwMillis() - enteringMS < waitingMS) && !expectedResponse ) {
_process(); _process();
expectedResponse = (mGetCommand(_msg) == cmd && _msg.type == msgtype); expectedResponse = (mGetCommand(_msg) == cmd && _msg.type == msgType);
} }
return expectedResponse; return expectedResponse;
} }
+3 -4
View File
@@ -41,7 +41,7 @@
* |-|------|-------|-----------------------------------------------|---------------------------------------------------------------------------- * |-|------|-------|-----------------------------------------------|----------------------------------------------------------------------------
* | | MCO | BGN | INIT %%s,CP=%%s,LIB=%%s | Core initialization, capabilities (CP), library version (VER) * | | MCO | BGN | INIT %%s,CP=%%s,LIB=%%s | Core initialization, capabilities (CP), library version (VER)
* | | MCO | BGN | BFR | Callback before() * | | MCO | BGN | BFR | Callback before()
* | | MCO | BGN | MTR | MY_TRANSPORT_RELAX enabled * | | MCO | BGN | MTR | MY_TRANSPORT_RELAXED enabled
* | | MCO | BGN | STP | Callback setup() * | | MCO | BGN | STP | Callback setup()
* | | MCO | BGN | INIT OK,TSP=%%d | Core initialised, transport status (TSP), 1=initialised, 0=not initialised * | | MCO | BGN | INIT OK,TSP=%%d | Core initialised, transport status (TSP), 1=initialised, 0=not initialised
* | | MCO | BGN | NODE UNLOCKED | Node successfully unlocked (see signing chapter) * | | MCO | BGN | NODE UNLOCKED | Node successfully unlocked (see signing chapter)
@@ -110,10 +110,9 @@ typedef struct {
typedef struct { typedef struct {
controllerConfig_t controllerConfig; //!< Controller config controllerConfig_t controllerConfig; //!< Controller config
// 8 bit // 8 bit
bool registered : 1; //!< Flag node registered bool nodeRegistered : 1; //!< Flag node registered
bool presentationSent : 1; //!< Flag presentation sent bool presentationSent : 1; //!< Flag presentation sent
bool registrationRequested : 1; //!< Flag registration requested uint8_t reserved : 6; //!< reserved
uint8_t reserved : 5; //!< reserved
} coreConfig_t; } coreConfig_t;
+54 -54
View File
@@ -31,7 +31,7 @@ static transportState_t stFailure = { stFailureTransition, stFailureUpdate };
static transportSM_t _transportSM; static transportSM_t _transportSM;
// transport config // transport config
transportConfig_t transportConfig; static transportConfig_t _transportConfig;
// callbacks // callbacks
transportCallback_t transportOk_cb = NULL; transportCallback_t transportOk_cb = NULL;
@@ -41,7 +41,7 @@ extern MyMessage _msg; // incoming message
extern MyMessage _msgTmp; // outgoing message extern MyMessage _msgTmp; // outgoing message
#if defined(MY_RAM_ROUTING_TABLE_ENABLED) #if defined(MY_RAM_ROUTING_TABLE_ENABLED)
static routingTable _transportRoutingTable; //!< routing table static routingTable_t _transportRoutingTable; //!< routing table
static uint32_t _lastRoutingTableSave; //!< last routing table dump static uint32_t _lastRoutingTableSave; //!< last routing table dump
#endif #endif
@@ -75,7 +75,7 @@ void stInitTransition(void) {
#endif #endif
// Read node settings (ID, parent ID, GW distance) from EEPROM // Read node settings (ID, parent ID, GW distance) from EEPROM
hwReadConfigBlock((void*)&transportConfig, (void*)EEPROM_NODE_ID_ADDRESS, sizeof(transportConfig_t)); hwReadConfigBlock((void*)&_transportConfig, (void*)EEPROM_NODE_ID_ADDRESS, sizeof(transportConfig_t));
} }
void stInitUpdate(void) { void stInitUpdate(void) {
@@ -91,9 +91,9 @@ void stInitUpdate(void) {
#if defined(MY_GATEWAY_FEATURE) #if defined(MY_GATEWAY_FEATURE)
// Set configuration for gateway // Set configuration for gateway
TRANSPORT_DEBUG(PSTR("TSM:INIT:GW MODE\n")); TRANSPORT_DEBUG(PSTR("TSM:INIT:GW MODE\n"));
transportConfig.parentNodeId = GATEWAY_ADDRESS; _transportConfig.parentNodeId = GATEWAY_ADDRESS;
transportConfig.distanceGW = 0u; _transportConfig.distanceGW = 0u;
transportConfig.nodeId = GATEWAY_ADDRESS; _transportConfig.nodeId = GATEWAY_ADDRESS;
transportSetAddress(GATEWAY_ADDRESS); transportSetAddress(GATEWAY_ADDRESS);
// GW mode: skip FPAR,ID,UPL states // GW mode: skip FPAR,ID,UPL states
transportSwitchSM(stReady); transportSwitchSM(stReady);
@@ -101,12 +101,12 @@ void stInitUpdate(void) {
if ((uint8_t)MY_NODE_ID != AUTO) { if ((uint8_t)MY_NODE_ID != AUTO) {
TRANSPORT_DEBUG(PSTR("TSM:INIT:STATID=%d\n"),(uint8_t)MY_NODE_ID); TRANSPORT_DEBUG(PSTR("TSM:INIT:STATID=%d\n"),(uint8_t)MY_NODE_ID);
// Set static ID // Set static ID
transportConfig.nodeId = (uint8_t)MY_NODE_ID; _transportConfig.nodeId = (uint8_t)MY_NODE_ID;
// Save static ID to eeprom (for bootloader) // Save static ID to eeprom (for bootloader)
hwWriteConfig(EEPROM_NODE_ID_ADDRESS, (uint8_t)MY_NODE_ID); hwWriteConfig(EEPROM_NODE_ID_ADDRESS, (uint8_t)MY_NODE_ID);
} }
// assign ID if set // assign ID if set
if (transportConfig.nodeId == AUTO || transportAssignNodeID(transportConfig.nodeId)) { if (_transportConfig.nodeId == AUTO || transportAssignNodeID(_transportConfig.nodeId)) {
// if node ID valid (>0 and <255), proceed to next state // if node ID valid (>0 and <255), proceed to next state
transportSwitchSM(stParent); transportSwitchSM(stParent);
} }
@@ -127,14 +127,14 @@ void stParentTransition(void) {
#if defined(MY_PARENT_NODE_IS_STATIC) #if defined(MY_PARENT_NODE_IS_STATIC)
TRANSPORT_DEBUG(PSTR("TSM:FPAR:STATP=%d\n"), (uint8_t)MY_PARENT_NODE_ID); // static parent TRANSPORT_DEBUG(PSTR("TSM:FPAR:STATP=%d\n"), (uint8_t)MY_PARENT_NODE_ID); // static parent
_transportSM.findingParentNode = false; _transportSM.findingParentNode = false;
transportConfig.distanceGW = 1u; // assumption, CHKUPL:GWDC will update this variable _transportConfig.distanceGW = 1u; // assumption, CHKUPL:GWDC will update this variable
transportConfig.parentNodeId = (uint8_t)MY_PARENT_NODE_ID; _transportConfig.parentNodeId = (uint8_t)MY_PARENT_NODE_ID;
// save parent ID to eeprom (for bootloader) // save parent ID to eeprom (for bootloader)
hwWriteConfig(EEPROM_PARENT_NODE_ID_ADDRESS, (uint8_t)MY_PARENT_NODE_ID); hwWriteConfig(EEPROM_PARENT_NODE_ID_ADDRESS, (uint8_t)MY_PARENT_NODE_ID);
#else #else
_transportSM.findingParentNode = true; _transportSM.findingParentNode = true;
transportConfig.distanceGW = DISTANCE_INVALID; // Set distance to max and invalidate parent node ID _transportConfig.distanceGW = DISTANCE_INVALID; // Set distance to max and invalidate parent node ID
transportConfig.parentNodeId = AUTO; _transportConfig.parentNodeId = AUTO;
// Broadcast find parent request // Broadcast find parent request
(void)transportRouteMessage(build(_msgTmp, BROADCAST_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_REQUEST).set("")); (void)transportRouteMessage(build(_msgTmp, BROADCAST_ADDRESS, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_REQUEST).set(""));
#endif #endif
@@ -149,7 +149,7 @@ void stParentUpdate(void) {
#else #else
if (transportTimeInState() > MY_TRANSPORT_STATE_TIMEOUT_MS || _transportSM.preferredParentFound) { if (transportTimeInState() > MY_TRANSPORT_STATE_TIMEOUT_MS || _transportSM.preferredParentFound) {
// timeout or preferred parent found // timeout or preferred parent found
if (transportConfig.parentNodeId != AUTO) { if (_transportConfig.parentNodeId != AUTO) {
// parent assigned // parent assigned
TRANSPORT_DEBUG(PSTR("TSM:FPAR:OK\n")); // find parent ok TRANSPORT_DEBUG(PSTR("TSM:FPAR:OK\n")); // find parent ok
_transportSM.findingParentNode = false; _transportSM.findingParentNode = false;
@@ -179,7 +179,7 @@ void stParentUpdate(void) {
// stID: verify and request ID if necessary // stID: verify and request ID if necessary
void stIDTransition(void) { void stIDTransition(void) {
TRANSPORT_DEBUG(PSTR("TSM:ID\n")); // verify/request node ID TRANSPORT_DEBUG(PSTR("TSM:ID\n")); // verify/request node ID
if (transportConfig.nodeId == AUTO) { if (_transportConfig.nodeId == AUTO) {
// send ID request // send ID request
setIndication(INDICATION_REQ_NODEID); setIndication(INDICATION_REQ_NODEID);
TRANSPORT_DEBUG(PSTR("TSM:ID:REQ\n")); // request node ID TRANSPORT_DEBUG(PSTR("TSM:ID:REQ\n")); // request node ID
@@ -188,7 +188,7 @@ void stIDTransition(void) {
} }
void stIDUpdate(void) { void stIDUpdate(void) {
if (transportConfig.nodeId != AUTO) { if (_transportConfig.nodeId != AUTO) {
// current node ID is valid // current node ID is valid
TRANSPORT_DEBUG(PSTR("TSM:ID:OK\n")); TRANSPORT_DEBUG(PSTR("TSM:ID:OK\n"));
setIndication(INDICATION_GOT_NODEID); setIndication(INDICATION_GOT_NODEID);
@@ -227,9 +227,9 @@ void stUplinkUpdate(void) {
// uplink ok, i.e. GW replied // uplink ok, i.e. GW replied
TRANSPORT_DEBUG(PSTR("TSM:UPL:OK\n")); // uplink ok TRANSPORT_DEBUG(PSTR("TSM:UPL:OK\n")); // uplink ok
//_transportSM.pingActive = false; ==> set false upon receiving I_PONG //_transportSM.pingActive = false; ==> set false upon receiving I_PONG
if (_transportSM.pingResponse != transportConfig.distanceGW) { if (_transportSM.pingResponse != _transportConfig.distanceGW) {
TRANSPORT_DEBUG(PSTR("TSM:UPL:DGWC,O=%d,N=%d\n"), transportConfig.distanceGW, _transportSM.pingResponse); // distance to GW changed TRANSPORT_DEBUG(PSTR("TSM:UPL:DGWC,O=%d,N=%d\n"), _transportConfig.distanceGW, _transportSM.pingResponse); // distance to GW changed
transportConfig.distanceGW = _transportSM.pingResponse; _transportConfig.distanceGW = _transportSM.pingResponse;
} }
transportSwitchSM(stReady); // proceed to next state transportSwitchSM(stReady); // proceed to next state
} }
@@ -263,7 +263,7 @@ void stReadyTransition(void) {
if (transportOk_cb) { if (transportOk_cb) {
transportOk_cb(); transportOk_cb();
} }
TRANSPORT_DEBUG(PSTR("TSM:READY:PARAM,ID=%d,PAR=%d,DIS=%d\n"), transportConfig.nodeId, transportConfig.parentNodeId, transportConfig.distanceGW); TRANSPORT_DEBUG(PSTR("TSM:READY:PARAM,ID=%d,PAR=%d,DIS=%d\n"), _transportConfig.nodeId, _transportConfig.parentNodeId, _transportConfig.distanceGW);
} }
// stReadyUpdate: monitors link // stReadyUpdate: monitors link
@@ -393,9 +393,9 @@ bool transportCheckUplink(const bool force) {
_transportSM.lastUplinkCheck = hwMillis(); _transportSM.lastUplinkCheck = hwMillis();
TRANSPORT_DEBUG(PSTR("TSF:CKU:OK\n")); TRANSPORT_DEBUG(PSTR("TSF:CKU:OK\n"));
// did distance to GW change upstream, eg. re-routing of uplink nodes // did distance to GW change upstream, eg. re-routing of uplink nodes
if (hopsCount != transportConfig.distanceGW) { if (hopsCount != _transportConfig.distanceGW) {
TRANSPORT_DEBUG(PSTR("TSF:CKU:DGWC,O=%d,N=%d\n"), transportConfig.distanceGW, hopsCount); // distance to GW changed TRANSPORT_DEBUG(PSTR("TSF:CKU:DGWC,O=%d,N=%d\n"), _transportConfig.distanceGW, hopsCount); // distance to GW changed
transportConfig.distanceGW = hopsCount; _transportConfig.distanceGW = hopsCount;
} }
return true; return true;
} }
@@ -408,7 +408,7 @@ bool transportCheckUplink(const bool force) {
bool transportAssignNodeID(const uint8_t newNodeId) { bool transportAssignNodeID(const uint8_t newNodeId) {
// verify if ID valid // verify if ID valid
if (newNodeId != GATEWAY_ADDRESS && newNodeId != AUTO) { if (newNodeId != GATEWAY_ADDRESS && newNodeId != AUTO) {
transportConfig.nodeId = newNodeId; _transportConfig.nodeId = newNodeId;
transportSetAddress(newNodeId); transportSetAddress(newNodeId);
// Write ID to EEPROM // Write ID to EEPROM
hwWriteConfig(EEPROM_NODE_ID_ADDRESS, newNodeId); hwWriteConfig(EEPROM_NODE_ID_ADDRESS, newNodeId);
@@ -418,14 +418,14 @@ bool transportAssignNodeID(const uint8_t newNodeId) {
else { else {
TRANSPORT_DEBUG(PSTR("!TSF:SID:FAIL,ID=%d\n"),newNodeId); // ID is invalid, cannot assign ID TRANSPORT_DEBUG(PSTR("!TSF:SID:FAIL,ID=%d\n"),newNodeId); // ID is invalid, cannot assign ID
setIndication(INDICATION_ERR_NET_FULL); setIndication(INDICATION_ERR_NET_FULL);
transportConfig.nodeId = AUTO; _transportConfig.nodeId = AUTO;
return false; return false;
} }
} }
bool transportRouteMessage(MyMessage &message) { bool transportRouteMessage(MyMessage &message) {
const uint8_t destination = message.destination; const uint8_t destination = message.destination;
uint8_t route = transportConfig.parentNodeId; // by default, all traffic is routed via parent node uint8_t route = _transportConfig.parentNodeId; // by default, all traffic is routed via parent node
if (_transportSM.findingParentNode && destination != BROADCAST_ADDRESS) { if (_transportSM.findingParentNode && destination != BROADCAST_ADDRESS) {
TRANSPORT_DEBUG(PSTR("!TSF:RTE:FPAR ACTIVE\n")); // find parent active, message not sent TRANSPORT_DEBUG(PSTR("!TSF:RTE:FPAR ACTIVE\n")); // find parent active, message not sent
@@ -434,7 +434,7 @@ bool transportRouteMessage(MyMessage &message) {
} }
if (destination == GATEWAY_ADDRESS) { if (destination == GATEWAY_ADDRESS) {
route = transportConfig.parentNodeId; // message to GW always routes via parent route = _transportConfig.parentNodeId; // message to GW always routes via parent
} }
else if (destination == BROADCAST_ADDRESS) { else if (destination == BROADCAST_ADDRESS) {
route = BROADCAST_ADDRESS; // message to BC does not require routing route = BROADCAST_ADDRESS; // message to BC does not require routing
@@ -446,9 +446,9 @@ bool transportRouteMessage(MyMessage &message) {
if (route == AUTO) { if (route == AUTO) {
TRANSPORT_DEBUG(PSTR("!TSF:RTE:%d UNKNOWN\n"), destination); // route unknown TRANSPORT_DEBUG(PSTR("!TSF:RTE:%d UNKNOWN\n"), destination); // route unknown
#if !defined(MY_GATEWAY_FEATURE) #if !defined(MY_GATEWAY_FEATURE)
if (message.last != transportConfig.parentNodeId) { if (message.last != _transportConfig.parentNodeId) {
// message not from parent, i.e. child node - route it to parent // message not from parent, i.e. child node - route it to parent
route = transportConfig.parentNodeId; route = _transportConfig.parentNodeId;
} }
else { else {
// route unknown and msg received from parent, send it to destination assuming in rx radius // route unknown and msg received from parent, send it to destination assuming in rx radius
@@ -460,14 +460,14 @@ bool transportRouteMessage(MyMessage &message) {
#endif #endif
} }
#else #else
route = transportConfig.parentNodeId; // not a repeater, all traffic routed via parent route = _transportConfig.parentNodeId; // not a repeater, all traffic routed via parent
#endif #endif
} }
// send message // send message
const bool result = transportSendWrite(route, message); const bool result = transportSendWrite(route, message);
#if !defined(MY_GATEWAY_FEATURE) #if !defined(MY_GATEWAY_FEATURE)
// update counter // update counter
if (route == transportConfig.parentNodeId) { if (route == _transportConfig.parentNodeId) {
if (!result) { if (!result) {
setIndication(INDICATION_ERR_TX); setIndication(INDICATION_ERR_TX);
_transportSM.failedUplinkTransmissions++; _transportSM.failedUplinkTransmissions++;
@@ -496,16 +496,16 @@ bool transportSendRoute(MyMessage &message) {
} }
// only be used inside transport // only be used inside transport
bool transportWait(const uint32_t ms, const uint8_t cmd, const uint8_t msgtype){ bool transportWait(const uint32_t waitingMS, const uint8_t cmd, const uint8_t msgType){
const uint32_t enter = hwMillis(); const uint32_t enterMS = hwMillis();
// invalidate msg type // invalidate msg type
_msg.type = !msgtype; _msg.type = !msgType;
bool expectedResponse = false; bool expectedResponse = false;
while ((hwMillis() - enter < ms) && !expectedResponse) { while ((hwMillis() - enterMS < waitingMS) && !expectedResponse) {
// process incoming messages // process incoming messages
transportProcessFIFO(); transportProcessFIFO();
doYield(); doYield();
expectedResponse = (mGetCommand(_msg) == cmd && _msg.type == msgtype); expectedResponse = (mGetCommand(_msg) == cmd && _msg.type == msgType);
} }
return expectedResponse; return expectedResponse;
} }
@@ -513,7 +513,7 @@ bool transportWait(const uint32_t ms, const uint8_t cmd, const uint8_t msgtype){
uint8_t transportPingNode(const uint8_t targetId) { uint8_t transportPingNode(const uint8_t targetId) {
if(!_transportSM.pingActive){ if(!_transportSM.pingActive){
TRANSPORT_DEBUG(PSTR("TSF:PNG:SEND,TO=%d\n"), targetId); TRANSPORT_DEBUG(PSTR("TSF:PNG:SEND,TO=%d\n"), targetId);
if(targetId == transportConfig.nodeId) { if(targetId == _transportConfig.nodeId) {
// pinging self // pinging self
_transportSM.pingResponse = 0u; _transportSM.pingResponse = 0u;
} }
@@ -581,7 +581,7 @@ void transportProcessMessage(void) {
// update routing table if msg not from parent // update routing table if msg not from parent
#if defined(MY_REPEATER_FEATURE) #if defined(MY_REPEATER_FEATURE)
#if !defined(MY_GATEWAY_FEATURE) #if !defined(MY_GATEWAY_FEATURE)
if (last != transportConfig.parentNodeId) { if (last != _transportConfig.parentNodeId) {
#else #else
// GW doesn't have parent // GW doesn't have parent
{ {
@@ -595,7 +595,7 @@ void transportProcessMessage(void) {
_transportSM.msgReceived = true; _transportSM.msgReceived = true;
// Is message addressed to this node? // Is message addressed to this node?
if (destination == transportConfig.nodeId) { if (destination == _transportConfig.nodeId) {
// prevent buffer overflow by limiting max. possible message length (5 bits=31 bytes max) to MAX_PAYLOAD (25 bytes) // prevent buffer overflow by limiting max. possible message length (5 bits=31 bytes max) to MAX_PAYLOAD (25 bytes)
mSetLength(_msg, min(mGetLength(_msg),(uint8_t)MAX_PAYLOAD)); mSetLength(_msg, min(mGetLength(_msg),(uint8_t)MAX_PAYLOAD));
// null terminate data // null terminate data
@@ -606,7 +606,7 @@ void transportProcessMessage(void) {
_msgTmp = _msg; // Copy message _msgTmp = _msg; // Copy message
mSetRequestAck(_msgTmp, false); // Reply without ack flag (otherwise we would end up in an eternal loop) mSetRequestAck(_msgTmp, false); // Reply without ack flag (otherwise we would end up in an eternal loop)
mSetAck(_msgTmp, true); // set ACK flag mSetAck(_msgTmp, true); // set ACK flag
_msgTmp.sender = transportConfig.nodeId; _msgTmp.sender = _transportConfig.nodeId;
_msgTmp.destination = sender; _msgTmp.destination = sender;
// send ACK, use transportSendRoute since ACK reply is not internal, i.e. if !transportOK do not reply // send ACK, use transportSendRoute since ACK reply is not internal, i.e. if !transportOK do not reply
(void)transportSendRoute(_msgTmp); (void)transportSendRoute(_msgTmp);
@@ -634,15 +634,15 @@ void transportProcessMessage(void) {
if (isValidDistance(distance)) { if (isValidDistance(distance)) {
distance++; // Distance to gateway is one more for us w.r.t. parent distance++; // Distance to gateway is one more for us w.r.t. parent
// update settings if distance shorter or preferred parent found // update settings if distance shorter or preferred parent found
if (((isValidDistance(distance) && distance < transportConfig.distanceGW) || (!_autoFindParent && sender == (uint8_t)MY_PARENT_NODE_ID)) && !_transportSM.preferredParentFound) { if (((isValidDistance(distance) && distance < _transportConfig.distanceGW) || (!_autoFindParent && sender == (uint8_t)MY_PARENT_NODE_ID)) && !_transportSM.preferredParentFound) {
// Found a neighbor closer to GW than previously found // Found a neighbor closer to GW than previously found
if (!_autoFindParent && sender == (uint8_t)MY_PARENT_NODE_ID) { if (!_autoFindParent && sender == (uint8_t)MY_PARENT_NODE_ID) {
_transportSM.preferredParentFound = true; _transportSM.preferredParentFound = true;
TRANSPORT_DEBUG(PSTR("TSF:MSG:FPAR PREF\n")); // find parent, preferred parent found TRANSPORT_DEBUG(PSTR("TSF:MSG:FPAR PREF\n")); // find parent, preferred parent found
} }
transportConfig.distanceGW = distance; _transportConfig.distanceGW = distance;
transportConfig.parentNodeId = sender; _transportConfig.parentNodeId = sender;
TRANSPORT_DEBUG(PSTR("TSF:MSG:FPAR OK,ID=%d,D=%d\n"), transportConfig.parentNodeId, transportConfig.distanceGW); TRANSPORT_DEBUG(PSTR("TSF:MSG:FPAR OK,ID=%d,D=%d\n"), _transportConfig.parentNodeId, _transportConfig.distanceGW);
} }
} }
} }
@@ -704,7 +704,7 @@ void transportProcessMessage(void) {
// only reply if node is fully operational // only reply if node is fully operational
if (type == I_FIND_PARENT_REQUEST) { if (type == I_FIND_PARENT_REQUEST) {
#if defined(MY_REPEATER_FEATURE) #if defined(MY_REPEATER_FEATURE)
if (sender != transportConfig.parentNodeId) { // no circular reference if (sender != _transportConfig.parentNodeId) { // no circular reference
TRANSPORT_DEBUG(PSTR("TSF:MSG:FPAR REQ,ID=%d\n"), sender); // FPAR: find parent request TRANSPORT_DEBUG(PSTR("TSF:MSG:FPAR REQ,ID=%d\n"), sender); // FPAR: find parent request
// check if uplink functional - node can only be parent node if link to GW functional // check if uplink functional - node can only be parent node if link to GW functional
// this also prevents circular references in case GW ooo // this also prevents circular references in case GW ooo
@@ -713,7 +713,7 @@ void transportProcessMessage(void) {
TRANSPORT_DEBUG(PSTR("TSF:MSG:GWL OK\n")); // GW uplink ok TRANSPORT_DEBUG(PSTR("TSF:MSG:GWL OK\n")); // GW uplink ok
// random delay minimizes collisions // random delay minimizes collisions
delay(hwMillis() & 0x3ff); delay(hwMillis() & 0x3ff);
(void)transportRouteMessage(build(_msgTmp, sender, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_RESPONSE).set(transportConfig.distanceGW)); (void)transportRouteMessage(build(_msgTmp, sender, NODE_SENSOR_ID, C_INTERNAL, I_FIND_PARENT_RESPONSE).set(_transportConfig.distanceGW));
} }
else { else {
TRANSPORT_DEBUG(PSTR("!TSF:MSG:GWL FAIL\n")); // GW uplink fail, do not respond to parent request TRANSPORT_DEBUG(PSTR("!TSF:MSG:GWL FAIL\n")); // GW uplink fail, do not respond to parent request
@@ -728,10 +728,10 @@ void transportProcessMessage(void) {
} }
#if !defined(MY_GATEWAY_FEATURE) #if !defined(MY_GATEWAY_FEATURE)
if (type == I_DISCOVER_REQUEST) { if (type == I_DISCOVER_REQUEST) {
if (last == transportConfig.parentNodeId) { if (last == _transportConfig.parentNodeId) {
// random wait to minimize collisions // random wait to minimize collisions
delay(hwMillis() & 0x3ff); delay(hwMillis() & 0x3ff);
(void)transportRouteMessage(build(_msgTmp, sender, NODE_SENSOR_ID, C_INTERNAL, I_DISCOVER_RESPONSE).set(transportConfig.parentNodeId)); (void)transportRouteMessage(build(_msgTmp, sender, NODE_SENSOR_ID, C_INTERNAL, I_DISCOVER_RESPONSE).set(_transportConfig.parentNodeId));
// no return here (for fwd if repeater) // no return here (for fwd if repeater)
} }
} }
@@ -740,7 +740,7 @@ void transportProcessMessage(void) {
// controlled BC relay // controlled BC relay
#if defined(MY_REPEATER_FEATURE) #if defined(MY_REPEATER_FEATURE)
// controlled BC repeating: forward only if message received from parent and sender not self to prevent circular fwds // controlled BC repeating: forward only if message received from parent and sender not self to prevent circular fwds
if(last == transportConfig.parentNodeId && sender != transportConfig.nodeId && isTransportReady()){ if(last == _transportConfig.parentNodeId && sender != _transportConfig.nodeId && isTransportReady()){
TRANSPORT_DEBUG(PSTR("TSF:MSG:FWD BC MSG\n")); // controlled broadcast msg forwarding TRANSPORT_DEBUG(PSTR("TSF:MSG:FWD BC MSG\n")); // controlled broadcast msg forwarding
(void)transportRouteMessage(_msg); (void)transportRouteMessage(_msg);
} }
@@ -750,7 +750,7 @@ void transportProcessMessage(void) {
if (command != C_INTERNAL) { if (command != C_INTERNAL) {
#if !defined(MY_GATEWAY_FEATURE) #if !defined(MY_GATEWAY_FEATURE)
// only proceed if message received from parent // only proceed if message received from parent
if (last != transportConfig.parentNodeId) { if (last != _transportConfig.parentNodeId) {
return; return;
} }
#endif #endif
@@ -825,7 +825,7 @@ void transportProcessFIFO(void) {
} }
bool transportSendWrite(const uint8_t to, MyMessage &message) { bool transportSendWrite(const uint8_t to, MyMessage &message) {
message.last = transportConfig.nodeId; // Update last message.last = _transportConfig.nodeId; // Update last
// sign message if required // sign message if required
if (!signerSignMsg(message)) { if (!signerSignMsg(message)) {
TRANSPORT_DEBUG(PSTR("!TSF:MSG:SIGN FAIL\n")); TRANSPORT_DEBUG(PSTR("!TSF:MSG:SIGN FAIL\n"));
@@ -849,22 +849,22 @@ bool transportSendWrite(const uint8_t to, MyMessage &message) {
return result; return result;
} }
void transportRegisterTransportOkCallback(transportCallback_t cb) void transportRegisterOkCallback(transportCallback_t cb)
{ {
transportOk_cb = cb; transportOk_cb = cb;
} }
uint8_t transportGetNodeId(void) uint8_t transportGetNodeId(void)
{ {
return transportConfig.nodeId; return _transportConfig.nodeId;
} }
uint8_t transportGetParentNodeId(void) uint8_t transportGetParentNodeId(void)
{ {
return transportConfig.parentNodeId; return _transportConfig.parentNodeId;
} }
uint8_t transportGetDistanceGW(void) uint8_t transportGetDistanceGW(void)
{ {
return transportConfig.distanceGW; return _transportConfig.distanceGW;
} }
+17 -18
View File
@@ -190,8 +190,8 @@
#endif #endif
#define _autoFindParent (bool)(MY_PARENT_NODE_ID == AUTO) //!< returns true if static parent id is undefined #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 isValidDistance(_distance) (bool)(_distance!=DISTANCE_INVALID) //!< returns true if distance is valid
#define isValidParent(parent) (bool)(parent != AUTO) //!< returns true if parent is valid #define isValidParent(_parent) (bool)(_parent != AUTO) //!< returns true if parent is valid
// RX queue // RX queue
#if defined(MY_RX_MESSAGE_BUFFER_FEATURE) #if defined(MY_RX_MESSAGE_BUFFER_FEATURE)
@@ -206,23 +206,22 @@
#endif #endif
/** /**
* @brief Callback * @brief Callback type
* */
*/
typedef void(*transportCallback_t)(void); typedef void(*transportCallback_t)(void);
/** /**
* @brief Node configuration * @brief Node configuration
* *
* This structure stores node-related configurations * This structure stores node-related configurations
*/ */
typedef struct { typedef struct {
uint8_t nodeId; //!< Current node id uint8_t nodeId; //!< Current node id
uint8_t parentNodeId; //!< Where this node sends its messages uint8_t parentNodeId; //!< Where this node sends its messages
uint8_t distanceGW; //!< This nodes distance to sensor net gateway (number of hops) uint8_t distanceGW; //!< This nodes distance to sensor net gateway (number of hops)
} transportConfig_t; } transportConfig_t;
/** /**
* @brief SM state * @brief SM state
* *
* This structure stores SM state definitions * This structure stores SM state definitions
@@ -233,10 +232,10 @@ typedef struct {
} transportState_t; } transportState_t;
/** /**
* @brief Status variables and SM state * @brief Status variables and SM state
* *
* This structure stores transport status and SM variables * This structure stores transport status and SM variables
*/ */
typedef struct { typedef struct {
// SM variables // SM variables
transportState_t* currentState; //!< pointer to current fsm state transportState_t* currentState; //!< pointer to current fsm state
@@ -263,7 +262,7 @@ typedef struct {
*/ */
typedef struct { typedef struct {
uint8_t route[SIZE_ROUTES]; //!< route for node uint8_t route[SIZE_ROUTES]; //!< route for node
} routingTable; } routingTable_t;
// PRIVATE functions // PRIVATE functions
@@ -349,12 +348,12 @@ void transportProcessMessage(void);
bool transportAssignNodeID(const 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 waitingMS Time to wait and process incoming messages in ms
* @param cmd Specific command * @param cmd Specific command
* @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(const uint32_t ms, const uint8_t cmd, const uint8_t msgtype); bool transportWait(const uint32_t waitingMS, 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