数据的传输方式及数据接收



寻址方式

地址类型(Addresstypes)

ZigBee设备有两种类型的地址。一种是64IEEE地址,即MAC地址,另一种是16位网络地址。

64位地址使全球唯一的地址,设备将在它的生命周期中一直拥有它。它通常由制造商或者被安装时设置。这些地址由IEEE来维护和分配。

16为网络地址是当设备加入网络后分配的。它在网络中是唯一的,用来在网络中鉴别设备和发送数据。

 

 

 

Z-Stack寻址(Addressinginz-stack)

为了向一个在ZigBee网络中的设备发送数据,应用程序通常使用AF_DataRequest()函数。数据包将要发送给一个afAddrType_t(ZComDef.h中定义)类型的目标设备。

Typedefstruct

{

union{

uint16shortAddr;

}addr;

afAddrMode_taddrMode;

byteendPoint;

}afAddrType_t;

注意,除了网络地址之外,还要指定地址模式参数。目的地址模式可以设置为以下几个值:typedef enum

{

afAddrNotPresent=AddrNotPresent,

afAddr16Bit=Addr16Bit,

afAddrGroup=AddrGroup,

afAddrBroadcast=AddrBroadcast

}afAddrMode_t;

因为在Zigbee中,数据包可以单点传送(unicast),多点传送(multicast)或者广播传送,所以必须有地址模式参数。一个单点传送数据包只发送给一个设备,多点传送数据包则要传送给一组设备,而广播数据包则要发送给整个网络的所有节点。

这个将在下面详细解释。

 

单点传送(Unicast)

Uicast是标准寻址模式,它将数据包发送给一个已经知道网络地址的网络设备。将afAddrMode设置为Addr16Bit并且在数据包中携带目标设备地址。

 

间接传送(Indirect)

当应用程序不知道数据包的目标设备在哪里的时候使用的模式。

将模式设置为AddrNotPresent并且目标地址没有指定。取代它的是从发送设备的栈的绑定表中查找目标设备。这种特点称之为源绑定。当数据向下发送到达栈中,从绑定表中查找并且使用该目标地址。这样,数据包将被处理成为一个标准的单点传送数据包。如果在绑定表中找到多个设备,则向每个设备都发送一个数据包的拷贝。有一个选项可以讲绑定表保存在协调器(Coordinator)当中。发送设备将数据包发送给协调器,协调器查找它栈中的绑定表,然后将数据发送给最终的目标设备。这个附加的特性叫做协调器绑定(CoordinatorBinding)

 

广播传送(broadcast)

当应用程序需要将数据包发送给网络的每一个设备时,使用这种模式。地址模式设置为AddrBroadcast

目标地址可以设置为下面广播地址的一种:

NWK_BROADCAST_SHORTADDR_DEVALL(0xFFFF)——数据包将被传送到网络上的所有设备,包括睡眠中的设备。对于睡眠中的设备,数据包将被保留在其父亲节点直到查询到它,或者消息超时(NWK_INDIRECT_MSG_TIMEOUTf8wConifg.cfg)

NWK_BROADCAST_SHORTADDR_DEVRXON(0xFFFD)——数据包将被传送到网络上的所有在空闲时打开接收的设备(RXONWHENIDLE),也就是说,除了睡眠中的所有设备。

NWK_BROADCAST_SHORTADDR_DEVZCZR(0xFFFC)——数据包发送给所有的路由器,包括协调器。

0xFFFE--通过绑定表中的地址进行发送。

 

组寻址(GroupAddressing)

当应用程序需要将数据包发送给网络上的一组设备时,使用该模式。地址模式设置为afAddrGroup并且addr.shortAddr设置为组ID

在使用这个功能呢之前,必须在网络中定义组。(参见Z-stackAPI文档中的aps_AddGroup()函数)。注意组可以用来关联间接寻址。再绑定表中找到的目标地址可能是是单点传送或者是一个组地址。另外,广播发送可以看做是一个组寻址的特例。

 

重要设备地址(ImportantDeviceAdresses)

应用程序可能需要知道它的设备地址和父亲地址。

使用下面的函数获取设备地址(ZStackAPI中定义)

1、NLME_GetShortAddr()——返回本设备的16位网络地址

2、NLME_GetExtAddr()——返回本设备的64位扩展地址使用下面的函数获取该设备的父亲设备的地址:

1、NLME_GetCoordShortAddr()——返回本设备的父亲设备的16位网络地址

2、NLME_GetCoordExtAddr()——返回本设备的父亲设备的64位扩展地址

 

 

 

数据的发送,广播、组播、点对点

AF_DataRequest(afAddrType_t*dstAddr,endPointDesc_t*srcEP,uint16cID,uint16len,uint8*buf,uint8*transID,uint8options,uint8radius);

AF_DataRequest函数最终调用APSDE_DataReq原语,而我们只需要了解AF_DataRequest函数的参数,就可非常灵活的以各种方式来发送数据。

