绑定确认过程

注1:本文以ZStack-cc2530-2.3.1-1.4.0里的Collector-Sensor为例。

注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();传送数据。


BINDING KuangJunBin:本文是作者根据TI Z-Stack开发文档,ZigBee Specification-2007,《Zigbee Wireless Networking》等英文资料整合和翻译而成,采用中英双语对照方便读者理解,文中翻译不当之处,望广大同行不吝赐教。推广ZigBee技术,提高国内电子行业的国际影响力,是我们无线通讯工程师的愿景。本文欢迎转载,请保留作者信息和出处,作为支持我继续努力前行的动力,谢谢! E-mail:kuangjunbin@gmail.com In the Zigbee 2006 release,the binding mechanism is implemented in all devices and is called source binding. Binding allows an application to send a packet without knowing the destination address,the APS layer determines the destination address from its binding table,and then forwards the message on to the destination application(or multiple applications)or group. ZigBee2006版本中规定,在全部节点中实现绑定机制,并将其称为源绑定绑定机制允许一个应用服务在不知道目标地址的情况下向对方(的应用服务)发送数据包。发送时使用的目标地址将由应用支持子层(APS)从绑定表中自动获得,从而能使消息顺利被目标节点的一个或多个应用服务,乃至分组接收。 Binding Table 1.Defined in RAM,but can be saved in Flash if the NV_RESTORE compiler option is used 2.Stored on source node(REFLECTOR compiler option required) 3.Entries map messages to their intended destination 4.Each entry in the binding table contains the following: typedef struct { uint16 srcIdx;//Source index uint8 srcEP;//Source endpoint uint8 dstGroupMode;//Specifies normal or group addressing uint16 dstIdx;//Destination index or group address uint8 dstEP;//Destination endpoint uint8 numClusterIds;//Number of cluster IDs in the clusterIdList below uint16 clusterIdList[MAX_BINDING_CLUSTER_IDS]; }BindingEntry_t; 绑定表 1. 绑定表存放的位置是内存中预先定义的RAM块,如果编译选项NV_RESTORE被激活,也能保存在Flash里。 2. 绑定表放置在源节点(需要激活编译选项REFLECTOR)。 3. 绑定表的条目把需要发送的消息映射到它们的目标地址上。 4. 绑定表中每个条目(entry)包括以下内容: 绑定表条目结构体的定义
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值