We have a cc2530 based system with a single gateway, and multiple routers and sensor modules. All communications is between sensors and the gateway, and never between sensors. Routers are also setup as sensors, if only to ensure connectivity. The system works, however, it does not reliably route when a router goes offline, i.e. a sensor connected through a router will not reroute to ensure connectivity to the gateway and will only come back online once the router it was originally connected to comes back. This was tested in rather close proximity to ensure that there were alternative routes.
I am using the z-stack simple API with only a slight modification to get signal strengths from incoming packets. This was built up from the sample code. Somewhere along the line I must have set some parameter incorrectly, or am doing something out of order so that the routing tables are not correct. I am hoping that someone can take a look at my stripped down code and tell me what I missed. There is no issue with initial connectivity, just rerouting when a node goes offline. I'm guessing either I have a parameter incorrect, or my error handling in some of the events is not correct.
The sensor and router use almost identical code. Both send a periodic report back to the gateway. The router functionality is handled by the Z-stack simple API. Since this forum doesn't appear to have a good way to paste code with proper indentation, I'm attaching the reduced code stripped to the essentials.
Sensor + Router code:
void bindAll(bool create)
{
zb_BindDevice( create, CMD_ID_SENSOR_GATEWAY, (uint8 *)NULL );
}
void zb_HandleOsalEvent( uint16 event )
{
if(event & SYS_EVENT_MSG)
{
}
if( event & ZB_ENTRY_EVENT )
{
uint8 startupOption;
zb_ReadConfiguration(ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startupOption);
if (!(startupOption & ZCD_STARTOPT_DEFAULT_NETWORK_STATE))
{
startupOption |= ZCD_STARTOPT_DEFAULT_NETWORK_STATE;
zb_WriteConfiguration(ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startupOption);
zb_SystemReset();
}
#ifdef _REPEATER
uint8 logicalType;
zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );
if ( logicalType != ZG_DEVICETYPE_ROUTER )
{
logicalType = ZG_DEVICETYPE_ROUTER;
zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
zb_SystemReset();
}
#endif
osal_start_timerEx(sapi_TaskID, EVT_REPORT, 50);
zb_StartRequest();
}
if (event & EVT_START_REQUEST) {
zb_StartRequest();
}
if ( event & EVT_REPORT )
osal_start_timerEx(sapi_TaskID, EVT_REPORT, 100);
}
if ( event & MY_FIND_COLLECTOR_EVT )
{
// Delete previous binding
if ((appState==APP_REPORT) || (appState == APP_SLEEP))
{
bindAll(FALSE);
}
// Find and bind to a collector device
bindAll(TRUE);
}
}
void zb_StartConfirm( uint8 status )
{
// If the device sucessfully started, change state to running
if ( status == ZB_SUCCESS )
{
#ifdef _REPEATER
#else
zb_AllowBind(0);
#endif
// Set event to bind to a collector
osal_set_event( sapi_TaskID, MY_FIND_COLLECTOR_EVT );
}
else {
osal_start_timerEx( sapi_TaskID, EVT_START_REQUEST, 2000 );
}
}
void zb_BindConfirm( uint16 commandId, uint8 status )
{
static uint8 failCount = 0;
if( status == ZB_SUCCESS )
{
osal_set_event( sapi_TaskID, EVT_REPORT );
failCount = 0;
}
else
{
failCount++;
if (failCount > 3) {
zb_SystemReset();
}
osal_start_timerEx( sapi_TaskID, MY_FIND_COLLECTOR_EVT, myBindRetryDelay );
}
}
void zb_SendDataConfirm( uint8 handle, uint8 status )
{
static uint8 registerFailCount = 0;
if(status != ZB_SUCCESS)
{
registerFailCount++;
if (registerFailCount > 3) {
zb_SystemReset();
}
}
else
{
registerFailCount = 0;
}
}
Gateway code:
void zb_HandleOsalEvent( uint16 event )
{
uint8 logicalType;
if(event & SYS_EVENT_MSG)
{
}
if( event & ZB_ENTRY_EVENT )
{
// Force the device type to coordinator
zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );
if ( logicalType != ZG_DEVICETYPE_COORDINATOR )
{
logicalType = ZG_DEVICETYPE_COORDINATOR;
zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
zb_SystemReset();
}
// Start the device
zb_StartRequest();
}
if ( event & MY_START_EVT )
{
zb_StartRequest();
}
if ( event & MY_FIND_COLLECTOR_EVT ) {}
}
void zb_StartConfirm( uint8 status )
{
// If the device sucessfully started, change state to running
if ( status == ZB_SUCCESS )
{
zb_AllowBind( 0xFF ); // Permanently enable allow bind mode
}
else
{
// Try again later with a delay
osal_start_timerEx( sapi_TaskID, MY_START_EVT, myStartRetryDelay );
}
}
Config:
Sensor also has the following flags:
NWK_AUTO_POLL
HOLD_AUTO_START
REFLECTOR
POWER_SAVING
NV_INIT
DEVICE_LOGICAL_TYPE=ZG_DEVICETYPE_ENDDEVICE
ZIGBEEPRO
HAL_LED=FALSE
HAL_KEY=FALSE
HAL_SPI=FALSE
HAL_IRGEN=FALSE
HAL_UART_DMA_RX_MAX=128
HAL_UART_DMA_TX_MAX=128
HAL_UART=TRUE
INT_HEAP_LEN=2048
and in Enddev.cfg:
-DCPU32MHZ // CC2530s Run at 32MHz
-DROOT=__near_func // MAC/ZMAC code in NEAR
/* MAC Settings */
-DMAC_CFG_TX_DATA_MAX=3
-DMAC_CFG_TX_MAX=6
-DMAC_CFG_RX_MAX=3
Router has the following flags:
HOLD_AUTO_START
BUILD_ALL_DEVICES
REFLECTOR
NV_INIT
DEVICE_LOGICAL_TYPE=ZG_DEVICETYPE_ROUTER
ZIGBEEPRO
HAL_LED=FALSE
HAL_KEY=FALSE
HAL_SPI=FALSE
HAL_IRGEN=FALSE
HAL_UART_DMA_RX_MAX=128
HAL_UART_DMA_TX_MAX=128
HAL_UART=TRUE
INT_HEAP_LEN=2048
_REPEATER
Gateway has the following flags:
HOLD_AUTO_START
BUILD_ALL_DEVICES
REFLECTOR
NV_INIT
DEVICE_LOGICAL_TYPE=ZG_DEVICETYPE_COORDINATOR
ZDO_COORDINATOR
RTR_NWK
CONCENTRATOR_ENABLE=true
ZIGBEEPRO
HAL_LED=FALSE
HAL_KEY=FALSE
HAL_SPI=FALSE
HAL_IRGEN=FALSE
HAL_UART_DMA_RX_MAX=128
HAL_UART_DMA_TX_MAX=128
HAL_UART=TRUE
INT_HEAP_LEN=2048