查看: 8640|回复: 10

关于协议栈中绑定流程的一点认识(一)

[复制链接]
shaomengchao 发表于 2010-12-8 01:00:36 | 显示全部楼层 |阅读模式
之前发了关于match的帖子,趁着还有劲头我就接着看了关于协议栈中关于bind服务的内容。看了之后才发现,bind要比match复杂的多了,好在参考了小峰的博客(http://wjf88223.blog.163.com/blog/static/3516800120105110493623/)才勉强看下,在这里向小峰表示十二分的感谢。虽然关于bind服务小峰已经说的很详细了,但我还是脸皮很厚的写点自己的认识,也算是记录下自己的学习过程吧。
      和之前的帖子一样,我还是参考了ZStack-CC2530-2.3.1-1.4.0\Projects\zstack\Samples\GenericApp例程
       在协议栈中关于bind的服务主要有一下几类。
    End_Device_Bind_req       ((uint16)0x0020)
    Bind_req                            ((uint16)0x0021)
    Unbind_req                       ((uint16)0x0022)
     Bind_rsp                          (Bind_req | ZDO_RESPONSE_BIT)
    End_Device_Bind_rsp        (End_Device_Bind_req | ZDO_RESPONSE_BIT)
    Unbind_rsp                         (Unbind_req | ZDO_RESPONSE_BIT)
我借由GenericApp中 End_Device_Bind_req  服务请求来一步步说明bind蛋疼的传来传去的流程。
   假设一个bind节点1,它要发出End_Device_Bind_req请求。这个是在 GenericApp_HandleKeys发出的
  if ( keys & HAL_KEY_SW_2 )
    {
      HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );

      // Initiate an End Device Bind Request for the mandatory endpoint
      dstAddr.addrMode = Addr16Bit;
      dstAddr.addr.shortAddr = 0x0000; // Coordinator
      ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
                            GenericApp_epDesc.endPoint,
                            GENERICAPP_PROFID,
                            GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                            GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                            FALSE );
    }

在ZIGBEE SPECIFICATION有如下的描述
The End_Device_Bind_req is generated from a Local Device wishing to perform End Device Bind with a Remote Device. The                          End_Device_Bind_req is generated, typically based on some user action like a button press. The destination addressing on
this command shall be unicast, and the destination address shall be that of the  ZigBee Coordinator.
就是说这个End_Device_Bind_req 请求是发给我们的 Coordinator,代码也是这样写的。
ZDP_EndDeviceBindReq具体内容我就不贴出来了,这个函数很简单就是发送一个End_Device_Bind_req格式帧给Coordinator,帧格式为
LocalCoordinator(本地nwk地址) + SrcExtAddr (本地ieee地址)+ ep(请求bind的endpoint) + ProfileID +  NumInClusters(簇的个数) + NumOutClusters(簇列表)

就这样这个End_Device_Bind_req请求到了Coordinator,接收部分我不想多说了,要说又是一大堆了。但要注意的是Coordinator的End_Device_Bind_req请求处理函数不是在CONST zdpMsgProcItem_t zdpMsgProcs[]数组,我们不能像Match_Desc_req那样轻松的借由AF_INCOMING_MSG_CMD进入 ZDP_IncomingData调用服务函数的。相比的要绕个弯子,我们先要注册一下。
void ZDApp_RegisterCBs( void )
{
#if defined ( ZDO_IEEEADDR_REQUEST ) || defined ( REFLECTOR )
  ZDO_RegisterForZDOMsg( ZDAppTaskID, IEEE_addr_rsp );
#endif
#if defined ( ZDO_NWKADDR_REQUEST ) || defined ( REFLECTOR )
  ZDO_RegisterForZDOMsg( ZDAppTaskID, NWK_addr_rsp );
#endif
#if ZG_BUILD_COORDINATOR_TYPE
  ZDO_RegisterForZDOMsg( ZDAppTaskID, Bind_rsp );
  ZDO_RegisterForZDOMsg( ZDAppTaskID, Unbind_rsp );
  ZDO_RegisterForZDOMsg( ZDAppTaskID, End_Device_Bind_req ); //注册了End_Device_Bind_req 服务
#endif
#if defined ( REFLECTOR )
  ZDO_RegisterForZDOMsg( ZDAppTaskID, Bind_req );
  ZDO_RegisterForZDOMsg( ZDAppTaskID, Unbind_req );
#endif
}
这个注册函数和之前帖子提到的
ZDO_RegisterForZDOMsg( GenericApp_TaskID, End_Device_Bind_rsp );
ZDO_RegisterForZDOMsg( GenericApp_TaskID, Match_Desc_rsp );
功能一样。
End_Device_Bind_req 服务调用分为2步,首先在ZDP_IncomingData中的ZDO_SendMsgCBs标记ZDO_CB_MSG然后通过osal调用ZDApp_ProcessMsgCBs真正的完成。
ZDApp_ProcessMsgCBs这个函数之后我们会多次打交道,我在这只贴相出于End_Device_Bind_req有关的部分
switch ( inMsg->clusterID )
  {.........
case End_Device_Bind_req:
      if (ZG_DEVICE_COORDINATOR_TYPE)
      {
        ZDEndDeviceBind_t bindReq;
        ZDO_ParseEndDeviceBindReq( inMsg, &bindReq );
        ZDO_MatchEndDeviceBind( &bindReq );

        // Freeing the cluster lists - if allocated.
        if ( bindReq.numInClusters )
          osal_mem_free( bindReq.inClusters );
        if ( bindReq.numOutClusters )
          osal_mem_free( bindReq.outClusters );
      }
      break;
你看人家强调只有COORDINATOR才能处理End_Device_Bind_req请求吧,与我们之前发送部分是吻合的。
说了这么多我们从只是从bind节点到了Coordinator,End_Device_Bind_req请求处理ZDO_MatchEndDeviceBind还没开始呢。别急啊,bind服务就是传来传去让你头疼的。我们要心平气和的慢慢来。感觉说这么多一个帖子太长了,我们下回再讲吧。

评分

1

查看全部评分

wuxiujiang 发表于 2010-12-8 09:43:59 | 显示全部楼层
支持!  来学习了……
outman 发表于 2010-12-8 09:59:04 | 显示全部楼层
想把自己学到的东西写出来,可不是件容易事,尤其是很多人都不愿意这样干。感谢楼主的共享精神,辛苦了!
xiaoyige 发表于 2011-1-27 16:28:09 | 显示全部楼层
顶顶顶顶顶顶
zpsky 发表于 2011-4-23 20:32:05 | 显示全部楼层
学习这个果然是要有耐心的,还要尽量不头晕
xiaoyu_0920 发表于 2011-4-24 08:54:05 | 显示全部楼层
请教楼主:终端设备绑定和匹配描述符绑定有什么区别?
bamboozz 发表于 2011-10-24 11:02:46 | 显示全部楼层
分析得不错,很细致。
zifeng 发表于 2011-10-26 13:07:29 | 显示全部楼层
牛叉啊!!!!!
lizheng86312 发表于 2012-8-29 13:25:07 | 显示全部楼层
学到东西了。顶。。。
tlk214 发表于 2013-8-12 11:09:15 | 显示全部楼层
学习绑定流程(一),楼主万岁!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表