Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
dbt_scanner01.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 <cinttypes>
27 
28 #include <jau/dfa_utf8_decode.hpp>
29 
30 #include <direct_bt/DirectBT.hpp>
31 
32 extern "C" {
33  #include <unistd.h>
34 }
35 
36 using namespace direct_bt;
37 using namespace jau;
38 
39 /**
40  * This C++ direct_bt scanner example is a TinyB backward compatible and not fully event driven.
41  * It uses a more fine grained control via BTGattHandler
42  * <p>
43  * For a more user convenient and readable approach see dbt_scanner00.cpp or dbt_scanner10.cpp!
44  * </p>
45  * <p>
46  * This example does not represent the recommended utilization of Direct-BT.
47  * </p>
48  */
49 
50 std::shared_ptr<BTDevice> deviceFound = nullptr;
51 std::mutex mtxDeviceFound;
52 std::condition_variable cvDeviceFound;
53 
55  void adapterSettingsChanged(BTAdapter &a, const AdapterSetting oldmask, const AdapterSetting newmask,
56  const AdapterSetting changedmask, const uint64_t timestamp) override {
57  fprintf(stderr, "****** Native Adapter SETTINGS_CHANGED: %s -> %s, changed %s\n",
58  to_string(oldmask).c_str(),
59  to_string(newmask).c_str(),
60  to_string(changedmask).c_str());
61  fprintf(stderr, "Status BTAdapter:\n");
62  fprintf(stderr, "%s\n", a.toString().c_str());
63  (void)timestamp;
64  }
65 
66  void discoveringChanged(BTAdapter &a, const ScanType currentMeta, const ScanType changedType, const bool changedEnabled, const bool keepAlive, const uint64_t timestamp) override {
67  fprintf(stderr, "****** DISCOVERING: meta %s, changed[%s, enabled %d, keepAlive %d]: %s\n",
68  to_string(currentMeta).c_str(), to_string(changedType).c_str(), changedEnabled, keepAlive, a.toString().c_str());
69  (void)timestamp;
70  }
71 
72  bool deviceFound(std::shared_ptr<BTDevice> device, const uint64_t timestamp) override {
73  fprintf(stderr, "****** FOUND__: %s\n", device->toString(true).c_str());
74  fprintf(stderr, "Status Adapter:\n");
75  fprintf(stderr, "%s\n", device->getAdapter().toString().c_str());
76  {
77  std::unique_lock<std::mutex> lockRead(mtxDeviceFound); // RAII-style acquire and relinquish via destructor
78  ::deviceFound = device;
79  cvDeviceFound.notify_all(); // notify waiting getter
80  return true;
81  }
82  (void)timestamp;
83  }
84  void deviceUpdated(std::shared_ptr<BTDevice> device, const EIRDataType updateMask, const uint64_t timestamp) override {
85  fprintf(stderr, "****** UPDATED: %s of %s\n", to_string(updateMask).c_str(), device->toString(true).c_str());
86  (void)timestamp;
87  }
88  void deviceConnected(std::shared_ptr<BTDevice> device, const uint16_t handle, const uint64_t timestamp) override {
89  fprintf(stderr, "****** CONNECTED: %s\n", device->toString(true).c_str());
90  (void)handle;
91  (void)timestamp;
92  }
93  void devicePairingState(std::shared_ptr<BTDevice> device, const SMPPairingState state, const PairingMode mode, const uint64_t timestamp) override {
94  fprintf(stderr, "****** PAIRING STATE: state %s, mode %s, %s\n",
95  to_string(state).c_str(), to_string(mode).c_str(), device->toString().c_str());
96  (void)timestamp;
97  }
98  void deviceReady(std::shared_ptr<BTDevice> device, const uint64_t timestamp) override {
99  fprintf(stderr, "****** READY: %s\n", device->toString().c_str());
100  (void)timestamp;
101  }
102  void deviceDisconnected(std::shared_ptr<BTDevice> device, const HCIStatusCode reason, const uint16_t handle, const uint64_t timestamp) override {
103  fprintf(stderr, "****** DISCONNECTED: Reason 0x%X (%s), old handle %s: %s\n",
104  static_cast<uint8_t>(reason), to_string(reason).c_str(),
105  to_hexstring(handle).c_str(), device->toString(true).c_str());
106  (void)handle;
107  (void)timestamp;
108  }
109 
110  std::string toString() const override {
111  return "MyAdapterStatusListener[this "+to_hexstring(this)+"]";
112  }
113 };
114 
116 
118 
119  void notificationReceived(BTGattCharRef charDecl,
120  const TROOctets& charValue, const uint64_t timestamp) override {
121  const std::shared_ptr<BTDevice> dev = charDecl->getDeviceChecked();
122  const uint64_t tR = getCurrentMilliseconds();
123  fprintf(stderr, "****** GATT Notify (td %" PRIu64 " ms, dev-discovered %" PRIu64 " ms): From %s\n",
124  (tR-timestamp), (tR-dev->ts_creation), dev->toString().c_str());
125  if( nullptr != charDecl ) {
126  fprintf(stderr, "****** decl %s\n", charDecl->toString().c_str());
127  }
128  fprintf(stderr, "****** rawv %s\n", charValue.toString().c_str());
129  }
130 
131  void indicationReceived(BTGattCharRef charDecl,
132  const TROOctets& charValue, const uint64_t timestamp,
133  const bool confirmationSent) override
134  {
135  const std::shared_ptr<BTDevice> dev = charDecl->getDeviceChecked();
136  const uint64_t tR = getCurrentMilliseconds();
137  fprintf(stderr, "****** GATT Indication (confirmed %d, td(msg %" PRIu64 " ms, dev-discovered %" PRIu64 " ms): From %s\n",
138  confirmationSent, (tR-timestamp), (tR-dev->ts_creation), dev->toString().c_str());
139  if( nullptr != charDecl ) {
140  fprintf(stderr, "****** decl %s\n", charDecl->toString().c_str());
141  if( _TEMPERATURE_MEASUREMENT == *charDecl->value_type ) {
142  std::shared_ptr<GattTemperatureMeasurement> temp = GattTemperatureMeasurement::get(charValue);
143  if( nullptr != temp ) {
144  fprintf(stderr, "****** valu %s\n", temp->toString().c_str());
145  }
146  }
147  }
148  fprintf(stderr, "****** rawv %s\n", charValue.toString().c_str());
149  }
150 };
151 
152 // #define SHOW_STATIC_SERVICE_CHARACTERISTIC_COMPOSITION 1
153 
154 int main(int argc, char *argv[])
155 {
156  bool ok = true, foundDevice=false;
157  int dev_id = 0; // default
158  bool waitForEnter=false;
160  bool forever = false;
161 
162  /**
163  * BT Core Spec v5.2: Vol 3, Part A L2CAP Spec: 7.9 PRIORITIZING DATA OVER HCI
164  *
165  * In order for guaranteed channels to meet their guarantees,
166  * L2CAP should prioritize traffic over the HCI transport in devices that support HCI.
167  * Packets for Guaranteed channels should receive higher priority than packets for Best Effort channels.
168  * ...
169  * I have noticed that w/o HCI le_connect, overall communication takes twice as long!!!
170  */
171  bool doHCI_Connect = true;
172 
173  for(int i=1; i<argc; i++) {
174  if( !strcmp("-wait", argv[i]) ) {
175  waitForEnter = true;
176  } else if( !strcmp("-forever", argv[i]) ) {
177  forever = true;
178  } else if( !strcmp("-dev_id", argv[i]) && argc > (i+1) ) {
179  dev_id = atoi(argv[++i]);
180  } else if( !strcmp("-skipConnect", argv[i]) ) {
181  doHCI_Connect = false;
182  } else if( !strcmp("-mac", argv[i]) && argc > (i+1) ) {
183  std::string macstr = std::string(argv[++i]);
184  waitForDevice = BDAddressAndType(EUI48(macstr), BDAddressType::BDADDR_UNDEFINED);
185  }
186  }
187  fprintf(stderr, "dev_id %d\n", dev_id);
188  fprintf(stderr, "doHCI_Connect %d\n", doHCI_Connect);
189  fprintf(stderr, "waitForDevice: %s\n", waitForDevice.toString().c_str());
190 
191  if( waitForEnter ) {
192  fprintf(stderr, "Press ENTER to continue\n");
193  getchar();
194  }
195  BTManager & mngr = BTManager::get();
196 
197  std::shared_ptr<BTAdapter> adapter = mngr.getAdapter(dev_id);
198  if( nullptr == adapter ) {
199  fprintf(stderr, "adapter dev_id %d not available.\n", dev_id);
200  exit(1);
201  }
202  if( !adapter->isValid() ) {
203  fprintf(stderr, "Adapter invalid: %s\n", adapter->toString().c_str());
204  exit(1);
205  }
206  if( !adapter->isPowered() ) {
207  fprintf(stderr, "Adapter not powered: %s\n", adapter->toString().c_str());
208  exit(1);
209  }
210  fprintf(stderr, "Using adapter: %s\n", adapter->toString().c_str());
211 
212  adapter->addStatusListener(std::shared_ptr<AdapterStatusListener>(new MyAdapterStatusListener()));
213 
214  const uint64_t t0 = getCurrentMilliseconds();
215 
216  while( ok && ( forever || !foundDevice ) ) {
217  ok = HCIStatusCode::SUCCESS == adapter->startDiscovery(true /* keepAlive */);
218  if( !ok) {
219  perror("Adapter start discovery failed");
220  goto out;
221  }
222 
223  std::shared_ptr<BTDevice> device = nullptr;
224  {
225  std::unique_lock<std::mutex> lockRead(mtxDeviceFound); // RAII-style acquire and relinquish via destructor
226  while( nullptr == device ) { // FIXME deadlock, waiting forever!
227  cvDeviceFound.wait(lockRead);
228  if( nullptr != deviceFound ) {
229  foundDevice = deviceFound->getAddressAndType().matches(waitForDevice); // match
230  if( foundDevice || ( BDAddressAndType::ANY_DEVICE == waitForDevice && deviceFound->getAddressAndType().isLEAddress() ) ) {
231  // match or any LE device
232  device.swap(deviceFound); // take over deviceFound
233  }
234  }
235  }
236  }
237  adapter->stopDiscovery();
238 
239  if( ok && nullptr != device ) {
240  const uint64_t t1 = getCurrentMilliseconds();
241 
242  //
243  // HCI LE-Connect
244  // (Without: Overall communication takes ~twice as long!!!)
245  //
246  if( doHCI_Connect ) {
247  HCIStatusCode res;
248  if( ( res = device->connectDefault() ) != HCIStatusCode::SUCCESS ) {
249  fprintf(stderr, "Connect: Failed res %s, %s\n", to_string(res).c_str(), device->toString().c_str());
250  // we tolerate the failed immediate connect, as it might happen at a later time
251  } else {
252  fprintf(stderr, "Connect: Success\n");
253  }
254  } else {
255  fprintf(stderr, "Connect: Skipped %s\n", device->toString().c_str());
256  }
257  const uint64_t t3 = getCurrentMilliseconds();
258  const uint64_t td03 = t3 - t0;
259  const uint64_t td13 = t3 - t1;
260  const uint64_t td01 = t1 - t0;
261  fprintf(stderr, " discovery-only %" PRIu64 " ms,\n"
262  " connect-only %" PRIu64 " ms,\n"
263  " discovered to hci-connected %" PRIu64 " ms,\n"
264  " total %" PRIu64 " ms,\n",
265  td01, td13, (t3 - device->getCreationTimestamp()), td03);
266 
267  //
268  // GATT Processing
269  //
270  const uint64_t t4 = getCurrentMilliseconds();
271  // let's check further for full GATT
272  std::shared_ptr<BTGattHandler> gatt = device->getGattHandler();
273  if( nullptr != gatt ) {
274  fprintf(stderr, "GATT usedMTU %d (server) -> %d (used)\n", gatt->getServerMTU(), gatt->getUsedMTU());
275 
276  gatt->addCharListener( std::shared_ptr<BTGattCharListener>( new MyGattCharListener() ) );
277 
279  const uint64_t t5 = getCurrentMilliseconds();
280  {
281  const uint64_t td45 = t5 - t4; // connect -> gatt complete
282  const uint64_t td05 = t5 - t0; // total
283  fprintf(stderr, "\n\n\n");
284  fprintf(stderr, "GATT primary-services completed\n");
285  fprintf(stderr, " gatt connect -> gatt complete %" PRIu64 " ms,\n"
286  " discovered to gatt complete %" PRIu64 " ms,\n"
287  " total %" PRIu64 " ms\n\n",
288  td45, (t5 - device->getCreationTimestamp()), td05);
289  }
290  std::shared_ptr<GattGenericAccessSvc> ga = device->getGattGenericAccess();
291  if( nullptr != ga ) {
292  fprintf(stderr, " GenericAccess: %s\n\n", ga->toString().c_str());
293  }
294  if( nullptr != gatt && gatt->isConnected() ) {
295  std::shared_ptr<GattDeviceInformationSvc> di = gatt->getDeviceInformation(primServices);
296  if( nullptr != di ) {
297  fprintf(stderr, " DeviceInformation: %s\n\n", di->toString().c_str());
298  }
299  }
300 
301  for(size_t i=0; i<primServices.size() && gatt->isConnected(); i++) {
302  BTGattService & primService = *primServices.at(i);
303  fprintf(stderr, " [%2.2d] Service %s\n", (int)i, primService.toString().c_str());
304  fprintf(stderr, " [%2.2d] Service Characteristics\n", (int)i);
305  jau::darray<BTGattCharRef> & serviceCharacteristics = primService.characteristicList;
306  for(size_t j=0; j<serviceCharacteristics.size() && gatt->isConnected(); j++) {
307  BTGattChar & serviceChar = *serviceCharacteristics.at(j);
308  fprintf(stderr, " [%2.2d.%2.2d] Decla: %s\n", (int)i, (int)j, serviceChar.toString().c_str());
311  if( gatt->readCharacteristicValue(serviceChar, value) ) {
312  fprintf(stderr, " [%2.2d.%2.2d] Value: %s\n", (int)i, (int)j, value.toString().c_str());
313  }
314  }
315  BTGattDescRef cccd = serviceChar.getClientCharConfig();
316  if( nullptr != cccd ) {
317  const bool enableNotification = serviceChar.hasProperties(BTGattChar::PropertyBitVal::Notify);
318  const bool enableIndication = serviceChar.hasProperties(BTGattChar::PropertyBitVal::Indicate);
319  if( enableNotification || enableIndication ) {
320  bool res = gatt->configNotificationIndication(*cccd, enableNotification, enableIndication);
321  fprintf(stderr, " [%2.2d.%2.2d] Config Notification(%d), Indication(%d): Result %d\n",
322  (int)i, (int)j, enableNotification, enableIndication, res);
323  }
324  }
325  }
326  }
327  // FIXME sleep 1s for potential callbacks ..
328  sleep(1);
329  } else {
330  fprintf(stderr, "GATT connect failed: %s\n", gatt->getStateString().c_str());
331  }
332  device->disconnect(); // OK if not connected, also issues device->disconnectGATT() -> gatt->disconnect()
333  device->remove(); // implicit disconnect as well
334  } // if( ok && nullptr != device )
335  }
336 
337 #ifdef SHOW_STATIC_SERVICE_CHARACTERISTIC_COMPOSITION
338  //
339  // Show static composition of Services and Characteristics
340  //
341  for(size_t i=0; i<GATT_SERVICES.size(); i++) {
342  const GattServiceCharacteristic * gsc = GATT_SERVICES.at(i);
343  fprintf(stderr, "GattServiceCharacteristic %d: %s\n", (int)i, gsc->toString().c_str());
344  }
345 #endif /* SHOW_STATIC_SERVICE_CHARACTERISTIC_COMPOSITION */
346 
347 out:
348  return 0;
349 }
350 
direct_bt::BTGattService::characteristicList
jau::darray< BTGattCharRef > characteristicList
List of Characteristic Declarations as shared reference.
Definition: BTGattService.hpp:97
direct_bt::BTAdapter::stopDiscovery
HCIStatusCode stopDiscovery() noexcept
Closes the discovery session.
Definition: BTAdapter.cpp:756
direct_bt::BTDevice::connectDefault
HCIStatusCode connectDefault() noexcept
Establish a default HCI connection to this device, using certain default parameter.
Definition: BTDevice.cpp:532
jau::darray::at
const_reference at(size_type i) const
Like std::vector::at(size_type), immutable reference.
Definition: darray.hpp:719
direct_bt::AdapterSetting
AdapterSetting
Adapter Setting Bits.
Definition: BTTypes1.hpp:136
DirectBT.hpp
direct_bt::BTGattHandler::getDeviceInformation
std::shared_ptr< GattDeviceInformationSvc > getDeviceInformation(jau::darray< BTGattServiceRef > &primServices)
Definition: BTGattHandler.cpp:1096
direct_bt::BTGattChar::hasProperties
bool hasProperties(const PropertyBitVal v) const noexcept
Definition: BTGattChar.hpp:216
direct_bt::BTDevice::remove
void remove() noexcept
Disconnects this device via disconnect(..) if getConnected()==true and explicitly removes its shared ...
Definition: BTDevice.cpp:1784
Notify
@ Notify
Definition: test_datatype02.hpp:109
direct_bt::GattGenericAccessSvc::toString
std::string toString() const noexcept
Definition: GATTNumbers.cpp:382
direct_bt::GattTemperatureMeasurement::get
static std::shared_ptr< GattTemperatureMeasurement > get(const TROOctets &source) noexcept
Definition: GATTNumbers.cpp:414
direct_bt::BDAddressAndType::ANY_DEVICE
static const BDAddressAndType ANY_DEVICE
Using EUI48::ANY_DEVICE and BDAddressType::BDADDR_UNDEFINED to match any device.
Definition: BTAddress.hpp:426
direct_bt::GattServiceCharacteristic::toString
std::string toString() const noexcept
Definition: GATTNumbers.cpp:304
direct_bt::EIRDataType
EIRDataType
Bit mask of 'Extended Inquiry Response' (EIR) data fields, indicating a set of related data.
Definition: BTTypes0.hpp:752
_TEMPERATURE_MEASUREMENT
static const uuid16_t _TEMPERATURE_MEASUREMENT(GattCharacteristicType::TEMPERATURE_MEASUREMENT)
dfa_utf8_decode.hpp
direct_bt
Definition: ATTPDUTypes.hpp:171
direct_bt::BTGattChar
Definition: BTGattChar.hpp:75
direct_bt::AdapterStatusListener
BTAdapter status listener for BTDevice discovery events: Added, updated and removed; as well as for c...
Definition: BTAdapter.hpp:67
direct_bt::GattServiceCharacteristic
Definition: GattNumbers.hpp:195
MyGattCharListener
Definition: dbt_scanner01.cpp:117
direct_bt::uuid16_t
Definition: UUID.hpp:98
direct_bt::BDAddressAndType::toString
std::string toString() const noexcept
Definition: BTTypes0.cpp:333
jau
Definition: basic_algos.hpp:34
direct_bt::BTDevice::getCreationTimestamp
uint64_t getCreationTimestamp() const noexcept
Returns the timestamp in monotonic milliseconds when this device instance has been created,...
Definition: BTDevice.hpp:253
direct_bt::BTGattService
Representing a complete [Primary] Service Declaration including its list of Characteristic Declaratio...
Definition: BTGattService.hpp:67
direct_bt::ScanType
ScanType
Meta ScanType as derived from BTMode, with defined value mask consisting of BDAddressType bits.
Definition: BTTypes0.hpp:294
direct_bt::BTDevice::toString
std::string toString() const noexcept override
Definition: BTDevice.hpp:303
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::BTAdapter::isPowered
bool isPowered() const noexcept
Returns whether the adapter is valid, plugged in and powered.
Definition: BTAdapter.hpp:437
direct_bt::HCIStatusCode
HCIStatusCode
BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes.
Definition: HCITypes.hpp:124
jau::darray< BTGattServiceRef >
direct_bt::BTGattCharRef
std::shared_ptr< BTGattChar > BTGattCharRef
Definition: BTGattChar.hpp:409
direct_bt::BTDevice::getGattGenericAccess
std::shared_ptr< GattGenericAccessSvc > getGattGenericAccess()
Returns the shared GenericAccess instance, retrieved by getGattService() or nullptr if not available.
Definition: BTDevice.cpp:1590
direct_bt::BTGattCharListener
BTGattChar event listener for notification and indication events.
Definition: BTGattChar.hpp:435
TEMPERATURE_MEASUREMENT
@ TEMPERATURE_MEASUREMENT
Definition: test_datatype02.hpp:82
direct_bt::BTGattHandler::getServerMTU
uint16_t getServerMTU() const noexcept
Definition: BTGattHandler.hpp:265
direct_bt::BTAdapter::toString
std::string toString() const noexcept override
Definition: BTAdapter.hpp:784
direct_bt::BTGattHandler::Defaults::MAX_ATT_MTU
@ MAX_ATT_MTU
main
int main(int argc, char *argv[])
Definition: dbt_scanner01.cpp:154
direct_bt::BTManager::get
static BTManager & get(const BTMode defaultBTMode=BTMode::NONE)
Retrieves the singleton instance.
Definition: BTManager.hpp:320
Indicate
@ Indicate
Definition: test_datatype02.hpp:110
direct_bt::BTDevice::disconnect
HCIStatusCode disconnect(const HCIStatusCode reason=HCIStatusCode::REMOTE_USER_TERMINATED_CONNECTION) noexcept
Disconnect the LE or BREDR peer's GATT and HCI connection.
Definition: BTDevice.cpp:1701
mtxDeviceFound
std::mutex mtxDeviceFound
Definition: dbt_scanner01.cpp:51
direct_bt::BTDevice::ts_creation
const uint64_t ts_creation
Definition: BTDevice.hpp:220
direct_bt::GattDeviceInformationSvc::toString
std::string toString() const noexcept
Definition: GATTNumbers.cpp:407
jau::darray::size
constexpr size_type size() const noexcept
Like std::vector::size().
Definition: darray.hpp:668
Read
@ Read
Definition: test_datatype02.hpp:106
direct_bt::PairingMode
PairingMode
Bluetooth secure pairing mode.
Definition: BTTypes0.hpp:261
MyAdapterStatusListener
Definition: dbt_scanner00.cpp:55
direct_bt::BTManager
A thread safe singleton handler of the Linux Kernel's BlueZ manager control channel.
Definition: BTManager.hpp:201
direct_bt::BTGattChar::getClientCharConfig
BTGattDescRef getClientCharConfig() noexcept
Definition: BTGattChar.hpp:225
direct_bt::BTAdapter::addStatusListener
bool addStatusListener(std::shared_ptr< AdapterStatusListener > l)
Add the given listener to the list if not already present.
Definition: BTAdapter.cpp:548
direct_bt::BTGattChar::toString
std::string toString() const noexcept override
Definition: BTGattChar.cpp:106
direct_bt::BTGattHandler::addCharListener
bool addCharListener(std::shared_ptr< BTGattCharListener > l)
Add the given listener to the list if not already present.
Definition: BTGattHandler.cpp:105
direct_bt::BTGattHandler::getUsedMTU
uint16_t getUsedMTU() const noexcept
Definition: BTGattHandler.hpp:266
direct_bt::TROOctets
Transient read only octet data, i.e.
Definition: OctetTypes.hpp:59
direct_bt::to_string
std::string to_string(const BDAddressType type) noexcept
Definition: BTTypes0.cpp:129
direct_bt::BTAdapter
BTAdapter represents one Bluetooth Controller.
Definition: BTAdapter.hpp:250
direct_bt::BTGattHandler::getStateString
std::string getStateString() const noexcept
Definition: BTGattHandler.hpp:255
direct_bt::GATT_SERVICES
const jau::darray< const GattServiceCharacteristic * > GATT_SERVICES
Definition: GATTNumbers.cpp:196
jau::getCurrentMilliseconds
uint64_t getCurrentMilliseconds() noexcept
Returns current monotonic time in milliseconds.
Definition: basic_types.cpp:47
charValue
static int charValue
Definition: dbt_scanner10.cpp:121
direct_bt::EUI48
A packed 48 bit EUI-48 identifier, formerly known as MAC-48 or simply network device MAC address (Med...
Definition: BTAddress.hpp:388
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
direct_bt::BTAdapter::isValid
bool isValid() const noexcept
Returns whether the adapter is valid, i.e.
Definition: BTAdapter.hpp:480
direct_bt::BTGattService::toString
std::string toString() const noexcept override
Definition: BTGattService.cpp:66
direct_bt::BTGattHandler::isConnected
bool isConnected() const noexcept
Definition: BTGattHandler.hpp:253
direct_bt::HCIStatusCode::SUCCESS
@ SUCCESS
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
deviceFound
std::shared_ptr< BTDevice > deviceFound
This C++ direct_bt scanner example is a TinyB backward compatible and not fully event driven.
Definition: dbt_scanner01.cpp:50
direct_bt::POctets::toString
std::string toString() const
Definition: OctetTypes.hpp:666
direct_bt::POctets
Persistent octet data, i.e.
Definition: OctetTypes.hpp:451
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::BTAdapter::startDiscovery
HCIStatusCode startDiscovery(const bool keepAlive=true, const bool le_scan_active=false, const uint16_t le_scan_interval=24, const uint16_t le_scan_window=24, const uint8_t filter_policy=0x00)
Starts a new discovery session.
Definition: BTAdapter.cpp:679
cvDeviceFound
std::condition_variable cvDeviceFound
Definition: dbt_scanner01.cpp:52
direct_bt::SMPPairingState
SMPPairingState
SMP Pairing Process state definition.
Definition: SMPTypes.hpp:101
direct_bt::BTGattHandler::number
static constexpr int number(const Defaults d)
Definition: BTGattHandler.hpp:149
direct_bt::BDAddressAndType
Unique Bluetooth EUI48 address and BDAddressType tuple.
Definition: BTAddress.hpp:417
direct_bt::BTGattDescRef
std::shared_ptr< BTGattDesc > BTGattDescRef
Definition: BTGattDesc.hpp:177
direct_bt::BTManager::getAdapter
std::shared_ptr< BTAdapter > getAdapter(const uint16_t dev_id) const noexcept
Returns the DBTAdapter with the given dev_id, or nullptr if not found.
Definition: BTManager.cpp:624
direct_bt::BTDevice::getAdapter
BTAdapter & getAdapter() const
Returns the managing adapter.
Definition: BTDevice.hpp:243
direct_bt::BTGattHandler::discoverCompletePrimaryServices
jau::darray< BTGattServiceRef > & discoverCompletePrimaryServices(std::shared_ptr< BTGattHandler > shared_this)
Discover all primary services and all its characteristics declarations including their client config.
Definition: BTGattHandler.cpp:513
direct_bt::GattTemperatureMeasurement::toString
std::string toString() const noexcept
Definition: GATTNumbers.cpp:453
direct_bt::BDAddressType::BDADDR_UNDEFINED
@ BDADDR_UNDEFINED
Undefined.