AF_DataRequest函数的调用会触发afDataConfirm(...)函数

数据的发送结果也由afDataConfirm(...)函数返回

AF_DataRequest函数返回的值并不是真正的发送结果。

 

函数参数说明

*dstAddr--发送目的地址+端点地址和传送模式

*srcEP--(答复或确认)终端的描述(比如操作系统中任务ID等)源EP

cID--Profile指定的有效的集群号

len--发送数据长度

*buf--发送数据缓冲区

*transID--任务ID

options--有效位掩码的发送选项

radius--传送跳数,通常设置为AF_DEFAULT_RADIUS

 

afAddrType_t*dstAddr

Typedef struct

{

union{

uint16shortAddr; //短地址}addr;

afAddrMode_taddrMode; //传送模式

byteendPoint; //端点号

}afAddrType_t;

 

endPointDesc_t*srcEP

Typedefstruct

{

byteendPoint;//端点号

byte*task_id;//那一个任务的端点号

SimpleDescriptionFormat_t*simpleDesc; //简单的端点描述     afNetworkLatencyReq_tlatencyReq;

}endPointDesc_t;

 

SimpleDescriptionFormat_t

Typedefstruct

{

byteEndPoint; //EP

uint16AppProfId; //应用规范ID

uint16AppDeviceId; //特定规范ID的设备类型

byteAppDevVer:4; //特定规范ID的设备的版本

byteReserved:4; //AF_V1_SUPPORTusesforAppFlags:4.

byteAppNumInClusters; //输入簇ID的个数

cId_t*pAppInClusterList; //输入簇ID的列表

byteAppNumOutClusters; //输出簇ID的个数

cId_t*pAppOutClusterList; //输出簇ID的列表

}SimpleDescriptionFormat_t;

 

ClusterID--具体应用串ID

 

uint8 options

发送模式选项有如下选项

#defineAF_FRAGMENTED0x01

#defineAF_ACK_REQUEST0x10

#defineAF_DISCV_ROUTE0x20

#defineAF_EN_SECURITY0x40

#defineAF_SKIP_ROUTING0x80

其中AF_ACK_REQUEST为发送后需要接收方的确认

 

uint8 radius 传输跳数或传输半径,默认值为10

 

广播发送

广播发送时,分为三种广播,如果想使用广播发送,则只需将dstAddr->addrMode设为AddrBroadcastdstAddr->addr->shortAddr设置为相应的广播类型即可。

具体的定义如下:

NWK_BROADCAST_SHORTADDR_DEVALL(0xFFFF)——数据包将被传送到网络上的所有设备,包括睡眠中的设备。对于睡眠中的设备,数据包将被保留在其父亲节点直到查询到它,或者消息超时。

NWK_BROADCAST_SHORTADDR_DEVRXON(0xFFFD)——数据包将被传送到网络上的所有在空闲时打开接收的设备(RXONWHENIDLE),也就是说,除了睡眠中的所有设备。

NWK_BROADCAST_SHORTADDR_DEVZCZR(0xFFFC)——数据包发送给所有的路由器,包括协调器。

 

组播发送

如果设备想传输数据到某一组设备,那么只需将dstAddr->addrMode设为AddrGroupdstAddr->addr->shortAddr设置为相应的组ID即可。

代码如下:

//Setupfortheflashcommand'sdestinationaddress-Group1

SampleApp_Flash_DstAddr.addrMode=(afAddrMode_t)afAddrGroup;

SampleApp_Flash_DstAddr.endPoint=SAMPLEAPP_ENDPOINT;

SampleApp_Flash_DstAddr.addr.shortAddr=SAMPLEAPP_FLASH_GROUP;

//Fillouttheendpointdescription.

SampleApp_epDesc.endPoint=SAMPLEAPP_ENDPOINT;

SampleApp_epDesc.task_id=&SampleApp_TaskID;SampleApp_epDesc.simpleDesc

=(SimpleDescriptionFormat_t*)&SampleApp_SimpleDesc;

SampleApp_epDesc.latencyReq=noLatencyReqs;

根据上面代码的配置,然后使用AF_DataRequest()函数来进行组播发送。

 

点对点的发送

点对点的传输需要知道目标设备的短地址,需要将dstAddr->addrMode设为Addr16BitdstAddr->addr->shortAddr设置为目标设备的短地址即可。

代码如下:

SampleApp_Flash_DstAddr.addrMode=(afAddrMode_t)afAddr16Bit;

SampleApp_Flash_DstAddr.endPoint=SAMPLEAPP_ENDPOINT;

SampleApp_Flash_DstAddr.addr.shortAddr=0x00;//Fillouttheendpointdescription.

SampleApp_epDesc.endPoint=SAMPLEAPP_ENDPOINT;

SampleApp_epDesc.task_id=&SampleApp_TaskID;

SampleApp_epDesc.simpleDesc

=(SimpleDescriptionFormat_t*)&SampleApp_SimpleDesc;

SampleApp_epDesc.latencyReq=noLatencyReqs;

根据上面代码的配置,然后使用AF_DataRequest()函数来进行点对点发送。

 

绑定设备数据的发送

 

绑定设备数据的发送目标设备可以是一个设备、也可以是多个设备、还可以是一组设备,这要看绑定表中的绑定信息。

绑定设备数据的发送,需要将dstAddr->addrMode设为AddrNotPresentdstAddr->addr->shortAddr可以忽略,cID设置为绑定时注册的命令号。代码如下:

 

dstAddr.addrMode=afAddrNotPresent; //Settheendpoint

dstAddr.endPoint=sapi_epDesc.simpleDesc->EndPoint; //Fillouttheendpointdescription.

sapi_epDesc.endPoint=zb_SimpleDesc.EndPoint;

sapi_epDesc.task_id=&sapi_TaskID;

sapi_epDesc.simpleDesc=(SimpleDescriptionFormat_t*)&zb_SimpleDesc;

sapi_epDesc.latencyReq=noLatencyReqs;

根据上面代码的配置,然后使用AF_DataRequest()函数来进行绑定数据的发送。

 

数据的接收

 

当收到数据时会触发afIncomingData函数,afIncomingData函数会对信息进行过滤,看是否为本设备的信息,是的话进而调用afBuildMSGIncoming函数,代码如下:

if((aff->ProfileID==epProfileID)||((epDesc->endPoint==ZDO_EP)&&(aff->ProfileID==ZDO_PROFILE_ID)))

{

{

afBuildMSGIncoming(aff,epDesc,SrcAddress,LinkQuality,SecurityUse,timestamp);

 

}

}

 

afBuildMSGIncoming 函数中根据需要发送到的任务ID,添加相应任务的AF_INCOMING_MSG_CMD事件。在相应的AF_INCOMING_MSG_CMD事件中会对信息做进一步的处理,代码如下:

 

MSGpkt->hdr.event=AF_INCOMING_MSG_CMD;

MSGpkt->groupId=aff->GroupID;

MSGpkt->clusterId=aff->ClusterID;

afCopyAddress(&MSGpkt->srcAddr,SrcAddress);

MSGpkt->srcAddr.endPoint=aff->SrcEndPoint;

MSGpkt->endPoint=epDesc->endPoint;

MSGpkt->wasBroadcast=aff->wasBroadcast;

MSGpkt->LinkQuality=LinkQuality;

MSGpkt->SecurityUse=SecurityUse;

MSGpkt->timestamp=timestamp;

 

MSGpkt->cmd.TransSeqNumber=0;

MSGpkt->cmd.DataLength=aff->asduLength;

if(MSGpkt->cmd.DataLength)

{

MSGpkt->cmd.Data=(byte*)(MSGpkt+1);

osal_memcpy(MSGpkt->cmd.Data,asdu,MSGpkt->cmd.DataLength);}

Else

{

MSGpkt->cmd.Data=NULL;

}

 

afIncomingData函数的参数每个参数的详细说明如下:

 

aps_FrameFormat_t*afftypedefstruct{

byteFrmCtrl; //传输模式标识0x0C;与那些信息有关

byteXtndFrmCtrl; //0x00byteDstEndPoint;//目的EP

byteSrcEndPoint; //源端EP

uint16GroupID; //ID

uint16ClusterID; //接收的串

uint16ProfileID; //源模式标识符

bytewasBroadcast; //是否为广播传输0x00

byteapsHdrLen; //

byte*asdu; //应用数据

byteasduLength; //ASDU的长度

byteApsCounter; //每接收一次会加1

uint8transID; //任务ID

uint8BlkCount; //

uint8AckBits; //接收确认选项

}aps_FrameFormat_t;

 

zAddrType_t*SrcAddresstypedefstruct{

union{

uint16shortAddr; //16位短地址ZLongAddr_textAddr;//64位长地址}addr;

byteaddrMode; //地址模式}zAddrType_t;

 

组的加入或退出

APSME-ADD-GROUP.request{GroupAddress,Endpoint} 原语用来将设备添加到某组中APSME-REMOVE-GROUP.request{GroupAddress,Endpoint} 原语用来将设备从某组中删除。

 

其中的参数只有组地址和端点号,没有短地址等,添加或删除组成员只能在本地设备进行,不能远程进行,比如一个设备直接添加或删除另一个设备。

代码如下:

//设置EP

#defineSAMPLEAPP_ENDPOINT20 //配置组表结构

SampleApp_Group.ID=0x0001;

osal_memcpy(SampleApp_Group.name,"Group1",7); /添加到组

aps_AddGroup(SAMPLEAPP_ENDPOINT,&SampleApp_Group);

 

//指定组ID

#defineSAMPLEAPP_FLASH_GROUP0x0001 //设置EP

#defineSAMPLEAPP_ENDPOINT20 //从组中移除

aps_RemoveGroup(SAMPLEAPP_ENDPOINT,SAMPLEAPP_FLASH_GROUP);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值