Other Parts Discussed in Thread: Z-STACK, SIMPLELINK-CC13X2-26X2-SDK
First, make z-stack to support manufacturer attribute.
Manufacturer flag can be added into "accessControl" of "zclAttribute_t", because one device has only one manufacturer code. The "ACCESS_CONTROL_COMMAND" flag is not used in z-stack, and we can use it to mark "manufacturer code" flag.
... #define ACCESS_CONTROL_COMMAND 0x08 ... // Access Control for manufacturer-specific attribute, fixed by luoyiming 2020-01-08 #define ACCESS_MANU_ATTR ACCESS_CONTROL_COMMAND ...
So the attribute-access function in z-stack should be fixed to supports "ACCESS_MANU_ATTR". In "zcl.h" and "zcl.c", define a new function "zclFindAttrRecEx" to instead of "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 );
}
Function "zclFindNextAttrRec" also needs to be fixed to supports manufacturer-code
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 );
}
define a new function in "zcl.c" ti support manufacturer code
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;
}
Add manufacturer-code processing in "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;
}
...
}
}