Part Number: CC2652R
Other Parts Discussed in Thread: Z-STACK
Tool/software: TI-RTOS
As we know, the new version of ZCL has defined two command "ZCL_CMD_DISCOVER_CMDS_RECEIVED" and "ZCL_CMD_DISCOVER_CMDS_GEN" to query what specific commands dose the target device support. But in fact in Z-stack, devices can send and receive and execute commands which can't be queried by "ZCL_CMD_DISCOVER_CMDS_RECEIVED" and "ZCL_CMD_DISCOVER_CMDS_GEN".
So I suggest fix ZCL.c like this
first, add a new function "zclMatchCmdRecs"
static uint8 zclMatchCmdRecs( uint8 endpoint, uint16 clusterID, uint8 cmdID, uint8 flag )
{
uint8 i;
zclCmdRecsList_t *pRec = zclFindCmdRecsList( endpoint );
if ( pRec != NULL )
{
for ( i = 0; i < pRec->numCommands; i++ )
{
if ( pRec->pCmdRecs[i].clusterID == clusterID && pRec->pCmdRecs[i].cmdID == cmdID )
{
if( (pRec->pCmdRecs[i].flag & flag) != 0 ) //Match
{
return ( TRUE ); // EMBEDDED RETURN
}
}
}
return ( FALSE );
}
return ( TRUE ); //Not match un-registered command
}
then, add this code in function "zcl_SendCommandEx"
ZStatus_t zcl_SendCommandEx( uint8 srcEP, afAddrType_t *destAddr,
uint16 clusterID, uint8 cmd, uint8 specific, uint8 direction,
uint8 disableDefaultRsp, uint16 manuCode, uint8 seqNum,
uint16 cmdFormatLen, uint8 *cmdFormat, uint8 isReqFromApp )
{
endPointDesc_t *epDesc;
zclFrameHdr_t hdr;
uint8 *msgBuf;
uint16 msgLen;
uint8 *pBuf;
uint8 options;
ZStatus_t status;
#ifdef ZCL_DISCOVER
if( specific ) //Match command with command record, added by Luoyiming 2019-06-26
{
if( direction == ZCL_FRAME_SERVER_CLIENT_DIR )
{
if( !zclMatchCmdRecs( srcEP, clusterID, cmd, CMD_DIR_SERVER_GENERATED ) )
{
return ( ZFailure );
}
}
else
{
if( !zclMatchCmdRecs( srcEP, clusterID, cmd, CMD_DIR_CLIENT_GENERATED ) )
{
return ( ZFailure );
}
}
}
#endif // ZCL_DISCOVER
...
}
then add this code in function"zcl_ProcessMessageMSG"
zclProcMsgStatus_t zcl_ProcessMessageMSG( afIncomingMSGPacket_t *pkt )
{
...
// Is this a foundation type message
if ( !interPanMsg && zcl_ProfileCmd( inMsg.hdr.fc.type ) )
{
...
}
else // Not a foundation type message, so it must be specific to the cluster ID.
{
uint8 supCmd = TRUE;
#ifdef ZCL_DISCOVER
//Match command with command record, added by Luoyiming 2019-06-26
if( inMsg.hdr.fc.direction == ZCL_FRAME_SERVER_CLIENT_DIR )
{
supCmd = zclMatchCmdRecs( pkt->endPoint, pkt->clusterId, inMsg.hdr.commandID, CMD_DIR_CLIENT_RECEIVED );
}
else
{
supCmd = zclMatchCmdRecs( pkt->endPoint, pkt->clusterId, inMsg.hdr.commandID, CMD_DIR_SERVER_RECEIVED );
}
#endif // ZCL_DISCOVER
if ( pInPlugin && pInPlugin->pfnIncomingHdlr && supCmd )
{
// The return value of the plugin function will be
// ZSuccess - Supported and need default response
// ZFailure - Unsupported
// ZCL_STATUS_CMD_HAS_RSP - Supported and do not need default rsp
// ZCL_STATUS_INVALID_FIELD - Supported, but the incoming msg is wrong formatted
// ZCL_STATUS_INVALID_VALUE - Supported, but the request not achievable by the h/w
// ZCL_STATUS_SOFTWARE_FAILURE - Supported but ZStack memory allocation fails
status = pInPlugin->pfnIncomingHdlr( &inMsg );
if ( status == ZCL_STATUS_CMD_HAS_RSP || ( interPanMsg && status == ZSuccess ) )
{
rawAFMsg = NULL;
return ( ZCL_PROC_SUCCESS ); // We're done
}
}
...
}