*********************************************************************
* @fn AF_DataRequest
*dstAddr--发送目的地址+端点地址(端点号)和传送模式
*srcEP --源(答复或确认)终端的描述(比如操作系统中任务ID等)源EP
cID --被Profile指定的有效的集群号
len --发送数据长度
*buf --发送数据缓冲区
*transID --任务ID号
options --有效位掩码的发送选项
radius --传送跳数,通常设置为AF_DEFAULT_RADIUS
*/
uint8 AF_DataRequestDiscoverRoute = TRUE;
afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
uint8 options, uint8 radius )
{
pDescCB pfnDescCB;
ZStatus_t stat;
APSDE_DataReq_t req;
afDataReqMTU_t mtu;
// Verify source end point
if ( srcEP == NULL )
{
return afStatus_INVALID_PARAMETER;
}
#if !defined( REFLECTOR )
if ( dstAddr->addrMode == afAddrNotPresent )
{
return afStatus_INVALID_PARAMETER;
}
#endif
// Validate broadcasting
if ( ( dstAddr->addrMode == afAddr16Bit ) ||
( dstAddr->addrMode == afAddrBroadcast ) )
{
// Check for valid broadcast values
if( ADDR_NOT_BCAST != NLME_IsAddressBroadcast( dstAddr->addr.shortAddr ) )
{
// Force mode to broadcast
dstAddr->addrMode = afAddrBroadcast;
}
else
{
// Address is not a valid broadcast type
if ( dstAddr->addrMode == afAddrBroadcast )
{
return afStatus_INVALID_PARAMETER;
}
}
}
else if ( dstAddr->addrMode != afAddr64Bit &&
dstAddr->addrMode != afAddrGroup &&
dstAddr->addrMode != afAddrNotPresent )
{
return afStatus_INVALID_PARAMETER;
}
// Set destination address
req.dstAddr.addrMode = dstAddr->addrMode;
if ( dstAddr->addrMode == afAddr64Bit )
osal_cpyExtAddr( req.dstAddr.addr.extAddr, dstAddr->addr.extAddr );
else
req.dstAddr.addr.shortAddr = dstAddr->addr.shortAddr;
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 );
}
}
else if ( 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 = AF_DataRequestDiscoverRoute;//(uint8)((options & AF_DISCV_ROUTE) ? 1 : 0);
req.radiusCounter = radius;
#if defined ( INTER_PAN )
req.dstPanId = dstAddr->panId;
if ( StubAPS_InterPan( dstAddr->panId, dstAddr->endPoint ) )
{
if ( len > INTERP_DataReqMTU() )
{
stat = afStatus_INVALID_PARAMETER;
}
else
{
stat = INTERP_DataReq( &req );
}
}
else
#endif // INTER_PAN
{
if (len > afDataReqMTU( &mtu ) )
{
if (apsfSendFragmented)
{
stat = (*apsfSendFragmented)( &req );
}
else
{
stat = afStatus_INVALID_PARAMETER;
}
}
else
{
stat = APSDE_DataReq( &req );
}
}
参数详解如下:
其中
1、afAddrType_t *dstAddr
af地址类型
typedefstruct
{
union
{
uint16 shortAddr; //短地址
}addr;
afAddrMode_t addrMode; //传送模式
byte endPoint; //端点号
}afAddrType_t;
2、endPointDesc_t *srcEP
端点描述
typedefstruct
{
byteendPoint; //端点号
byte*task_id; //那一个任务的端点号 (调用任务的ID)
SimpleDescriptionFormat_t *simpleDesc; //简单的端点描述
afNetworkLatencyReq_tlatencyReq;
}endPointDesc_t;
3、SimpleDescriptionFormat_t
简单描述格式
typedefstruct
{
byte EndPoint; //EP
uint16 AppProfId; //应用规范ID
uint16 AppDeviceId; //特定规范ID的设备类型
byte AppDevVer:4; //特定规范ID的设备的版本
byte Reserved:4; //AF_V1_SUPPORTusesforAppFlags:4.
byte AppNumInClusters; //输入簇ID的个数
cId_t *pAppInClusterList; //输入簇ID的列表
byte AppNumOutClusters; //输出簇ID的个数
cId_t *pAppOutClusterList; //输出簇ID的列表
}SimpleDescriptionFormat_t;
4、uint16 cID
ClusterID--具体应用串ID
5、uint8 options
发送模式选项有如下选项
#defineAF_FRAGMENTED 0x01
#defineAF_ACK_REQUEST 0x10 要求APS应答,这是应用层的应答,只在直接发送(单播)时使用。
#defineAF_DISCV_ROUTE 0x20
#defineAF_EN_SECURITY 0x40
#defineAF_SKIP_ROUTING 0x80 设置这个选项将跳过路由而直接发送消息
终点设备将不向其父亲发送消息。在直接发送(单播)和广播消息时很好用。
终点设备将不向其父亲发送消息。在直接发送(单播)和广播消息时很好用。
其中AF_ACK_REQUEST为发送后需要接收方的确认
6、uint8 radius
传输跳数或传输半径,默认值为10