SimpleApp例程中两种绑定机制程序流程
2012-05-22 10:21
465 查看
建立一个绑定表格有3种方式:
(1)ZDO绑定请求:一个试运转的工具能告诉这个设备制作一个绑定报告
(2)ZDO终端设备绑定请求:设备能告诉协调器他们想建立绑定表格报告。该协调器将使协调并在这两个设备上创建绑定表格条目。
(3)设备应用:在设备上的应用能建立或管理一个绑定表格。
[b]有两种可用的机制配置设备绑定:
(1)如果目的设备的扩展地址是已知的,则zb_BindDeviceRequest()函数能创建一个绑定条目。
(2)如果扩展地址是未知的,则一个"按钮"可以利用。这样的话,这个目的设备首先处于一种状态,它将被zb_AllowBindResponse()发出一个匹配响应;然后在源设备处,zb_AllowBindRequest()函数带着空地址出发.[/b]
[b] 以上两种绑定机制,最终都是用函数APSME_BindRequest()创建绑定。不同的是,前者采用的目的地址是64位扩展地址,而后者采用的目的地址是16位网络地址。前者已知扩展地址,调用了ZDP_NwkAddrReq()函数获得目的设备短地址;后者利用描述匹配得到了短地址,然后调用了ZDP_IEEEAddrReq()函数,获取目的设备的扩展地址.[/b]
1、已知扩展地址的绑定
这里可以直接调用函数zb_BindDevice()发起绑定请求:
zb_BindDevice ( uint8 create, //是否创建绑定,TRUE则创建,FALSE则解除
uint16 commandId, //命令ID,基于某命令的绑定,相当于簇
uint8 *pDestination ) //指向扩展地址的指针
[b]函数程序如下(已知扩展地址的绑定部分)
******************************************
void zb_BindDevice ( uint8 create, uint16 commandId, uint8 *pDestination )
{
zAddrType_t destination;
uint8 ret = ZB_ALREADY_IN_PROGRESS;[/b]
[b] if ( create ) //create = true 建立绑定
{
if (sapi_bindInProgress == 0xffff) //不允许绑定过程??
{
//---------------------------------
if ( pDestination ) //已知扩展地址的绑定,即*pDestination 为非NULL
{
destination.addrMode = Addr64Bit;
osal_cpyExtAddr( destination.addr.extAddr, pDestination );[/b]
[b] //直接调用APS绑定请求函数
ret = APSME_BindRequest( sapi_epDesc.endPoint, //源EP
commandId, //簇ID
&destination, //目的地址模式
sapi_epDesc.endPoint ); //目的EP[/b]
[b] if ( ret == ZSuccess ) //绑定成功
{
// Find nwk addr 发现网络地址,得到被绑定设备的短地址
ZDP_NwkAddrReq(pDestination, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 );
osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 250 );
}
}
//---------------------------------
else //未知目的扩展地址,即*pDestination=NULL
{
ret = ZB_INVALID_PARAMETER;
destination.addrMode = Addr16Bit;
destination.addr.shortAddr = NWK_BROADCAST_SHORTADDR; //0xffff 描述符匹配请求:广播
/*如果commandId是输出簇,则检测是否与本终端输出簇列表中的某一项相匹配(相同)*/
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 );
}
/*如果commandId是输入簇,则检测是否与本终端输入簇列表中的某一项相匹配(相同)*/
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 );
}[/b]
[b] if ( ret == ZB_SUCCESS )
{
// Set a timer to make sure bind completes
osal_start_timerEx(sapi_TaskID, ZB_BIND_TIMER, AIB_MaxBindingTime);
sapi_bindInProgress = commandId;
return; // dont send cback event
}
}
//---------------------------------
}[/b]
[b] SAPI_SendCback( SAPICB_BIND_CNF, ret, commandId );
}
else //create = false 删除绑定
{
// Remove local bindings for the commandId
BindingEntry_t *pBind;[/b]
[b] // Loop through bindings an remove any that match the cluster
while ( pBind = bindFind( sapi_epDesc.simpleDesc->EndPoint, commandId, 0 ) )
{
bindRemoveEntry(pBind);
}
osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 250 );
}
return;
}[/b]
[b]******************************************
在上面已知扩展地址的绑定程序中调用了APS绑定函数APSME_BindRequest(),这个函数在两个设备间建立绑定,通过APSME_BIND.confirm原语返回,而且这两者是不可分割的。如果绑定成功,则调用函数ZDP_NwkAddrReq()得到目的设备的短地址。ZDP_NwkAddrReq()这个函数可以产生一个根据已知遥远设备的IEEE地址,请求得到16位短地址的信息.该信息以广播的方式发送给网络中的所有设备.[/b]
[b]2、未知扩展地址的绑定(simpApp例子中默认的绑定机制)
该绑定方式下,在发送绑定请求前,先要让被绑定的目的设备处于允许绑定模式。可以调用函数zb_AllowBind()进入该模式,函数如下:[/b]
[b]******************************************[/b]
[b]//函数设置设备处于允许绑定模式
//timerout=0x00:不允许绑定
//timerout=0xff:一直处于绑定模式
//0<timeout<65:允许绑定的时间(单位/秒)[/b]
[b]void zb_AllowBind ( uint8 timeout )
{[/b]
[b] osal_stop_timerEx(sapi_TaskID, ZB_ALLOW_BIND_TIMER);[/b]
[b] if ( timeout == 0 )
{
afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE);
}
else
{
afSetMatch(sapi_epDesc.simpleDesc->EndPoint, TRUE); //设置允许响应匹配描述符请求
if ( timeout != 0xFF )
{
if ( timeout > 64 )
{
timeout = 64;
}
//设置了允许匹配后,开启一个定时器,时间为timeout*1000,
//时间一到触发sapi任务ZB_ALLOW_BIND_TIMER事件,SAPI_ProcessEvent()对其的处理是
//afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE)而取消允许绑定
osal_start_timerEx(sapi_TaskID, ZB_ALLOW_BIND_TIMER, timeout*1000);
}
}
return;
}
******************************************
参数timeout是进入绑定模式持续的时间(s)。如果设置为OxFF,则设备在任何时候都在允许绑定模式;如果设置为OxOO,则设备将通过该命令取消允许绑定模式.
调用该函数使设备在给定时间内进入允许绑定模式.一个在允许绑定模式下同等的设备调用函数zb_BindDevice()能与之建立绑定,此时目的扩展地址为空(参见上面zb_BindDevice()未知目的扩展地址部分).zb_AllowBind()调用afSetMatch(),使之允许响应ZDO的匹配描述符请求.
以上设置目的设备允许绑定模式(比如simpleApp的灯设备),那在目的设备处于允许绑定模式的时间内,源设备(比如simpleApp的开关设备)可以调用zb_BindDevice()来发起绑定请求.此时执行的程序如下:[/b]
[b]******************************************
void zb_BindDevice ( uint8 create, uint16 commandId, uint8 *pDestination )
{
…………
//---------------------------------
else //未知目的扩展地址,即*pDestination=NULL
{
ret = ZB_INVALID_PARAMETER;
destination.addrMode = Addr16Bit;
destination.addr.shortAddr = NWK_BROADCAST_SHORTADDR; //0xffff
/*如果commandId是输出簇,则检测是否与本终端输出簇列表中的某一项相匹配(相同)*/
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 );
}
/*如果commandId是输入簇,则检测是否与本终端输入簇列表中的某一项相匹配(相同)*/
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 );
}[/b]
[b] if ( ret == ZB_SUCCESS )
{
// Set a timer to make sure bind completes 设置一个时间,确保绑定完成
osal_start_timerEx(sapi_TaskID, ZB_BIND_TIMER, AIB_MaxBindingTime);
sapi_bindInProgress = commandId; //允许基于commandId命令的绑定过程
return; // dont send cback event
}
}
//---------------------------------
…………
}
******************************************
在之中调用了函数ZDP_MatchDescReq(),将建立和发送一个匹配描述符请求。用这个函数在一个应用中的输入/输出簇列表中搜索匹配某条件的设备/应用。该绑定响应处理在SAPI_ProcessEvent事件处理函数中
case ZDO_CB_MSG: /*ZDO信息数据*/
SAPI_ProcessZDOMsgs( (zdoIncomingMsg_t *)pMsg );
看下SAPI_ProcessZDOMsgs()函数[/b]
[b]******************************************
// SAPI_Init()函数中注册了以下两个ZDO信息
// ZDO_RegisterForZDOMsg( sapi_TaskID, NWK_addr_rsp );
// ZDO_RegisterForZDOMsg( sapi_TaskID, Match_Desc_rsp );[/b]
[b]void SAPI_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg )
{
switch ( inMsg->clusterID )
{
//--------------------
case NWK_addr_rsp:
…………
//--------------------
case Match_Desc_rsp:
{
zAddrType_t dstAddr;
ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );[/b]
[b] if ( sapi_bindInProgress != 0xffff ) //commandId
{
// Create a binding table entry 创建一个绑定条目
dstAddr.addrMode = Addr16Bit;
dstAddr.addr.shortAddr = pRsp->nwkAddr; [/b]
[b] /*调用这个函数来实现两个设备的绑定*/
if ( APSME_BindRequest( sapi_epDesc.simpleDesc->EndPoint, //源EP
sapi_bindInProgress, //簇ID
&dstAddr, //目的地址模式
pRsp->epList[0] ) == ZSuccess ) //目的EP
//成功实现绑定后
{
//zb_BindDevice()中开启了一个定时器,用于接收Match_Desc_rsp计时
//如果接收到,则停止这个定时器,如下;如果溢出,则触发相应任务事件
osal_stop_timerEx(sapi_TaskID, ZB_BIND_TIMER);
osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 250 );
sapi_bindInProgress = 0xffff;[/b]
[b] // Find IEEE addr
ZDP_IEEEAddrReq( pRsp->nwkAddr, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 );[/b]
[b] // Send bind confirm callback to application
zb_BindConfirm( sapi_bindInProgress, ZB_SUCCESS );
}
}
}
break;
}
}
******************************************[/b]
[b]以上内容摘自《zigbee2006无线网络与无线定位实战》这本书,根据协议版本的不同作了一些修改。
实例中的两种绑定机制,第一种(已知扩展地址的绑定)流程,就是zb_BindDevice()根据扩展地址直接调用APSME_BindRequest()创建绑定条目实现绑定,再得到其16位网络地址;第二种(未知扩展地址的绑定),因地址未知,须先经过一个描述符匹配过程得到相匹配设备的16位短地址,然后通过APSME_BindRequest()创建绑定条目实现绑定,再得到其扩展地址.[/b]
相关文章推荐
- 绑定(4)通过SimpleApp例程理解绑定的流程
- 绑定(5)通过SimpleApp例程理解绑定的流程
- 通过SimpleApp例程总结绑定的流程
- zstack SimpleApp和GenericApp实例绑定程序流程
- zigbee绑定机制的代码体现————SimpleApp为例
- Simple实例中的两种绑定机制
- 关于ZStack-CC2530-2.3.0-1.4.0中simpleApp例子的 终端节点入网以及绑定操作(二)
- iPhone应用提交流程:如何将App程序发布到App Store?
- iPhone应用提交流程:如何将App程序发布到App Store?
- IOS开发 APP提交程序上传流程
- iPhone应用提交流程:如何将App程序发布到App Store?
- PJSIP学习笔记——从simple_pjsua.c示例程序了解PJSUA-LIB的基本使用流程
- 关于ZStack-CC2530-2.3.0-1.4.0中simpleApp例子的 终端节点入网以及绑定操作(三)
- mapreduce的任务切片规划机制、job提交流程、Mapreduce中的分区Partitioner与流量汇总程序开发
- 微信小程序自学第二课:app及页面的生命周期、使用setData绑定数据
- erlang app程序打包及启动流程
- iPhone应用提交流程:如何将App程序发布到App Store?
- iPhone应用提交流程:如何将App程序发布到App Store
- 关于ZStack-CC2530-2.3.0-1.4.0中simpleApp例子的 终端节点入网以及绑定操作(四)
- Android app退出程序的两种方式