/********************************************************************* * @fn zclElectricalMeasurement_Send_GetMeasurementProfileRsp * * @brief Call to send out Electrical Measurement Get Measurement Profile Response. This will * tell the client the appropriate parameters of the measurement profile. * * @param srcEP - Sending application's endpoint * @param dstAddr - where you want the message to go * @param pPayload: * startTime - represents the end time of the most chronologically recent interval being requested * status - table status enumeration lists the valid values returned in status field * profileIntervalPeriod - time frame used to capture parameter for profiling purposes * numberOfIntervalsDelivered - number of intervals the device is returning * attributeID - attribute that has been profiled by the application * intervals - array of intervals that depend on numberOfIntervalsDelivered, type based on attributeID * @param disableDefaultRsp - whether to disable the Default Response command * @param seqNum - sequence number * * @return ZStatus_t */ ZStatus_t zclElectricalMeasurement_Send_GetMeasurementProfileRsp( uint8 srcEP, afAddrType_t *dstAddr, zclElectricalMeasurementGetMeasurementProfileRsp_t *pPayload, uint8 disableDefaultRsp, uint8 seqNum ) { uint8 i; uint8 offset; uint8 *pBuf; // variable length payload uint8 attrRtn; uint8 calculatedAttrLen; uint16 calculatedIntervalSize; uint16 calculatedBufLen; ZStatus_t status; zclAttrRec_t attrRec; // determine if attribute ID is found per EP and cluster ID attrRtn = zclFindAttrRec( dstAddr->endPoint, ZCL_CLUSTER_ID_HA_ELECTRICAL_MEASUREMENT, pPayload->attributeID, &attrRec ); if ( attrRtn == TRUE ) { // if found, determine length of attribute based on given type calculatedAttrLen = zclGetDataTypeLength( attrRec.attr.dataType ); } calculatedIntervalSize = calculatedAttrLen * pPayload->numberOfIntervalsDelivered; // get a buffer large enough to hold the whole packet, including size of variable array calculatedBufLen = ( 9 + calculatedIntervalSize ); pBuf = zcl_mem_alloc( calculatedBufLen ); if ( !pBuf ) { return ( ZMemError ); // no memory, return failure } pBuf[0] = BREAK_UINT32(pPayload->startTime, 0); pBuf[1] = BREAK_UINT32(pPayload->startTime, 1); pBuf[2] = BREAK_UINT32(pPayload->startTime, 2); pBuf[3] = BREAK_UINT32(pPayload->startTime, 3); pBuf[4] = pPayload->status; pBuf[5] = pPayload->profileIntervalPeriod; pBuf[6] = pPayload->numberOfIntervalsDelivered; pBuf[7] = LO_UINT16(pPayload->attributeID); pBuf[8] = HI_UINT16(pPayload->attributeID); offset = 9; for ( i = 0; i < calculatedIntervalSize; i++ ) { pBuf[offset++] = pPayload->pIntervals[i]; } status = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_HA_ELECTRICAL_MEASUREMENT, COMMAND_ELECTRICAL_MEASUREMENT_GET_MEASUREMENT_PROFILE_RSP, TRUE, ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, calculatedBufLen, pBuf ); zcl_mem_free( pBuf ); return ( status ); }
/**************************************************************************** * @fn zclDiagnostic_GetAttribData() * * @brief Gets the Z-Stack attribute data for a specific ZCL Diagnostics * AttributeID. * * @param none. * * @return none. */ static ZStatus_t zclDiagnostic_GetAttribData( uint16 zclAttrId, uint16 *zdiagsAttrId, uint16 *dataLen ) { uint8 i; uint8 attrTableSize = sizeof(zclDiagsAttrTable); for ( i = 0; i < attrTableSize; i++ ) { if ( zclDiagsAttrTable[i].zclAttrId == zclAttrId ) { *zdiagsAttrId = zclDiagsAttrTable[i].ZDiagsAttrId; *dataLen = (uint16)zclGetDataTypeLength( zclDiagsAttrTable[i].dataType ); return ( ZSuccess ); } } return ( ZFailure ); }
/********************************************************************* * @fn OTA_Send_ReadAttrInd * * @brief Notifies the console about attribute values for a device. * * @param none. * * @return none */ void OTA_Send_ReadAttrInd(uint16 cluster, uint16 shortAddr, zclReadRspStatus_t *pAttr) { uint8 buffer[OTA_APP_READ_ATTRIBUTE_IND_LEN]; uint8 *pBuf = buffer; uint8 len; *pBuf++ = OTA_SYSAPP_ENDPOINT; *pBuf++ = OTA_APP_READ_ATTRIBUTE_IND; *pBuf++ = LO_UINT16(_NIB.nwkPanId); *pBuf++ = HI_UINT16(_NIB.nwkPanId); *pBuf++ = LO_UINT16(cluster); *pBuf++ = HI_UINT16(cluster); *pBuf++ = LO_UINT16(shortAddr); *pBuf++ = HI_UINT16(shortAddr); *pBuf++ = LO_UINT16(pAttr->attrID); *pBuf++ = HI_UINT16(pAttr->attrID); *pBuf++ = pAttr->status; *pBuf++ = pAttr->dataType; len = zclGetDataTypeLength(pAttr->dataType); // We should not be reading attributes greater than 8 bytes in length if (len <= 8) { *pBuf++ = len; if (len) { uint8 *pStr; switch ( pAttr->dataType ) { case ZCL_DATATYPE_UINT8: *pBuf = *((uint8 *)pAttr->data); break; case ZCL_DATATYPE_UINT16: *pBuf++ = LO_UINT16( *((uint16*)pAttr->data) ); *pBuf++ = HI_UINT16( *((uint16*)pAttr->data) ); break; case ZCL_DATATYPE_UINT32: pBuf = osal_buffer_uint32( pBuf, *((uint32*)pAttr->data) ); break; case ZCL_DATATYPE_IEEE_ADDR: pStr = (uint8*)pAttr->data; osal_memcpy( pBuf, pStr, 8 ); break; default: break; } } } else *pBuf = 0; // Send the indication MT_BuildAndSendZToolResponse(MT_RPC_SYS_APP, MT_APP_MSG, OTA_APP_READ_ATTRIBUTE_IND_LEN, buffer); }