📄 zdapp.c
字号:
if ( events & ZDO_SECMGR_EVENT )
{
ZDSecMgrEvent();
// Return unprocessed events
return (events ^ ZDO_SECMGR_EVENT);
}
#endif // defined( ZDSECMGR_COMMERCIAL )
#if ( SECURE != 0 )
if ( events & ZDO_DEVICE_AUTH )
{
ZDApp_DeviceAuthEvt();
// Return unprocessed events
return (events ^ ZDO_DEVICE_AUTH);
}
#endif // SECURE
if ( events & ZDO_NWK_UPDATE_NV )
{
ZDApp_SaveNetworkStateEvt();
// Return unprocessed events
return (events ^ ZDO_NWK_UPDATE_NV);
}
#if ( SECURE != 0 )
if ( events & ZDO_FRAMECOUNTER_CHANGE )
{
if ( nwkFrameCounterChanges++ > MAX_NWK_FRAMECOUNTER_CHANGES )
ZDApp_SaveNwkKey();
// Return unprocessed events
return (events ^ ZDO_FRAMECOUNTER_CHANGE);
}
#endif
if ( events & ZDO_DEVICE_RESET )
{
// The device has been in the UNAUTH state, so reset
// Note: there will be no return from this call
SystemReset();
}
// Discard or make more handlers
return 0;
}
/*********************************************************************
* Application Functions
*/
/*********************************************************************
* @fn ZDOInitDevice
*
* @brief Start the device in the network. This function will read
* ZCD_NV_STARTUP_OPTION (NV item) to determine whether or not to
* restore the network state of the device.
*
* @param startDelay - timeDelay to start device (in milliseconds).
* There is a jitter added to this delay:
* ((NWK_START_DELAY + startDelay)
* + (osal_rand() & EXTENDED_JOINING_RANDOM_MASK))
*
* NOTE: If the application would like to force a "new" join, the
* application should set the ZCD_STARTOPT_DEFAULT_NETWORK_STATE
* bit in the ZCD_NV_STARTUP_OPTION NV item before calling
* this function. "new" join means to not restore the network
* state of the device. Use zgWriteStartupOptions() to set these
* options.
*
* @return
* ZDO_INITDEV_RESTORED_NETWORK_STATE - The device's network state was
* restored.
* ZDO_INITDEV_NEW_NETWORK_STATE - The network state was initialized.
* This could mean that ZCD_NV_STARTUP_OPTION said to not restore, or
* it could mean that there was no network state to restore.
* ZDO_INITDEV_LEAVE_NOT_STARTED - Before the reset, a network leave was issued
* with the rejoin option set to TRUE. So, the device was not
* started in the network (one time only). The next time this
* function is called it will start.
*/
uint8 ZDOInitDevice( uint16 startDelay )
{
uint8 networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE;
uint16 extendedDelay = 0;
devState = DEV_INIT; // Remove the Hold state
// Initialize leave control logic
ZDApp_LeaveCtrlInit();
// Check leave control reset settings
ZDApp_LeaveCtrlStartup( &devState, &startDelay );
// Leave may make the hold state come back
if ( devState == DEV_HOLD )
return ( ZDO_INITDEV_LEAVE_NOT_STARTED ); // Don't join - (one time).
#if defined ( NV_RESTORE )
// Get Keypad directly to see if a reset nv is needed.
// Hold down the SW_BYPASS_NV key (defined in OnBoard.h)
// while booting to skip past NV Restore.
if ( HalKeyRead() == SW_BYPASS_NV )
networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE;
else
{
// Determine if NV should be restored
networkStateNV = ZDApp_ReadNetworkRestoreState();
}
if ( networkStateNV == ZDO_INITDEV_RESTORED_NETWORK_STATE )
{
networkStateNV = ZDApp_RestoreNetworkState();
}
else
{
// Wipe out the network state in NV
NLME_InitNV();
NLME_SetDefaultNV();
}
#endif
if ( networkStateNV == ZDO_INITDEV_NEW_NETWORK_STATE )
{
ZDAppDetermineDeviceType();
// Only delay if joining network - not restoring network state
extendedDelay = (uint16)((NWK_START_DELAY + startDelay)
+ (osal_rand() & EXTENDED_JOINING_RANDOM_MASK));
}
// Initialize device security
ZDApp_SecInit( networkStateNV );
// Trigger the network start
ZDApp_NetworkInit( extendedDelay );
return ( networkStateNV );
}
/*********************************************************************
* @fn ZDApp_ReadNetworkRestoreState
*
* @brief Read the ZCD_NV_STARTUP_OPTION NV Item to state whether
* or not to restore the network state.
* If the read value has the ZCD_STARTOPT_DEFAULT_NETWORK_STATE
* bit set return the ZDO_INITDEV_NEW_NETWORK_STATE.
*
* @param none
*
* @return ZDO_INITDEV_NEW_NETWORK_STATE
* or ZDO_INITDEV_RESTORED_NETWORK_STATE based on whether or
* not ZCD_STARTOPT_DEFAULT_NETWORK_STATE bit is set in
* ZCD_NV_STARTUP_OPTION
*/
uint8 ZDApp_ReadNetworkRestoreState( void )
{
uint8 networkStateNV = ZDO_INITDEV_RESTORED_NETWORK_STATE;
// Look for the New Network State option.
if ( zgReadStartupOptions() & ZCD_STARTOPT_DEFAULT_NETWORK_STATE )
{
networkStateNV = ZDO_INITDEV_NEW_NETWORK_STATE;
}
return ( networkStateNV );
}
/*********************************************************************
* @fn ZDAppDetermineDeviceType()
*
* @brief Determines the type of device to start. Right now
* this only works with the SOFT_START feature. So it doesn't
* support the end device type.
*
* Looks at zgDeviceLogicalType and determines what type of
* device to start. The types are:
* ZG_DEVICETYPE_COORDINATOR
* ZG_DEVICETYPE_ROUTER
* ZG_DEVICETYPE_ENDDEVICE - not supported yet.
* ZG_DEVICETYPE_SOFT - looks for coordinator, if one doesn't
* exist, becomes one. This option is should only be used
* if the system is manually configured and you are insured
* that the first device is started before all the other
* devices are started.
*
* @param none
*
* @return none
*/
void ZDAppDetermineDeviceType( void )
{
if ( zgDeviceLogicalType == ZG_DEVICETYPE_ENDDEVICE )
return;
#if defined ( SOFT_START )
if ( zgDeviceLogicalType == ZG_DEVICETYPE_COORDINATOR )
{
devStartMode = MODE_HARD; // Start as a coordinator
ZDO_Config_Node_Descriptor.LogicalType = NODETYPE_COORDINATOR;
}
else
{
if ( zgDeviceLogicalType == ZG_DEVICETYPE_ROUTER )
{
softStartAllowCoord = FALSE; // Don't allow coord to start
continueJoining = TRUE;
}
devStartMode = MODE_JOIN; // Assume joining
}
#endif // SOFT_START
}
/*********************************************************************
* @fn ZDApp_NetworkStartEvt()
*
* @brief Process the Network Start Event
*
* @param none
*
* @return none
*/
void ZDApp_NetworkStartEvt( void )
{
if ( nwkStatus == ZSuccess )
{
// Successfully started a ZigBee network
if ( devState == DEV_COORD_STARTING )
{
devState = DEV_ZB_COORD;
}
osal_pwrmgr_device( PWRMGR_ALWAYS_ON );
osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT );
}
else
{
// Try again with a higher energy threshold !!
if ( ( NLME_GetEnergyThreshold() + ENERGY_SCAN_INCREMENT ) < 0xff )
{
NLME_SetEnergyThreshold( (uint8)(NLME_GetEnergyThreshold() + ENERGY_SCAN_INCREMENT) );
osal_set_event( ZDAppTaskID, ZDO_NETWORK_INIT );
}
else
{
// Failed to start network. Enter a dormant state (until user intervenes)
devState = DEV_INIT;
osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT );
}
}
}
#if ( SECURE != 0 )
/*********************************************************************
* @fn ZDApp_DeviceAuthEvt()
*
* @brief Process the Device Authentic Event
*
* @param none
*
* @return none
*/
void ZDApp_DeviceAuthEvt( void )
{
// received authentication from trust center
if ( devState == DEV_END_DEVICE_UNAUTH )
{
// Stop the reset timer so it doesn't reset
ZDApp_ResetTimerCancel();
devState = DEV_END_DEVICE;
osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT );
// Set the Power Manager Device
#if defined ( POWER_SAVING )
osal_pwrmgr_device( PWRMGR_BATTERY );
#endif
#if defined ( RTR_NWK )
if ( ZDO_Config_Node_Descriptor.LogicalType != NODETYPE_DEVICE )
{
// NOTE: first two parameters are not used, see NLMEDE.h for details
NLME_StartRouterRequest( 0, 0, false );
}
#endif // RTR
// Notify to save info into NV
ZDApp_NVUpdate();
// Save off the security
ZDApp_SaveNwkKey();
#if defined ( ZDO_ENDDEVICE_ANNCE_GENERATE )
ZDP_EndDeviceAnnce( ZDAppNwkAddr.addr.shortAddr, saveExtAddr,
ZDO_Config_Node_Descriptor.CapabilityFlags, 0 );
#endif
}
else
{
ZDApp_NVUpdate();
}
}
#endif
/*********************************************************************
* @fn ZDApp_SaveNetworkStateEvt()
*
* @brief Process the Save the Network State Event
*
* @param none
*
* @return none
*/
void ZDApp_SaveNetworkStateEvt( void )
{
#if defined ( NV_RESTORE )
#if defined ( NV_TURN_OFF_RADIO )
// Turn off the radio's receiver during an NV update
byte RxOnIdle;
byte x = false;
ZMacGetReq( ZMacRxOnIdle, &RxOnIdle );
ZMacSetReq( ZMacRxOnIdle, &x );
#endif
// Update the Network State in NV
NLME_UpdateNV( NWK_NV_NIB_ENABLE |
NWK_NV_DEVICELIST_ENABLE |
NWK_NV_BINDING_ENABLE |
NWK_NV_ADDRMGR_ENABLE );
// Reset the NV startup option to resume from NV by
// clearing the "New" join option.
zgWriteStartupOptions( FALSE, ZCD_STARTOPT_DEFAULT_NETWORK_STATE );
#if defined ( NV_TURN_OFF_RADIO )
ZMacSetReq( ZMacRxOnIdle, &RxOnIdle );
#endif
#endif // NV_RESTORE
}
/*********************************************************************
* @fn ZDApp_RestoreNetworkState()
*
* @brief This function will restore the network state of the
* device if the network state is stored in NV.
*
* @param none
*
* @return
* ZDO_INITDEV_RESTORED_NETWORK_STATE - The device's network state was
* restored.
* ZDO_INITDEV_NEW_NETWORK_STATE - The network state was not used.
* This could mean that zgStartupOption said to not restore, or
* it could mean that there was no network state to restore.
*
*/
uint8 ZDApp_RestoreNetworkState( void )
{
byte nvStat;
#if ( SECURE != 0 )
nwkActiveKeyItems keyItems;
#endif
// Initialize NWK NV items
nvStat = NLME_InitNV();
if ( nvStat != NV_OPER_FAILED )
{
if ( NLME_RestoreFromNV() )
{
// Are we a coordinator
ZDAppNwkAddr.addr.shortAddr = NLME_GetShortAddr();
if ( ZDAppNwkAddr.addr.shortAddr == 0 )
{
ZDO_Config_Node_Descriptor.LogicalType = NODETYPE_COORDINATOR;
}
devStartMode = MODE_RESUME;
}
else
nvStat = NV_ITEM_UNINIT;
#if ( SECURE != 0 )
nwkFrameCounterChanges = 0;
osal_memset( &keyItems, 0, sizeof( nwkActiveKeyItems ) );
osal_nv_item_init( ZCD_NV_NWKKEY, sizeof(nwkActiveKeyItems), (void *)&keyItems );
#if defined ( ZDO_COORDINATOR )
ZDApp_RestoreNwkKey();
#endif // ZDO_COORDINATOR
#endif // SECURE
// The default for RxOnWhenIdle is true for RTR_NWK and false for end devices
// [setup in the NLME_RestoreFromNV()]. Change it here if you want something
// other than default.
}
if ( nvStat == ZSUCCESS )
return ( ZDO_INITDEV_RESTORED_NETWORK_STATE );
else
return ( ZDO_INITDEV_NEW_NETWORK_STATE );
}
/*********************************************************************
* @fn ZDApp_InitUserDesc()
*
* @brief Initialize the User Descriptor, the descriptor is read from NV
* when needed. If you want to initialize the User descriptor to
* something other than all zero, do it here.
*
* @param none
*
* @return none
*/
void ZDApp_InitUserDesc( void )
{
UserDescriptorFormat_t ZDO_DefaultUserDescriptor;
// Initialize the User Descriptor, the descriptor is read from NV
// when needed. If you want to initialize the User descriptor to something
// other than all zero, do it here.
osal_memset( &ZDO_DefaultUserDescriptor, 0, sizeof( UserDescriptorFormat_t ) );
if ( ZSUCCESS == osal_nv_item_init( ZCD_NV_USERDESC,
sizeof(UserDescriptorFormat_t), (void*)&ZDO_DefaultUserDescriptor ) )
{
if ( ZSUCCESS == osal_nv_read( ZCD_NV_USERDESC, 0,
sizeof(UserDescriptorFormat_t), (void*)&ZDO_DefaultUserDescriptor ) )
{
if ( ZDO_DefaultUserDescriptor.len != 0 )
{
ZDO_Config_Node_Descriptor.UserDescAvail = TRUE;
}
}
}
}
/*********************************************************************
* @fn ZDAppCheckForHoldKey()
*
* @brief Check for key to set the device into Hold Auto Start
*
* @param none
*
* @return none
*/
void ZDAppCheckForHoldKey( void )
{
#if (defined HAL_KEY) && (HAL_KEY == TRUE)
// Get Keypad directly to see if a HOLD_START is needed.
// Hold down the SW_BYPASS_START key (see OnBoard.h)
// while booting to avoid starting up the device.
if ( HalKeyRead () == SW_BYPASS_START)
{
// Change the device state to HOLD on start up
devState = DEV_HOLD;
}
#endif // HAL_KEY
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -