zdobject.c
来自「一些基于IRA环境开发的zigbee实例程序」· C语言 代码 · 共 2,264 行 · 第 1/5 页
C
2,264 行
#if defined(LCD_SUPPORTED )
// HalLcdWriteString( "End Device Bind", HAL_LCD_LINE_1 );
//Print6(HAL_LCD_LINE_1,10,"End Device Bind",1);
Print8(HAL_LCD_LINE_1,10,"End Device Bind",1);
if ( Status == ZDP_SUCCESS )
//HalLcdWriteString( "Success Sent", HAL_LCD_LINE_2 );
Print8(HAL_LCD_LINE_2,10,"Success Sent",1);
else
// HalLcdWriteString( "Timeout", HAL_LCD_LINE_2 );
Print8(HAL_LCD_LINE_2,10,"Timeout",1);
#endif
}
#endif // REFLECTOR
#if defined ( ZDO_COORDINATOR )
/*********************************************************************
* @fn ZDO_CompareClusterLists
*
* @brief Compare one list to another list
*
* @param numList1 - number of items in list 1
* @param list1 - first list of cluster IDs
* @param numList2 - number of items in list 2
* @param list2 - second list of cluster IDs
* @param pMatches - buffer to put matches
*
* @return number of matches
*/
static byte ZDO_CompareClusterLists( byte numList1, uint16 *list1,
byte numList2, uint16 *list2, uint16 *pMatches )
{
byte x, y;
uint16 z;
byte numMatches = 0;
// Check the first in against the seconds out
for ( x = 0; x < numList1; x++ )
{
for ( y = 0; y < numList2; y++ )
{
z = list2[y];
if ( list1[x] == z )
pMatches[numMatches++] = z;
}
}
return ( numMatches );
}
#endif // ZDO_COORDINATOR
/*********************************************************************
* Utility functions
*/
/*********************************************************************
* @fn ZDO_CompareByteLists
*
* @brief Compares two lists for matches.
*
* @param ACnt - number of entries in list A
* @param AList - List A
* @param BCnt - number of entries in list B
* @param BList - List B
*
* @return true if a match is found
*/
byte ZDO_AnyClusterMatches( byte ACnt, uint16 *AList, byte BCnt, uint16 *BList )
{
byte x, y;
for ( x = 0; x < ACnt; x++ )
{
for ( y = 0; y < BCnt; y++ )
{
if ( AList[x] == BList[y] )
{
return true;
}
}
}
return false;
}
/*********************************************************************
* Callback functions from ZDProfile
*/
/*********************************************************************
* @fn ZDO_ProcessNodeDescReq
*
* @brief This function processes and responds to the
* Node_Desc_req message.
*
* @param inMsg - incoming message
*
* @return none
*/
void ZDO_ProcessNodeDescReq( zdoIncomingMsg_t *inMsg )
{
uint16 aoi = BUILD_UINT16( inMsg->asdu[0], inMsg->asdu[1] );
NodeDescriptorFormat_t *desc = NULL;
if ( aoi == ZDAppNwkAddr.addr.shortAddr )
{
desc = &ZDO_Config_Node_Descriptor;
}
if ( desc != NULL )
{
ZDP_NodeDescMsg( inMsg, aoi, desc );
}
else
{
ZDP_GenericRsp( inMsg->TransSeq, &(inMsg->srcAddr),
ZDP_INVALID_REQTYPE, aoi, Node_Desc_rsp, inMsg->SecurityUse );
}
}
/*********************************************************************
* @fn ZDO_ProcessPowerDescReq
*
* @brief This function processes and responds to the
* Node_Power_req message.
*
* @param inMsg - incoming request
*
* @return none
*/
void ZDO_ProcessPowerDescReq( zdoIncomingMsg_t *inMsg )
{
uint16 aoi = BUILD_UINT16( inMsg->asdu[0], inMsg->asdu[1] );
NodePowerDescriptorFormat_t *desc = NULL;
if ( aoi == ZDAppNwkAddr.addr.shortAddr )
{
desc = &ZDO_Config_Power_Descriptor;
}
if ( desc != NULL )
{
ZDP_PowerDescMsg( inMsg, aoi, desc );
}
else
{
ZDP_GenericRsp( inMsg->TransSeq, &(inMsg->srcAddr),
ZDP_INVALID_REQTYPE, aoi, Power_Desc_rsp, inMsg->SecurityUse );
}
}
/*********************************************************************
* @fn ZDO_ProcessSimpleDescReq
*
* @brief This function processes and responds to the
* Simple_Desc_req message.
*
* @param inMsg - incoming message (request)
*
* @return none
*/
void ZDO_ProcessSimpleDescReq( zdoIncomingMsg_t *inMsg )
{
SimpleDescriptionFormat_t *sDesc = NULL;
uint16 aoi = BUILD_UINT16( inMsg->asdu[0], inMsg->asdu[1] );
byte endPoint = inMsg->asdu[2];
byte free = false;
byte stat = ZDP_SUCCESS;
if ( (endPoint == ZDO_EP) || (endPoint > MAX_ENDPOINTS) )
{
stat = ZDP_INVALID_EP;
}
else if ( aoi == ZDAppNwkAddr.addr.shortAddr )
{
free = afFindSimpleDesc( &sDesc, endPoint );
if ( sDesc == NULL )
{
stat = ZDP_NOT_ACTIVE;
}
}
else
{
#if defined ( RTR_NWK )
stat = ZDP_DEVICE_NOT_FOUND;
#else
stat = ZDP_INVALID_REQTYPE;
#endif
}
ZDP_SimpleDescMsg( inMsg, stat, sDesc );
if ( free )
{
osal_mem_free( sDesc );
}
}
/*********************************************************************
* @fn ZDO_ProcessActiveEPReq
*
* @brief This function processes and responds to the
* Active_EP_req message.
*
* @param inMsg - incoming message (request)
*
* @return none
*/
void ZDO_ProcessActiveEPReq( zdoIncomingMsg_t *inMsg )
{
byte cnt = 0;
uint16 aoi;
byte stat = ZDP_SUCCESS;
aoi = BUILD_UINT16( inMsg->asdu[0], inMsg->asdu[1] );
if ( aoi == NLME_GetShortAddr() )
{
cnt = afNumEndPoints() - 1; // -1 for ZDO endpoint descriptor
afEndPoints( (uint8 *)ZDOBuildBuf, true );
}
else
{
stat = ZDP_INVALID_REQTYPE;
}
ZDP_ActiveEPRsp( inMsg->TransSeq, &(inMsg->srcAddr), stat,
aoi, cnt, (uint8 *)ZDOBuildBuf, inMsg->SecurityUse );
}
/*********************************************************************
* @fn ZDO_ConvertOTAClusters
*
* @brief This function will convert the over-the-air cluster list
* format to an internal format.
*
* @param inMsg - incoming message (request)
*
* @return pointer to incremented inBuf
*/
uint8 *ZDO_ConvertOTAClusters( uint8 cnt, uint8 *inBuf, uint16 *outList )
{
uint8 x;
for ( x = 0; x < cnt; x++ )
{
// convert ota format to internal
outList[x] = BUILD_UINT16( inBuf[0], inBuf[1] );
inBuf += sizeof( uint16 );
}
return ( inBuf );
}
/*********************************************************************
* @fn ZDO_ProcessMatchDescReq
*
* @brief This function processes and responds to the
* Match_Desc_req message.
*
* @param inMsg - incoming message (request)
*
* @return none
*/
void ZDO_ProcessMatchDescReq( zdoIncomingMsg_t *inMsg )
{
uint8 epCnt = 0;
uint8 numInClusters;
uint16 *inClusters = NULL;
uint8 numOutClusters;
uint16 *outClusters = NULL;
epList_t *epDesc;
SimpleDescriptionFormat_t *sDesc = NULL;
uint8 allocated;
uint8 *msg;
uint16 aoi;
uint16 profileID;
// Parse the incoming message
msg = inMsg->asdu;
aoi = BUILD_UINT16( msg[0], msg[1] );
profileID = BUILD_UINT16( msg[2], msg[3] );
msg += 4;
if ( ADDR_BCAST_NOT_ME == NLME_IsAddressBroadcast(aoi) )
{
ZDP_MatchDescRsp( inMsg->TransSeq, &(inMsg->srcAddr), ZDP_INVALID_REQTYPE,
ZDAppNwkAddr.addr.shortAddr, 0, NULL, inMsg->SecurityUse );
return;
}
else if ( (ADDR_NOT_BCAST == NLME_IsAddressBroadcast(aoi)) && (aoi != ZDAppNwkAddr.addr.shortAddr) )
{
ZDP_MatchDescRsp( inMsg->TransSeq, &(inMsg->srcAddr), ZDP_INVALID_REQTYPE,
ZDAppNwkAddr.addr.shortAddr, 0, NULL, inMsg->SecurityUse );
return;
}
numInClusters = *msg++;
if ( numInClusters )
{
inClusters = (uint16*)osal_mem_alloc( numInClusters * sizeof( uint16 ) );
msg = ZDO_ConvertOTAClusters( numInClusters, msg, inClusters );
}
numOutClusters = *msg++;
if ( numOutClusters )
{
outClusters = (uint16 *)osal_mem_alloc( numOutClusters * sizeof( uint16 ) );
msg = ZDO_ConvertOTAClusters( numOutClusters, msg, outClusters );
}
// First count the number of endpoints that match.
epDesc = epList;
while ( epDesc )
{
// Don't search endpoint 0 and check if response is allowed
if ( epDesc->epDesc->endPoint != ZDO_EP && (epDesc->flags&eEP_AllowMatch) )
{
if ( epDesc->pfnDescCB )
{
sDesc = (SimpleDescriptionFormat_t *)epDesc->pfnDescCB( AF_DESCRIPTOR_SIMPLE, epDesc->epDesc->endPoint );
allocated = TRUE;
}
else
{
sDesc = epDesc->epDesc->simpleDesc;
allocated = FALSE;
}
if ( sDesc && sDesc->AppProfId == profileID )
{
uint8 *uint8Buf = (uint8 *)ZDOBuildBuf;
// If there are no search input/ouput clusters - respond
if ( ((numInClusters == 0) && (numOutClusters == 0))
// Are there matching input clusters?
|| (ZDO_AnyClusterMatches( numInClusters, inClusters,
sDesc->AppNumInClusters, sDesc->pAppInClusterList ))
// Are there matching output clusters?
|| (ZDO_AnyClusterMatches( numOutClusters, outClusters,
sDesc->AppNumOutClusters, sDesc->pAppOutClusterList )) )
{
// Notify the endpoint of the match.
uint8 bufLen = sizeof( ZDO_MatchDescRspSent_t ) + (numOutClusters + numInClusters) * sizeof(uint16);
ZDO_MatchDescRspSent_t *pRspSent = (ZDO_MatchDescRspSent_t *) osal_msg_allocate( bufLen );
if (pRspSent)
{
pRspSent->hdr.event = ZDO_MATCH_DESC_RSP_SENT;
pRspSent->nwkAddr = inMsg->srcAddr.addr.shortAddr;
pRspSent->numInClusters = numInClusters;
pRspSent->numOutClusters = numOutClusters;
if (numInClusters)
{
pRspSent->pInClusters = (uint16*) (pRspSent + 1);
osal_memcpy(pRspSent->pInClusters, inClusters, numInClusters * sizeof(uint16));
}
else
{
pRspSent->pInClusters = NULL;
}
if (numOutClusters)
{
pRspSent->pOutClusters = (uint16*)(pRspSent + 1) + numInClusters;
osal_memcpy(pRspSent->pOutClusters, outClusters, numOutClusters * sizeof(uint16));
}
else
{
pRspSent->pOutClusters = NULL;
}
osal_msg_send( *epDesc->epDesc->task_id, (uint8 *)pRspSent );
}
uint8Buf[epCnt++] = sDesc->EndPoint;
}
}
if ( allocated )
osal_mem_free( sDesc );
}
epDesc = epDesc->nextDesc;
}
// Send the message only if at least one match found.
if ( epCnt )
{
if ( ZSuccess == ZDP_MatchDescRsp( inMsg->TransSeq, &(inMsg->srcAddr), ZDP_SUCCESS,
ZDAppNwkAddr.addr.shortAddr, epCnt, (uint8 *)ZDOBuildBuf, inMsg->SecurityUse ) )
{
#if defined( LCD_SUPPORTED )
//HalLcdWriteScreen( "Match Desc Req", "Rsp Sent" );
// ClearScreen();
Print8(HAL_LCD_LINE_2,10,"Match Desc Req",1);
Print8(HAL_LCD_LINE_3,10,"Rsp Sent",1);
#endif
}
}
else
{
#if defined( LCD_SUPPORTED )
// HalLcdWriteScreen( "Match Desc Req", "Non Matched" );
//ClearScreen();
Print8(HAL_LCD_LINE_2,10,"Match Desc Req",1);
Print8(HAL_LCD_LINE_3,10,"Rsp Sent",1);
#endif
}
if ( inClusters )
osal_mem_free( inClusters );
if ( outClusters )
osal_mem_free( outClusters );
}
/*********************************************************************
* @fn ZDO_ProcessBindUnbindReq()
*
* @brief Called to process a Bind or Unbind Request message.
*
* @param inMsg - incoming message (request)
* @param pReq - place to put parsed information
*
* @return none
*/
void ZDO_ProcessBindUnbindReq( zdoIncomingMsg_t *inMsg, ZDO_BindUnbindReq_t *pReq )
{
zAddrType_t SourceAddr; // Binding Source addres
byte bindStat;
SourceAddr.addrMode = Addr64Bit;
osal_cpyExtAddr( SourceAddr.addr.extAddr, pReq->srcAddress );
// If the local device is not the primary binding cache
// check the src address of the bind request.
// If it is not the local device's extended address
// discard the request.
if ( !osal_ExtAddrEqual( SourceAddr.addr.extAddr, NLME_GetExtAddr()) ||
(pReq->dstAddress.addrMode != Addr64Bit &&
pReq->dstAddress.addrMode != AddrGroup) )
{
bindStat = ZDP_NOT_SUPPORTED;
}
else
{
// Check source & destination endpoints
if ( (pReq->srcEndpoint == 0 || pReq->srcEndpoint > MAX_ENDPOINTS)
|| (( pReq->dstAddress.addrMode == Addr64Bit ) &&
(pReq->dstEndpoint == 0 || pReq->dstEndpoint > MAX_ENDPOINTS)) )
{
bindStat = ZDP_INVALID_EP;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?