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; } ... } }