📄 af.c
字号:
if ( hdr == NULL )
{
hdr = multiInit( dstAddr, srcEndPoint, clusterID, FrameType,
txOptions, DiscoverRoute, RadiusCounter );
if ( hdr == NULL )
{
return afStatus_MEM_FAIL;
}
}
if ( FALSE == multiAppend( hdr, (byte)DataLength, Data,
CommandType, AttribDataType, AttribId, ErrorCode ) )
{
if ( hdr->msg != NULL )
{
multiSend( hdr, TransSeqNumber, RadiusCounter );
}
else
{
osal_mem_free( hdr );
}
hdr = NULL;
return afStatus_MEM_FAIL;
}
// Only supporting up to 16 concatenated messages.
if ( (AddOrSend == SEND_MESSAGE) || (hdr->transCount >= 16) )
{
stat = multiSend( hdr, TransSeqNumber, RadiusCounter );
hdr = NULL;
}
else
{
stat = afStatus_SUCCESS;
(*TransSeqNumber)++;
}
return stat;
}
#endif
#if ( AF_V1_SUPPORT || AF_KVP_SUPPORT )
/*********************************************************************
* @fn afFillAndSendMessage
*
* @brief Fills in the cmd format structure and sends the out-going message.
*
* input parameters
*
* @param *dstAddr - Full ZB destination address: Nwk Addr + End Point.
* @param srcEndPoint - Origination (i.e. respond to or ack to) End Point.
* @param clusterID - A valid cluster ID as specified by the Profile.
* @param TransCount - Set to 1.
* @param FrameType - A valid frame type (see prev def of FRAMETYPE_...)
* @param *TransSeqNumber - A pointer to a byte which can be modified and
* which will be used as the transaction sequence number of the msg.
* @param CommandType -
* KVP Frame Type : A valid command type (see prev def of CMDTYPE_...)
* MSG Frame Type : Set to 0.
* @param AttribDataType -
* KVP Frame Type : A valid data type (see prev def of DATATYPE_...)
* MSG Frame Type : Set to 0.
* @param AttribId -
* KVP Frame Type : A valid Attribute ID as specified by the Profile.
* (e.g. see OnOffSRC_OnOff in HomeControlLighting.h).
* MSG Frame Type : Set to 0.
* @param ErrorCode -
* KVP Frame Type : A valid error code (see prev def of ERRORCODE_...)
* Note: Set to 0 unless the CommandType is one of the CMDTYPE_..._ACK.
* MSG Frame Type : Set to 0.
* @param DataLength - Number of bytes of data pointed to by next param.
* KVP Frame Type : This must match value expected for the
* AttributeDataType specified above or the send will fail.
* MSG Frame Type : No restriction or checks.
* @param *Data - A pointer to the data bytes to send.
* @param txOptions - A valid bit mask (see prev def of APS_TX_OPTIONS_)
* @param DiscoverRoute - Normally set to FALSE. Perhaps set to TRUE after
* receiving an AF_DATA_CONFIRM_CMD with status other than ZSuccess.
* @param RadiusCounter - Normally set to AF_DEFAULT_RADIUS.
*
* output parameters
*
* @param *TransSeqNumber - Incremented by one if the return value is success.
*
* @return afStatus_t - See previous definition of afStatus_... types.
*/
afStatus_t afFillAndSendMessage (
afAddrType_t *dstAddr, byte srcEndPoint, cId_t clusterID,
byte TransCount, byte FrameType, byte *TransSeqNumber,
byte CommandType, byte AttribDataType, uint16 AttribId, byte ErrorCode,
byte DataLength, byte *Data,
byte txOptions, byte DiscoverRoute, byte RadiusCounter )
{
const byte proVer = NLME_GetProtocolVersion();
afStatus_t stat = afStatus_FAILED;
byte *buf = Data;
#if ( AF_KVP_SUPPORT )
if ( FrameType == FRAMETYPE_KVP )
{
return afAddOrSendMessage( dstAddr, srcEndPoint, clusterID,
SEND_MESSAGE, FrameType, TransSeqNumber,
CommandType, AttribDataType, AttribId, ErrorCode,
DataLength, Data, txOptions, DiscoverRoute, RadiusCounter );
}
#endif
if ( FrameType != FRAMETYPE_MSG )
{
return afStatus_INVALID_PARAMETER;
}
if ( TransCount != 1 )
{
return afStatus_INVALID_PARAMETER;
}
if ( proVer == ZB_PROT_V1_0 )
{
buf = osal_mem_alloc( (short)(DataLength+3) );
if ( buf == NULL )
{
return afStatus_MEM_FAIL;
}
buf[0] = BUILD_UINT8( FRAMETYPE_MSG, 1 );
buf[1] = *TransSeqNumber;
buf[2] = (byte)DataLength;
// Copy the data portion of the packet.
if ( Data && DataLength )
{
osal_memcpy( buf+3, Data, DataLength );
DataLength += 3;
}
else
{
DataLength = 3;
}
}
stat = afSend( dstAddr, srcEndPoint, clusterID,
DataLength, buf, TransSeqNumber, txOptions, RadiusCounter );
if ( proVer == ZB_PROT_V1_0 )
{
osal_mem_free( buf );
}
return stat;
}
#endif
/*********************************************************************
* @fn AF_DataRequest
*
* @brief Common functionality for invoking APSDE_DataReq() for both
* KVP-Send/SendMulti and MSG-Send.
*
* input parameters
*
* @param *dstAddr - Full ZB destination address: Nwk Addr + End Point.
* @param *srcEP - Origination (i.e. respond to or ack to) End Point Descr.
* @param cID - A valid cluster ID as specified by the Profile.
* @param len - Number of bytes of data pointed to by next param.
* @param *buf - A pointer to the data bytes to send.
* @param *transID - A pointer to a byte which can be modified and which will
* be used as the transaction sequence number of the msg.
* @param options - Valid bit mask of Tx options.
* @param radius - Normally set to AF_DEFAULT_RADIUS.
*
* output parameters
*
* @param *transID - Incremented by one if the return value is success.
*
* @return afStatus_t - See previous definition of afStatus_... types.
*/
#if ( AF_V1_SUPPORT )
static afStatus_t afDataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
uint8 options, uint8 radius )
#else
afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
uint8 options, uint8 radius )
#endif
{
pDescCB pfnDescCB;
ZStatus_t stat;
APSDE_DataReq_t req;
afDataReqMTU_t mtu;
if ( srcEP == NULL )
{
return afStatus_INVALID_PARAMETER;
}
// Enforce consistent values on the destination address / address mode.
if ( dstAddr->addrMode == afAddrNotPresent )
{
dstAddr->endPoint = ZDO_EP;
req.dstAddr.addr.shortAddr = afGetReflector( srcEP->endPoint );
}
else // Handle types: afAddr16Bit
{ // afAddrBroadcast
// afAddrGroup
req.dstAddr.addr.shortAddr = dstAddr->addr.shortAddr;
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 != afAddrGroup )
{
return afStatus_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 );
}
}
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 = (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 this is an EndPoint-to-EndPoint message on the same device, it will not
* get added to the NWK databufs. So it will not go OTA and it will not get
* a MACCB_DATA_CONFIRM_CMD callback. Thus it is necessary to generate the
* AF_DATA_CONFIRM_CMD here. Note that APSDE_DataConfirm() only generates one
* message with the first in line TransSeqNumber, even on a multi message.
*/
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;
}
/*********************************************************************
* @fn afFindEndPointDescList
*
* @brief Find the endpoint description entry from the endpoint
* number.
*
* @param EndPoint - Application Endpoint to look for
*
* @return the address to the endpoint/interface description entry
*/
static epList_t *afFindEndPointDescList( byte EndPoint )
{
epList_t *epSearch;
// Start at the beginning
epSearch = epList;
// Look through the list until the end
while ( epSearch )
{
// Is there a match?
if ( epSearch->epDesc->endPoint == EndPoint )
{
return ( epSearch );
}
else
epSearch = epSearch->nextDesc; // Next entry
}
return ( (epList_t *)NULL );
}
/*********************************************************************
* @fn afFindEndPointDesc
*
* @brief Find the endpoint description entry from the endpoint
* number.
*
* @param EndPoint - Application Endpoint to look for
*
* @return the address to the endpoint/interface description entry
*/
endPointDesc_t *afFindEndPointDesc( byte EndPoint )
{
epList_t *epSearch;
// Look for the endpoint
epSearch = afFindEndPointDescList( EndPoint );
if ( epSearch )
return ( epSearch->epDesc );
else
return ( (endPointDesc_t *)NULL );
}
/*********************************************************************
* @fn afFindSimpleDesc
*
* @brief Find the Simple Descriptor from the endpoint number.
*
* @param EP - Application Endpoint to look for.
*
* @return Non-zero to indicate that the descriptor memory must be freed.
*/
byte afFindSimpleDesc( SimpleDescriptionFormat_t **ppDesc, byte EP )
{
epList_t *epItem = afFindEndPointDescList( EP );
byte rtrn = FALSE;
if ( epItem )
{
if ( epItem->pfnDescCB )
{
*ppDesc = epItem->pfnDescCB( AF_DESCRIPTOR_SIMPLE, EP );
rtrn = TRUE;
}
else
{
*ppDesc = epItem->epDesc->simpleDesc;
}
}
else
{
*ppDesc = NULL;
}
return rtrn;
}
/*********************************************************************
* @fn afGetDescCB
*
* @brief Get the Descriptor callback function.
*
* @param epDesc - pointer to the endpoint descriptor
*
* @return function pointer or NULL
*/
static pDescCB afGetDescCB( endPointDesc_t *epDesc )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -