发送函数AFDataRequest.docx
《发送函数AFDataRequest.docx》由会员分享,可在线阅读,更多相关《发送函数AFDataRequest.docx(7页珍藏版)》请在冰豆网上搜索。
发送函数AFDataRequest
Z-Stack中发送数据通过在应用层调用函数voidSampleApp_SendFlashMessage(uint16flashTime)完成,其中flashTime为发送的数据,这个函数在应用中通过调用
afStatus_tAF_DataRequest(afAddrType_t*dstAddr,endPointDesc_t*srcEP,
uint16cID,uint16len,uint8*buf,uint8*transID,
uint8options,uint8radius)
函数完成数据的发送。
如果熟悉了其中的每个参数的含义,就可以很灵活的使用发送函数发送自己的数据。
第一个参数dstAddr,在文件AF.h中,该参数是一个结构体的指针。
在该参数中除了指定了网络地址外,还需要指定目的地址的模式参数。
typedefstruct
{
union
{
uint16shortAddr;
}addr;
afAddrMode_taddrMode;//afAddrMode_t是一个枚举类型模式参数
byteendPoint;//指定的端点号端点241—254保留端点范围1-240
}afAddrType_t;
下面的是afAddrMode_t结构体的定义
typedefenum
{
afAddrNotPresent=AddrNotPresent,//按照绑定表进行绑定传输
afAddr16Bit=Addr16Bit,//指定目标网络地址进行单薄传输16位
afAddrGroup=AddrGroup,//组播传输
afAddrBroadcast=AddrBroadcast//广播传输
}afAddrMode_t;
enum
{
AddrNotPresent=0,
AddrGroup=1,
Addr16Bit=2,
Addr64Bit=3,//指定IEEE地址进行单播传输64位
AddrBroadcast=15
};
注意:
ZigBee设备有两种类型的地址。
一种是64位IEEE地址(物理),即MAC地址,另一种是16位网络地址。
64位地址使全球唯一的地址,设备将在它的生命周期中一直拥有它。
它通常由制造商或者被安装时设置。
这些地址由IEEE来维护和分配。
16为网络地址是当设备加入网络后由协调器或路由器分配的。
它在网络中是唯一的,用来在网络中鉴别设备和发送数据。
第二个参数endPointDesc_t*srcEP,也是一个结构体的指针,源网络地址描述,每个终端都必须要有一个ZigBeezz的简单描述。
typedefstruct
{
byteendPoint;//端点号
byte*task_id;//PointertolocationoftheApplicationtaskID.
SimpleDescriptionFormat_t*simpleDesc;//设备的简单描述
afNetworkLatencyReq_tlatencyReq;//枚举结构必须用noLatencyReqs填充
}endPointDesc_t;
目标设备的简单描述结构
typedefstruct
{
byteEndPoint;//EPID(EP=EndPoint)
uint16AppProfId;//profileID(剖面ID)
uint16AppDeviceId;//DeviceID
byteAppDevVer:
4;//DeviceVersion0x00为Version1.0
byteReserved:
4;//AF_V1_SUPPORTusesforAppFlags:
4.
byteAppNumInClusters;//终端支持的输入簇的个数
cId_t*pAppInClusterList;//指向输入ClusterID列表的指针
byteAppNumOutClusters;//输出簇的个数
cId_t*pAppOutClusterList;//指向输出CluseterID列表的指针
}SimpleDescriptionFormat_t;
typedefenum
{
noLatencyReqs,
fastBeacons,
slowBeacons
}afNetworkLatencyReq_t;
第三个参数:
uint16cID簇ID
第四个参数:
len要发送的数据的长度
第五个参数:
uint8*buf指向发送数据缓冲的指针
第六个参数:
uint8*transID事务序列号指针。
如果消息缓存发送,这个函数将增加这个数字
第七个参数:
发送选项,可以由下面一项,或几项相或得到
AF_ACK_REQUEST0x10要求APS应答,这是应用层的应答,只在直接发送(单播)时使用。
AF_DISCV_ROUTE0x20总要包含这个选项
AF_SKIP_ROUTING0x80设置这个选项将导致设备跳过路由而直接发送消息。
终点设备将不向其父亲发送消息。
在直接发送(单播)和广播消息时很好用。
第八个参数:
uint8radius最大的跳数,用默认值AF_DEFAULT_RADIUS
返回值:
该函数的返回值:
afStatus_t类型枚举型的,成功或
typedefenum
{
afStatus_SUCCESS,
afStatus_FAILED=0x80,
afStatus_MEM_FAIL,
afStatus_INVALID_PARAMETER
}afStatus_t;
下面是这个函数完整的源代码:
afStatus_tAF_DataRequest(afAddrType_t*dstAddr,endPointDesc_t*srcEP,
uint16cID,uint16len,uint8*buf,uint8*transID,
uint8options,uint8radius)
{
pDescCBpfnDescCB;
ZStatus_tstat;
APSDE_DataReq_treq;
afDataReqMTU_tmtu;
//Verifysourceendpoint判断源节点是否为空
if(srcEP==NULL)
{
returnafStatus_INVALID_PARAMETER;
}
#if!
defined(REFLECTOR)
if(dstAddr->addrMode==afAddrNotPresent)
{
returnafStatus_INVALID_PARAMETER;
}
#endif
//Verifydestinationaddress判断目的地址
req.dstAddr.addr.shortAddr=dstAddr->addr.shortAddr;
//Validatebroadcasting判断地址的模式
if((dstAddr->addrMode==afAddr16Bit)||
(dstAddr->addrMode==afAddrBroadcast))
{
//Checkforvalidbroadcastvalues核对有效的广播值
if(ADDR_NOT_BCAST!
=NLME_IsAddressBroadcast(dstAddr->addr.shortAddr))
{
//Forcemodetobroadcast强制转换成广播模式
dstAddr->addrMode=afAddrBroadcast;
}
else
{
//Addressisnotavalidbroadcasttype地址不是一个有效的广播地址类型
if(dstAddr->addrMode==afAddrBroadcast)
{
returnafStatus_INVALID_PARAMETER;
}
}
}
elseif(dstAddr->addrMode!
=afAddrGroup&&
dstAddr->addrMode!
=afAddrNotPresent)
{
returnafStatus_INVALID_PARAMETER;
}
req.dstAddr.addrMode=dstAddr->addrMode;
req.profileID=ZDO_PROFILE_ID;
if((pfnDescCB=afGetDescCB(srcEP)))
{
uint16*pID=(uint16*)(pfnDescCB(
AF_DESCRIPTOR_PROFILE_ID,srcEP->endPoint));
if(pID)
{
req.profileID=*pID;
osal_mem_free(pID);
}
}
elseif(srcEP->simpleDesc)
{
req.profileID=srcEP->simpleDesc->AppProfId;
}
req.txOptions=0;
if((options&AF_ACK_REQUEST)&&
(req.dstAddr.addrMode!
=AddrBroadcast)&&
(req.dstAddr.addrMode!
=AddrGroup))
{
req.txOptions|=APS_TX_OPTIONS_ACK;
}
if(options&AF_SKIP_ROUTING)
{
req.txOptions|=APS_TX_OPTIONS_SKIP_ROUTING;
}
if(options&AF_EN_SECURITY)
{
req.txOptions|=APS_TX_OPTIONS_SECURITY_ENABLE;
mtu.aps.secure=TRUE;
}
else
{
mtu.aps.secure=FALSE;
}
mtu.kvp=FALSE;
req.transID=*transID;
req.srcEP=srcEP->endPoint;
req.dstEP=dstAddr->endPoint;
req.clusterID=cID;
req.asduLen=len;
req.asdu=buf;
req.discoverRoute=TRUE;//(uint8)((options&AF_DISCV_ROUTE)?
1:
0);
req.radiusCounter=radius;
if(len>afDataReqMTU(&mtu))
{
if(apsfSendFragmented)
{
req.txOptions|=AF_FRAGMENTED|APS_TX_OPTIONS_ACK;
stat=(*apsfSendFragmented)(&req);
}
else
{
stat=afStatus_INVALID_PARAMETER;
}
}
else
{
stat=APSDE_DataReq(&req);
}
if((req.dstAddr.addrMode==Addr16Bit)&&
(req.dstAddr.addr.shortAddr==NLME_GetShortAddr()))
{
afDataConfirm(srcEP->endPoint,*transID,stat);
}
if(stat==afStatus_SUCCESS)
{
(*transID)++;
}
return(afStatus_t)stat;
}