zdobject.c
来自「一些基于IRA环境开发的zigbee实例程序」· C语言 代码 · 共 2,264 行 · 第 1/5 页
C
2,264 行
matchED = (ZDMatchEndDeviceBind_t *)osal_mem_alloc( sizeof ( ZDMatchEndDeviceBind_t ) );
if ( matchED )
{
// Clear the structure
osal_memset( (uint8 *)matchED, 0, sizeof ( ZDMatchEndDeviceBind_t ) );
// Copy the first request's information
if ( !ZDO_CopyMatchInfo( &(matchED->ed1), bindReq ) )
{
status = ZDP_NO_ENTRY;
sendRsp = TRUE;
}
}
else
{
status = ZDP_NO_ENTRY;
sendRsp = TRUE;
}
if ( !sendRsp )
{
// Set into the correct state
matchED->state = ZDMATCH_WAIT_REQ;
// Setup the timeout
APS_SetEndDeviceBindTimeout( AIB_MaxBindingTime, ZDO_EndDeviceBindMatchTimeoutCB );
}
}
else
{
matchED->state = ZDMATCH_SENDING_BINDS;
// Copy the 2nd request's information
if ( !ZDO_CopyMatchInfo( &(matchED->ed2), bindReq ) )
{
status = ZDP_NO_ENTRY;
sendRsp = TRUE;
}
// Make a source match for ed1
matchED->ed1numMatched = ZDO_CompareClusterLists(
matchED->ed1.numOutClusters, matchED->ed1.outClusters,
matchED->ed2.numInClusters, matchED->ed2.inClusters, ZDOBuildBuf );
if ( matchED->ed1numMatched )
{
// Save the match list
matchED->ed1Matched = osal_mem_alloc( (short)(matchED->ed1numMatched * sizeof ( uint16 )) );
if ( matchED->ed1Matched )
{
osal_memcpy( matchED->ed1Matched, ZDOBuildBuf, (matchED->ed1numMatched * sizeof ( uint16 )) );
}
else
{
// Allocation error, stop
status = ZDP_NO_ENTRY;
sendRsp = TRUE;
}
}
// Make a source match for ed2
matchED->ed2numMatched = ZDO_CompareClusterLists(
matchED->ed2.numOutClusters, matchED->ed2.outClusters,
matchED->ed1.numInClusters, matchED->ed1.inClusters, ZDOBuildBuf );
if ( matchED->ed2numMatched )
{
// Save the match list
matchED->ed2Matched = osal_mem_alloc( (short)(matchED->ed2numMatched * sizeof ( uint16 )) );
if ( matchED->ed2Matched )
{
osal_memcpy( matchED->ed2Matched, ZDOBuildBuf, (matchED->ed2numMatched * sizeof ( uint16 )) );
}
else
{
// Allocation error, stop
status = ZDP_NO_ENTRY;
sendRsp = TRUE;
}
}
if ( (sendRsp == FALSE) && (matchED->ed1numMatched || matchED->ed2numMatched) )
{
// Do the first unbind/bind state
ZDMatchSendState( ZDMATCH_REASON_START, ZDP_SUCCESS, 0 );
}
else
{
status = ZDP_NO_MATCH;
sendRsp = TRUE;
}
}
if ( sendRsp )
{
// send response to this requester
dstAddr.addrMode = Addr16Bit;
dstAddr.addr.shortAddr = bindReq->srcAddr;
ZDP_EndDeviceBindRsp( bindReq->TransSeq, &dstAddr, status, bindReq->SecurityUse );
if ( matchED->state == ZDMATCH_SENDING_BINDS )
{
// send response to first requester
dstAddr.addrMode = Addr16Bit;
dstAddr.addr.shortAddr = matchED->ed1.srcAddr;
ZDP_EndDeviceBindRsp( matchED->ed1.TransSeq, &dstAddr, status, matchED->ed1.SecurityUse );
}
// Process ended - release memory used
ZDO_RemoveMatchMemory();
}
}
static void ZDO_RemoveMatchMemory( void )
{
if ( matchED )
{
if ( matchED->ed2Matched )
osal_mem_free( matchED->ed2Matched );
if ( matchED->ed1Matched )
osal_mem_free( matchED->ed1Matched );
if ( matchED->ed1.inClusters )
osal_mem_free( matchED->ed1.inClusters );
if ( matchED->ed1.outClusters )
osal_mem_free( matchED->ed1.outClusters );
if ( matchED->ed2.inClusters )
osal_mem_free( matchED->ed2.inClusters );
if ( matchED->ed2.outClusters )
osal_mem_free( matchED->ed2.outClusters );
osal_mem_free( matchED );
matchED = (ZDMatchEndDeviceBind_t *)NULL;
}
}
static uint8 ZDO_CopyMatchInfo( ZDEndDeviceBind_t *destReq, ZDEndDeviceBind_t *srcReq )
{
uint8 allOK = TRUE;
// Copy bind information into the match info structure
osal_memcpy( (uint8 *)destReq, srcReq, sizeof ( ZDEndDeviceBind_t ) );
// Copy input cluster IDs
if ( srcReq->numInClusters )
{
destReq->inClusters = osal_mem_alloc( (short)(srcReq->numInClusters * sizeof ( uint16 )) );
if ( destReq->inClusters )
{
// Copy the clusters
osal_memcpy( (uint8*)(destReq->inClusters), (uint8 *)(srcReq->inClusters),
(srcReq->numInClusters * sizeof ( uint16 )) );
}
else
allOK = FALSE;
}
// Copy output cluster IDs
if ( srcReq->numOutClusters )
{
destReq->outClusters = osal_mem_alloc( (short)(srcReq->numOutClusters * sizeof ( uint16 )) );
if ( destReq->outClusters )
{
// Copy the clusters
osal_memcpy( (uint8 *)(destReq->outClusters), (uint8 *)(srcReq->outClusters),
(srcReq->numOutClusters * sizeof ( uint16 )) );
}
else
allOK = FALSE;
}
if ( !allOK )
{
if ( destReq->inClusters )
osal_mem_free( destReq->inClusters );
if ( destReq->outClusters )
osal_mem_free( destReq->outClusters );
}
return ( allOK );
}
uint8 ZDMatchSendState( uint8 reason, uint8 status, uint8 TransSeq )
{
uint8 *dstIEEEAddr;
uint8 dstEP;
zAddrType_t dstAddr;
zAddrType_t destinationAddr;
uint16 msgType;
uint16 clusterID;
ZDEndDeviceBind_t *ed = NULL;
uint8 rspStatus = ZDP_SUCCESS;
if ( matchED == NULL )
return ( FALSE );
// Check sequence number
if ( reason == ZDMATCH_REASON_BIND_RSP || reason == ZDMATCH_REASON_UNBIND_RSP )
{
if ( TransSeq != matchED->transSeq )
return( FALSE ); // ignore the message
}
// turn off timer
APS_SetEndDeviceBindTimeout( 0, ZDO_EndDeviceBindMatchTimeoutCB );
if ( reason == ZDMATCH_REASON_TIMEOUT )
{
rspStatus = ZDP_TIMEOUT; // The process will stop
}
if ( reason == ZDMATCH_REASON_START || reason == ZDMATCH_REASON_BIND_RSP )
{
matchED->sending = ZDMATCH_SENDING_UNBIND;
if ( reason == ZDMATCH_REASON_BIND_RSP && status != ZDP_SUCCESS )
{
rspStatus = status;
}
}
else if ( reason == ZDMATCH_REASON_UNBIND_RSP )
{
if ( status == ZDP_SUCCESS )
{
matchED->sending = ZDMATCH_SENDING_UNBIND;
}
else
{
matchED->sending = ZDMATCH_SENDING_BIND;
}
}
if ( reason != ZDMATCH_REASON_START && matchED->sending == ZDMATCH_SENDING_UNBIND )
{
// Move to the next cluster ID
if ( matchED->ed1numMatched )
matchED->ed1numMatched--;
else if ( matchED->ed2numMatched )
matchED->ed2numMatched--;
}
// What message do we send now
if ( matchED->ed1numMatched )
{
ed = &(matchED->ed1);
clusterID = matchED->ed1Matched[matchED->ed1numMatched-1];
dstIEEEAddr = matchED->ed2.ieeeAddr;
dstEP = matchED->ed2.endpoint;
}
else if ( matchED->ed2numMatched )
{
ed = &(matchED->ed2);
clusterID = matchED->ed2Matched[matchED->ed2numMatched-1];
dstIEEEAddr = matchED->ed1.ieeeAddr;
dstEP = matchED->ed1.endpoint;
}
dstAddr.addrMode = Addr16Bit;
// Send the next message
if ( rspStatus == ZDP_SUCCESS && ed )
{
// Send unbind/bind message to source
if ( matchED->sending == ZDMATCH_SENDING_UNBIND )
msgType = Unbind_req;
else
msgType = Bind_req;
dstAddr.addr.shortAddr = ed->srcAddr;
// Save off the transaction sequence number
matchED->transSeq = ZDP_TransID;
destinationAddr.addrMode = Addr64Bit;
osal_cpyExtAddr( destinationAddr.addr.extAddr, dstIEEEAddr );
ZDP_BindUnbindReq( msgType, &dstAddr, ed->ieeeAddr, ed->endpoint, clusterID,
&destinationAddr, dstEP, ed->SecurityUse );
// Set timeout for response
APS_SetEndDeviceBindTimeout( AIB_MaxBindingTime, ZDO_EndDeviceBindMatchTimeoutCB );
}
else
{
// Send the response messages to requesting devices
// send response to first requester
dstAddr.addr.shortAddr = matchED->ed1.srcAddr;
ZDP_EndDeviceBindRsp( matchED->ed1.TransSeq, &dstAddr, rspStatus, matchED->ed1.SecurityUse );
// send response to second requester
if ( matchED->state == ZDMATCH_SENDING_BINDS )
{
dstAddr.addr.shortAddr = matchED->ed2.srcAddr;
ZDP_EndDeviceBindRsp( matchED->ed2.TransSeq, &dstAddr, rspStatus, matchED->ed2.SecurityUse );
}
// Process ended - release memory used
ZDO_RemoveMatchMemory();
}
return ( TRUE );
}
static void ZDO_EndDeviceBindMatchTimeoutCB( void )
{
ZDMatchSendState( ZDMATCH_REASON_TIMEOUT, ZDP_TIMEOUT, 0 );
}
#endif // ZDO_COORDINATOR
/*********************************************************************
* ZDO MESSAGE PARSING API FUNCTIONS
*/
/*********************************************************************
* @fn ZDO_ParseEndDeviceBindReq
*
* @brief This function parses the End_Device_Bind_req message.
*
* NOTE: The clusters lists in bindReq are allocated in this
* function and must be freed by that calling function.
*
* @param inMsg - incoming message (request)
* @param bindReq - pointer to place to parse message to
*
* @return none
*/
void ZDO_ParseEndDeviceBindReq( zdoIncomingMsg_t *inMsg, ZDEndDeviceBind_t *bindReq )
{
uint8 *msg;
// Parse the message
bindReq->TransSeq = inMsg->TransSeq;
bindReq->srcAddr = inMsg->srcAddr.addr.shortAddr;
bindReq->SecurityUse = inMsg->SecurityUse;
msg = inMsg->asdu;
bindReq->localCoordinator = BUILD_UINT16( msg[0], msg[1] );
msg += 2;
osal_cpyExtAddr( &(bindReq->ieeeAddr), msg );
msg += Z_EXTADDR_LEN;
bindReq->endpoint = *msg++;
bindReq->profileID = BUILD_UINT16( msg[0], msg[1] );
msg += 2;
bindReq->numInClusters = *msg++;
bindReq->inClusters = NULL;
if ( bindReq->numInClusters )
{
bindReq->inClusters = (uint16*)osal_mem_alloc( (bindReq->numInClusters * sizeof( uint16 )) );
msg = ZDO_ConvertOTAClusters( bindReq->numInClusters, msg, bindReq->inClusters );
}
bindReq->numOutClusters = *msg++;
bindReq->outClusters = NULL;
if ( bindReq->numOutClusters )
{
bindReq->outClusters = (uint16*)osal_mem_alloc( (bindReq->numOutClusters * sizeof( uint16 )) );
msg = ZDO_ConvertOTAClusters( bindReq->numOutClusters, msg, bindReq->outClusters );
}
}
/*********************************************************************
* @fn ZDO_ParseBindUnbindReq
*
* @brief This function parses the Bind_req or Unbind_req message.
*
* @param inMsg - incoming message (request)
* @param pReq - place to put parsed information
*
* @return none
*/
void ZDO_ParseBindUnbindReq( zdoIncomingMsg_t *inMsg, ZDO_BindUnbindReq_t *pReq )
{
uint8 *msg;
msg = inMsg->asdu;
osal_cpyExtAddr( pReq->srcAddress, msg );
msg += Z_EXTADDR_LEN;
pReq->srcEndpoint = *msg++;
pReq->clusterID = BUILD_UINT16( msg[0], msg[1] );
msg += 2;
pReq->dstAddress.addrMode = *msg++;
if ( pReq->dstAddress.addrMode == Addr64Bit )
{
osal_cpyExtAddr( pReq->dstAddress.addr.extAddr, msg );
msg += Z_EXTADDR_LEN;
pReq->dstEndpoint = *msg;
}
else
{
// copy group address
pReq->dstAddress.addr.shortAddr = BUILD_UINT16( msg[0], msg[1] );
}
}
/*********************************************************************
* @fn ZDO_ParseAddrRsp
*
* @brief Turns the inMsg (incoming message) into the out parsed
* structure.
*
* @param inMsg - incoming message
*
* @return pointer to parsed structures. This structure was
* allocated using osal_mem_alloc, so it must be freed
* by the calling function [osal_mem_free()].
*/
ZDO_NwkIEEEAddrResp_t *ZDO_ParseAddrRsp( zdoIncomingMsg_t *inMsg )
{
ZDO_NwkIEEEAddrResp_t *rsp;
uint8 *msg;
byte cnt = 0;
// Calculate the number of items in the list
if ( inMsg->asduLen > (1 + Z_EXTADDR_LEN + 2) )
cnt = inMsg->asdu[1 + Z_EXTADDR_LEN + 2];
else
cnt = 0;
// Make buffer
rsp = (ZDO_NwkIEEEAddrResp_t *)osal_mem_alloc( sizeof(ZDO_NwkIEEEAddrResp_t) + (cnt * sizeof ( uint16 )) );
if ( rsp )
{
msg = inMsg->asdu;
rsp->status = *msg++;
if ( rsp->status == ZDO_SUCCESS )
{
osal_cpyExtAddr( rsp->extAddr, msg );
msg += Z_EXTADDR_LEN;
rsp->nwkAddr = BUILD_UINT16( msg[0], msg[1] );
msg += 2;
rsp->numAssocDevs = 0;
// StartIndex field is only present if NumAssocDev field is non-zero.
if ( cnt > 0 )
{
uint16 *pList = &(rsp->devList[0]);
byte n = cnt;
rsp->numAssocDevs = *msg++;
rsp->startIndex = *msg++;
while (
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?