/*********************************************************************
 * @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 );
}
示例#2
0
/****************************************************************************
 * @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 );
}
示例#3
0
/*********************************************************************
 * @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);
}