📄 zdprofile.c
字号:
len++;
}
return fillAndSend( &ZDP_TransID, &dstAddr, End_Device_annce, len );
}
#endif // ZDO_ENDDEVICE_ANNCE_REQUEST
/*********************************************************************
* Address Responses
*/
/*********************************************************************
* @fn zdpProcessAddrReq
*
* @brief Process an incoming NWK_addr_req or IEEE_addr_req message and then
* build and send a corresponding NWK_addr_rsp or IEEE_addr_rsp msg.
*
* @param seq - Message sequence number of the request.
* @param src - Source address of the request.
* @param msg - Incoming request message.
* @param cId - Cluster ID of the request.
* @param sty - Security enable/disable options.
*
* @return none
*/
static void zdpProcessAddrReq(
byte seq, zAddrType_t *src, byte *msg, uint16 cId, byte sty )
{
byte reqType = msg[(cId == NWK_addr_req) ? Z_EXTADDR_LEN : sizeof( uint16 ) ];
uint16 aoi = INVALID_NODE_ADDR;
byte *ieee = NULL;
if ( cId == NWK_addr_req )
{
ieee = msg;
if ( osal_ExtAddrEqual( saveExtAddr, ieee ) )
{
aoi = ZDAppNwkAddr.addr.shortAddr;
}
/*
else if ( reqType == ZDP_ADDR_REQTYPE_MEMBERSHIP )
{
//ggg - what to do?
}
*/
#if defined( ZDO_CACHE ) && ( CACHE_DEV_MAX > 0 )
else
{
aoi = ZDCacheGetNwkAddr( msg );
}
#endif
}
else // if ( cId == IEEE_addr_req )
{
aoi = BUILD_UINT16( msg[0], msg[1] );
if ( aoi == ZDAppNwkAddr.addr.shortAddr )
{
ieee = saveExtAddr;
}
#if defined( ZDO_CACHE ) && ( CACHE_DEV_MAX > 0 )
else
{
ieee = ZDCacheGetExtAddr( aoi );
}
#endif
}
if ( (aoi != INVALID_NODE_ADDR) && (ieee != NULL) )
{
byte *pBuf = ZDP_TmpBuf;
// Status + IEEE-Addr + Nwk-Addr.
byte len = 1 + Z_EXTADDR_LEN + 2;
byte stat = ((reqType == ZDP_ADDR_REQTYPE_SINGLE) ||
(reqType == ZDP_ADDR_REQTYPE_EXTENDED) ||
((reqType == ZDP_ADDR_REQTYPE_MEMBERSHIP) && (cId == NWK_addr_req)) ) ?
ZDP_SUCCESS : ZDP_INVALID_REQTYPE;
*pBuf++ = stat;
pBuf = osal_cpyExtAddr( pBuf, ieee );
*pBuf++ = LO_UINT16( aoi );
*pBuf++ = HI_UINT16( aoi );
#if defined( RTR_NWK )
if ( (reqType == ZDP_ADDR_REQTYPE_EXTENDED) &&
(aoi == ZDAppNwkAddr.addr.shortAddr) )
{
byte cnt = 0;
uint16 *list = AssocMakeList( &cnt );
// NumAssocDev field is only present on success.
*pBuf++ = cnt;
len++;
if ( list != NULL )
{
byte idx =
msg[(((cId == NWK_addr_req) ? Z_EXTADDR_LEN : sizeof( uint16 )) + 1)];
uint16 *pList = list + idx;
// StartIndex field is only present if NumAssocDev field is non-zero.
*pBuf++ = idx;
len++;
if ( cnt > idx )
{
cnt -= idx;
len += (cnt * sizeof( uint16 ));
}
else
{
cnt = 0;
}
while ( cnt != 0 )
{
*pBuf++ = LO_UINT16( *pList );
*pBuf++ = HI_UINT16( *pList );
pList++;
cnt--;
}
osal_mem_free( (byte *)list );
}
}
#endif
ZDP_TxOptions = AF_MSG_ACK_REQUEST;
fillAndSend( &seq, src, (cId_t)(cId | ZDO_RESPONSE_BIT), len );
ZDP_TxOptions = AF_TX_OPTIONS_NONE;
}
}
/*********************************************************************
* @fn ZDP_NodeDescMsg
*
* @brief Builds and sends a Node Descriptor message, unicast to the
* specified device.
*
* @param dstAddr - destination address
* @param nwkAddr - 16 bit network address for device
* @param pNodeDesc - pointer to the node descriptor
* @param SecurityEnable - Security Options
*
* @return afStatus_t
*/
afStatus_t ZDP_NodeDescMsg( byte TransSeq, zAddrType_t *dstAddr,
uint16 nwkAddr, NodeDescriptorFormat_t *pNodeDesc, byte SecurityEnable )
{
byte proVer = NLME_GetProtocolVersion();
byte *pBuf = ZDP_TmpBuf;
byte len;
if ( proVer == ZB_PROT_V1_0 )
{
len = 1 + 2 + 8; // Status + nwkAddr + Node descriptor
}
else
{
len = 1 + 2 + 10; // Status + nwkAddr + Node descriptor
}
*pBuf++ = ZDP_SUCCESS;
*pBuf++ = LO_UINT16( nwkAddr );
*pBuf++ = HI_UINT16( nwkAddr );
if ( proVer == ZB_PROT_V1_0 )
{
*pBuf++ = (byte)(pNodeDesc->LogicalType & 0x07);
}
else
{
*pBuf++ = (byte)((pNodeDesc->ComplexDescAvail << 3) |
(pNodeDesc->UserDescAvail << 4) |
(pNodeDesc->LogicalType & 0x07));
}
*pBuf++ = (byte)((pNodeDesc->FrequencyBand << 3) | (pNodeDesc->APSFlags & 0x07));
*pBuf++ = pNodeDesc->CapabilityFlags;
*pBuf++ = pNodeDesc->ManufacturerCode[0];
*pBuf++ = pNodeDesc->ManufacturerCode[1];
*pBuf++ = pNodeDesc->MaxBufferSize;
*pBuf++ = pNodeDesc->MaxTransferSize[0];
*pBuf++ = pNodeDesc->MaxTransferSize[1];
if ( proVer != ZB_PROT_V1_0 )
{
*pBuf++ = LO_UINT16( pNodeDesc->ServerMask );
*pBuf++ = HI_UINT16( pNodeDesc->ServerMask );
}
return fillAndSend( &TransSeq, dstAddr, Node_Desc_rsp, len );
}
/*********************************************************************
* @fn ZDP_PowerDescMsg
*
* @brief Builds and sends a Power Descriptor message, unicast to the
* specified device.
*
* @param dstAddr - destination address
* @param Status - message status (ZDP_SUCCESS or other)
* @param nwkAddr - 16 bit network address for device
* @param pPowerDesc - pointer to the node descriptor
* @param SecurityEnable - Security Options
*
* @return afStatus_t
*/
afStatus_t ZDP_PowerDescMsg( byte TransSeq, zAddrType_t *dstAddr,
uint16 nwkAddr, NodePowerDescriptorFormat_t *pPowerDesc, byte SecurityEnable )
{
byte *pBuf = ZDP_TmpBuf;
byte len = 1 + 2 + 2; // Status + nwkAddr + Node Power descriptor.
*pBuf++ = ZDP_SUCCESS;
*pBuf++ = LO_UINT16( nwkAddr );
*pBuf++ = HI_UINT16( nwkAddr );
*pBuf++ = (byte)((pPowerDesc->AvailablePowerSources << 4)
| (pPowerDesc->PowerMode & 0x0F));
*pBuf++ = (byte)((pPowerDesc->CurrentPowerSourceLevel << 4)
| (pPowerDesc->CurrentPowerSource & 0x0F));
return fillAndSend( &TransSeq, dstAddr, Power_Desc_rsp, len );
}
/*********************************************************************
* @fn ZDP_SimpleDescMsg
*
* @brief Builds and sends a Simple Descriptor message, unicast to the
* specified device.
*
* @param dstAddr - destination address
* @param Status - message status (ZDP_SUCCESS or other)
* @param pSimpleDesc - pointer to the node descriptor
* @param SecurityEnable - Security Options
*
* @return afStatus_t
*/
afStatus_t ZDP_SimpleDescMsg( byte TransSeq, zAddrType_t *dstAddr, byte Status,
SimpleDescriptionFormat_t *pSimpleDesc,
cId_t clusterID, byte SecurityEnable )
{
uint8 *pBuf = ZDP_TmpBuf;
uint8 i, len;
uint8 protoVer;
protoVer = NLME_GetProtocolVersion();
if ( Status == ZDP_SUCCESS && pSimpleDesc )
{
// Status + NWKAddrOfInterest + desc length + empty simple descriptor.
len = 1 + 2 + 1 + 8;
len += (pSimpleDesc->AppNumInClusters + pSimpleDesc->AppNumOutClusters)
* ((protoVer != ZB_PROT_V1_0) ? sizeof ( uint16 ) : sizeof( uint8 ));
}
else
{
len = 2; // Status + desc length
}
if ( len >= ZDP_BUF_SZ-1 )
{
return afStatus_MEM_FAIL;
}
*pBuf++ = Status;
*pBuf++ = LO_UINT16( ZDAppNwkAddr.addr.shortAddr );
*pBuf++ = HI_UINT16( ZDAppNwkAddr.addr.shortAddr );
if ( len > 2 )
{
*pBuf++ = len - 4; // Simple descriptor length
*pBuf++ = pSimpleDesc->EndPoint;
*pBuf++ = LO_UINT16( pSimpleDesc->AppProfId );
*pBuf++ = HI_UINT16( pSimpleDesc->AppProfId );
*pBuf++ = LO_UINT16( pSimpleDesc->AppDeviceId );
*pBuf++ = HI_UINT16( pSimpleDesc->AppDeviceId );
if ( protoVer == ZB_PROT_V1_0 )
{
*pBuf++ = (byte)((pSimpleDesc->AppDevVer << 4) | (pSimpleDesc->Reserved));
}
else
{
*pBuf++ = (byte)(pSimpleDesc->AppDevVer << 4);
}
*pBuf++ = pSimpleDesc->AppNumInClusters;
if ( pSimpleDesc->AppNumInClusters )
{
for (i=0; i<pSimpleDesc->AppNumInClusters; ++i)
{
*pBuf++ = LO_UINT16( pSimpleDesc->pAppInClusterList[i] );
if ( protoVer != ZB_PROT_V1_0 )
{
*pBuf++ = HI_UINT16( pSimpleDesc->pAppInClusterList[i] );
}
}
}
*pBuf++ = pSimpleDesc->AppNumOutClusters;
if ( pSimpleDesc->AppNumOutClusters )
{
for (i=0; i<pSimpleDesc->AppNumOutClusters; ++i)
{
*pBuf++ = LO_UINT16( pSimpleDesc->pAppOutClusterList[i] );
if ( protoVer != ZB_PROT_V1_0 )
{
*pBuf++ = HI_UINT16( pSimpleDesc->pAppOutClusterList[i] );
}
}
}
}
else
{
*pBuf = 0; // Description Length = 0;
}
return fillAndSend( &TransSeq, dstAddr, clusterID, len );
}
/*********************************************************************
* @fn ZDP_EPRsp
*
* @brief This builds and send an endpoint list. Used in
* Active_EP_rsp and Match_Desc_Rsp
* message. This function sends unicast message to the
* requesting device.
*
* @param MsgType - either Active_EP_rsp or Match_Desc_Rsp
* @param dstAddr - destination address
* @param Status - message status (ZDP_SUCCESS or other)
* @param nwkAddr - Device's short address that this response describes
* @param Count - number of endpoint/interfaces in list
* @param pEPIntfList - Array of Endpoint/Interfaces
* @param SecurityEnable - Security Options
*
* @return afStatus_t
*/
afStatus_t ZDP_EPRsp( uint16 MsgType, byte TransSeq, zAddrType_t *dstAddr,
byte Status, uint16 nwkAddr, byte Count,
byte *pEPList,
byte SecurityEnable )
{
byte *pBuf = ZDP_TmpBuf;
byte len = 1 + 2 + 1; // Status + nwkAddr + endpoint/interface count.
byte txOptions;
if ( MsgType == Match_Desc_rsp )
txOptions = AF_MSG_ACK_REQUEST;
else
txOptions = 0;
*pBuf++ = Status;
*pBuf++ = LO_UINT16( nwkAddr );
*pBuf++ = HI_UINT16( nwkAddr );
*pBuf++ = Count; // Endpoint/Interface count
if ( Count )
{
len += Count;
osal_memcpy( pBuf, pEPList, Count );
}
FillAndSendTxOptions( &TransSeq, dstAddr, MsgType, len, txOptions );
}
#if defined ( ZDO_USERDESC_RESPONSE )
/*********************************************************************
* @fn ZDP_UserDescRsp
*
* @brief Build and send the User Decriptor Response.
*
*
* @param dstAddr - destination address
* @param nwkAddrOfInterest -
* @param userDesc -
* @param SecurityEnable - Security Options
*
* @return ZStatus_t
*/
ZStatus_t ZDP_UserDescRsp( byte TransSeq, zAddrType_t *dstAddr,
uint16 nwkAddrOfInterest, UserDescriptorFormat_t *userDesc,
byte SecurityEnable )
{
byte *pBuf = ZDP_TmpBuf;
byte len = 1 + 2 + 1; // Status + nwkAddr + descriptor length.
len += userDesc->len;
*pBuf++ = ZSUCCESS;
*pBuf++ = LO_UINT16( nwkAddrOfInterest );
*pBuf++ = HI_UINT16( nwkAddrOfInterest );
*pBuf++ = userDesc->len;
osal_memcpy( pBuf, userDesc->desc, userDesc->len );
return (ZStatus_t)fillAndSend( &TransSeq, dstAddr, User_Desc_rsp, len );
}
#endif // ZDO_USERDESC_RESPONSE
#if defined ( ZDO_SERVERDISC_RESPONSE )
/*********************************************************************
* @fn ZDP_ServerDiscRsp
*
* @brief Build and send the Server_Discovery_rsp response.
*
* @param transID - Transaction sequence number of request.
* @param dstAddr - Network Destination Address.
* @param status - Status of response to request.
* @param aoi - Network Address of Interest of request.
* @param serverMask - Bit map of service(s) being sought.
* @param SecurityEnable - Security Options
*
* @return ZStatus_t
*/
ZStatus_t ZDP_ServerDiscRsp( byte transID, zAddrType_t *dstAddr, byte status,
uint16 aoi, uint16 serverMask, byte SecurityEnable )
{
const byte len = 1 + 2; // status + aoi + mask.
byte *pBuf = ZDP_TmpBuf;
*pBuf++ = status;
*pBuf++ = LO_UINT16( serverMask );
*pBuf++ = HI_UINT16( serverMask );
return (ZStatus_t)fillAndSend( &transID, dstAddr, Server_Discovery_rsp, len );
}
#endif // ZDO_USERDESC_RESPONSE
/*********************************************************************
* @fn ZDP_GenericRsp
*
* @brief Sends a response message with only the parameter status
* byte and the addr of interest for data.
* This function sends unicast message to the
* requesting device.
*
* @param dstAddr - destination address
* @param status - generic status for response
* @param aoi - address of interest
* @param dstAddr - destination address
* @param rspId - response cluster ID
* @param SecurityEnable - Security Options
*
* @return afStatus_t
*/
afStatus_t ZDP_GenericRsp( byte TransSeq, zAddrType_t *dstAddr,
byte status, uint16 aoi, uint16 rspID, byte SecurityEnable )
{
uint8 len;
ZDP_TmpBuf[0] = status;
ZDP_TmpBuf[1] = LO_UINT16( aoi );
ZDP_TmpBuf[2] = HI_UINT16( aoi );
if ( NLME_GetProtocolVersion() != ZB_PROT_V1_0 )
{
// Length byte
ZDP_TmpBuf[3] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -