/*
 * Copyright 2017-2026 Espressif Systems (Shanghai) PTE LTD
 * Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
 * esp-nimble-cpp, NimBLE-Arduino contributors.
 * Copyright 2017 Neil Kolban
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * BLE2904.h
 *
 *  Created on: Dec 23, 2017
 *      Author: kolban
 *
 *  Modified on: Feb 18, 2025
 *      Author: lucasssvaz (based on kolban's and h2zero's work)
 *      Description: Added support for NimBLE
 */

#ifndef COMPONENTS_CPP_UTILS_BLE2904_H_
#define COMPONENTS_CPP_UTILS_BLE2904_H_

#include "soc/soc_caps.h"
#include "sdkconfig.h"
#if defined(SOC_BLE_SUPPORTED) || defined(CONFIG_ESP_HOSTED_ENABLE_BT_NIMBLE)
#if defined(CONFIG_BLUEDROID_ENABLED) || defined(CONFIG_NIMBLE_ENABLED)

/***************************************************************************
 *                           Common includes                               *
 ***************************************************************************/

#include "BLEDescriptor.h"

/***************************************************************************
 *                            Common types                                 *
 ***************************************************************************/

struct BLE2904_Data {
  uint8_t m_format;
  int8_t m_exponent;
  uint16_t m_unit;  // See https://www.bluetooth.com/specifications/assigned-numbers/units
  uint8_t m_namespace;
  uint16_t m_description;
} __attribute__((packed));

/***************************************************************************
 *                           Common functions                              *
 ***************************************************************************/

/**
 * @brief Descriptor for Characteristic Presentation Format.
 *
 * This is a convenience descriptor for the Characteristic Presentation Format which has a UUID of 0x2904.
 *
 * See also:
 * https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
 */
class BLE2904 : public BLEDescriptor {
public:
  /***************************************************************************
   *                         Common public constants                         *
   ***************************************************************************/

  static const uint8_t FORMAT_BOOLEAN = 1;
  static const uint8_t FORMAT_UINT2 = 2;
  static const uint8_t FORMAT_UINT4 = 3;
  static const uint8_t FORMAT_UINT8 = 4;
  static const uint8_t FORMAT_UINT12 = 5;
  static const uint8_t FORMAT_UINT16 = 6;
  static const uint8_t FORMAT_UINT24 = 7;
  static const uint8_t FORMAT_UINT32 = 8;
  static const uint8_t FORMAT_UINT48 = 9;
  static const uint8_t FORMAT_UINT64 = 10;
  static const uint8_t FORMAT_UINT128 = 11;
  static const uint8_t FORMAT_SINT8 = 12;
  static const uint8_t FORMAT_SINT12 = 13;
  static const uint8_t FORMAT_SINT16 = 14;
  static const uint8_t FORMAT_SINT24 = 15;
  static const uint8_t FORMAT_SINT32 = 16;
  static const uint8_t FORMAT_SINT48 = 17;
  static const uint8_t FORMAT_SINT64 = 18;
  static const uint8_t FORMAT_SINT128 = 19;
  static const uint8_t FORMAT_FLOAT32 = 20;
  static const uint8_t FORMAT_FLOAT64 = 21;
  static const uint8_t FORMAT_SFLOAT16 = 22;
  static const uint8_t FORMAT_SFLOAT32 = 23;
  static const uint8_t FORMAT_IEEE20601 = 24;
  static const uint8_t FORMAT_UTF8 = 25;
  static const uint8_t FORMAT_UTF16 = 26;
  static const uint8_t FORMAT_OPAQUE = 27;
  static const uint8_t FORMAT_MEDASN1 = 28;

  /***************************************************************************
   *                         Common public functions                         *
   ***************************************************************************/

  BLE2904();
  void setDescription(uint16_t);
  void setExponent(int8_t exponent);
  void setFormat(uint8_t format);
  void setNamespace(uint8_t namespace_value);
  void setUnit(uint16_t unit);

private:
  /***************************************************************************
   *                         Common private properties                         *
   ***************************************************************************/

  BLE2904_Data m_data;
};  // BLE2904

#endif /* CONFIG_BLUEDROID_ENABLED || CONFIG_NIMBLE_ENABLED */
#endif /* SOC_BLE_SUPPORTED || CONFIG_ESP_HOSTED_ENABLE_BT_NIMBLE */

#endif /* COMPONENTS_CPP_UTILS_BLE2904_H_ */
