Appendix E.2: Adding Manufacturer-specific Commands
To add a manufacturer-specific command to a cluster:
Ensure that a manufacturer ID code has been specified, as described in Appendix E.1.
In the zcl_options.h file, define a Command ID for the new command (you must not use a value already used by another command) - for example, to add a command with an ID of 0x20 to the Basic cluster, the relevant line is:
#define E_CLD_BASIC_CMD_MANU_SPEC 0x20In your application code, introduce a handling routine for the new command into the command handler function that is registered when the cluster instance is created - for example, in the case of the Basic cluster, this handler function is eCLD_BasicCommandHandler(), which is registered when the function eCLD_BasicCreateBasic() is called. Do this as follows:
a) Define a handler routine specifically for the new command - for example, in the case of the Basic cluster, this function may be eCLD_BasicHandleManuSpecCommand() and has the prototype:
ZPS_tsAfEvent *pZPSevent, tsZCL_EndPointDefinition *psEndPointDefinition, tsZCL_ClusterInstance *psClusterInstance); ```
b\) Add the Command ID and the above command-specific handler function into the registered command handler function - for example, in the case of the Basic cluster, the code for **eCLD\_BasicCommandHandler\(\)** would be modified as shown in the fragment below:
PUBLIC teZCL_Status eCLD_BasicCommandHandler(
ZPS_tsAfEvent *pZPSevent,
tsZCL_EndPointDefinition *psEndPointDefinition,
tsZCL_ClusterInstance *psClusterInstance)
{...
// SERVER
switch(u8CommandIdentifier)
{
case(E_CLD_BASIC_CMD_RESET_TO_FACTORY_DEFAULTS):
{
eCLD_BasicHandleResetToFactoryDefaultsCommand(pZPSevent, psEndPointDefinition, psClusterInstance);
break;
}
case(E_CLD_BASIC_CMD_MANU_SPEC):
eCLD_BasicHandleManuSpecCommand(pZPSevent, psEndPointDefinition, psClusterInstance);
break;
default:
{
// unlock
eZCL_ReleaseMutex(psEndPointDefinition);
return(E_ZCL_FAIL);
break;
}
}
...
}
4. Add a command payload structure for the new command into the source (**.c**) file for the cluster - for example:
typedef struct { uint8 u8PayloadField1; uint16 u16PayloadField2; uint16 u16PayloadField3; uint32 u32PayloadField4; }tsMS_ManuSpecCommand;
5. Add a function for sending the command to a remote node into the header (**.h**) and source (**.c**) files for the cluster - for example, in the case of the Basic cluster, the function might be:
PUBLIC teZCL_Status eCLD_BasicCommandManuSpecSend( uint8 u8SourceEndpoint, uint8 u8DestinationEndpoint, tsZCL_Address *psDestinationAddress, tsMS_ManuSpecCommand *psManuSpecPayload, uint8 *pu8TransactionSequenceNumber) { teZCL_Status eZCL_Status; tsZCL_TxPayloadItem asPayloadDefinition[] = { {1, E_ZCL_UINT8, &psManuSpecPayload->u8PayloadField1}, {1, E_ZCL_UINT16, &psManuSpecPayload->u16PayloadField2}, {1, E_ZCL_UINT16, &psManuSpecPayload->u16PayloadField3}, {1, E_ZCL_UINT32, &psManuSpecPayload->u32PayloadField4} }; eZCL_Status = eZCL_CustomCommandSend(u8SourceEndpoint, u8DestinationEndpoint, psDestinationAddress, GENERAL_CLUSTER_ID_BASIC, TRUE, E_CLD_BASIC_CMD_MANU_SPEC, pu8TransactionSequenceNumber, asPayloadDefinition, TRUE, HA_MANUFACTURER_CODE, sizeof(asPayloadDefinition) / sizeof(tsZCL_TxPayloadItem)); return eZCL_Status; }
**Parent topic:**[Appendix E: Manufacturer-specific attributes and commands](../../appendix/topics/manufacturer-specific_attributes_and_commands.md)