Thread 中讨论的其他器件:Z-stack、 SIMPLELINK-CC13X2-26X2-SDK
首先、制作 z-stack 以支持 Manufacturer 属性。
可以将制造商标志添加到"zclAttribute_t"的"accessControl"中、 因为一个器件只有一个制造商代码。 "access_control_command"标志未在 z-stack 中使用、我们可以使用它来标记"制造商代码"标志。
... #define ACCESS_CONTROL_COMMAND 0x08 ... // Access Control for manufacturer-specific attribute, fixed by luoyiming 2020-01-08 #define ACCESS_MANU_ATTR ACCESS_CONTROL_COMMAND ...
因此、z-stack 中的属性访问函数应固定为支持"access_manu_attr"。 在"zcl.h"和"zcl.c"中、将新函数"zclFindAttrRecEx"定义为"zclFindAttrRec"、而不是"zclFindAttrRec"
#define zclFindAttrRec(ep,cId,attr,rec) zclFindAttrRecEx(ep,cId,0,0,attr,rec,NULL)
extern uint8_t zclFindAttrRecEx( uint8_t endpoint, uint16_t realClusterID, uint16_t manuCode, uint8_t direction,
uint16_t attrId, zclAttrRec_t *pAttr, uint8_t *idx );
uint8_t zclFindAttrRecEx( uint8_t endpoint, uint16_t clusterID, uint16_t manuCode, uint8_t direction,
uint16_t attrId, zclAttrRec_t *pAttr, uint8_t *idx )
{
uint8_t x;
zclAttrRecsList *pRec = zclFindAttrRecsList( endpoint );
uint8_t matchManuCode = FALSE;
// match manufacturer-cluster, fixed by luoyiming 2020-01-08
// don't execute for wildcard manufacturer ID, luoyiming add at 2020-01-09
if ( ( clusterID < 0xFC00 ) && ( manuCode != 0 ) && ( manuCode != 0xFFFF ) )
{
matchManuCode = TRUE;
}
if ( pRec != NULL )
{
for ( x = 0; x < pRec->numAttributes; x++ )
{
// match manufacturer attribute at first, luoyiming 2020-01-08
if ( ( pRec->attrs[x].attr.accessControl & ACCESS_MANU_ATTR ) && matchManuCode == FALSE )
{
continue;
}
if ( pRec->attrs[x].clusterID == clusterID && pRec->attrs[x].attr.attrId == attrId )
{
//match direction, fixed by luoyiming 2019-11-16
if ( (pRec->attrs[x].attr.accessControl & ACCESS_GLOBAL) ||
( GET_BIT( &(pRec->attrs[x].attr.accessControl), ACCESS_CONTROL_MASK ) == direction ) )
{
*pAttr = pRec->attrs[x];
// return the attribute's index, luoyiming 2021-07-04
if( idx != NULL )
{
*idx = x;
}
return ( TRUE ); // EMBEDDED RETURN
}
}
}
}
return ( FALSE );
}
还需要修复函数"zclFindNextAttrRec"以支持制造商代码
static uint8_t zclFindNextAttrRec( uint8_t endpoint, uint16_t clusterID, uint16_t manuCode, uint8_t direction,
uint16_t *attrId, zclAttrRec_t *pAttr, uint8_t *startIdx, bool cmpAttr )
{
zclAttrRecsList *pRec = zclFindAttrRecsList( endpoint );
uint8_t attrDir;
uint8_t matchManuCode = FALSE;
//match manufacturer-cluster, fixed by luoyiming 2020-01-08
if ( ( clusterID < 0xFC00 ) && ( manuCode != 0 ) )
{
matchManuCode = TRUE;
}
if ( pRec != NULL )
{
uint16_t x;
for ( x = *startIdx; x < pRec->numAttributes; x++ )
{
// match manufacturer attribute at first, luoyiming 2020-01-08
if ( ( pRec->attrs[x].attr.accessControl & ACCESS_MANU_ATTR ) && matchManuCode == FALSE )
{
continue;
}
if ( pRec->attrs[x].clusterID == clusterID )
{
// compare attrId or not, fixed by luoyiming 2021-07-04
if( (pRec->attrs[x].attr.attrId >= *attrId) || (cmpAttr == false) )
{
// also make sure direction is right
attrDir = (pRec->attrs[x].attr.accessControl & ACCESS_CLIENT) ? 1 : 0;
if ( (attrDir == direction) || (pRec->attrs[x].attr.accessControl & ACCESS_GLOBAL) )
{
// return attribute and found attribute ID
*pAttr = pRec->attrs[x];
*attrId = pAttr->attr.attrId;
*startIdx = x; // Update startIdx for next loop, luoyiming 2020-07-11
return ( TRUE ); // EMBEDDED RETURN
}
}
}
}
}
return ( FALSE );
}
在"zcl.c" ti 支持制造商代码中定义新函数
uint8_t zcl_MatchClusterManuCode( uint16_t clusterID, uint16_t manuCode )
{
uint16_t node_manuCode;
// no manufacturer code processing
if ( manuCode == 0 && clusterID < 0xFC00 )
{
return TRUE;
}
// get local manufacturer code for manufacturer-specific indication, luoyiming 2020-01-15
node_manuCode = zcl_GetManuCode( clusterID );
// manufacturer code is valid, match with node's manu-code or wildcard manu-code, luoyiming 2020-01-09
if ( ( node_manuCode != 0 ) && ( node_manuCode == manuCode || 0xFFFF == manuCode ) )
{
return TRUE;
}
return FALSE;
}
在"zcl_ProcessMessageMSG"中添加制造商代码处理
zclProcMsgStatus_t zcl_ProcessMessageMSG( afIncomingMSGPacket_t *pkt )
{
// Is this a foundation type message
if ( !interPanMsg && zcl_ProfileCmd( inMsg.hdr.fc.type ) )
{
if ( CMD_REQ_IND( inMsg.hdr.commandID ) &&
( inMsg.hdr.fc.manuSpecific ) && // add by luoyiming 2019-5-19
( !zcl_MatchClusterManuCode( inMsg.msg->clusterId, inMsg.hdr.manuCode )) ) // manu code match cluster fail, fix at 2019-10-20
{
// We don't support any manufacturer specific command
status = ZCL_STATUS_UNSUP_MANU_GENERAL_COMMAND;
}
...
}
}