📄 zdobject.c
字号:
else
HalLcdWriteString( "Timeout", HAL_LCD_LINE_2 );
#endif
}
#endif // REFLECTOR
#if defined ( REFLECTOR ) || 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 // REFLECTOR || ZDO_COORDINATOR
#if defined ( REFLECTOR )
/*********************************************************************
* @fn ZDO_DoEndDeviceBind
*
* @brief Process the End Device Bind Req from ZDApp
*
* @param bindReq - Bind Request Information
* @param SecurityUse - Security enable/disable
*
* @return none
*/
void ZDO_DoEndDeviceBind( ZDEndDeviceBind_t *bindReq )
{
uint8 numMatches;
uint8 Status;
BindingEntry_t *pBind;
AddrMgrEntry_t addrEntry;
zAddrType_t SrcAddr;
SrcAddr.addrMode = Addr16Bit;
SrcAddr.addr.shortAddr = bindReq->srcAddr;
// Ask for IEEE address
if ( (bindReq->srcAddr != ZDAppNwkAddr.addr.shortAddr) )
{
addrEntry.user = ADDRMGR_USER_BINDING;
addrEntry.nwkAddr = bindReq->srcAddr;
Status = AddrMgrEntryLookupNwk( &addrEntry );
if ( Status == TRUE)
{
// Add a reference to entry
AddrMgrEntryAddRef( &addrEntry );
}
else
{
// If we have the extended address
if ( NLME_GetProtocolVersion() != ZB_PROT_V1_0 )
{
osal_cpyExtAddr( addrEntry.extAddr, bindReq->ieeeAddr );
}
// Not in address manager?
AddrMgrEntryUpdate( &addrEntry ); // Add it
}
if ( AddrMgrExtAddrValid( addrEntry.extAddr ) == FALSE )
{
ZDP_IEEEAddrReq( bindReq->srcAddr, ZDP_ADDR_REQTYPE_SINGLE, 0, false );
}
}
if ( ZDO_EDBind ) // End Device Bind in progress
{
Status = ZDP_NO_MATCH;
if ( bindReq->profileID == ZDO_EDBind->ProfileID )
{
// Check the first in against the seconds out
numMatches = ZDO_CompareClusterLists(
ZDO_EDBind->numOutClusters, ZDO_EDBind->outClusters,
bindReq->numInClusters, bindReq->inClusters, ZDOBuildBuf );
if ( numMatches )
{
// if existing bind exists, remove it
pBind = bindFindExisting( &(ZDO_EDBind->SrcAddr), ZDO_EDBind->epIntf,
&SrcAddr, bindReq->endpoint );
if ( pBind )
{
bindRemoveEntry( pBind );
Status = ZDP_SUCCESS;
}
// else add new binding table entry
else if ( bindAddEntry( &(ZDO_EDBind->SrcAddr), ZDO_EDBind->epIntf,
&SrcAddr, bindReq->endpoint, numMatches, ZDOBuildBuf ) )
Status = ZDP_SUCCESS;
else
Status = ZDP_TABLE_FULL;
}
// Check the second in against the first out
numMatches = ZDO_CompareClusterLists( bindReq->numOutClusters, bindReq->outClusters,
ZDO_EDBind->numInClusters, ZDO_EDBind->inClusters,
ZDOBuildBuf );
if ( numMatches )
{
// if existing bind exists, remove it
pBind = bindFindExisting( &SrcAddr, bindReq->endpoint, &(ZDO_EDBind->SrcAddr),
ZDO_EDBind->epIntf );
if ( pBind )
{
bindRemoveEntry( pBind );
Status = ZDP_SUCCESS;
}
// else add new binding table entry
else if ( bindAddEntry( &SrcAddr, bindReq->endpoint, &(ZDO_EDBind->SrcAddr),
ZDO_EDBind->epIntf, numMatches, ZDOBuildBuf ) )
Status = ZDP_SUCCESS;
else
Status = ZDP_TABLE_FULL;
}
}
if ( Status == ZDP_SUCCESS )
{
// We've found a match, so we don't have to wait for the timeout
APS_SetEndDeviceBindTimeout( 10, ZDO_EndDeviceTimeoutCB ); // psuedo stop end device timeout
// Notify to save info into NV
osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 250 );
}
ZDO_EDBind->status = Status;
// Send the response message to the device sending this message
ZDO_SendEDBindRsp( bindReq->TransSeq, &SrcAddr, Status, bindReq->SecurityUse );
}
else // Start a new End Device Bind
{
// Copy the info
ZDO_EDBind = osal_mem_alloc( sizeof( ZDO_EDBind_t ) );
if ( ZDO_EDBind )
{
osal_memcpy( &(ZDO_EDBind->SrcAddr), &SrcAddr, sizeof( zAddrType_t ) );
ZDO_EDBind->LocalCoordinator = bindReq->localCoordinator;
ZDO_EDBind->epIntf = bindReq->endpoint;
ZDO_EDBind->ProfileID = bindReq->profileID;
ZDO_EDBind->SrcTransSeq = bindReq->TransSeq;
ZDO_EDBind->numInClusters = bindReq->numInClusters;
if ( bindReq->numInClusters )
{
ZDO_EDBind->inClusters = osal_mem_alloc( (short)(bindReq->numInClusters * sizeof(uint16)) );
if ( ZDO_EDBind->inClusters )
{
osal_memcpy( ZDO_EDBind->inClusters, bindReq->inClusters, (bindReq->numInClusters * sizeof( uint16 )) );
}
else
{
// Force no clusters
ZDO_EDBind->numInClusters = 0;
}
}
else
ZDO_EDBind->inClusters = NULL;
ZDO_EDBind->numOutClusters = bindReq->numOutClusters;
if ( bindReq->numOutClusters )
{
ZDO_EDBind->outClusters = osal_mem_alloc( (short)(bindReq->numOutClusters*sizeof(uint16)) );
if ( ZDO_EDBind->outClusters )
{
osal_memcpy( ZDO_EDBind->outClusters, bindReq->outClusters, (bindReq->numOutClusters * sizeof( uint16 )) );
}
else
{
ZDO_EDBind->numOutClusters = 0;
}
}
else
ZDO_EDBind->outClusters = NULL;
ZDO_EDBind->SecurityUse = bindReq->SecurityUse;
ZDO_EDBind->status = ZDP_TIMEOUT;
// Setup the timer
APS_SetEndDeviceBindTimeout( AIB_MaxBindingTime, ZDO_EndDeviceTimeoutCB );
}
}
}
#endif // REFLECTOR
/*********************************************************************
* Utility functions
*/
/*********************************************************************
* @fn ZDO_CreateAlignedUINT16List
*
* @brief Creates a list of cluster IDs that is guaranteed to be aligned.
* according to the needs of the target. If thre device is running
* Protocol version 1.0 the incoming buffer will have only a single
* byte for the cluster ID.
*
* Depends on the malloc taking care of alignment.
*
* When cluster ID went to 16 bits alignment for cluster IDs became
* an issue.
*
* @param num - number of entries in list
* @param buf - pointer to list
*
* @return pointer to aligned list. Null if can't allocate memory.
* Caller's responsibility to free memory.
*/
static uint16 *ZDO_CreateAlignedUINT16List(uint8 num, uint8 *buf)
{
uint16 *ptr;
if ((ptr=osal_mem_alloc((short)(num*sizeof(uint16))))) {
uint8 i, ubyte, inc;
inc = (ZB_PROT_V1_1 == NLME_GetProtocolVersion()) ? 2 : 1;
for (i=0; i<num; ++i) {
// set upper byte to 0 if we're talking Version 1.0. otherwise
// the buffer contains 16 bit cluster IDs.
ubyte = (2 == inc) ? buf[1] : 0;
ptr[i] = BUILD_UINT16(buf[0], ubyte);
buf += inc;
}
}
return ptr;
}
/*********************************************************************
* @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 src - Source address
* @param msg - NWKAddrOfInterest
* @param sty - Security enable/disable
*
* @return none
*/
void ZDO_ProcessNodeDescReq( byte seq, zAddrType_t *src, byte *msg, byte sty )
{
uint16 aoi = BUILD_UINT16( msg[0], msg[1] );
NodeDescriptorFormat_t *desc = NULL;
byte stat = ZDP_INVALID_REQTYPE;
if ( aoi == ZDAppNwkAddr.addr.shortAddr )
{
desc = &ZDO_Config_Node_Descriptor;
}
#if defined( ZDO_CACHE ) && ( CACHE_DEV_MAX > 0 )
else if ( CACHE_SERVER )
{
desc = (NodeDescriptorFormat_t *)ZDCacheGetDesc( aoi, eNodeDesc, &stat );
}
#endif
if ( desc != NULL )
{
ZDP_NodeDescMsg( seq, src, aoi, desc, sty );
}
else
{
ZDP_GenericRsp( seq, src, stat, aoi, Node_Desc_rsp, sty );
}
}
/*********************************************************************
* @fn ZDO_ProcessPowerDescReq
*
* @brief This function processes and responds to the
* Node_Power_req message.
*
* @param src - Source address
* @param msg - NWKAddrOfInterest
* @param sty - Security enable/disable
*
* @return none
*/
void ZDO_ProcessPowerDescReq( byte seq, zAddrType_t *src, byte *msg, byte sty )
{
uint16 aoi = BUILD_UINT16( msg[0], msg[1] );
NodePowerDescriptorFormat_t *desc = NULL;
byte stat = ZDP_INVALID_REQTYPE;
if ( aoi == ZDAppNwkAddr.addr.shortAddr )
{
desc = &ZDO_Config_Power_Descriptor;
}
#if defined( ZDO_CACHE ) && ( CACHE_DEV_MAX > 0 )
else if ( CACHE_SERVER )
{
desc = (NodePowerDescriptorFormat_t *)ZDCacheGetDesc(aoi,ePowerDesc,&stat);
}
#endif
if ( desc != NULL )
{
ZDP_PowerDescMsg( seq, src, aoi, desc, sty );
}
else
{
ZDP_GenericRsp( seq, src, stat, aoi, Power_Desc_rsp, sty );
}
}
/*********************************************************************
* @fn ZDO_ProcessSimpleDescReq
*
* @brief This function processes and responds to the
* Simple_Desc_req message.
*
* @param src - Source address
* @param msg - message data
* @param sty - Security enable/disable
*
* @return none
*/
void ZDO_ProcessSimpleDescReq( byte seq, zAddrType_t *src, byte *msg, byte sty )
{
SimpleDescriptionFormat_t *sDesc = NULL;
uint16 aoi = BUILD_UINT16( msg[0], msg[1] );
byte endPoint = msg[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;
}
}
#if defined( ZDO_CACHE ) && ( CACHE_DEV_MAX > 0 )
else if ( CACHE_SERVER )
{
stat = endPoint;
sDesc = (SimpleDescriptionFormat_t *)ZDCacheGetDesc(aoi, eSimpDesc, &stat);
}
#endif
else
{
#if defined ( RTR_NWK )
stat = ZDP_DEVICE_NOT_FOUND;
#else
stat = ZDP_INVALID_REQTYPE;
#endif
}
ZDP_SimpleDescMsg( seq, src, stat, sDesc, Simple_Desc_rsp, sty );
if ( free )
{
osal_mem_free( sDesc );
}
}
/*********************************************************************
* @fn ZDO_ProcessActiveEPReq
*
* @brief This function processes and responds to the
* Active_EP_req message.
*
* @param src - Source address
* @param sty - Security enable/disable
*
* @return none
*/
void ZDO_ProcessActiveEPReq( byte seq, zAddrType_t *src, byte *msg, byte sty )
{
uint16 aoi = BUILD_UINT16( msg[0], msg[1] );
byte cnt = CACHE_EP_MAX;
byte stat = ZDP_SUCCESS;
if ( aoi == ZDAppNwkAddr.addr.shortAddr )
{
cnt = afNumEndPoints() - 1; // -1 for ZDO endpoint descriptor
afEndPoints( (uint8 *)ZDOBuildBuf, true );
}
#if defined( ZDO_CACHE ) && ( CACHE_DEV_MAX > 0 )
else if ( CACHE_SERVER )
{
cnt = *((byte *)ZDCacheGetDesc(aoi, eActEPDesc, (uint8 *)ZDOBuildBuf));
// If cnt = 0, err code in 1st byte of buf, otherwise EP list is in the buf.
if ( cnt == 0 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -