绑定机制详解.doc_第1页
绑定机制详解.doc_第2页
绑定机制详解.doc_第3页
绑定机制详解.doc_第4页
绑定机制详解.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

这里主要再讨论一下绑定的机制,绑定是ZigBee中应该是比较重要的一个部分。前面的几篇文章也对绑定有了具体的分析,主要分析了两种绑定方式,介绍了绑定的流程,源代码方面。这里主要是理清整个绑定在组网中的概念。绑定是和EndPoint紧密联系在一起的,其中很多是自己通过看资料,自己的一些理解,当中肯定有不正确的地方,欢迎有兴趣的一起讨论。ZigBee中还有一个重要的概念端点,理解的不是很清楚,现在再一次总结分析一下,端点是应用对象存在的地方,ZigBee允许多个应用同时位于一个节点上,例如一个节点具有控制灯光的功能,又具有感应温度的功能,又具有收发文本消息的功能,这种设计有利于复杂ZigBee设备的出现。我们可以从ZigBee的体系结构图中可以看到可以有240个应用,也就是说一个物理的ZigBee设备的话,可以有240个具体的应用,例如上面提到的其中的三种具体的应用。一共有二个特殊的端点,即端点0和端点255。端点0用于整个ZigBee设备的配置和管理。应用程序可以透过端点0与ZigBee堆栈的其它层通讯,因而实现对这些层的初始化和配置。附属在端点0的对象被称为ZigBee设备对象(ZDO)。端点255用于向所有端点的广播。端点241到254是保留端点。所有端点都使用应用支持子层(APS)提供的服务。APS透过网络层和安全服务提供层与端点相接,并为数据传送、安全和固定服务,因此能够适配不同但兼容的设备,如带灯的开关。下面是终端的描述符的结构体定义。typedef structbyte endPoint; /EP号byte *task_id; /指向任务编号的指针.SimpleDescriptionFormat_t *simpleDesc; /设备的简单描述afNetworkLatencyReq_t latencyReq; /枚举类型 endPointDesc_t;/设备的简单描述结构typedef structbyte EndPoint; /EPIDuint16 AppProfId; / Profile IDuint16 AppDeviceId; / Device IDbyte AppDevVer:4; / Device Versionbyte Reserved:4; /AF_V1_SUPPORT uses for AppFlags:4. Reservedbyte AppNumInClusters; /输入命令个数cId_t *pAppInClusterList; /输入命令列表byte AppNumOutClusters; /输出命令个数cId_t *pAppOutClusterList; /输出命令列表 SimpleDescriptionFormat_t;下面是在SerialApp程序中简单描述符的定义。const SimpleDescriptionFormat_t SerialApp_SimpleDesc =SERIALAPP_ENDPOINT,/intEndpoint;SERIALAPP_PROFID,/uint16 AppProfId2;SERIALAPP_DEVICEID,/uint16 AppDeviceId2;SERIALAPP_DEVICE_VERSION,/intAppDevVer:4;SERIALAPP_FLAGS,/intAppFlags:4;SERIALAPP_MAX_CLUSTERS,/byteAppNumInClusters;(cId_t *)SerialApp_ClusterList,/byte *pAppInClusterList;SERIALAPP_MAX_CLUSTERS,/byteAppNumOutClusters;(cId_t *)SerialApp_ClusterList/byte *pAppOutClusterList;const endPointDesc_t SerialApp_epDesc =SERIALAPP_ENDPOINT,&SerialApp_TaskID,(SimpleDescriptionFormat_t *)&SerialApp_SimpleDesc,noLatencyReqs; 在TI给的例子中都只是定义了一个端点,猜想是不是每一个应用中都必须有一个相应的端点,也就会有一个相应的端点描述符。例如这里的三个应用,一个节点具有控制灯光的功能,又具有感应温度的功能,又具有收发文本消息的功能,那么需要占用三个端点号,也就会需要三个端点的描述符,因为在发送数据的函数中会用到这个端点的描述符。AF_DataRequest( &SerialApp_RspDstAddr,(endPointDesc_t *)&SerialApp_epDesc,SERIALAPP_CLUSTERID2,SERIAL_APP_RSP_CNT, rspBuf,&SerialApp_MsgID, 0, AF_DEFAULT_RADIUS ); 在绑定的应用中必须要用到端点的描述符,可不可以这样理解就是说,在绑定时其实并不是两个设备之间的绑定,其实质是在这两个设备上两个端点之间的绑定,再进一步说就是两个应用之间的绑定,因为在一个终端中可能有很多的应用,也就是端点,可不以在一个端点中只和其中的一个应用进行绑定,也就是只和其中的一个端点进行绑定,其他的端点可以使用别的地址方式,如直接地址模式,或者是广播地址的方式,进行数据的处理。虽然和同一个设备进行了绑定,但是其中的应用并不相同。描述符匹配是不是就是这个意思。如果两个设备没有相同的描述符是不会绑定成功的。case Match_Desc_rsp:ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );if ( pRsp )if ( pRsp-status = ZSuccess & pRsp-cnt )SerialApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;SerialApp_DstAddr.addr.shortAddr = pRsp-nwkAddr;/ Take the first endpoint, Can be changed to search through endpointsSerialApp_DstAddr.endPoint = pRsp-epList0;/ Light LEDHalLedSet( HAL_LED_4, HAL_LED_MODE_ON );osal_mem_free( pRsp );Break; 在下面的函数中是绑定必须要执行一个处理函数,这个函数就是处理和回应对Match_Desc_req消息。这个函数在绑定的第三篇文章中也有分析到。void ZDO_ProcessMatchDescReq( zdoIncomingMsg_t *inMsg )uint8 epCnt = 0;uint8 numInClusters;uint16 *inClusters = NULL;uint8 numOutClusters;uint16 *outClusters = NULL;epList_t *epDesc;SimpleDescriptionFormat_t *sDesc = NULL;uint8 allocated;uint8 *msg;uint16 aoi;uint16 profileID;/ Parse the incoming messagemsg = inMsg-asdu;aoi = BUILD_UINT16( msg0, msg1 );profileID = BUILD_UINT16( msg2, msg3 );msg += 4;if ( ADDR_BCAST_NOT_ME = NLME_IsAddressBroadcast(aoi) )ZDP_MatchDescRsp( inMsg-TransSeq, &(inMsg-srcAddr), ZDP_INVALID_REQTYPE,ZDAppNwkAddr.addr.shortAddr, 0, NULL, inMsg-SecurityUse );return;else if ( (ADDR_NOT_BCAST = NLME_IsAddressBroadcast(aoi) & (aoi != ZDAppNwkAddr.addr.shortAddr) )ZDP_MatchDescRsp( inMsg-TransSeq, &(inMsg-srcAddr), ZDP_INVALID_REQTYPE,ZDAppNwkAddr.addr.shortAddr, 0, NULL, inMsg-SecurityUse );return;numInClusters = *msg+;if ( numInClusters )inClusters = (uint16*)osal_mem_alloc( numInClusters * sizeof( uint16 ) );msg = ZDO_ConvertOTAClusters( numInClusters, msg, inClusters );numOutClusters = *msg+;if ( numOutClusters )outClusters = (uint16 *)osal_mem_alloc( numOutClusters * sizeof( uint16 ) );msg = ZDO_ConvertOTAClusters( numOutClusters, msg, outClusters );/* First count the number of endpoints that match.typedef structendPointDesc_t *epDesc;eEP_Flags flags;pDescCBpfnDescCB;/ Dont use if this function pointer is NULL.void *nextDesc; epList_t;*/epDesc = epList;while ( epDesc )/扫描本节点的全部EP,看是否有匹配的?这个是一个链表的形式存储的。/ Dont search endpoint 0 and check if response is allowed /不扫描端点0if ( epDesc-epDesc-endPoint != ZDO_EP & (epDesc-flags&eEP_AllowMatch) )if ( epDesc-pfnDescCB )sDesc = (SimpleDescriptionFormat_t *)epDesc-pfnDescCB( AF_DESCRIPTOR_SIMPLE, epDesc-epDesc-endPoint );allocated = TRUE;elsesDesc = epDesc-epDesc-simpleDesc;allocated = FALSE;if ( sDesc & sDesc-AppProfId = profileID)/如果profileID相同,这里也就说明了为什么会在绑定的时候要求profileID相同了。sDesc不为空的话, uint8 *uint8Buf = (uint8 *)ZDOBuildBuf;/ If there are no search input/ouput clusters respond/在这里对EP中的输入/输出簇列表进行了比较,也就是ZDP_MatchDescReq发送来的,SerialApp_ClusterListif ( (numInClusters = 0) & (numOutClusters = 0)/ Are there matching input clusters?| (ZDO_AnyClusterMatches( numInClusters, inClusters,sDesc-AppNumInClusters, sDesc-pAppInClusterList )/ Are there matching output clusters?| (ZDO_AnyClusterMatches( numOutClusters, outClusters,sDesc-AppNumOutClusters, sDesc-pAppOutClusterList )/ Notify the endpoint of the match.通知终端匹配uint8 bufLen = sizeof( ZDO_MatchDescRspSent_t ) + (numOutClusters + numInClusters) * sizeof(uint16);ZDO_MatchDescRspSent_t *pRspSent = (ZDO_MatchDescRspSent_t *) osal_msg_allocate( bufLen );if (pRspSent)pRspSent-hdr.event = ZDO_MATCH_DESC_RSP_SENT;pRspSent-nwkAddr = inMsg-srcAddr.addr.shortAddr;pRspSent-numInClusters = numInClusters;pRspSent-numOutClusters = numOutClusters;if (numInClusters)pRspSent-pInClusters = (uint16*) (pRspSent + 1);osal_memcpy(pRspSent-pInClusters, inClusters, numInClusters * sizeof(uint16);elsepRspSent-pInClusters = NULL;if (numOutClusters)pRspSent-pOutClusters = (uint16*)(pRspSent + 1) + numInClusters;osal_memcpy(pRspSent-pOutClusters, outClusters, numOutClusters * sizeof(uint16);elsepRspSent-pOutClusters = NULL;osal_msg_send( *epDesc-epDesc-task_id, (uint8 *)pRspSent );uint8BufepCnt+ = sDesc-EndPoint;/匹配EndPoint列表,这个就是Match_Desc_rsp回传的内容之一if ( allocated )osal_mem_free( sDesc );epDesc = epDesc-nextDesc;/ Send the message only if at least one match found.如果发现至少有一个匹配的以后,发送匹配消息if ( epCnt )if ( ZSuccess = ZDP_MatchDescRsp( inMsg-TransSeq, &(inMsg-srcAddr), ZDP_SUCCESS,ZDAppNwkAddr.addr.shortAddr, epCnt, (uint8 *)ZDOBuildBuf, inMsg-SecurityUse ) )#if defined( LCD_SUPPORTED )HalLcdWriteScreen( Match Desc Req, Rsp Sent );#endifelse#if defined( LCD_SUPPORTED )HalLcdWriteScreen( Match Desc Req, Non Matched );#endifif ( inClusters )osal_mem_free( inClusters );if ( outClusters )osal_mem_free( outClusters ); 从上面的代码内容中也可以看到,当两个节点绑定时,进行的匹配实质是描述符之间的匹配。当然绑定时可能有多个的描述符的匹配,不知道我这样的理解是否正确,如果网友有这方面的经验欢迎讨论一下!这里还有一点就是绑定服务只能在“互补”设备之间建立。那就是,只有分别在两个节点的简单描述结构体(simple descriptor structure)中,同时注册了相同的命令标识符(command_id)并且方向相反(一个属于输出指令“output”,另一个属于输入指令“input”),才能成功建立绑定。通过查看TI给我例子程序中,只有开头的例程才算是真正意义上的一个是输出,一个是输入。对于灯结点是输入,const cId_t zb_InCmdListNUM_IN_CMD_CONTROLLER =TOGGLE_LIGHT_CMD_ID;/ Define SimpleDescriptor for Switch deviceconst SimpleDescriptionFormat_t zb_SimpleDesc =MY_ENDPOINT_ID,/EndpointMY_PROFILE_ID,/Profile IDDEV_ID_CONTROLLER,/Device IDDEVICE_VERSION_CONTROLLER,/Device Version0,/ReservedNUM_IN_CMD_CONTROLLER,/Number of Input Commands(cId_t *) zb_InCmdList,/Input Command ListNUM_OUT_CMD_CONTROLLER,/Number of Output Commands(cId_t *) NULL/Output Command List;对于开关结点是输出。const cId_t zb_OutCmdListNUM_OUT_CMD_SWITCH =TOGGLE_LIGHT_CMD_ID;/ Define SimpleDescriptor for Switch deviceconst SimpleDescriptionFormat_t zb_SimpleDesc =MY_ENDPOINT_ID,/EndpointMY_PROFILE_ID,/Profile IDDEV_ID_SWITCH,/Device IDDEVICE_VERSION_SWITCH,/Device Version0,/ReservedNUM_IN_CMD_SWITCH,/Number of Input Commands(cId_t *) NULL,/Input Command ListNUM_OUT_CMD_SWITCH,/Number of Output Commands(cId_t *) zb_OutCmdList/Output Command List; 可以在GenericApp和SerialApp的例程中看到,并没有严格的按照这样的命令来。例如下面的SampleApp例程中,当然这样也是两个设备中的命令也是相反的,只是没有开关那个例程中更加直观,const cId_t GenericApp_ClusterListGENERICAPP_MAX_CLUSTERS =GENERICAPP_CLUSTERID;const SimpleDescriptionFormat_t GenericApp_SimpleDesc =GENERICAPP_ENDPOINT,/int Endpoint;GENERICAPP_PROFID,/uint16 AppProfId2;GENERICAPP_DEVICEID,/uint16 AppDeviceId2;GENERICAPP_DEVICE_VERSION,/intAppDevVer:4;GENERICAPP_FLAGS,/intAppFlags:4;GENERICAPP_MAX_CLUSTERS,/byteAppNumInClusters;(cId_t *)GenericApp_ClusterList,/byte *pAppInClusterList;GENERICAPP_MAX_CLUSTERS,/byteAppNumInClusters;(cId_t *)GenericApp_ClusterList/byte *pAppInClusterList; APS绑定表是在静态RAM中定义的一张表,定义在nwk_globals.c中。表的大小可以通过f8wConfig.cfg中的/* Maximum number of entries in the Binding table. */-DNWK_MAX_BINDING_ENTRIES=10/* Maximum number of cluster IDs for each binding table entry. */-DMAX_BINDING_CLUSTER_IDS=5只有定义了REFLECTOR或者COORDINATOR_BINDING才能包含此表,用REFLECTOR编译选项来支持APS层的源绑定。邦定表结构 BindingEntry_ttypedef structuint16 srcIdx;/ Ad

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论