NimBLE-Arduino 2.4.0
Loading...
Searching...
No Matches
NimBLECharacteristic.h
1/*
2 * Copyright 2020-2026 Ryan Powell <ryan@nable-embedded.io> and
3 * esp-nimble-cpp, NimBLE-Arduino contributors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#ifndef NIMBLE_CPP_CHARACTERISTIC_H_
19#define NIMBLE_CPP_CHARACTERISTIC_H_
20
21#include "nimconfig.h"
22#if CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL
23
25class NimBLEService;
28class NimBLE2904;
29
30# include "NimBLELocalValueAttribute.h"
31
32# include <string>
33# include <vector>
34
41class NimBLECharacteristic : public NimBLELocalValueAttribute {
42 public:
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);
51
53
54 std::string toString() const;
55 void addDescriptor(NimBLEDescriptor* pDescriptor);
56 void removeDescriptor(NimBLEDescriptor* pDescriptor, bool deleteDsc = false);
57 uint16_t getProperties() const;
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;
63
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);
68 uint32_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE,
69 uint16_t maxLen = BLE_ATT_ATTR_MAX_LEN);
71 NimBLEDescriptor* getDescriptorByUUID(const char* uuid, uint16_t index = 0) const;
72 NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID& uuid, uint16_t index = 0) const;
73 NimBLEDescriptor* getDescriptorByHandle(uint16_t handle) const;
75
77
78 /*********************** Template Functions ************************/
79
80# if __cplusplus < 201703L
87 template <typename T>
88# ifdef _DOXYGEN_
89 bool
90# else
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,
93 bool>::type
94# endif
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);
97 }
98
104 template <typename T>
105# ifdef _DOXYGEN_
106 bool
107# else
108 typename std::enable_if<Has_c_str_length<T>::value && !Has_data_size<T>::value, bool>::type
109# endif
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);
112 }
113
120 template <typename T>
121# ifdef _DOXYGEN_
122 bool
123# else
124 typename std::enable_if<Has_data_size<T>::value && Has_value_type<T>::value, bool>::type
125# endif
126 notify(const T& v, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const {
127 return notify(reinterpret_cast<const uint8_t*>(v.data()), v.size() * sizeof(typename T::value_type), connHandle);
128 }
129
135 template <typename T>
136# ifdef _DOXYGEN_
137 bool
138# else
139 typename std::enable_if<Has_data_size<T>::value && !Has_value_type<T>::value, bool>::type
140# endif
141 notify(const T& v, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const {
142 return notify(reinterpret_cast<const uint8_t*>(v.data()), v.size(), connHandle);
143 }
144
151 template <typename T>
152# ifdef _DOXYGEN_
153 bool
154# else
155 typename std::enable_if<!std::is_pointer<T>::value && !std::is_array<T>::value && !Has_c_str_length<T>::value &&
156 !Has_data_size<T>::value,
157 bool>::type
158# endif
159 indicate(const T& v, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const {
160 return indicate(reinterpret_cast<const uint8_t*>(&v), sizeof(T), connHandle);
161 }
162
168 template <typename T>
169# ifdef _DOXYGEN_
170 bool
171# else
172 typename std::enable_if<Has_c_str_length<T>::value && !Has_data_size<T>::value, bool>::type
173# endif
174 indicate(const T& s, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const {
175 return indicate(reinterpret_cast<const uint8_t*>(s.c_str()), s.length(), connHandle);
176 }
177
184 template <typename T>
185# ifdef _DOXYGEN_
186 bool
187# else
188 typename std::enable_if<Has_data_size<T>::value && Has_value_type<T>::value, bool>::type
189# endif
190 indicate(const T& v, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const {
191 return indicate(reinterpret_cast<const uint8_t*>(v.data()), v.size() * sizeof(typename T::value_type), connHandle);
192 }
193
199 template <typename T>
200# ifdef _DOXYGEN_
201 bool
202# else
203 typename std::enable_if<Has_data_size<T>::value && !Has_value_type<T>::value, bool>::type
204# endif
205 indicate(const T& v, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const {
206 return indicate(reinterpret_cast<const uint8_t*>(v.data()), v.size(), connHandle);
207 }
208
209# else
210
221 template <typename T>
222 typename std::enable_if<!std::is_pointer<T>::value && !std::is_array<T>::value, bool>::type notify(
223 const T& value, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const {
224 if constexpr (Has_data_size<T>::value) {
225 if constexpr (Has_value_type<T>::value) {
226 return notify(reinterpret_cast<const uint8_t*>(value.data()),
227 value.size() * sizeof(typename T::value_type),
228 connHandle);
229 } else {
230 return notify(reinterpret_cast<const uint8_t*>(value.data()), value.size(), connHandle);
231 }
232 } else if constexpr (Has_c_str_length<T>::value) {
233 return notify(reinterpret_cast<const uint8_t*>(value.c_str()), value.length(), connHandle);
234 } else {
235 return notify(reinterpret_cast<const uint8_t*>(&value), sizeof(value), connHandle);
236 }
237 }
238
249 template <typename T>
250 typename std::enable_if<!std::is_pointer<T>::value && !std::is_array<T>::value, bool>::type indicate(
251 const T& value, uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const {
252 if constexpr (Has_data_size<T>::value) {
253 if constexpr (Has_value_type<T>::value) {
254 return indicate(reinterpret_cast<const uint8_t*>(value.data()),
255 value.size() * sizeof(typename T::value_type),
256 connHandle);
257 } else {
258 return indicate(reinterpret_cast<const uint8_t*>(value.data()), value.size(), connHandle);
259 }
260 } else if constexpr (Has_c_str_length<T>::value) {
261 return indicate(reinterpret_cast<const uint8_t*>(value.c_str()), value.length(), connHandle);
262 } else {
263 return indicate(reinterpret_cast<const uint8_t*>(&value), sizeof(value), connHandle);
264 }
265 }
266# endif
267
268 private:
269 friend class NimBLEServer;
270 friend class NimBLEService;
271
272 void setService(NimBLEService* pService);
273 void readEvent(NimBLEConnInfo& connInfo) override;
274 void writeEvent(const uint8_t* val, uint16_t len, NimBLEConnInfo& connInfo) override;
275 bool sendValue(const uint8_t* value,
276 size_t length,
277 bool is_notification = true,
278 uint16_t connHandle = BLE_HS_CONN_HANDLE_NONE) const;
279
280 NimBLECharacteristicCallbacks* m_pCallbacks{nullptr};
281 NimBLEService* m_pService{nullptr};
282 std::vector<NimBLEDescriptor*> m_vDescriptors{};
283}; // NimBLECharacteristic
284
293 public:
295 virtual void onRead(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo);
296 virtual void onWrite(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo);
297 virtual void onStatus(NimBLECharacteristic* pCharacteristic, int code); // deprecated
298 virtual void onStatus(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, int code);
299 virtual void onSubscribe(NimBLECharacteristic* pCharacteristic, NimBLEConnInfo& connInfo, uint16_t subValue);
300};
301
302#endif // CONFIG_BT_ENABLED && CONFIG_BT_NIMBLE_ROLE_PERIPHERAL
303#endif // NIMBLE_CPP_CHARACTERISTIC_H_
Descriptor for Characteristic Presentation Format.
Definition NimBLE2904.h:39
Callbacks that can be associated with a BLE characteristic to inform of events.
Definition NimBLECharacteristic.h:292
virtual void onSubscribe(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo, uint16_t subValue)
Callback function called when a client changes subscription status.
Definition NimBLECharacteristic.cpp:429
virtual void onRead(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo)
Callback function to support a read request.
Definition NimBLECharacteristic.cpp:383
virtual void onStatus(NimBLECharacteristic *pCharacteristic, int code)
Callback function to support a Notify/Indicate Status report.
Definition NimBLECharacteristic.cpp:403
virtual void onWrite(NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo)
Callback function to support a write request.
Definition NimBLECharacteristic.cpp:392
The model of a BLE Characteristic.
Definition NimBLECharacteristic.h:41
uint16_t getProperties() const
Get the properties of the characteristic.
Definition NimBLECharacteristic.cpp:205
NimBLEDescriptor * getDescriptorByHandle(uint16_t handle) const
Return the BLE Descriptor for the given handle.
Definition NimBLECharacteristic.cpp:192
void setCallbacks(NimBLECharacteristicCallbacks *pCallbacks)
Set the callback handlers for this characteristic.
Definition NimBLECharacteristic.cpp:344
void removeDescriptor(NimBLEDescriptor *pDescriptor, bool deleteDsc=false)
Remove a descriptor from the characteristic.
Definition NimBLECharacteristic.cpp:136
bool indicate(const T &s, uint16_t connHandle=BLE_HS_CONN_HANDLE_NONE) const
Template to send a indication with a value from a class that has a c_str() and length() method.
Definition NimBLECharacteristic.h:174
~NimBLECharacteristic()
Destructor.
Definition NimBLECharacteristic.cpp:53
NimBLEService * getService() const
Get the service that owns this characteristic.
Definition NimBLECharacteristic.cpp:212
bool notify(const T &v, uint16_t connHandle=BLE_HS_CONN_HANDLE_NONE) const
Template to send a notification with a value from a struct or array.
Definition NimBLECharacteristic.h:95
bool indicate(const T &v, uint16_t connHandle=BLE_HS_CONN_HANDLE_NONE) const
Template to send an indication with a value from a struct or array.
Definition NimBLECharacteristic.h:159
NimBLEDescriptor * createDescriptor(const char *uuid, uint32_t properties=NIMBLE_PROPERTY::READ|NIMBLE_PROPERTY::WRITE, uint16_t maxLen=BLE_ATT_ATTR_MAX_LEN)
Create a new BLE Descriptor associated with this characteristic.
Definition NimBLECharacteristic.cpp:66
bool indicate(uint16_t connHandle=BLE_HS_CONN_HANDLE_NONE) const
Send an indication.
Definition NimBLECharacteristic.cpp:226
bool notify(const T &s, uint16_t connHandle=BLE_HS_CONN_HANDLE_NONE) const
Template to send a notification with a value from a class that has a c_str() and length() method.
Definition NimBLECharacteristic.h:110
NimBLECharacteristicCallbacks * getCallbacks() const
Get the callback handlers for this characteristic.
Definition NimBLECharacteristic.cpp:355
bool notify(uint16_t connHandle=BLE_HS_CONN_HANDLE_NONE) const
Send a notification.
Definition NimBLECharacteristic.cpp:248
NimBLE2904 * create2904()
Create a Characteristic Presentation Format Descriptor for this characteristic.
Definition NimBLECharacteristic.cpp:94
NimBLEDescriptor * getDescriptorByUUID(const char *uuid, uint16_t index=0) const
Return the BLE Descriptor for the given UUID.
Definition NimBLECharacteristic.cpp:164
void addDescriptor(NimBLEDescriptor *pDescriptor)
Add a descriptor to the characteristic.
Definition NimBLECharacteristic.cpp:104
std::string toString() const
Return a string representation of the characteristic.
Definition NimBLECharacteristic.cpp:363
Connection information.
Definition NimBLEConnInfo.h:33
A model of a BLE descriptor.
Definition NimBLEDescriptor.h:33
The model of a BLE server.
Definition NimBLEServer.h:62
The model of a BLE service.
Definition NimBLEService.h:34
A model of a BLE UUID.
Definition NimBLEUUID.h:41