} #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 the security for type of device
ZDApp_SecInit( networkStateNV ); //初始化安全属性
// Trigger the network start
ZDApp_NetworkInit( extendedDelay );//开启网络初始化函数
// set broadcast address mask to support broadcast filtering
NLME_SetBroadcastFilter( ZDO_Config_Node_Descriptor.CapabilityFlags );
return ( networkStateNV ); }
好,我们进入到网络初始化函数当中,看看终端节点如何进行网络初始化,在此之前我们看过的函数与协调器执行的函数没有什么区别,在这以后区别开始出现了。
void ZDApp_NetworkInit( uint16 delay ) {
if ( delay ) {
// Wait awhile before starting the device
osal_start_timerEx( ZDAppTaskID, ZDO_NETWORK_INIT, delay ); } else {
osal_set_event( ZDAppTaskID, ZDO_NETWORK_INIT ); //设置了一个网络初始化事件,在ZDO层的任务处理函数中处理。
} }
找到 UINT16 ZDApp_event_loop( uint8 task_id, UINT16 events )中的:
if ( events & ZDO_NETWORK_INIT ) {
devState = DEV_INIT;//改变设备状态为初始化状态。
ZDO_StartDevice( (uint8)ZDO_Config_Node_Descriptor.LogicalType, devStartMode,
DEFAULT_BEACON_ORDER,
DEFAULT_SUPERFRAME_ORDER );//开启设备函数,参数分别为设备类型,启动模式,信标帧,超帧.第一个参数是在初始化设备时调用初始化节点描述符函数里赋值的。
return (events ^ ZDO_NETWORK_INIT); }
进入到启动设备函数中,看看源代码:
void ZDO_StartDevice( byte logicalType, devStartModes_t startMode, byte beaconOrder, byte superframeOrder ) {
ZStatus_t ret;
#if defined ( ZIGBEE_FREQ_AGILITY ) static uint8 discRetries = 0; #endif
#if defined ( ZIGBEE_COMMISSIONING ) static uint8 scanCnt = 0; #endif
ret = ZUnsupportedMode;
if ( ZG_BUILD_COORDINATOR_TYPE && logicalType == NODETYPE_COORDINATOR )//条件不通过,不是协调器 {
if ( startMode == MODE_HARD ) {
devState = DEV_COORD_STARTING;
ret = NLME_NetworkFormationRequest( zgConfigPANID,
zgApsUseExtendedPANID, zgDefaultChannelList,
zgDefaultStartingScanDuration, beaconOrder,
superframeOrder, false ); }
else if ( startMode == MODE_RESUME ) {
// Just start the coordinator devState = DEV_COORD_STARTING;
ret = NLME_StartRouterRequest( beaconOrder, beaconOrder, false ); } else {
#if defined( LCD_SUPPORTED )
HalLcdWriteScreen( \#endif } }
if ( ZG_BUILD_JOINING_TYPE && (logicalType == NODETYPE_ROUTER || logicalType == NODETYPE_DEVICE) )//条件通过 {
if ( (startMode == MODE_JOIN) || (startMode == MODE_REJOIN) )//条件通过 {
devState = DEV_NWK_DISC; //将设备状态修改为网络发现状态
#if defined( MANAGED_SCAN ) ZDOManagedScan_Next();
ret = NLME_NetworkDiscoveryRequest( managedScanChannelMask, BEACON_ORDER_15_MSEC ); #else
ret = NLME_NetworkDiscoveryRequest( zgDefaultChannelList, zgDefaultStartingScanDuration );//向网络层发送网络发现请求,交由网络层处理。怎么处理代码看不到。
#if defined ( ZIGBEE_FREQ_AGILITY )
if ( !( ZDO_Config_Node_Descriptor.CapabilityFlags & CAPINFO_RCVR_ON_IDLE ) &&
( ret == ZSuccess ) && ( ++discRetries == 4 ) ) {
// For devices with RxOnWhenIdle equals to FALSE, any network channel
// change will not be recieved. On these devices or routers that have
// lost the network, an active scan shall be conducted on the Default
// Channel list using the extended PANID to find the network. If the
// extended PANID isn't found using the Default Channel list, an scan
// should be completed using all channels. zgDefaultChannelList = MAX_CHANNELS_24GHZ; }
#endif // ZIGBEE_FREQ_AGILITY
#if defined ( ZIGBEE_COMMISSIONING )
if (startMode == MODE_REJOIN && scanCnt++ >= 5 ) {
// When ApsUseExtendedPanID is commissioned to a non zero value via
// application specific means, the device shall conduct an active scan
// on the Default Channel list and join the PAN with the same // ExtendedPanID. If the PAN is not found, an scan should be completed
// on all channels.
// When devices rejoin the network and the PAN is not found from zgDefaultChannelList = MAX_CHANNELS_24GHZ; }
#endif // ZIGBEE_COMMISSIONING #endif }
else if ( startMode == MODE_RESUME ) {
if ( logicalType == NODETYPE_ROUTER ) {
ZMacScanCnf_t scanCnf; devState = DEV_NWK_ORPHAN;
scanCnf.hdr.Status = ZSUCCESS;
scanCnf.ScanType = ZMAC_ORPHAN_SCAN; scanCnf.UnscannedChannels = 0; scanCnf.ResultListSize = 0;
nwk_ScanJoiningOrphan(&scanCnf); ret = ZSuccess; } else
{
devState = DEV_NWK_ORPHAN;
ret = NLME_OrphanJoinRequest( zgDefaultChannelList,
zgDefaultStartingScanDuration ); } } else {
#if defined( LCD_SUPPORTED )
HalLcdWriteScreen( \#endif } }
if ( ret != ZSuccess )
osal_start_timerEx(ZDAppTaskID, ZDO_NETWORK_INIT, NWK_RETRY_DELAY ); }
关于ZStack-CC2530-2.3.0-1.4.0中simpleApp例子的 终端节点入网以及绑定操作(二)
当终端节点的ZDO向网络层发送完发现网络请求后,网络层操作完成后会向ZDO层发送发现网络确认,ZDO层利用ZDO_NetworkDiscoveryConfirmCB函数来对确认进行处理。下面看一下该函数的代码:
ZStatus_t ZDO_NetworkDiscoveryConfirmCB( uint8 ResultCount, networkDesc_t *NetworkList ) {
networkDesc_t *pNwkDesc = NetworkList; ZDO_NetworkDiscoveryCfm_t msg; uint8 i = ResultCount; uint8 stackProfile; uint8 stackProfilePro; uint8 selected;
#if defined ( ZDO_MGMT_NWKDISC_RESPONSE ) if ( zdappMgmtNwkDiscReqInProgress ) {
zdappMgmtNwkDiscReqInProgress = false;
ZDO_FinishProcessingMgmtNwkDiscReq( ResultCount, NetworkList ); return ( ZSuccess ); } #endif