14.2.3.5.4 Sending a Cluster-specific command
To send a cluster specific command the ZCL_CommandReq() function is used with the pointer to an instance of the ZCL_Request_t type as an argument that is used very similar as in ZCL_AttributeReq() function for general cluster commands described in Section Sending a General cluster command
Argument’s fields include command ID, source endpoint, destination addressing information, command payload and command payload’s length, pointers to a confirmation callback function, and a field configuring default response. These paremters are defined in ZCL_Request_t structure.
If a cluster-specific command requires specific ZCL response command per its specification in cluster definition file , then ZCL_Notify callback for the ZCL request will be triggered only after such response command is received, or until timeout for it reception expires. Immediately after such ZCL_Notify the callback function for the ZCL response command as specified for supported cluster commands will be called as well.
Command payload formatting
For cluster-specific commands the command’s payload is set to the pointer to an instance of a special type defined for each command in the cluster header file. The payload length can be calculated with the help of the sizeof operator applied to this type.
ZCL_OtauImageBlockReq_t *tmpOtauReq = &zclReqMem.uImageBlockReq; ZCL_Request_t *tmpZclReq = &.zclCommandReq; // fill the ZCL_Request_t structure fields for outgoing request. tmpZclReq->dstAddressing.addrMode = APS_SHORT_ADDRESS; tmpZclReq->dstAddressing.addr.shortAddress = actvServer->serverShortAddress; tmpZclReq->dstAddressing.endpointId = actvServer->serverEndpoint; tmpZclReq->dstAddressing.profileId = zclOtauMem.initParam.profileId; tmpZclReq->dstAddressing.clusterId = OTAU_CLUSTER_ID; tmpZclReq->dstAddressing.clusterSide = ZCL_SERVER_CLUSTER_TYPE; tmpZclReq->dstAddressing.manufacturerSpecCode = 0; tmpZclReq->dstAddressing.sequenceNumber = ZCL_GetNextSeqNumber(); tmpZclReq->endpointId = zclOtauMem.initParam.otauEndpoint; tmpZclReq->id = id; tmpZclReq->defaultResponse = ZCL_FRAME_CONTROL_ENABLE_DEFAULT_RESPONSE; tmpZclReq->requestLength = length; tmpZclReq->requestPayload = payload; tmpZclReq->responseWaitTimeout = rspWaitTime; tmpZclReq->ZCL_Notify = otauSomeRequestConfirm; // fill the command structu/paremeters of the cluster command tmpOtauReq->controlField.blockRequestDelayPresent = 1; tmpOtauReq->controlField.reqNodeIeeeAddrPresent = 0; tmpOtauReq->controlField.reserved = 0; tmpOtauReq->manufacturerId = csManufacturerId; tmpOtauReq->imageType = clientMem->downloadingImgType; memcpy(&tmpOtauReq->firmwareVersion,&clientMem->newFirmwareVersion,sizeof(ZCL_OtauFirmwareVersion_t)); tmpOtauReq->fileOffset = clientMem->imageAuxParam.requestFileOffset; tmpOtauReq->maxDataSize = clientMem->imageAuxParam.requestBlockSize; tmpOtauReq->minimumBlockPeriod = otauClientAttributes.minimumBlockPeriod.value; ZCL_CommandReq(tmpZclReq);
Note that for a cluster-specific command the application shall use the ZCL_GetNextSeqNumber() function to obtain ZCL sequence numbers set it to the sequenceNumber field in the dstAddressing structure of the argument of ZCL_CommandReq().