This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
协议栈:Z-Stack 3.0.2
协调器:CC2538
1、问题描述
(1)我用终端主动发送 “Discover Commands Received Response” 命令给协调器。
(2)协调器在应用层的 ZCL_CMD_DISCOVER_CMDS_RECEIVED_RSP 中处理此消息。
(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; 呢,这两者有区别吗?
你好,请使用下面的函数进行解析:
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 array pDiscoverRspCmd = (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 ); }
我是通过更改 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_RECEIVED uint8 numCmd; // number of provided commands uint8 *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_RECEIVED uint8 numCmd; // number of provided commands uint8 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 range for ( 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 command cmdRsp.pCmdID = zcl_mem_alloc( i ); // size of number of commands returned if ( 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 requested cmdRsp.cmdType = pInMsg->hdr.commandID; // store number of commands returned cmdRsp.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 range for ( 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 command cmdRsp = (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 requested cmdRsp->cmdType = pInMsg->hdr.commandID; // store number of commands returned cmdRsp->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; } } /* ----------------------------------------- */
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++;
}
}
应该没有什么问题吧