Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
BTGattChar.cpp
Go to the documentation of this file.
1 /*
2  * Author: Sven Gothel <sgothel@jausoft.com>
3  * Copyright (c) 2020 Gothel Software e.K.
4  * Copyright (c) 2020 ZAFENA AB
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 #include <cstring>
27 #include <string>
28 #include <memory>
29 #include <cstdint>
30 #include <vector>
31 #include <cstdio>
32 
33 #include <algorithm>
34 
35 #include <jau/debug.hpp>
36 
37 #include "BTDevice.hpp"
38 #include "BTGattChar.hpp"
39 #include "BTGattHandler.hpp"
40 
41 using namespace direct_bt;
42 using namespace jau;
43 
44 #define CHAR_DECL_PROPS_ENUM(X) \
45  X(BTGattChar,Broadcast,broadcast) \
46  X(BTGattChar,Read,read) \
47  X(BTGattChar,WriteNoAck,write-without-response) \
48  X(BTGattChar,WriteWithAck,write) \
49  X(BTGattChar,Notify,notify) \
50  X(BTGattChar,Indicate,indicate) \
51  X(BTGattChar,AuthSignedWrite,authenticated-signed-writes) \
52  X(BTGattChar,ExtProps,extended-properties)
53 
54 /**
55  "reliable-write"
56  "writable-auxiliaries"
57  "encrypt-read"
58  "encrypt-write"
59  "encrypt-authenticated-read"
60  "encrypt-authenticated-write"
61  "secure-read" (Server only)
62  "secure-write" (Server only)
63  "authorize"
64  */
65 
66 #define CASE2_TO_STRING2(U,V,W) case U::V: return #W;
67 
68 static std::string _getPropertyBitValStr(const BTGattChar::PropertyBitVal prop) noexcept {
69  switch(prop) {
71  default: ; // fall through intended
72  }
73  return "Unknown property";
74 }
75 
76 std::string BTGattChar::getPropertiesString(const PropertyBitVal properties) noexcept {
77  const PropertyBitVal none = static_cast<PropertyBitVal>(0);
78  const uint8_t one = 1;
79  bool has_pre = false;
80  std::string out("[");
81  for(int i=0; i<8; i++) {
82  const PropertyBitVal propertyBit = static_cast<PropertyBitVal>( one << i );
83  if( none != ( properties & propertyBit ) ) {
84  if( has_pre ) { out.append(", "); }
85  out.append(_getPropertyBitValStr(propertyBit));
86  has_pre = true;
87  }
88  }
89  out.append("]");
90  return out;
91 }
92 
95  const PropertyBitVal none = static_cast<PropertyBitVal>(0);
96  const uint8_t one = 1;
97  for(int i=0; i<8; i++) {
98  const PropertyBitVal propertyBit = static_cast<PropertyBitVal>( one << i );
99  if( none != ( properties & propertyBit ) ) {
100  out.push_back( std::unique_ptr<std::string>( new std::string( _getPropertyBitValStr(propertyBit) ) ) );
101  }
102  }
103  return out;
104 }
105 
106 std::string BTGattChar::toString() const noexcept {
107  uint16_t service_handle_end = 0xffff;
108  BTGattServiceRef serviceRef = getServiceUnchecked();
109  std::string service_uuid_str = "";
110  std::string service_name = "";
111  std::string char_name = "";
112  std::string desc_str = ", descr[ ";
113 
114  if( nullptr != serviceRef ) {
115  std::unique_ptr<const uuid_t> & service_uuid = serviceRef->type;
116  service_uuid_str = service_uuid->toString();
117  service_handle_end = serviceRef->endHandle;
118 
119  if( uuid_t::TypeSize::UUID16_SZ == service_uuid->getTypeSize() ) {
120  const uint16_t uuid16 = (static_cast<const uuid16_t*>(service_uuid.get()))->value;
121  service_name = ", "+GattServiceTypeToString(static_cast<GattServiceType>(uuid16));
122  }
123  }
124  if( uuid_t::TypeSize::UUID16_SZ == value_type->getTypeSize() ) {
125  const uint16_t uuid16 = (static_cast<const uuid16_t*>(value_type.get()))->value;
126  char_name = ", "+GattCharacteristicTypeToString(static_cast<GattCharacteristicType>(uuid16));
127  }
128  for(size_t i=0; i<descriptorList.size(); i++) {
129  const BTGattDescRef cd = descriptorList[i];
130  desc_str += cd->toString() + ", ";
131  }
132  desc_str += " ]";
133  return "[handle "+to_hexstring(handle)+", props "+to_hexstring(properties)+" "+getPropertiesString(properties)+
134  ", value[type 0x"+value_type->toString()+", handle "+to_hexstring(value_handle)+char_name+desc_str+
135  "], service[type 0x"+service_uuid_str+
136  ", handle[ "+to_hexstring(service_handle)+".."+to_hexstring(service_handle_end)+" ]"+
137  service_name+", enabled[notify "+std::to_string(enabledNotifyState)+", indicate "+std::to_string(enabledIndicateState)+"] ] ]";
138 }
139 
140 std::string BTGattChar::toShortString() const noexcept {
141  std::string char_name = "";
142 
143  if( uuid_t::TypeSize::UUID16_SZ == value_type->getTypeSize() ) {
144  const uint16_t uuid16 = (static_cast<const uuid16_t*>(value_type.get()))->value;
145  char_name = ", "+GattCharacteristicTypeToString(static_cast<GattCharacteristicType>(uuid16));
146  }
147  return "[handle "+to_hexstring(handle)+", props "+to_hexstring(properties)+" "+getPropertiesString(properties)+
148  ", value[handle "+to_hexstring(value_handle)+char_name+
149  "], service["+
150  ", handle[ "+to_hexstring(service_handle)+".. ]"+
151  ", enabled[notify "+std::to_string(enabledNotifyState)+", indicate "+std::to_string(enabledIndicateState)+"] ] ]";
152 }
153 
154 std::shared_ptr<BTGattService> BTGattChar::getServiceChecked() const {
155  std::shared_ptr<BTGattService> ref = wbr_service.lock();
156  if( nullptr == ref ) {
157  throw IllegalStateException("GATTCharacteristic's service already destructed: "+toShortString(), E_FILE_LINE);
158  }
159  return ref;
160 }
161 
162 std::shared_ptr<BTGattHandler> BTGattChar::getGattHandlerUnchecked() const noexcept {
163  std::shared_ptr<BTGattService> s = getServiceUnchecked();
164  if( nullptr != s ) {
165  return s->getGattHandlerUnchecked();
166  }
167  return nullptr;
168 }
169 
170 std::shared_ptr<BTGattHandler> BTGattChar::getGattHandlerChecked() const {
171  return getServiceChecked()->getGattHandlerChecked();
172 }
173 
174 std::shared_ptr<BTDevice> BTGattChar::getDeviceUnchecked() const noexcept {
175  std::shared_ptr<BTGattService> s = getServiceUnchecked();
176  if( nullptr != s ) {
177  return s->getDeviceUnchecked();
178  }
179  return nullptr;
180 }
181 
182 std::shared_ptr<BTDevice> BTGattChar::getDeviceChecked() const {
183  return getServiceChecked()->getDeviceChecked();
184 }
185 
186 bool BTGattChar::configNotificationIndication(const bool enableNotification, const bool enableIndication, bool enabledState[2]) {
187  enabledState[0] = false;
188  enabledState[1] = false;
189 
190  const bool hasEnableNotification = hasProperties(BTGattChar::PropertyBitVal::Notify);
191  const bool hasEnableIndication = hasProperties(BTGattChar::PropertyBitVal::Indicate);
192  if( !hasEnableNotification && !hasEnableIndication ) {
193  DBG_PRINT("Characteristic has neither Notify nor Indicate property present: %s", toString().c_str());
194  return false;
195  }
196 
197  std::shared_ptr<BTDevice> device = getDeviceUnchecked();
198  std::shared_ptr<BTGattHandler> gatt = nullptr != device ? device->getGattHandler() : nullptr;
199  if( nullptr == gatt ) {
200  if( !enableNotification && !enableIndication ) {
201  // OK to have GATTHandler being shutdown @ disable
202  DBG_PRINT("Characteristic's device GATTHandle not connected: %s", toShortString().c_str());
203  return false;
204  }
205  throw IllegalStateException("Characteristic's device GATTHandle not connected: "+
206  toString(), E_FILE_LINE);
207  }
208  const bool resEnableNotification = hasEnableNotification && enableNotification;
209  const bool resEnableIndication = hasEnableIndication && enableIndication;
210 
211  if( resEnableNotification == enabledNotifyState &&
212  resEnableIndication == enabledIndicateState )
213  {
214  enabledState[0] = resEnableNotification;
215  enabledState[1] = resEnableIndication;
216  DBG_PRINT("GATTCharacteristic::configNotificationIndication: Unchanged: notification[shall %d, has %d: %d == %d], indication[shall %d, has %d: %d == %d]",
217  enableNotification, hasEnableNotification, enabledNotifyState, resEnableNotification,
218  enableIndication, hasEnableIndication, enabledIndicateState, resEnableIndication);
219  return true;
220  }
221 
222  BTGattDescRef cccd = this->getClientCharConfig();
223  if( nullptr == cccd ) {
224  DBG_PRINT("Characteristic has no ClientCharacteristicConfig descriptor: %s", toString().c_str());
225  return false;
226  }
227  bool res = gatt->configNotificationIndication(*cccd, resEnableNotification, resEnableIndication);
228  DBG_PRINT("GATTCharacteristic::configNotificationIndication: res %d, notification[shall %d, has %d: %d -> %d], indication[shall %d, has %d: %d -> %d]",
229  res,
230  enableNotification, hasEnableNotification, enabledNotifyState, resEnableNotification,
231  enableIndication, hasEnableIndication, enabledIndicateState, resEnableIndication);
232  if( res ) {
233  enabledNotifyState = resEnableNotification;
234  enabledIndicateState = resEnableIndication;
235  enabledState[0] = resEnableNotification;
236  enabledState[1] = resEnableIndication;
237  }
238  return res;
239 }
240 
241 bool BTGattChar::enableNotificationOrIndication(bool enabledState[2]) {
242  const bool hasEnableNotification = hasProperties(BTGattChar::PropertyBitVal::Notify);
243  const bool hasEnableIndication = hasProperties(BTGattChar::PropertyBitVal::Indicate);
244 
245  const bool enableNotification = hasEnableNotification;
246  const bool enableIndication = !enableNotification && hasEnableIndication;
247 
248  return configNotificationIndication(enableNotification, enableIndication, enabledState);
249 }
250 
252  private:
253  const BTGattChar * associatedChar;
254  std::shared_ptr<BTGattChar::Listener> delegate;
255 
256  public:
257  DelegatedBTGattCharListener(const BTGattChar * characteristicMatch, std::shared_ptr<BTGattChar::Listener> l) noexcept
258  : associatedChar(characteristicMatch), delegate(l) { }
259 
260  bool match(const BTGattChar & characteristic) noexcept override {
261  if( nullptr == associatedChar ) {
262  return true;
263  }
264  return *associatedChar == characteristic;
265  }
266 
268  const TROOctets& charValue, const uint64_t timestamp) override {
269  delegate->notificationReceived(charDecl, charValue, timestamp);
270  }
271 
273  const TROOctets& charValue, const uint64_t timestamp,
274  const bool confirmationSent) override {
275  delegate->indicationReceived(charDecl, charValue, timestamp, confirmationSent);
276  }
277 
278  bool operator==(const DelegatedBTGattCharListener& rhs) const noexcept
279  { return delegate.get() == rhs.delegate.get(); }
280 
281  bool operator!=(const DelegatedBTGattCharListener& rhs) const noexcept
282  { return !(*this == rhs); }
283 };
284 
285 bool BTGattChar::addCharListener(std::shared_ptr<BTGattChar::Listener> l) {
286  return getDeviceChecked()->addCharListener( std::shared_ptr<BTGattCharListener>( new DelegatedBTGattCharListener(this, l) ) );
287 }
288 
289 bool BTGattChar::addCharListener(std::shared_ptr<BTGattChar::Listener> l, bool enabledState[2]) {
290  if( !enableNotificationOrIndication(enabledState) ) {
291  return false;
292  }
293  return addCharListener(l);
294 }
295 
296 int BTGattChar::removeAllAssociatedCharListener(bool disableIndicationNotification) {
297  if( disableIndicationNotification ) {
298  bool enabledState[2];
299  configNotificationIndication(false, false, enabledState);
300  }
301  return getDeviceChecked()->removeAllAssociatedCharListener(this);
302 }
303 
304 bool BTGattChar::readValue(POctets & res, int expectedLength) {
305  std::shared_ptr<BTDevice> device = getDeviceChecked();
306  std::shared_ptr<BTGattHandler> gatt = device->getGattHandler();
307  if( nullptr == gatt ) {
308  throw IllegalStateException("Characteristic's device GATTHandle not connected: "+toShortString(), E_FILE_LINE);
309  }
310  return gatt->readCharacteristicValue(*this, res, expectedLength);
311 }
312 /**
313  * BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.3 Write Characteristic Value
314  */
315 bool BTGattChar::writeValue(const TROOctets & value) {
316  std::shared_ptr<BTDevice> device = getDeviceChecked();
317  std::shared_ptr<BTGattHandler> gatt = device->getGattHandler();
318  if( nullptr == gatt ) {
319  throw IllegalStateException("Characteristic's device GATTHandle not connected: "+toShortString(), E_FILE_LINE);
320  }
321  return gatt->writeCharacteristicValue(*this, value);
322 }
323 
324 /**
325  * BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.1 Write Characteristic Value Without Response
326  */
328  std::shared_ptr<BTDevice> device = getDeviceChecked();
329  std::shared_ptr<BTGattHandler> gatt = device->getGattHandler();
330  if( nullptr == gatt ) {
331  throw IllegalStateException("Characteristic's device GATTHandle not connected: "+toShortString(), E_FILE_LINE);
332  }
333  return gatt->writeCharacteristicValueNoResp(*this, value);
334 }
direct_bt::BTGattChar::getPropertiesString
static std::string getPropertiesString(const PropertyBitVal properties) noexcept
Returns string values as defined in https://git.kernel.org/pub/scm/bluetooth/bluez....
Definition: BTGattChar.cpp:76
BTGattHandler.hpp
direct_bt::GattServiceType
GattServiceType
GATT Service Type, each encapsulating a set of Characteristics.
Definition: GattNumbers.hpp:64
Notify
@ Notify
Definition: test_datatype02.hpp:109
direct_bt::BTGattChar::readValue
bool readValue(POctets &res, int expectedLength=-1)
BT Core Spec v5.2: Vol 3, Part G GATT: 4.8.1 Read Characteristic Value.
Definition: BTGattChar.cpp:304
direct_bt
Definition: ATTPDUTypes.hpp:171
direct_bt::BTGattChar
Definition: BTGattChar.hpp:75
direct_bt::GattCharacteristicTypeToString
std::string GattCharacteristicTypeToString(const GattCharacteristicType v) noexcept
Definition: GATTNumbers.cpp:239
DelegatedBTGattCharListener
Definition: BTGattChar.cpp:251
direct_bt::BTGattServiceRef
std::shared_ptr< BTGattService > BTGattServiceRef
Definition: BTGattChar.hpp:60
direct_bt::uuid16_t
Definition: UUID.hpp:98
jau
Definition: basic_algos.hpp:34
direct_bt::uuid_t::getTypeSize
TypeSize getTypeSize() const noexcept
Definition: UUID.hpp:88
direct_bt::BTGattChar::getGattHandlerChecked
std::shared_ptr< BTGattHandler > getGattHandlerChecked() const
Definition: BTGattChar.cpp:170
DelegatedBTGattCharListener::notificationReceived
void notificationReceived(BTGattCharRef charDecl, const TROOctets &charValue, const uint64_t timestamp) override
Called from native BLE stack, initiated by a received notification associated with the given BTGattCh...
Definition: BTGattChar.cpp:267
direct_bt::BTGattHandler::readCharacteristicValue
bool readCharacteristicValue(const BTGattChar &c, POctets &res, int expectedLength=-1)
BT Core Spec v5.2: Vol 3, Part G GATT: 4.8.1 Read Characteristic Value.
Definition: BTGattHandler.cpp:753
direct_bt::GattCharacteristicType
GattCharacteristicType
GATT Assigned Characteristic Attribute Type for single logical value.
Definition: GattNumbers.hpp:88
jau::to_string
PRAGMA_DISABLE_WARNING_POP constexpr_cxx20 std::string to_string(const endian &v) noexcept
Return std::string representation of the given jau::endian.
Definition: byte_util.hpp:198
direct_bt::BTGattChar::addCharListener
bool addCharListener(std::shared_ptr< Listener > l)
Add the given BTGattChar::Listener to the listener list if not already present.
Definition: BTGattChar.cpp:285
direct_bt::BTGattChar::getDeviceChecked
std::shared_ptr< BTDevice > getDeviceChecked() const
Definition: BTGattChar.cpp:182
direct_bt::BTGattChar::removeAllAssociatedCharListener
int removeAllAssociatedCharListener(bool disableIndicationNotification)
Disables the notification and/or indication for this characteristic at BLE level if disableIndication...
Definition: BTGattChar.cpp:296
direct_bt::BTGattChar::getGattHandlerUnchecked
std::shared_ptr< BTGattHandler > getGattHandlerUnchecked() const noexcept
Definition: BTGattChar.cpp:162
E_FILE_LINE
#define E_FILE_LINE
Definition: basic_types.hpp:64
jau::darray
Implementation of a dynamic linear array storage, aka vector.
Definition: darray.hpp:102
jau::darray::push_back
constexpr void push_back(const value_type &x)
Like std::vector::push_back(), copy.
Definition: darray.hpp:991
DelegatedBTGattCharListener::DelegatedBTGattCharListener
DelegatedBTGattCharListener(const BTGattChar *characteristicMatch, std::shared_ptr< BTGattChar::Listener > l) noexcept
Definition: BTGattChar.cpp:257
direct_bt::BTGattCharRef
std::shared_ptr< BTGattChar > BTGattCharRef
Definition: BTGattChar.hpp:409
CHAR_DECL_PROPS_ENUM
#define CHAR_DECL_PROPS_ENUM(X)
Definition: BTGattChar.cpp:44
direct_bt::BTGattChar::getServiceChecked
std::shared_ptr< BTGattService > getServiceChecked() const
Definition: BTGattChar.cpp:154
direct_bt::BTGattCharListener
BTGattChar event listener for notification and indication events.
Definition: BTGattChar.hpp:435
direct_bt::BTGattChar::getPropertiesStringList
static jau::darray< std::unique_ptr< std::string > > getPropertiesStringList(const PropertyBitVal properties) noexcept
Definition: BTGattChar.cpp:93
Indicate
@ Indicate
Definition: test_datatype02.hpp:110
direct_bt::BTGattChar::Listener::notificationReceived
virtual void notificationReceived(BTGattCharRef charDecl, const TROOctets &charValue, const uint64_t timestamp)=0
Called from native BLE stack, initiated by a received notification associated with the given BTGattCh...
direct_bt::BTGattChar::PropertyBitVal
PropertyBitVal
BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.1.1 Characteristic Properties.
Definition: BTGattChar.hpp:86
direct_bt::BTGattChar::Listener::indicationReceived
virtual void indicationReceived(BTGattCharRef charDecl, const TROOctets &charValue, const uint64_t timestamp, const bool confirmationSent)=0
Called from native BLE stack, initiated by a received indication associated with the given BTGattChar...
direct_bt::BTGattChar::toString
std::string toString() const noexcept override
Definition: BTGattChar.cpp:106
direct_bt::BTGattHandler::writeCharacteristicValueNoResp
bool writeCharacteristicValueNoResp(const BTGattChar &c, const TROOctets &value)
BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.1 Write Characteristic Value Without Response.
Definition: BTGattHandler.cpp:859
debug.hpp
direct_bt::TROOctets
Transient read only octet data, i.e.
Definition: OctetTypes.hpp:59
DelegatedBTGattCharListener::match
bool match(const BTGattChar &characteristic) noexcept override
Custom filter for all event methods, which will not be called if this method returns false.
Definition: BTGattChar.cpp:260
jau::IllegalStateException
Definition: basic_types.hpp:117
charValue
static int charValue
Definition: dbt_scanner10.cpp:121
BTGattChar.hpp
jau::to_hexstring
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
Definition: string_util.hpp:104
DelegatedBTGattCharListener::operator==
bool operator==(const DelegatedBTGattCharListener &rhs) const noexcept
Definition: BTGattChar.cpp:278
direct_bt::BTGattChar::writeValue
bool writeValue(const TROOctets &value)
BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.3 Write Characteristic Value.
Definition: BTGattChar.cpp:315
direct_bt::uuid_t::toString
virtual std::string toString() const noexcept
Definition: UUID.hpp:94
DelegatedBTGattCharListener::operator!=
bool operator!=(const DelegatedBTGattCharListener &rhs) const noexcept
Definition: BTGattChar.cpp:281
direct_bt::BTGattChar::configNotificationIndication
bool configNotificationIndication(const bool enableNotification, const bool enableIndication, bool enabledState[2])
BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration.
Definition: BTGattChar.cpp:186
CASE2_TO_STRING2
#define CASE2_TO_STRING2(U, V, W)
"reliable-write" "writable-auxiliaries" "encrypt-read" "encrypt-write" "encrypt-authenticated-read" "...
Definition: BTGattChar.cpp:66
direct_bt::BTDevice::getGattHandler
std::shared_ptr< BTGattHandler > getGattHandler() noexcept
Returns the connected GATTHandler or nullptr, see connectGATT(), getGattService() and disconnect().
Definition: BTDevice.cpp:1520
direct_bt::BTGattHandler::writeCharacteristicValue
bool writeCharacteristicValue(const BTGattChar &c, const TROOctets &value)
BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.3 Write Characteristic Value.
Definition: BTGattHandler.cpp:849
direct_bt::BTGattChar::writeValueNoResp
bool writeValueNoResp(const TROOctets &value)
BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.1 Write Characteristic Value Without Response.
Definition: BTGattChar.cpp:327
direct_bt::uuid_t::TypeSize::UUID16_SZ
@ UUID16_SZ
direct_bt::BTGattService::getDeviceUnchecked
std::shared_ptr< BTDevice > getDeviceUnchecked() const noexcept
Definition: BTGattService.cpp:54
direct_bt::GattServiceTypeToString
std::string GattServiceTypeToString(const GattServiceType v) noexcept
Definition: GATTNumbers.cpp:207
direct_bt::POctets
Persistent octet data, i.e.
Definition: OctetTypes.hpp:451
DelegatedBTGattCharListener::indicationReceived
void indicationReceived(BTGattCharRef charDecl, const TROOctets &charValue, const uint64_t timestamp, const bool confirmationSent) override
Called from native BLE stack, initiated by a received indication associated with the given BTGattChar...
Definition: BTGattChar.cpp:272
direct_bt::BTGattHandler::configNotificationIndication
bool configNotificationIndication(BTGattDesc &cd, const bool enableNotification, const bool enableIndication)
BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration.
Definition: BTGattHandler.cpp:908
direct_bt::BTGattService::getGattHandlerUnchecked
std::shared_ptr< BTGattHandler > getGattHandlerUnchecked() const noexcept
Definition: BTGattService.hpp:112
direct_bt::BTGattChar::enableNotificationOrIndication
bool enableNotificationOrIndication(bool enabledState[2])
BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration.
Definition: BTGattChar.cpp:241
direct_bt::BTGattDescRef
std::shared_ptr< BTGattDesc > BTGattDescRef
Definition: BTGattDesc.hpp:177
BTDevice.hpp
direct_bt::BTGattChar::getDeviceUnchecked
std::shared_ptr< BTDevice > getDeviceUnchecked() const noexcept
Definition: BTGattChar.cpp:174
_getPropertyBitValStr
static std::string _getPropertyBitValStr(const BTGattChar::PropertyBitVal prop) noexcept
Definition: BTGattChar.cpp:68
DBG_PRINT
#define DBG_PRINT(...)
Use for environment-variable environment::DEBUG conditional debug messages, prefix '[elapsed_time] De...
Definition: debug.hpp:78