注2:看本文先弄懂绑定基本正确的流程。
传感节点发送网络,并且加入网络后,就会进入MY_FIND_COLLECTOR_EVT事件,注意事件的位运算操作,MY_FIND_COLLECTOR_EVT属于ZB_USER_EVENTS事件中的一种。按如下的流程:zb_HandleOsalEvent( )--zb_BindDevice(),在zb_BindDevice()函数里,会执行如下代码:
{
ret = ZB_INVALID_PARAMETER;
destination.addrMode = Addr16Bit;
destination.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
if ( ZDO_AnyClusterMatches( 1, &commandId, sapi_epDesc.simpleDesc->AppNumOutClusters,
sapi_epDesc.simpleDesc->pAppOutClusterList ) )
{
// Try to match with a device in the allow bind mode
ret = ZDP_MatchDescReq( &destination, NWK_BROADCAST_SHORTADDR,
sapi_epDesc.simpleDesc->AppProfId, 1, &commandId, 0, (cId_t *)NULL, 0 );
}
else if ( ZDO_AnyClusterMatches( 1, &commandId, sapi_epDesc.simpleDesc->AppNumInClusters,
sapi_epDesc.simpleDesc->pAppInClusterList ) )
{
ret = ZDP_MatchDescReq( &destination, NWK_BROADCAST_SHORTADDR,
sapi_epDesc.simpleDesc->AppProfId, 0, (cId_t *)NULL, 1, &commandId, 0 );
}
if ( ret == ZB_SUCCESS )
{
// Set a timer to make sure bind completes
#if ( ZG_BUILD_RTR_TYPE )
osal_start_timerEx(sapi_TaskID, ZB_BIND_TIMER, AIB_MaxBindingTime);
#else
// AIB_MaxBindingTime is not defined for an End Device
osal_start_timerEx(sapi_TaskID, ZB_BIND_TIMER, zgApsDefaultMaxBindingTime);
#endif
sapi_bindInProgress = commandId;
return; // dont send cback event
}
需要注意的是ret = ZDP_MatchDescReq( &destination, NWK_BROADCAST_SHORTADDR, sapi_epDesc.simpleDesc->AppProfId, 1, &commandId, 0, (cId_t *)NULL, 0 );本句最终会调用无线发射信号的语句,只要信号发送出去了(不论是否收到,也不管有没有匹配的端点),得到的ret总是为ZB_SUCCESS ,于是总会这一句:osal_start_timerEx(sapi_TaskID, ZB_BIND_TIMER,
zgApsDefaultMaxBindingTime);
而这一句的作用是发送完绑定请求(匹配描述符请求)后给应用层的一个确认。下面分两种情况来处理ZB_BIND_TIMER事件。
一、绑定不成功
传感节点将绑定请求信息(匹配描述符请求信息)发送给采聚节点后,就会等待采聚节点发过来匹配描述符响应事件,如果绑定不成功(原因很多,比如采聚节点没有开启允许绑定,采聚节点没有匹配端点),则传感节点收不到匹配描述符响应事件,经过zgApsDefaultMaxBindingTime段时间后,传感节点就会执行ZB_BIND_TIMER事件。依次经过如下流程:SAPI_BindConfirm--zb_BindConfirm,在zb_BindConfirm函数里,有如下代码
void zb_BindConfirm( uint16 commandId, uint8 status ){
(void)commandId;
if ( ( status == ZB_SUCCESS ) && ( myAppState == APP_START ) ) {
myAppState = APP_BOUND;
myApp_StartReporting();
}
else {
osal_start_timerEx( sapi_TaskID, MY_FIND_COLLECTOR_EVT, myBindRetryDelay );
}
}
上面程序会进入else分支,这样又会再次发送MY_FIND_COLLECTOR_EVT,在MY_FIND_COLLECTOR_EVT里,会进入绑定,这样就进入一个不断发送绑定请求的循环。
二、绑定成功
如果绑定成功,传感节点会收到采聚节点发送过来的Match_desp_res消息。传感节点程序执行的流程为ZDO层的AF_INCOMING_MSG_CMD--ZDP_IncomingData--- handled = ZDO_SendMsgCBs( &inMsg );--应用层的SYS_EVENT_MSG--ZDO_CB_MSG--SAPI_ProcessZDOMsgs( (zdoIncomingMsg_t *)pMsg );--Match_Desc_rsp:在这个事件里,会执行如下这句osal_stop_timerEx(sapi_TaskID, ZB_BIND_TIMER);这句会将ZB_BIND_TIMER事件取消。(上面程序流程执行过程比较复杂,如有不清楚的,请给我留言,我会帮你解答的。)在这个函数的下面有zb_BindConfirm( sapi_bindInProgress, ZB_SUCCESS );
void zb_BindConfirm( uint16 commandId, uint8 status ){
(void)commandId;
if ( ( status == ZB_SUCCESS ) && ( myAppState == APP_START ) ){
myAppState = APP_BOUND;
myApp_StartReporting();
}
else if(myAppState == APP_BOUND){
osal_start_timerEx( sapi_TaskID, MY_FIND_COLLECTOR_EVT, myBindRetryDelay );
}
}
这时会进入IF分支,进而通过 myApp_StartReporting();传送数据。
1985

被折叠的 条评论
为什么被折叠?



