协议栈:Z-Stack 3.0.2
协调器:CC2538
1、问题描述
(1)我用终端主动发送 “Discover Commands Received Response” 命令给协调器。
(2)协调器在应用层的 ZCL_CMD_DISCOVER_CMDS_RECEIVED_RSP 中处理此消息。
- static uint8 zclGenericApp_ProcessInDiscCmdsRspCmd( zclIncomingMsg_t *pInMsg )
- {
- zclDiscoverCmdsCmdRsp_t *discoverRspCmd;
- uint8 i;
- discoverRspCmd = (zclDiscoverCmdsCmdRsp_t *)pInMsg->attrCmd;
- for ( i = 0; i < discoverRspCmd->numCmd; i++ )
- {
- // Device is notified of the result of its attribute discovery command.
- }
- return ( TRUE );
- }
(3)发现获取到的命令ID与终端发送过来的命令ID不同。
2、我更改 zclDiscoverCmdsCmdRsp_t 结构体后就可以了。
将:
typedef struct
{
uint8 discComplete;
uint8 cmdType; // either ZCL_CMD_DISCOVER_CMDS_GEN or ZCL_CMD_DISCOVER_CMDS_RECEIVED
uint8 numCmd; // number of provided commands
uint8 *pCmdID; // variable length array
} zclDiscoverCmdsCmdRsp_t;
改为:
typedef struct
{
uint8 discComplete;
uint8 cmdType; // either ZCL_CMD_DISCOVER_CMDS_GEN or ZCL_CMD_DISCOVER_CMDS_RECEIVED
uint8 numCmd; // number of provided commands
uint8 pCmdID[]; // variable length array
} zclDiscoverCmdsCmdRsp_t;
为什么像 zclDiscoverAttrsRspCmd_t 、zclReportCmd_t 这些结构体都是用数组 uint8 pCmdID[]; 而 zclDiscoverCmdsCmdRsp_t 却是用 uint8 *pCmdID; 呢,这两者有区别吗?
Alvin Chen:
你好,请使用下面的函数进行解析:
static void *zclParseInDiscCmdsRspCmd( zclParseCmd_t *pCmd ) {zclDiscoverCmdsCmdRsp_t *pDiscoverRspCmd;uint8 *pBuf = pCmd->pData;uint8 numCmds = ZCLDISCRSPCMD_DATALEN(pCmd->dataLen);// length of command ID variable array// allocate memory for size of structure plus variable arraypDiscoverRspCmd = (zclDiscoverCmdsCmdRsp_t *)zcl_mem_alloc( sizeof ( zclDiscoverCmdsCmdRsp_t ) +( numCmds * sizeof(uint8) ) );if ( pDiscoverRspCmd != NULL ){uint8 i;pDiscoverRspCmd->discComplete = *pBuf++;pDiscoverRspCmd->numCmd = numCmds;for ( i = 0; i < numCmds; i++ ){pDiscoverRspCmd->pCmdID[i] = *pBuf++;}}return ( (void *)pDiscoverRspCmd ); }
Jesse Huang:
回复 Alvin Chen:
你好,你发给我的这个解析函数跟 Z-Stack 3.0.2 是一样的啊?
Jesse Huang:
回复 Alvin Chen:
我是通过更改 zclDiscoverCmdsCmdRsp_t 和 zclProcessInDiscCmd 处理函数来修复这个BUG的。我以为只有 Z-Stack 3.0.1 有这个问题,没想到 3.0.2 还是有这个问题。
/* 修订编号:20180913022 * ----- commented by Jesse_嘉伟 2018/05/03 ------ * typedef struct {uint8 discComplete;uint8 cmdType;// either ZCL_CMD_DISCOVER_CMDS_GEN or ZCL_CMD_DISCOVER_CMDS_RECEIVEDuint8 numCmd;// number of provided commandsuint8 *pCmdID;// variable length array } zclDiscoverCmdsCmdRsp_t; **//* ------ Added by Jesse_嘉伟 2018/05/03 ----- */ typedef struct {uint8 discComplete;uint8 cmdType;// either ZCL_CMD_DISCOVER_CMDS_GEN or ZCL_CMD_DISCOVER_CMDS_RECEIVEDuint8 numCmd;// number of provided commandsuint8 pCmdID[];// variable length array } zclDiscoverCmdsCmdRsp_t; /* ----------------------------------------- *//* 修订编号:20180913031 * ----- commented by Jesse_嘉伟 2018/05/03 ------ * static uint8 zclProcessInDiscCmd( zclIncoming_t *pInMsg ) {zclDiscoverCmdsCmd_t *pDiscoverCmd;zclDiscoverCmdsCmdRsp_t cmdRsp;ZStatus_t status;zclCommandRec_t cmdRec;uint8 cmdID;uint8 i;uint8 j;pDiscoverCmd = (zclDiscoverCmdsCmd_t *)pInMsg->attrCmd;// Find out the number of commands supported within the specified rangefor ( i = 0, cmdID = pDiscoverCmd->startCmdID; i < pDiscoverCmd->maxCmdID; i++, cmdID++ ){if ( !zclFindNextCmdRec( pInMsg->msg->endPoint, pInMsg->msg->clusterId, pInMsg->hdr.commandID, pInMsg->hdr.fc.direction, &cmdID, &cmdRec ) ){break;// Command not supported}}// Allocate space for the response commandcmdRsp.pCmdID = zcl_mem_alloc( i ); // size of number of commands returnedif ( cmdRsp.pCmdID == NULL ){return FALSE; // EMBEDDED RETURN}if ( i != 0 ){for ( j = 0, cmdID = pDiscoverCmd->startCmdID; j < i; j++, cmdID++ ){if ( !zclFindNextCmdRec( pInMsg->msg->endPoint, pInMsg->msg->clusterId, pInMsg->hdr.commandID, pInMsg->hdr.fc.direction, &cmdID, &cmdRec ) ){break; // Attribute not supported}cmdRsp.pCmdID[j] = cmdRec.cmdID;}}// Are there more commands to be discovered?if ( zclFindNextCmdRec( pInMsg->msg->endPoint, pInMsg->msg->clusterId, pInMsg->hdr.commandID, pInMsg->hdr.fc.direction, &cmdID, &cmdRec ) ){cmdRsp.discComplete = FALSE;}else{cmdRsp.discComplete = TRUE;}// pass the command requestedcmdRsp.cmdType = pInMsg->hdr.commandID;// store number of commands returnedcmdRsp.numCmd = j;status = zcl_SendDiscoverCmdsRspCmd( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,pInMsg->msg->clusterId, &cmdRsp, !(pInMsg->hdr.fc.direction),true, pInMsg->hdr.transSeqNum );zcl_mem_free( cmdRsp.pCmdID );if ( status == ZSuccess ){return TRUE;}else{return FALSE;} } **/ /* ------ Added by Jesse_嘉伟 2018/05/03 ----- */ static uint8 zclProcessInDiscCmd( zclIncoming_t *pInMsg ) {zclDiscoverCmdsCmd_t *pDiscoverCmd;zclDiscoverCmdsCmdRsp_t* cmdRsp;ZStatus_t status;zclCommandRec_t cmdRec;uint8 cmdID;uint8 i;uint8 j;pDiscoverCmd = (zclDiscoverCmdsCmd_t *)pInMsg->attrCmd;// Find out the number of commands supported within the specified rangefor ( i = 0, cmdID = pDiscoverCmd->startCmdID; i < pDiscoverCmd->maxCmdID; i++, cmdID++ ){if ( !zclFindNextCmdRec( pInMsg->msg->endPoint, pInMsg->msg->clusterId, pInMsg->hdr.commandID, pInMsg->hdr.fc.direction, &cmdID, &cmdRec ) ){break;// Command not supported}}// Allocate space for the response commandcmdRsp = (zclDiscoverCmdsCmdRsp_t *)zcl_mem_alloc( sizeof ( zclDiscoverCmdsCmdRsp_t ) + ( i * sizeof(uint8) ) );if ( cmdRsp == NULL ){return FALSE; // EMBEDDED RETURN}if ( i != 0 ){for ( j = 0, cmdID = pDiscoverCmd->startCmdID; j < i; j++, cmdID++ ){if ( !zclFindNextCmdRec( pInMsg->msg->endPoint, pInMsg->msg->clusterId, pInMsg->hdr.commandID, pInMsg->hdr.fc.direction, &cmdID, &cmdRec ) ){break; // Attribute not supported}cmdRsp->pCmdID[j] = cmdRec.cmdID;}}// Are there more commands to be discovered?if ( zclFindNextCmdRec( pInMsg->msg->endPoint, pInMsg->msg->clusterId, pInMsg->hdr.commandID, pInMsg->hdr.fc.direction, &cmdID, &cmdRec ) ){cmdRsp->discComplete = FALSE;}else{cmdRsp->discComplete = TRUE;}// pass the command requestedcmdRsp->cmdType = pInMsg->hdr.commandID;// store number of commands returnedcmdRsp->numCmd = j;status = zcl_SendDiscoverCmdsRspCmd( pInMsg->msg->endPoint, &pInMsg->msg->srcAddr,pInMsg->msg->clusterId, cmdRsp, !(pInMsg->hdr.fc.direction),true, pInMsg->hdr.transSeqNum );zcl_mem_free( cmdRsp );if ( status == ZSuccess ){return TRUE;}else{return FALSE;} } /* ----------------------------------------- */
Alvin Chen:
回复 Jesse Huang:
zclProcessInDiscCmd:
if ( i != 0 ){for ( j = 0, cmdID = pDiscoverCmd->startCmdID; j < i; j++, cmdID++ ){if ( !zclFindNextCmdRec( pInMsg->msg->endPoint, pInMsg->msg->clusterId, pInMsg->hdr.commandID, pInMsg->hdr.fc.direction, &cmdID, &cmdRec ) ){break; // Attribute not supported}cmdRsp.pCmdID[j] = cmdRec.cmdID;}}当用zcl_SendDiscoverCmdsRspCmd 回复里面:
uint8 *pBuf = pCmdBuf;// Load the buffer - serially*pBuf++ = pDiscoverRspCmd->discComplete;for ( i = 0; i < pDiscoverRspCmd->numCmd; i++ ){*pBuf++ = pDiscoverRspCmd->pCmdID[i];}在zclParseInDiscCmdsRspCmd 处理也是这么拿出来的.
if ( pDiscoverRspCmd != NULL ) { uint8 i; pDiscoverRspCmd->discComplete = *pBuf++; pDiscoverRspCmd->numCmd = numCmds;
for ( i = 0; i < numCmds; i++ ) { pDiscoverRspCmd->pCmdID[i] = *pBuf++; } }
应该没有什么问题吧
Jesse Huang:
回复 Alvin Chen:
好像是 zclProcessInDiscCmd 命令处理错误的问题,zclParseInDiscCmdsRspCmd 解析出来的 cmd id 还是正确的,你可以用原版的协议栈来测试一下。