18#ifndef NIMBLE_CPP_CHARACTERISTIC_H_
19#define NIMBLE_CPP_CHARACTERISTIC_H_
21#include "syscfg/syscfg.h"
22#if CONFIG_BT_NIMBLE_ENABLED && MYNEWT_VAL(BLE_ROLE_PERIPHERAL)
24class NimBLECharacteristicCallbacks;
26class NimBLECharacteristic;
27class NimBLEDescriptor;
30# include "NimBLELocalValueAttribute.h"
41class NimBLECharacteristic :
public NimBLELocalValueAttribute {
43 NimBLECharacteristic(
const char* uuid,
44 uint16_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE,
45 uint16_t maxLen = BLE_ATT_ATTR_MAX_LEN,
46 NimBLEService* pService =
nullptr);
48 uint16_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE,
49 uint16_t maxLen = BLE_ATT_ATTR_MAX_LEN,
50 NimBLEService* pService =
nullptr);
52 ~NimBLECharacteristic();
54 std::string toString()
const;
55 void addDescriptor(NimBLEDescriptor* pDescriptor);
56 void removeDescriptor(NimBLEDescriptor* pDescriptor,
bool deleteDsc =
false);
57 uint16_t getProperties()
const;
58 void setCallbacks(NimBLECharacteristicCallbacks* pCallbacks);
59 bool indicate(uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const;
60 bool indicate(
const uint8_t* value,
size_t length, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const;
61 bool notify(uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const;
62 bool notify(
const uint8_t* value,
size_t length, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const;
64 NimBLEDescriptor* createDescriptor(
const char* uuid,
65 uint32_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE,
66 uint16_t maxLen = BLE_ATT_ATTR_MAX_LEN);
67 NimBLEDescriptor* createDescriptor(
const NimBLEUUID& uuid,
68 uint32_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE,
69 uint16_t maxLen = BLE_ATT_ATTR_MAX_LEN);
70 NimBLE2904* create2904();
71 NimBLEDescriptor* getDescriptorByUUID(
const char* uuid)
const;
72 NimBLEDescriptor* getDescriptorByUUID(
const NimBLEUUID& uuid)
const;
73 NimBLEDescriptor* getDescriptorByHandle(uint16_t handle)
const;
74 NimBLEService* getService()
const;
76 NimBLECharacteristicCallbacks* getCallbacks()
const;
80# if __cplusplus < 201703L
91 typename std::enable_if<!std::is_pointer<T>::value && !std::is_array<T>::value && !Has_c_str_length<T>::value &&
92 !Has_data_size<T>::value,
95 notify(
const T& v, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const {
96 return notify(
reinterpret_cast<const uint8_t*
>(&v),
sizeof(T), connHandle);
104 template <
typename T>
108 typename std::enable_if<Has_c_str_length<T>::value && !Has_data_size<T>::value,
bool>::type
110 notify(
const T& s, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const {
111 return notify(
reinterpret_cast<const uint8_t*
>(s.c_str()), s.length(), connHandle);
119 template <
typename T>
123 typename std::enable_if<Has_data_size<T>::value,
bool>::type
125 notify(
const T& v, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const {
126 return notify(
reinterpret_cast<const uint8_t*
>(v.data()), v.size(), connHandle);
135 template <
typename T>
139 typename std::enable_if<!std::is_pointer<T>::value && !std::is_array<T>::value && !Has_c_str_length<T>::value &&
140 !Has_data_size<T>::value,
143 indicate(
const T& v, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const {
144 return indicate(
reinterpret_cast<const uint8_t*
>(&v),
sizeof(T), connHandle);
152 template <
typename T>
156 typename std::enable_if<Has_c_str_length<T>::value && !Has_data_size<T>::value,
bool>::type
158 indicate(
const T& s, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const {
159 return indicate(
reinterpret_cast<const uint8_t*
>(s.c_str()), s.length(), connHandle);
167 template <
typename T>
171 typename std::enable_if<Has_data_size<T>::value,
bool>::type
173 indicate(
const T& v, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const {
174 return indicate(
reinterpret_cast<const uint8_t*
>(v.data()), v.size(), connHandle);
189 template <
typename T>
190 typename std::enable_if<!std::is_pointer<T>::value && !std::is_array<T>::value,
bool>::type notify(
191 const T& value, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const {
192 if constexpr (Has_data_size<T>::value) {
193 return notify(
reinterpret_cast<const uint8_t*
>(value.data()), value.size(), connHandle);
194 }
else if constexpr (Has_c_str_length<T>::value) {
195 return notify(
reinterpret_cast<const uint8_t*
>(value.c_str()), value.length(), connHandle);
197 return notify(
reinterpret_cast<const uint8_t*
>(&value),
sizeof(value), connHandle);
211 template <
typename T>
212 typename std::enable_if<!std::is_pointer<T>::value && !std::is_array<T>::value,
bool>::type indicate(
213 const T& value, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const {
214 if constexpr (Has_data_size<T>::value) {
215 return indicate(
reinterpret_cast<const uint8_t*
>(value.data()), value.size(), connHandle);
216 }
else if constexpr (Has_c_str_length<T>::value) {
217 return indicate(
reinterpret_cast<const uint8_t*
>(value.c_str()), value.length(), connHandle);
219 return indicate(
reinterpret_cast<const uint8_t*
>(&value),
sizeof(value), connHandle);
225 friend class NimBLEServer;
226 friend class NimBLEService;
228 void setService(NimBLEService* pService);
230 void writeEvent(
const uint8_t* val, uint16_t len,
NimBLEConnInfo& connInfo)
override;
231 bool sendValue(
const uint8_t* value,
233 bool is_notification =
true,
234 uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE)
const;
236 NimBLECharacteristicCallbacks* m_pCallbacks{
nullptr};
237 NimBLEService* m_pService{
nullptr};
238 std::vector<NimBLEDescriptor*> m_vDescriptors{};
248class NimBLECharacteristicCallbacks {
250 virtual ~NimBLECharacteristicCallbacks() {}
251 virtual void onRead(NimBLECharacteristic* pCharacteristic,
NimBLEConnInfo& connInfo);
252 virtual void onWrite(NimBLECharacteristic* pCharacteristic,
NimBLEConnInfo& connInfo);
253 virtual void onStatus(NimBLECharacteristic* pCharacteristic,
int code);
254 virtual void onSubscribe(NimBLECharacteristic* pCharacteristic,
NimBLEConnInfo& connInfo, uint16_t subValue);
Connection information.
Definition NimBLEConnInfo.h:32
A model of a BLE UUID.
Definition NimBLEUUID.h:41