Thread 中讨论的其他器件:Z-stack
1、在文件 zcl.c 中、函数 zcl_SendReportCmd 不支持获取由 zclReadWriteCB 访问的属性值。
2、在文件 zcl.c 中、函数 zcl_getExternalFoundationHandler 的访问参数是 afIncomingMSGPclack_t 类型、这可能会影响返回错误 Task_ID 值。
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.
1、在文件 zcl.c 中、函数 zcl_SendReportCmd 不支持获取由 zclReadWriteCB 访问的属性值。
2、在文件 zcl.c 中、函数 zcl_getExternalFoundationHandler 的访问参数是 afIncomingMSGPclack_t 类型、这可能会影响返回错误 Task_ID 值。
您好 Aries、
由于报告现在已在基本器件行为规范中定义、因此现在、z-stack bdb 实现方案还支持通过回调访问属性。 查看 bdb_Reporting.c 中的 bdb_RepReport(),是一个名为 bdb_RepFindAttrEntry()的函数,即使访问需要回调,也会调用该函 数以查找属性记录,然后在找到属性后使用 zcl_SendReportCmd ()发送报告。
您能详细说明第2点吗? 我在这里看不到这个问题。
但 zcl_SendReportCmd() 无法通过 回调访问属性。 zcl_SendReportCmd ()应该像这样被修复。
ZStatus_t zcl_SendReportCmd (uint8 srcEP、afAddrType_t * dstAddr、
uint16 clusterID、zclReportCmd_t *报告 Cmd、
uint8 direction、uint8 disableDefaultRsp、uint8 seqnum)
{
uint16 dataLen = 0;
uint8 * buf;
ZStatus_t status;
uint8 i;
//计算命令的大小
(i = 0;i < reportCmd->numAttr;i++)
{
zclReport_t *报告记录=&(reportCmd->attitList[i]);
dataLen += 2 + 1;//属性 ID +数据类型
//属性数据
//dataLen += zclGetAttrDataLength (reportRec->datatype、reportRec->attatData);
if (reportRec->attatData)
{
dataLen += zclGetAttrDataLength (reportRec->datatype、reportRec->attatData);
}
其他
{
dataLen += zclGetAttrDataLengthUsingCB( srcEP、clusterID、reportRec->attroID );
}
}
buf = zcl_mem_alloc (dataLen);
if (buf!= NULL)
{
//串行加载缓冲区
uint8 *pBuf = buf;
对于( i=0;i< reportCmd->numAttr; i++)
{
zclReport_t *报告记录=&(reportCmd->attitList[i]);
*pBuf++= LO_UINT16( reportRec->attID );
*pBuf++= HI_UINT16( reportRec->attrID );
*pBuf++=报告接收->数据类型;
//pBuf = zclSerializeData( reportRec->datatype、reportRec->attatData、pBuf );
if ( reportRec->attatData !=空)
{
//将属性数据复制到要发送的缓冲区
pBuf = zclSerializeData( reportRec->datatype、reportRec->attatData、pBuf );
}
其他
{
uint16 dataLen;
//将属性数据直接读取到要发送的缓冲区中
zclReadAttrDataUsingCB( srcEP、clusterID、reportRec->attraID、pBuf、&dataLen );
pBuf += dataLen;
}
}
status = zcl_SendCommand (srcEP、dstAddr、clusterID、ZCL_CMD_REPORT、false、
方向、disableDefaultRsp、0、seqnum、dataLen、 Buf);
zcl_mem_free (buf);
}
否则
{
状态= ZMemError;
}
返回(状态);
}
数字2问题是 zcl.c 中"zcl_event_loop"函数中的欠代码
if (* msgPtr == AF_INVING_MSG_CMD) { zcl_ProcessMessageMSG((afIncomingMSGPacket_t *)msgPtr ); } 其他 { taskID = zcl_getExternalFoundationHandler((afIncomingMSGPacket_t *)msgPtr ); if (taskID!= task_no_task) { //将其发送到要处理的另一个任务。 OSAL_msg_send (taskID、msgPtr); dealloc = false; } }
zcl_SendReportCmd()已将属性数据保存在 zclReportCmd_t 类型的结构中的"reportCmd"中 属性报告现在是 BDB 状态机的一部分,因此 zcl_SendReportCmd()仅用于发送由 BDB 状态机指定的报告缓冲区,而不是解出要报告的属性列表。
typedef 结构
{ uint8 numAttr; //列表中的报告数 zclReport_t atttrList[];//属性报告列表 } zclReportCmd_t;
您可以查看 zclSampleTemperatureSensor_Init()中的温度传感器样本,其中 bdb_RepAddAttrCfgRecordDefaultToList()用于设置默认报告配置,然后 BDB 报告状态机解决与属性报告相关的所有问题。 另请查看 ZigBee 应用架构、ZigBee 联盟文档 和 基本器件行为规范。
对于第2个问题、您是否正在讨论直接使用端点而不是 msgPtr? 但是、函数的返回不受此影响。
在"bdb_reporting.c" 中的函数 bdb_RepReport()中 ,zclReportCmd_t 类型的 pReportCmd 由 zcl_SendReportCmd 发送。 pReportCmd 的成员"attrList[i].attrData"是访问缓冲区"gAttrDataValue"的数据指针类型。 "gAttrDataValue"只能携带一个 Attribute 值、但如果应该报告群集中存在多个属性、则会发生错误。
器件型号:CC2538
函数 zcl_SendReportCmd 可以在 bdb 报告触发后传递具有相同 cluster-ID 的多个属性。 在函数 bdb_RepReport 中、报告的属性值缓存在全局变量"gAttrDataValue"中、该变量只能缓存一个属性。 如果需要报告多个属性、则需要更多缓存。 因此、可以像这样修复函数 bdb_RepReport
静态空 bdb_RepReport( uint8 specificationCLusterEndpointIndex )
{afAddrType_t
dstAddr;
zclReportCmd_t *pReportCmd;
uint8 i;
bdbReportAttrClusterEndpoint_t* clusterEndpointItem = NULL;
if (specificationCLusterEndpointIndex = BDBREPORTINVALIDINDEX)
{
if (bdb_reportingNextClusterEndpointIndex < bdb_reportingClusterEndpointArrayCount)
{
clusterEndpointItem =&(bdb_reportingClusterEndpointArray[bdb_reportingNextClusterEndpointIndex]);
}
}
否则
{
clusterEndpointItem =&(bdb_reportingClusterEndpointArray[specificationCLusterEndpointIndex]);
}
//实际发送报告
if (clusterEndpointItem->consulatedMaxReportInt!= ZCL_Reporting_off && clusterEndpointItem->LinkedIn attendList.numItems)
{
dstAddr.addrMode =(afAddrMode_t) AddrNotPresent;
dstAddr.addr.shortAddr = 0;
dstAddr.endpoint = clusterEndpointItem->endpoint;
dstAddr.panId =_NIB.nwkPanId;
//pReportCmd = osal_mem_alloc( sizeof( zclReportCmd_t )+(clusterEndpointItem->attresnList.numItems* sizeof( zclReport_t ))));
uint8 *pbuffer = osal_mem_alloc ( sizeof( zclReportCmd_t )+(clusterEndpointItem->attrLinkedIn List.numItems*( sizeof( zclReport_t ))+ BDBREPORTING_MAX_ANALOG_ATTR_SIZE ));
//if (pReportCmd!= NULL)
if (pbuffer)
{
pReportCmd =(zclReportCmd_t*) pbuffer;
pbuffer+= sizeof (zclReportCmd_t)+(clusterEndpointItem->LinkedIn attList.numItems * sizeof (zclReport_t));
pReportCmd->numAttr = clusterEndpointItem->AttatLinkedIn List.numItems;
对于( i=0;i<clusterEndpointItem->attatesn LinkedIn List.numItems;++ i )
{
pReportCmd->attrList[i].attrID = 0xFFFF;
pReportCmd->atList[i].datatype = 0xFF;
pReportCmd->attrList[i].attrData =空;
bdbLinkedIn ListAttrItem_t* attrListItem = bdb_linkedListAttrGetAtIndex(&clusterEndpointItem->atLinkedIn List, i );
if (attrListItem!=空)
{
pReportCmd->attrList[i].attrID = attrListItem->data->attrID;
zclAttribute_t atttrRec;
uint8 attrRes = bdb_RepFindAttrEntry (clusterEndpointItem->EndPoint、clusterEndpointItem->cluster、attrListItem->data->attrID、&attrRec);
if (attrRes == BDBREPORTING_TRUE)
{
uint8 *dataPtr = pbuffer + i*BDBREPORTING_MAX_ANALOG_ATTR_SIZE;
pReportCmd->atList[i].datatype = attrRec.datatype;
//pReportCmd->attrList[i].attrData = attrRec.dataPtr;
OSAL_memcpy (dataPtr、attrRec.dataPtr、BDBREPORTING_MAX_ANALOG_ATTR_SIZE);
pReportCmd->attrList[i].attrData = dataPtr;
//更新上次报告的值
if (zclAnalogDataType (attrRec.datatype))
{
//仅当数据类型为模拟时
OSAL_memset (attrListItem->data->lastValueReported、0x00、BDBREPORTING_MAX_ANALOG_ATTR_SIZE);
OSAL_memcpy (attrListItem->data->lastValueReported、attrRec.dataPtr、zclGetDataTypeLength (attractRec.datatype));
}
}
}
zcl_SendReportCmd (clusterEndpointItem->endpoint、&dstAddr、
clusterEndpointItem->cluster、pReportCmd、
ZCL_FRAME_SERVER_CLIENT_DIR、BDB_REPORTING_DISABLE_DEFAULT_RSP、bdb_getZCLFrameCounter();
OSAL_mem_free( pReportCmd );
}
}