TI中文支持网
TI专业的中文技术问题搜集分享网站

Zs-tack中对于使用函数ReadWriteCB访问的Attribute,不能被Reporting。

在Z-stack中,使用pfnReadWriteCB访问的Attribute和实际分配了全局变量的Attribute有什么区别?为什么前者不能用Reporting的方式进行上报?

针对上述情况,我修改了ZCL.c下面的函数zcl_SendReportCmd,使其能够被Reporting

ZStatus_t zcl_SendReportCmd( uint8 srcEP, afAddrType_t *dstAddr,uint16 clusterID, zclReportCmd_t *reportCmd,uint8 direction, uint8 disableDefaultRsp, uint8 seqNum )
{uint16 dataLen = 0;uint8 *buf;ZStatus_t status;uint8 i;// calculate the size of the commandfor ( i = 0; i < reportCmd->numAttr; i++ ){zclReport_t *reportRec = &(reportCmd->attrList[i]);dataLen += 2 + 1; // Attribute ID + data type// Attribute Data//dataLen += zclGetAttrDataLength( reportRec->dataType, reportRec->attrData );if( reportRec->attrData ){dataLen += zclGetAttrDataLength( reportRec->dataType, reportRec->attrData );}else{dataLen += zclGetAttrDataLengthUsingCB( srcEP, clusterID, reportRec->attrID );}}buf = zcl_mem_alloc( dataLen );if ( buf != NULL ){// Load the buffer - seriallyuint8 *pBuf = buf;for ( i = 0; i < reportCmd->numAttr; i++ ){zclReport_t *reportRec = &(reportCmd->attrList[i]);*pBuf++ = LO_UINT16( reportRec->attrID );*pBuf++ = HI_UINT16( reportRec->attrID );*pBuf++ = reportRec->dataType;//pBuf = zclSerializeData( reportRec->dataType, reportRec->attrData, pBuf );if ( reportRec->attrData != NULL ){// Copy attribute data to the buffer to be sent outpBuf = zclSerializeData( reportRec->dataType, reportRec->attrData, pBuf );}else{uint16 dataLen;// Read attribute data directly into the buffer to be sent outzclReadAttrDataUsingCB( srcEP, clusterID, reportRec->attrID, pBuf, &dataLen );pBuf += dataLen;}}status = zcl_SendCommand( srcEP, dstAddr, clusterID, ZCL_CMD_REPORT, FALSE,direction, disableDefaultRsp, 0, seqNum, dataLen, buf );zcl_mem_free( buf );}else{status = ZMemError;}return ( status );
}

另外还要修改BDB_Reporting中的函数,这样改是否符合zigbee规范?

YiKai Chen:

看看你的問題跟 processors.wiki.ti.com/…/Zigbee_Known_Issues_and_Proposed_Fixes 裡的 BDB reporting doesn't support read/write attribute data callback functions 是否有關

Alvin Chen:

尝试替换下面的函数:

uint8 *gAttrDataValue;static uint8 bdb_RepFindAttrEntry( uint8 endpoint, uint16 cluster, uint16 attrID, zclAttribute_t* attrRes )
{epList_t *epCur = epList;uint8 i;zcl_memset(gAttrDataValue, 0, BDBREPORTING_MAX_ANALOG_ATTR_SIZE);for ( epCur = epList; epCur != NULL; epCur = epCur->nextDesc ){if( epCur->epDesc->endPoint == endpoint ){zclAttrRecsList* attrItem = zclFindAttrRecsList( epCur->epDesc->endPoint );if( (attrItem != NULL) && ( (attrItem->numAttributes > 0) && (attrItem->attrs != NULL) ) ){for ( i = 0; i < attrItem->numAttributes; i++ ){if ( ( attrItem->attrs[i].clusterID == cluster ) && ( attrItem->attrs[i].attr.attrId ==attrID ) ){uint16 dataLen;attrRes->attrId = attrItem->attrs[i].attr.attrId;attrRes->dataType = attrItem->attrs[i].attr.dataType;attrRes->accessControl = attrItem->attrs[i].attr.accessControl;dataLen = zclGetDataTypeLength(attrRes->dataType);zcl_ReadAttrData( endpoint, cluster, attrRes->attrId, gAttrDataValue, &dataLen );attrRes->dataPtr = gAttrDataValue;return BDBREPORTING_TRUE;}}}}}return BDBREPORTING_FALSE;
}

Aries Lord:

回复 Alvin Chen:

我已经自己完成了BDB_Reporting文件的修改,在调用bdb_RepFindAttrEntry后,判断attrRec.dataPtr是否为NULL,再进行分支操作。

Aries Lord:

回复 Alvin Chen:

你给的这段代码有bug,gAttrDataValue是一个野指针,而zcl_ReadAttrData需要填入的是一个buffer,其实可以在每次操作bdb_RepFindAttrEntry函数前对填入参数attrRes->dataPtr赋值一个Size= BDBREPORTING_MAX_ANALOG_ATTR_SIZE的Buffer,然后再用zcl_ReadAttrData直接填入attrRes->dataPtr指针。

参考我的代码

static uint8 bdb_RepFindAttrEntry( uint8 endpoint, uint16 cluster, uint16 attrID, zclAttribute_t* attrRes )
{epList_t *epCur = epList;uint8 i;uint8 found = BDBREPORTING_FALSE;for ( epCur = epList; epCur != NULL; epCur = epCur->nextDesc ){if( epCur->epDesc->endPoint == endpoint ){zclAttrRecsList* attrItem = zclFindAttrRecsList( epCur->epDesc->endPoint );if( (attrItem != NULL) && ( (attrItem->numAttributes > 0) && (attrItem->attrs != NULL) ) ){for ( i = 0; i < attrItem->numAttributes; i++ ){if ( ( attrItem->attrs[i].clusterID == cluster ) && ( attrItem->attrs[i].attr.attrId ==attrID ) ){attrRes->attrId = attrItem->attrs[i].attr.attrId;attrRes->dataType = attrItem->attrs[i].attr.dataType;attrRes->accessControl = attrItem->attrs[i].attr.accessControl;if(attrRes->dataPtr){uint16 dataLen = zclGetDataTypeLength(attrRes->dataType);zcl_ReadAttrData( endpoint, cluster, attrRes->attrId, attrRes->dataPtr, &dataLen );}else{attrRes->dataPtr = attrItem->attrs[i].attr.dataPtr;}return BDBREPORTING_TRUE;}}}}}return found;
}

然后进行如下调用

1

uint8dataBuf[BDBREPORTING_MAX_ANALOG_ATTR_SIZE];zclAttribute_t attrRec = {.dataPtr = dataBuf};uint8 attrRes = bdb_RepFindAttrEntry( clusterEndpointItem->endpoint, clusterEndpointItem->cluster, attrListItem->data->attrID, &attrRec );

在BDB_Reporting.c一共只有四处调用bdb_RepFindAttrEntry函数,每一处调用前都进行这种处理即可。

赞(0)
未经允许不得转载:TI中文支持网 » Zs-tack中对于使用函数ReadWriteCB访问的Attribute,不能被Reporting。
分享到: 更多 (0)