📄 af.c
字号:
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 = 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 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.
* Also note that a reflected msg will not have its confirmation generated
* here.
*/
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 )
{
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 == epDesc )
{
return ( epSearch->pfnDescCB );
}
else
epSearch = epSearch->nextDesc; // Next entry
}
return ( (pDescCB)NULL );
}
/*********************************************************************
* @fn afDataReqMTU
*
* @brief Get the Data Request MTU(Max Transport Unit).
*
* @param fields - afDataReqMTU_t
*
* @return uint8(MTU)
*/
uint8 afDataReqMTU( afDataReqMTU_t* fields )
{
uint8 len;
uint8 hdr;
if ( fields->kvp == TRUE )
{
hdr = AF_HDR_KVP_MAX_LEN;
}
else
{
hdr = AF_HDR_V1_1_MAX_LEN;
}
len = (uint8)(APSDE_DataReqMTU(&fields->aps) - hdr);
return len;
}
/*********************************************************************
* @fn afGetMatch
*
* @brief Set the allow response flag.
*
* @param ep - Application Endpoint to look for
* @param action - true - allow response, false - no response
*
* @return TRUE allow responses, FALSE no response
*/
uint8 afGetMatch( uint8 ep )
{
epList_t *epSearch;
// Look for the endpoint
epSearch = afFindEndPointDescList( ep );
if ( epSearch )
{
if ( epSearch->flags & eEP_AllowMatch )
return ( TRUE );
else
return ( FALSE );
}
else
return ( FALSE );
}
/*********************************************************************
* @fn afSetMatch
*
* @brief Set the allow response flag.
*
* @param ep - Application Endpoint to look for
* @param action - true - allow response, false - no response
*
* @return TRUE if success, FALSE if endpoint not found
*/
uint8 afSetMatch( uint8 ep, uint8 action )
{
epList_t *epSearch;
// Look for the endpoint
epSearch = afFindEndPointDescList( ep );
if ( epSearch )
{
if ( action )
{
epSearch->flags |= eEP_AllowMatch;
}
else
{
epSearch->flags &= (0xff ^ eEP_AllowMatch);
}
return ( TRUE );
}
else
return ( FALSE );
}
/*********************************************************************
* @fn afNumEndPoints
*
* @brief Returns the number of endpoints defined (including 0)
*
* @param none
*
* @return number of endpoints
*/
byte afNumEndPoints( void )
{
epList_t *epSearch;
byte endpoints;
// Start at the beginning
epSearch = epList;
endpoints = 0;
while ( epSearch )
{
endpoints++;
epSearch = epSearch->nextDesc;
}
return ( endpoints );
}
/*********************************************************************
* @fn afEndPoints
*
* @brief Fills in the passed in buffer with the endpoint (numbers).
* Use afNumEndPoints to find out how big a buffer to supply.
*
* @param epBuf - pointer to mem used
*
* @return void
*/
void afEndPoints( byte *epBuf, byte skipZDO )
{
epList_t *epSearch;
byte endPoint;
// Start at the beginning
epSearch = epList;
while ( epSearch )
{
endPoint = epSearch->epDesc->endPoint;
if ( !skipZDO || endPoint != 0 )
*epBuf++ = endPoint;
epSearch = epSearch->nextDesc;
}
}
/*********************************************************************
* Semi-Precision fuctions
*/
#if ( AF_FLOAT_SUPPORT )
/*********************************************************************
* @fn afCnvtSP_uint16
*
* @brief Converts uint16 to semi-precision structure format
*
* @param sp - semi-precision structure format
*
* @return 16 bit value for semiprecision.
*/
uint16 afCnvtSP_uint16( afSemiPrecision_t sp )
{
return ( ((sp.sign & 0x0001) << 15)
| ((sp.exponent & 0x001F) << 10)
| (sp.mantissa & 0x03FF) );
}
/*********************************************************************
* @fn afCnvtuint16_SP
*
* @brief Converts uint16 to semi-precision structure format
*
* @param rawSP - Raw representation of SemiPrecision
*
* @return SemiPrecision conversion.
*/
afSemiPrecision_t afCnvtuint16_SP( uint16 rawSP )
{
afSemiPrecision_t sp = {0,0,0};
sp.sign = ((rawSP >> 15) & 0x0001);
sp.exponent = ((rawSP >> 10) & 0x001F);
sp.mantissa = (rawSP & 0x03FF);
return ( sp );
}
/*********************************************************************
* @fn afCnvtFloat_SP
*
* @brief Converts float to semi-precision structure format
*
* @param f - float value to convert from
*
* NOTE: This function will convert to the closest possible
* representation in a 16 bit format. Meaning that
* the number may not be exact. For example, 10.7 will
* convert to 10.69531, because .7 is a repeating binary
* number. The mantissa for afSemiPrecision_t is 10 bits
* and .69531 is the 10 bit representative of .7.
*
* @return SemiPrecision conversion.
*/
afSemiPrecision_t afCnvtFloat_SP( float f )
{
afSemiPrecision_t sp = {0,0,0};
unsigned long mantissa;
unsigned int oldexp;
int tempexp;
float calcMant;
unsigned long *uf;
if ( f < 0 )
{
sp.sign = 1;
f = f * -1;
}
else
sp.sign = 0;
if ( f == 0 )
{
sp.exponent = (unsigned int)0;
sp.mantissa = (unsigned int)0;
}
else
{
uf = (void*)&f;
mantissa = *uf & 0x7fffff;
oldexp = (unsigned int)((*uf >> 23) & 0xff);
tempexp = oldexp - 127;
calcMant = (float)((float)(mantissa) / (float)(0x800000));
mantissa = (unsigned long)(calcMant * 1024);
sp.exponent = (unsigned int)(tempexp + 15);
sp.mantissa = (unsigned int)(mantissa);
}
return ( sp );
}
/*********************************************************************
* @fn afCnvtSP_Float
*
* @brief Converts semi-precision structure format to float
*
* @param sp - afSemiPrecision format to convert from
*
* @return float
*/
float afCnvtSP_Float( afSemiPrecision_t sp )
{
float a, b, c;
if ( sp.exponent == 0 && sp.mantissa == 0 )
{
a = 0;
b = 0;
}
else
{
a = (float)((float)1 + (float)((float)(sp.mantissa)/1024));
#if defined( __MWERKS__ )
b = powf( 2.0, (float)((float)sp.exponent - 15.0) );
#else
b = (float)pow( 2.0, sp.exponent - 15 );
#endif
}
if ( sp.sign )
c = a * b * -1;
else
c = a * b;
return ( c );
}
#endif
void afCopyAddress ( afAddrType_t *afAddr, zAddrType_t *zAddr )
{
afAddr->addrMode = (afAddrMode_t)zAddr->addrMode;
afAddr->addr.shortAddr = zAddr->addr.shortAddr;
}
/*********************************************************************
*********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -