📄 af.c
字号:
epDesc = pList->epDesc;
else
epDesc = NULL;
}
else
epDesc = NULL;
}
}
#if ( AF_KVP_SUPPORT )
/*********************************************************************
* @fn afBuildKVPIncoming
*
* @brief Build the message for the app
*
* @param
*
* @return
*/
static void afBuildKVPIncoming( aps_FrameFormat_t *aff, endPointDesc_t *epDesc,
zAddrType_t *SrcAddress, uint8 LinkQuality, byte SecurityUse )
{
afIncomingKVPPacket_t *KVPpkt = (afIncomingKVPPacket_t *)osal_mem_alloc(
sizeof( afIncomingKVPPacket_t ) );
byte *asdu = aff->asdu;
const byte total = LO_UINT8( *asdu++ );
byte count;
if ( KVPpkt == NULL )
{
return;
}
KVPpkt->hdr.event = ((total > 1) ? AF_INCOMING_GRP_KVP_CMD :
AF_INCOMING_KVP_CMD );
KVPpkt->clusterId = aff->ClusterID;
afCopyAddress( &(KVPpkt->srcAddr), SrcAddress );
KVPpkt->srcAddr.endPoint = aff->SrcEndPoint;
KVPpkt->endPoint = epDesc->endPoint;
KVPpkt->wasBroadcast = aff->wasBroadcast;
KVPpkt->LinkQuality = LinkQuality;
KVPpkt->SecurityUse = SecurityUse;
KVPpkt->totalTrans = total;
KVPpkt->cmd.TransSeqNumber = *asdu++;
for ( count = 1; count <= total; count++ )
{
afIncomingKVPPacket_t *msgKVPpkt;
KVPpkt->cmd.CommandType = LO_UINT8(*asdu);
KVPpkt->cmd.AttribDataType = HI_UINT8(*asdu++);
KVPpkt->cmd.AttribId = BUILD_UINT16( asdu[0], asdu[1] );
asdu += 2;
/* ErrorCode */
if ((KVPpkt->cmd.CommandType == CMDTYPE_GET_RESP) ||
(KVPpkt->cmd.CommandType == CMDTYPE_SET_RESP) ||
(KVPpkt->cmd.CommandType == CMDTYPE_EVENT_RESP))
{
KVPpkt->cmd.ErrorCode = *asdu++;
}
else
{
KVPpkt->cmd.ErrorCode = ERRORCODE_SUCCESS;
}
/* DataLength */
if ( (KVPpkt->cmd.CommandType == CMDTYPE_GET_ACK) ||
(KVPpkt->cmd.CommandType == CMDTYPE_SET_RESP) ||
(KVPpkt->cmd.CommandType == CMDTYPE_EVENT_RESP ) )
{
KVPpkt->cmd.DataLength = 0;
}
else if ((KVPpkt->cmd.AttribDataType == DATATYPE_CHAR_STR) ||
(KVPpkt->cmd.AttribDataType == DATATYPE_OCTET_STR))
{
KVPpkt->cmd.DataLength = *asdu++;
}
else
{
KVPpkt->cmd.DataLength = GetDataTypeLength( (byte)KVPpkt->cmd.AttribDataType );
}
msgKVPpkt = (afIncomingKVPPacket_t *)osal_msg_allocate( (short)
(sizeof( afIncomingKVPPacket_t ) + KVPpkt->cmd.DataLength) );
if ( msgKVPpkt == NULL )
{
// Maybe not enought for an octet string, but next might be no data,
// so don't return here, just continue to look at the rest.
asdu += KVPpkt->cmd.DataLength;
continue;
}
osal_memcpy( msgKVPpkt, KVPpkt, sizeof( afIncomingKVPPacket_t ) );
msgKVPpkt->count = count;
if ( msgKVPpkt->cmd.DataLength )
{
msgKVPpkt->cmd.Data = (byte *)(msgKVPpkt + 1);
osal_memcpy( msgKVPpkt->cmd.Data, asdu, msgKVPpkt->cmd.DataLength );
asdu += msgKVPpkt->cmd.DataLength;
}
else
{
msgKVPpkt->cmd.Data = NULL;
}
#if defined ( MT_AF_CB_FUNC )
// If MT has subscribed for this callback, don't send as a message.
if ( _afCallbackSub & CB_ID_AF_DATA_IND )
{
af_MTCB_IncomingData( (void *)msgKVPpkt );
// Release the memory.
osal_msg_deallocate( (void *)msgKVPpkt );
}
else
#endif
{
osal_msg_send( *(epDesc->task_id), (uint8*)msgKVPpkt );
}
}
osal_mem_free( KVPpkt );
}
#endif
/*********************************************************************
* @fn afBuildMSGIncoming
*
* @brief Build the message for the app
*
* @param
*
* @return pointer to next in data buffer
*/
static void afBuildMSGIncoming( aps_FrameFormat_t *aff, endPointDesc_t *epDesc,
zAddrType_t *SrcAddress, uint8 LinkQuality, byte SecurityUse,
uint32 timestamp )
{
afIncomingMSGPacket_t *MSGpkt;
#if ( AF_V1_SUPPORT )
const byte proVer = NLME_GetProtocolVersion();
const byte len = sizeof( afIncomingMSGPacket_t ) +
((proVer == ZB_PROT_V1_0) ? aff->asdu[2] : aff->asduLength);
byte *asdu = aff->asdu + ((proVer == ZB_PROT_V1_0) ? 1 : 0);
#else
const byte len = sizeof( afIncomingMSGPacket_t ) + aff->asduLength;
byte *asdu = aff->asdu;
#endif
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_allocate( len );
if ( MSGpkt == NULL )
{
return;
}
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;
#if ( AF_V1_SUPPORT )
if ( proVer == ZB_PROT_V1_0 )
{
MSGpkt->cmd.TransSeqNumber = *asdu++;
MSGpkt->cmd.DataLength = *asdu++;
}
else
#endif
{
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;
}
#if defined ( MT_AF_CB_FUNC )
// If MT has subscribed for this callback, don't send as a message.
if ( _afCallbackSub & CB_ID_AF_DATA_IND )
{
af_MTCB_IncomingData( (void *)MSGpkt );
// Release the memory.
osal_msg_deallocate( (void *)MSGpkt );
}
else
#endif
{
// Send message through task message.
osal_msg_send( *(epDesc->task_id), (uint8 *)MSGpkt );
}
}
#if ( AF_KVP_SUPPORT )
/*********************************************************************
* @fn multiInit
*
* @brief Initialize a multi header.
*
* @param none
*
* @return Pointer to the new memory allocated for the afMultiHdr_t structure.
*/
static afMultiHdr_t *multiInit( afAddrType_t *dstAddr,
byte srcEndPoint, uint16 clusterID, byte FrameType,
byte txOptions, bool DiscoverRoute, byte RadiusCounter )
{
afMultiHdr_t *hdr = (afMultiHdr_t *)osal_mem_alloc( sizeof( afMultiHdr_t ) );
if ( hdr == NULL )
{
return NULL;
}
hdr->clusterID = clusterID;
hdr->transCount = 0;
hdr->options = txOptions & AF_ACK_REQUEST;
hdr->options |= (DiscoverRoute) ? AF_DISCV_ROUTE : 0;
hdr->srcEP = srcEndPoint;
hdr->dstAddr.endPoint = dstAddr->endPoint;
hdr->dstAddr.addrMode = dstAddr->addrMode;
hdr->dstAddr.addr.shortAddr = dstAddr->addr.shortAddr;
hdr->msgLen = 0;
hdr->msg = NULL;
return hdr;
}
/*********************************************************************
* @fn multiAppend
*
* @brief Concatenate a new KVP message too a mulit-KVP message.
*
* @param none
*
* @return TRUE for success, FALSE otherwise.
*/
static bool multiAppend( afMultiHdr_t *hdr, byte bufLen, byte *buf,
byte CommandType, byte AttribDataType, uint16 AttribId, byte ErrorCode )
{
byte len = (byte)hdr->msgLen;
byte *msg = osal_mem_alloc( (short)(AF_HDR_KVP_MAX_LEN + bufLen + len) );
if ( msg == NULL )
{
return FALSE;
}
if ( hdr->msg == NULL ) // Need to make space for FrameType/Count & SeqNum.
{
len += 5;
hdr->msg = msg;
msg += 2;
}
else // Need to copy existing buffer over.
{
len += 3;
osal_memcpy( msg, hdr->msg, hdr->msgLen );
osal_mem_free( hdr->msg );
hdr->msg = msg;
msg += hdr->msgLen;
}
*msg++ = BUILD_UINT8( AttribDataType, CommandType );
*msg++ = LO_UINT16( AttribId);
*msg++ = HI_UINT16( AttribId );
if ((CommandType == CMDTYPE_GET_RESP) ||
(CommandType == CMDTYPE_SET_RESP) ||
(CommandType == CMDTYPE_EVENT_RESP) )
{
*msg++ = ErrorCode;
len++;
}
if ( (CommandType == CMDTYPE_GET_ACK) ||
(CommandType == CMDTYPE_SET_RESP) ||
(CommandType == CMDTYPE_EVENT_RESP ) )
{
bufLen = 0;
}
else if ((AttribDataType == DATATYPE_CHAR_STR) ||
(AttribDataType == DATATYPE_OCTET_STR))
{
*msg++ = bufLen;
len++;
}
if ( buf && bufLen )
{
osal_memcpy( msg, buf, bufLen );
len += bufLen;
}
hdr->msgLen = len;
hdr->transCount++;
return TRUE;
}
/*********************************************************************
* @fn multiSend
*
* @brief Send whatever has been buffered to send multi.
*
* @param none
*
* @return afStatus_t
*/
static afStatus_t multiSend( afMultiHdr_t *hdr, byte *seqNum, byte radius )
{
afStatus_t stat;
if ( hdr == NULL )
{
return afStatus_MEM_FAIL;
}
hdr->msg[0] = BUILD_UINT8( FRAMETYPE_KVP, hdr->transCount );
hdr->msg[1] = *seqNum;
stat = afSend( &hdr->dstAddr, hdr->srcEP, hdr->clusterID,
hdr->msgLen, hdr->msg, seqNum, hdr->options, radius );
osal_mem_free( hdr->msg );
osal_mem_free( hdr );
return stat;
}
/*********************************************************************
* @fn afAddOrSendMessage
*
* @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
* (e.g. see CLUSTERID_... defs in HomeControlLighting.h).
* @param AddOrSend - A valid afAddOrSend_t type.
* @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 afAddOrSendMessage(
afAddrType_t *dstAddr, byte srcEndPoint, cId_t clusterID,
afAddOrSend_t AddOrSend, byte FrameType, byte *TransSeqNumber,
byte CommandType, byte AttribDataType, uint16 AttribId, byte ErrorCode,
byte DataLength, byte *Data,
byte txOptions, byte DiscoverRoute, byte RadiusCounter )
{
static afMultiHdr_t *hdr;
afStatus_t stat = afStatus_FAILED;
if ( FrameType == FRAMETYPE_MSG )
{
if ( AddOrSend != SEND_MESSAGE )
{
return afStatus_INVALID_PARAMETER;
}
return afFillAndSendMessage( dstAddr, srcEndPoint, clusterID,
1, FrameType, TransSeqNumber, NULL, NULL, NULL, NULL,
DataLength, Data, txOptions, DiscoverRoute, RadiusCounter );
}
if ( FrameType != FRAMETYPE_KVP )
{
return afStatus_INVALID_PARAMETER;
}
// Cannot mix Cluster ID's in aggregation packet.
if ( (hdr != NULL) && (hdr->clusterID != clusterID) )
{
multiSend( hdr, TransSeqNumber, RadiusCounter );
hdr = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -