📄 zdprofile.c
字号:
* @param Status - message status (ZDP_SUCCESS or other)
* @param NeighborLqiEntries - Total number of entries found
* @param StartIndex - Starting index within the reporting list
* @param NeighborLqiCount - number of lists included
* in this message
* @param NeighborLqiList - List of NeighborLqiItems. This list
* is the list to be sent, not the entire list
* @param SecurityEnable - true if secure
*
* @return ZStatus_t
*/
ZStatus_t ZDP_MgmtLqiRsp( byte TransSeq, zAddrType_t *dstAddr,
byte Status,
byte NeighborLqiEntries,
byte StartIndex,
byte NeighborLqiCount,
ZDP_MgmtLqiItem_t* NeighborList,
byte SecurityEnable )
{
ZDP_MgmtLqiItem_t* list = NeighborList;
byte *buf, *pBuf;
byte len, x;
if ( ZSuccess != Status )
{
ZDP_TmpBuf[0] = Status;
return fillAndSend( &TransSeq, dstAddr, Mgmt_Lqi_rsp, 1 );
}
// (Status + NeighborLqiEntries + StartIndex + NeighborLqiCount) +
// neighbor LQI data.
len = (1 + 1 + 1 + 1) + (NeighborLqiCount * ZDP_MGMTLQI_EXTENDED_SIZE);
buf = osal_mem_alloc( len+1 );
if ( buf == NULL )
{
return afStatus_MEM_FAIL;
}
pBuf = buf+1;
*pBuf++ = Status;
*pBuf++ = NeighborLqiEntries;
*pBuf++ = StartIndex;
*pBuf++ = NeighborLqiCount;
for ( x = 0; x < NeighborLqiCount; x++ )
{
osal_cpyExtAddr( pBuf, list->extPanID); // Extended PanID
pBuf += Z_EXTADDR_LEN;
// EXTADDR
pBuf = osal_cpyExtAddr( pBuf, list->extAddr );
// NWKADDR
*pBuf++ = LO_UINT16( list->nwkAddr );
*pBuf++ = HI_UINT16( list->nwkAddr );
// DEVICETYPE
*pBuf = list->devType;
// RXONIDLE
*pBuf |= (uint8)(list->rxOnIdle << 2);
// RELATIONSHIP
*pBuf++ |= (uint8)(list->relation << 4);
// PERMITJOINING
*pBuf++ = (uint8)(list->permit);
// DEPTH
*pBuf++ = list->depth;
// LQI
*pBuf++ = list->lqi;
list++; // next list entry
}
FillAndSendBuffer( &TransSeq, dstAddr, Mgmt_Lqi_rsp, len, buf );
}
#endif // ZDO_MGMT_LQI_RESPONSE && RTR_NWK
#if defined ( ZDO_MGMT_RTG_RESPONSE )
/*********************************************************************
* @fn ZDP_MgmtRtgRsp
*
* @brief This builds and send a Mgmt_Rtg_rsp message. This
* function sends a unicast message.
*
* @param dstAddr - destination address of the message
* @param Status - message status (ZDP_SUCCESS or other)
* @param RoutingTableEntries - Total number of entries
* @param StartIndex - Starting index within the reporting list
* @param RoutingTableListCount - number of entries included
* in this message
* @param RoutingTableList - List of Routing Table entries
* @param SecurityEnable - true to enable security for this message
*
* @return ZStatus_t
*/
ZStatus_t ZDP_MgmtRtgRsp( byte TransSeq, zAddrType_t *dstAddr,
byte Status,
byte RoutingTableEntries,
byte StartIndex,
byte RoutingListCount,
rtgItem_t *RoutingTableList,
byte SecurityEnable )
{
byte *buf;
byte *pBuf;
// Status + RoutingTableEntries + StartIndex + RoutingListCount.
byte len = 1 + 1 + 1 + 1;
byte x;
// Add an array for Routing List data
len += (RoutingListCount * ZDP_ROUTINGENTRY_SIZE);
buf = osal_mem_alloc( (short)(len+1) );
if ( buf == NULL )
{
return afStatus_MEM_FAIL;
}
pBuf = buf+1;
*pBuf++ = Status;
*pBuf++ = RoutingTableEntries;
*pBuf++ = StartIndex;
*pBuf++ = RoutingListCount;
for ( x = 0; x < RoutingListCount; x++ )
{
*pBuf++ = LO_UINT16( RoutingTableList->dstAddress ); // Destination Address
*pBuf++ = HI_UINT16( RoutingTableList->dstAddress );
*pBuf++ = RoutingTableList->status;
*pBuf++ = LO_UINT16( RoutingTableList->nextHopAddress ); // Next hop
*pBuf++ = HI_UINT16( RoutingTableList->nextHopAddress );
RoutingTableList++; // Move to next list entry
}
FillAndSendBuffer( &TransSeq, dstAddr, Mgmt_Rtg_rsp, len, buf );
}
#endif // ZDO_MGMT_RTG_RESPONSE
#if defined ( ZDO_MGMT_BIND_RESPONSE ) && defined ( REFLECTOR )
/*********************************************************************
* @fn ZDP_MgmtBindRsp
*
* @brief This builds and send a Mgmt_Bind_rsp message. This
* function sends a unicast message.
*
* @param dstAddr - destination address of the message
* @param Status - message status (ZDP_SUCCESS or other)
* @param BindingTableEntries - Total number of entries
* @param StartIndex - Starting index within the reporting list
* @param BindingTableListCount - number of entries included
* in this message
* @param BindingTableList - List of Binding Table entries
* @param SecurityEnable - Security Options
*
* @return ZStatus_t
*/
ZStatus_t ZDP_MgmtBindRsp( byte TransSeq, zAddrType_t *dstAddr,
byte Status,
byte BindingTableEntries,
byte StartIndex,
byte BindingTableListCount,
apsBindingItem_t *BindingTableList,
byte SecurityEnable )
{
uint8 *buf;
uint8 *pBuf;
uint8 maxLen; // maxLen is the maximum packet length to allocate enough memory space
uint8 len; // Actual length varies due to different addrMode
uint8 x;
byte extZdpBindEntrySize = ZDP_BINDINGENTRY_SIZE + 1 + 1; // One more byte for cluserID and DstAddrMode
byte shortZdpBindEntrySize = ZDP_BINDINGENTRY_SIZE + 1 + 1 + 2 - 8 - 1; // clusterID + DstAddrMode + shortAddr - ExtAddr - DstEndpoint
// Status + BindingTableEntries + StartIndex + BindingTableListCount.
maxLen = 1 + 1 + 1 + 1;
maxLen += (BindingTableListCount * extZdpBindEntrySize ); //max length
buf = osal_mem_alloc( maxLen + 1 ); // +1 for transaction ID
if ( buf == NULL )
{
return afStatus_MEM_FAIL;
}
pBuf = buf+1;
*pBuf++ = Status;
*pBuf++ = BindingTableEntries;
*pBuf++ = StartIndex;
*pBuf++ = BindingTableListCount;
// Initial length = Status + BindingTableEntries + StartIndex + BindingTableListCount.
// length += ZDP_BINDINGENTRY_SIZE -- Version 1.0
// extZdpBindEntrySize -- Version 1.1 extended address mode
// shortZdpBindEntrySize -- Version 1.1 group address mode
len = 1 + 1 + 1 + 1;
for ( x = 0; x < BindingTableListCount; x++ )
{
pBuf = osal_cpyExtAddr( pBuf, BindingTableList->srcAddr );
*pBuf++ = BindingTableList->srcEP;
// Cluster ID
*pBuf++ = LO_UINT16( BindingTableList->clusterID );
*pBuf++ = HI_UINT16( BindingTableList->clusterID );
*pBuf++ = BindingTableList->dstAddr.addrMode;
if ( BindingTableList->dstAddr.addrMode == Addr64Bit )
{
len += extZdpBindEntrySize;
pBuf = osal_cpyExtAddr( pBuf, BindingTableList->dstAddr.addr.extAddr );
*pBuf++ = BindingTableList->dstEP;
}
else
{
len += shortZdpBindEntrySize;
*pBuf++ = LO_UINT16( BindingTableList->dstAddr.addr.shortAddr );
*pBuf++ = HI_UINT16( BindingTableList->dstAddr.addr.shortAddr );
}
BindingTableList++; // Move to next list entry
}
FillAndSendBuffer( &TransSeq, dstAddr, Mgmt_Bind_rsp, len, buf );
}
#endif // ZDO_MGMT_BIND_RESPONSE && REFLECTOR
/*********************************************************************
* Functions to register for ZDO Over-the-air messages
*/
/*********************************************************************
* @fn ZDO_RegisterForZDOMsg
*
* @brief Call this function to register of an incoming over
* the air ZDO message - probably a response message
* but requests can also be received.
* Messages are delivered to the task with ZDO_CB_MSG
* as the message ID.
*
* @param taskID - Where you would like the message delivered
* @param clusterID - What message?
*
* @return ZSuccess - successful, ZMemError if not
*/
ZStatus_t ZDO_RegisterForZDOMsg( uint8 taskID, uint16 clusterID )
{
ZDO_MsgCB_t *pList;
ZDO_MsgCB_t *pLast;
ZDO_MsgCB_t *pNew;
// Look for duplicate
pList = zdoMsgCBs;
while ( pList )
{
if ( pList->taskID == taskID && pList->clusterID == clusterID )
return ( ZSuccess );
pLast = pList;
pList = (ZDO_MsgCB_t *)pList->next;
}
// Add to the list
pNew = (ZDO_MsgCB_t *)osal_mem_alloc( sizeof ( ZDO_MsgCB_t ) );
if ( pNew )
{
pNew->taskID = taskID;
pNew->clusterID = clusterID;
pNew->next = NULL;
if ( zdoMsgCBs )
{
pLast->next = pNew;
}
else
zdoMsgCBs = pNew;
return ( ZSuccess );
}
else
return ( ZMemError );
}
/*********************************************************************
* @fn ZDO_RemoveRegisteredCB
*
* @brief Call this function if you don't want to receive the
* incoming message.
*
* @param taskID - Where the messages are being delivered.
* @param clusterID - What message?
*
* @return ZSuccess - successful, ZFailure if not found
*/
ZStatus_t ZDO_RemoveRegisteredCB( uint8 taskID, uint16 clusterID )
{
ZDO_MsgCB_t *pList;
ZDO_MsgCB_t *pLast = NULL;
pList = zdoMsgCBs;
while ( pList )
{
if ( pList->taskID == taskID && pList->clusterID == clusterID )
{
if ( pLast )
{
// remove this one from the linked list
pLast->next = pList->next;
}
else if ( pList->next )
{
// remove the first one from the linked list
zdoMsgCBs = pList->next;
}
else
{
// remove the only item from the list
zdoMsgCBs = (ZDO_MsgCB_t *)NULL;
}
osal_mem_free( pList );
return ( ZSuccess );
}
pLast = pList;
pList = pList->next;
}
return ( ZFailure );
}
/*********************************************************************
* @fn ZDO_SendMsgCBs
*
* @brief This function sends messages to registered tasks.
* Local to ZDO and shouldn't be called outside of ZDO.
*
* @param inMsg - incoming message
*
* @return TRUE if sent to at least 1 task, FALSE if not
*/
uint8 ZDO_SendMsgCBs( zdoIncomingMsg_t *inMsg )
{
uint8 ret = FALSE;
ZDO_MsgCB_t *pList = zdoMsgCBs;
while ( pList )
{
if ( pList->clusterID == inMsg->clusterID )
{
zdoIncomingMsg_t *msgPtr;
// Send the address to the task
msgPtr = (zdoIncomingMsg_t *)osal_msg_allocate( sizeof( zdoIncomingMsg_t ) + inMsg->asduLen );
if ( msgPtr )
{
// copy struct
osal_memcpy( msgPtr, inMsg, sizeof( zdoIncomingMsg_t ));
if ( inMsg->asduLen )
{
msgPtr->asdu = (byte*)(((byte*)msgPtr) + sizeof( zdoIncomingMsg_t ));
osal_memcpy( msgPtr->asdu, inMsg->asdu, inMsg->asduLen );
}
msgPtr->hdr.event = ZDO_CB_MSG;
osal_msg_send( pList->taskID, (uint8 *)msgPtr );
ret = TRUE;
}
}
pList = (ZDO_MsgCB_t *)pList->next;
}
return ( ret );
}
/*********************************************************************
* Incoming message processor
*/
/*********************************************************************
* @fn ZDP_IncomingData
*
* @brief This function indicates the transfer of a data PDU (ASDU)
* from the APS sub-layer to the ZDO.
*
* @param pData - Incoming Message
*
* @return none
*/
void ZDP_IncomingData( afIncomingMSGPacket_t *pData )
{
uint8 x = 0;
uint8 handled;
zdoIncomingMsg_t inMsg;
inMsg.srcAddr.addrMode = Addr16Bit;
inMsg.srcAddr.addr.shortAddr = pData->srcAddr.addr.shortAddr;
inMsg.wasBroadcast = pData->wasBroadcast;
inMsg.clusterID = pData->clusterId;
inMsg.SecurityUse = pData->SecurityUse;
inMsg.asduLen = pData->cmd.DataLength-1;
inMsg.asdu = pData->cmd.Data+1;
inMsg.TransSeq = pData->cmd.Data[0];
handled = ZDO_SendMsgCBs( &inMsg );
#if defined( MT_ZDO_FUNC )
MT_ZdoRsp( &inMsg );
#endif
while ( zdpMsgProcs[x].clusterID != 0xFFFF )
{
if ( zdpMsgProcs[x].clusterID == inMsg.clusterID )
{
zdpMsgProcs[x].pFn( &inMsg );
return;
}
x++;
}
// Handle unhandled messages
if ( !handled )
ZDApp_InMsgCB( &inMsg );
}
/*********************************************************************
*********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -