本帖最后由 冒汗的心情 于 2016-3-7 11:28 编辑
掉线:一般都什么样的问题容易引起掉线呢?比如硬件,软件的那些方面呢?协议栈哪里呢? 重连:要说掉线不好分析,若能重连也可以。 1:设备掉线重连: 掉线后进入下面回调函数 void ZDO_SyncIndicationCB( uint8 type, uint16 shortAddr ) 产生ZDO_NWK_JOIN_REQ 之后进入到 void ZDApp_ProcessOSALMsg( osal_event_hdr_t *msgPtr ) case ZDO_NWK_JOIN_REQ: devStartMode = MODE_RESUME;//改为resume模式 2.设备断电后重新上电,直接就是resume模式 ZDApp_NetworkInit( 0 );//初始化网络 启动osal_start_timerEx( ZDAppTaskID, ZDO_NETWORK_INIT, delay ); 进入到UINT16 ZDApp_event_loop( uint8 task_id, UINT16 events ) if ( events & ZDO_NETWORK_INIT ) devState = DEV_INIT;//初始化状态 ZDO_StartDevice();//开始入网 进入后执行最后一个else,以孤儿方式组网 devState = DEV_NWK_ORPHAN;
ret = NLME_OrphanJoinRequest( zgDefaultChannelList,
zgDefaultStartingScanDuration ); 等待回调函数 void ZDO_JoinConfirmCB( uint16 PanId, ZStatus_t Status ) 把结果通知ZDO_NWK_JOIN_IND 在此处void ZDApp_ProcessOSALMsg( osal_event_hdr_t *msgPtr ) case ZDO_NWK_JOIN_IND: 进入端末处理 ZDApp_ProcessNetworkJoin(); else if ( devState == DEV_NWK_ORPHAN || devState == DEV_NWK_REJOIN ) if (nwkStatus == ZSuccess) devState = DEV_END_DEVICE;
osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT );////至此入网成功 否则失败了 else
{ if ( devStartMode == MODE_RESUME )、、、掉线后恢复网络失败后到此处
{
if ( ++retryCnt <= MAX_RESUME_RETRY )//////此处非常不明白为什么第一次执行后,就判断由resume改成rejoin模式呢?上面路由节点是3次后换模式
{
if ( _NIB.nwkPanId == 0xFFFF || _NIB.nwkPanId == INVALID_PAN_ID )
devStartMode = MODE_JOIN;
else
{
devStartMode = MODE_REJOIN;
_tmpRejoinState = true;
}
}
// Do a normal join to the network after certain times of rejoin retries
else if( AIB_apsUseInsecureJoin == true )///////此处改为join模式还能恢复到原来的网络了吗?
{
devStartMode = MODE_JOIN;
} resume模式恢复网络失败后,清楚表后,重新执行网络初始化 // setup a retry for later... ZDApp_NetworkInit( (uint16)(NWK_START_DELAY
+ (osal_rand()& EXTENDED_JOINING_RANDOM_MASK)) ); } 之后再次进入void ZDO_StartDevice()//再次加入网络 这次执行路由或者终端节点处理中的 if ( (startMode == MODE_JOIN) || (startMode == MODE_REJOIN) )//////上1次执行的else的resume模式
devState = DEV_NWK_DISC; ret = NLME_NetworkDiscoveryRequest( zgDefaultChannelList, zgDefaultStartingScanDuration );////发现网络,这里具体是什么作用不是太清楚,开始模式为join和rejoin时,入网都要先执行NLME_NetworkDiscoveryRequest,进入case ZDO_NWK_DISC_CNF:尝试大于2次后再执行NLME_ReJoinRequest吗?为什么这样做呢? 等待回调函数 ZStatus_t ZDO_NetworkDiscoveryConfirmCB(uint8 status) ZDApp_SendMsg( ZDO_NWK_DISC_CNF,) 进入处理消息 void ZDApp_ProcessOSALMsg( osal_event_hdr_t *msgPtr ) case ZDO_NWK_DISC_CNF: 若尝试大于2次 else if ( devStartMode == MODE_REJOIN )
{ devState = DEV_NWK_REJOIN;//////切换rejoin方式入网 if ( NLME_ReJoinRequest( ZDO_UseExtendedPANID, pChosenNwk->logicalChannel) != ZSuccess ) ////////////////////以rejoin方式组网也是在ZDO_JoinConfirmCB等待入网的结果,成功则切换devState = DEV_END_DEVICE;osal_set_event( ZDAppTaskID, /////////////////////ZDO_STATE_CHANGE_EVT );失败则重新初始化网络 { ZDApp_NetworkInit( (uint16)(NWK_START_DELAY
+ ((uint16)(osal_rand()& EXTENDED_JOINING_RANDOM_MASK))) );
} 为什么有些设备就是容易掉线,甚至有的失败执行上述重连过程也连不回来的,最坏的情况当协调器允许入网时候,这个设备竟然重新入网而不是恢复原来的网络,上述重连过程我理解的对吗?哪里可能有问题导致重连失败呢?上述过程都是协议栈原来的代码,我并没有进行修改。 抓包发现,重连的设备开始阶段都会发送orphan Notification, 若协调器相应了回复coordinator realignment,则非常大的概率就成功入网继续Device Announce 若协调器没有响应,则掉线设备恢复网络失败,此时设备是否应该重新发送呢?但上面程序中指执行一次NLME_OrphanJoinRequest,失败后if ( ++retryCnt <= MAX_RESUME_RETRY )切换模式rejoin了。而改为NLME_ReJoinRequest方式入网。 但抓包发现能恢复原来网络的大多是orphan Notification,之后协调器及时回复coordinator realignment的。发送rejoin是较少的。
|