Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
BTManager.hpp
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#ifndef DBT_MANAGER_HPP_
27#define DBT_MANAGER_HPP_
28
29#include <cstring>
30#include <string>
31#include <cstdint>
32
33#include <mutex>
34#include <atomic>
35#include <thread>
36
37#include <jau/environment.hpp>
38#include <jau/ringbuffer.hpp>
39#include <jau/java_uplink.hpp>
40#include <jau/darray.hpp>
41#include <jau/cow_darray.hpp>
42#include <jau/octets.hpp>
44
45#include "BTTypes0.hpp"
46#include "BTIoctl.hpp"
47#include "HCIComm.hpp"
48#include "MgmtTypes.hpp"
49#include "BTAdapter.hpp"
50#include "jau/int_types.hpp"
51
52namespace direct_bt {
53
54 /** \addtogroup DBTUserAPI
55 *
56 * @{
57 */
58
59 class BTManager; // forward
60
61 /**
62 * Managment Singleton runtime environment properties
63 * <p>
64 * Also see {@link DBTEnv::getExplodingProperties(const std::string & prefixDomain)}.
65 * </p>
66 */
68 friend class BTManager;
69
70 private:
71 MgmtEnv() noexcept; // NOLINT(modernize-use-equals-delete)
72
73 public:
74 /** Global Debug flag, retrieved first to triggers DBTEnv initialization. */
75 const bool DEBUG_GLOBAL;
76
77 private:
78 const bool exploding; // just to trigger exploding properties
79
80 public:
81 /**
82 * Poll timeout for mgmt reader thread, defaults to 10s.
83 * <p>
84 * Environment variable is 'direct_bt.mgmt.reader.timeout'.
85 * </p>
86 */
88
89 /**
90 * Timeout for mgmt command replies, defaults to 3s.
91 * <p>
92 * Environment variable is 'direct_bt.mgmt.cmd.timeout'.
93 * </p>
94 */
96
97 /**
98 * Timeout for mgmt SET_POWER command reply, defaults to max(MGMT_COMMAND_REPLY_TIMEOUT, 6s).
99 * <p>
100 * Environment variable is 'direct_bt.mgmt.setpower.timeout'.
101 * </p>
102 */
104
105 /**
106 * Small ringbuffer capacity for synchronized commands, defaults to 64 messages.
107 * <p>
108 * Environment variable is 'direct_bt.mgmt.ringsize'.
109 * </p>
110 */
112
113 /**
114 * Debug all Mgmt event communication
115 * <p>
116 * Environment variable is 'direct_bt.debug.mgmt.event'.
117 * </p>
118 */
119 const bool DEBUG_EVENT;
120
121 private:
122 /** Maximum number of packets to wait for until matching a sequential command. Won't block as timeout will limit. */
123 const int32_t MGMT_READ_PACKET_MAX_RETRY;
124
125 public:
126 static MgmtEnv& get() noexcept {
127 /**
128 * Thread safe starting with C++11 6.7:
129 *
130 * If control enters the declaration concurrently while the variable is being initialized,
131 * the concurrent execution shall wait for completion of the initialization.
132 *
133 * (Magic Statics)
134 *
135 * Avoiding non-working double checked locking.
136 */
137 static MgmtEnv e;
138 return e;
139 }
140 };
141
142 /**
143 * Callback function to receive change events regarding the system's adapter set,
144 * e.g. a removed or added adapter due to user interaction or 'cold reset'.
145 * <p>
146 * When a new callback is added, all available adapter's will be reported as added,
147 * this allows a fully event driven workflow.
148 * </p>
149 * <p>
150 * The callback is performed on a dedicated thread,
151 * allowing the user to perform complex operations.
152 * </p>
153 * <p>
154 * If an adapter is being removed from the system,
155 * DBTAdapter::close() is being called by BTManager after issuing all
156 * ChangedAdapterSetFunc calls.
157 * </p>
158 *
159 * @param added true if adapter was newly added, otherwise removed from system
160 * @param adapter the shared DBTAdapter reference
161 * @see ChangedAdapterSetCallback
162 * @see BTManager::addChangedAdapterSetCallback()
163 * @see BTManager::removeChangedAdapterSetCallback()
164 * @see [Direct-BT Overview](namespacedirect__bt.html#details)
165 */
166 typedef void (*ChangedAdapterSetFunc)(bool added, std::shared_ptr<BTAdapter>& adapter);
167
168 /**
169 * Callback jau::function to receive change events regarding the system's adapter set,
170 * e.g. a removed or added adapter due to user interaction or 'cold reset'.
171 * <p>
172 * When a new callback is added, all available adapter's will be reported as added,
173 * this allows a fully event driven workflow.
174 * </p>
175 * <p>
176 * The callback is performed on a dedicated thread,
177 * allowing the user to perform complex operations.
178 * </p>
179 * <p>
180 * If an adapter is being removed from the system,
181 * DBTAdapter::close() is being called by BTManager after issuing all
182 * ChangedAdapterSetFunc calls.
183 * </p>
184 *
185 * @param added true if adapter was newly added, otherwise removed from system
186 * @param adapter the shared DBTAdapter reference
187 * @see ChangedAdapterSetFunc
188 * @see BTManager::addChangedAdapterSetCallback()
189 * @see BTManager::removeChangedAdapterSetCallback()
190 * @see [Direct-BT Overview](namespacedirect__bt.html#details)
191 */
192 typedef jau::function<void(bool, std::shared_ptr<BTAdapter>&)> ChangedAdapterSetCallback;
194
195 /**
196 * A thread safe singleton handler of the BTAdapter manager, e.g. Linux Kernel's BlueZ manager control channel.
197 *
198 * Implementation utilizes a lock free ringbuffer receiving data within its separate thread.
199 *
200 * Controlling Environment variables, see {@link MgmtEnv}.
201 *
202 * @see [Direct-BT Overview](namespacedirect__bt.html#details)
203 */
205 public:
206 enum Defaults : int32_t {
207 /* BT Core Spec v5.2: Vol 3, Part F 3.2.8: Maximum length of an attribute value. */
208 ClientMaxMTU = 512
209 };
210
212
213 private:
214 friend BTAdapter;
215
216 /** Default initialization with ::SMPIOCapability::NO_INPUT_NO_OUTPUT for PairingMode::JUST_WORKS. */
218
219 struct WhitelistElem {
220 uint16_t dev_id;
221 BDAddressAndType address_and_type;
223
224 WhitelistElem(uint16_t dev_id_, BDAddressAndType address_and_type_, HCIWhitelistConnectType ctype_)
225 : dev_id(dev_id_), address_and_type(std::move(address_and_type_)), ctype(ctype_) { }
226 };
228
229 const MgmtEnv & env;
230
231 jau::POctets rbuffer;
232 HCIComm comm;
233
234 jau::service_runner mgmt_reader_service;
236
237 std::recursive_mutex mtx_sendReply; // for send() and sendWithReply()
238
239 jau::sc_atomic_bool allowClose;
240
241 /** One MgmtAdapterEventCallbackList per event type, allowing multiple callbacks to be invoked for each event */
242 std::array<MgmtAdapterEventCallbackList, static_cast<uint16_t>(MgmtEvent::Opcode::MGMT_EVENT_TYPE_COUNT)> mgmtAdapterEventCallbackLists;
243 inline bool isValidMgmtEventCallbackListsIndex(const MgmtEvent::Opcode opc) const noexcept {
244 return static_cast<uint16_t>(opc) < mgmtAdapterEventCallbackLists.size();
245 }
246
247 ChangedAdapterSetCallbackList mgmtChangedAdapterSetCallbackList;
248
250 adapters_t adapters;
251
252 /**
253 * Using defaultIOCapability on added AdapterInfo.
254 * Sharing same dev_id <-> index mapping of adapterInfos using findAdapterInfoIndex().
255 * Piggy back reusing adapterInfos.get_write_mutex().
256 */
257 jau::darray<SMPIOCapability> adapterIOCapability;
258
259 void mgmtReaderWork(jau::service_runner& sr) noexcept;
260 void mgmtReaderEndLocked(jau::service_runner& sr) noexcept;
261
262 /**
263 * In case response size check or devID and optional opcode validation fails,
264 * function returns NULL.
265 *
266 * @param req the command request
267 * @param timeout timeout in fractions of seconds
268 * @return the resulting event or nullptr on failure (timeout)
269 */
270 std::unique_ptr<MgmtEvent> sendWithReply(MgmtCommand &req, const jau::fraction_i64& timeout) noexcept;
271
272 /**
273 * In case response size check or devID and optional opcode validation fails,
274 * function returns NULL.
275 *
276 * This override uses a timeout of MgmtEnv::MGMT_COMMAND_REPLY_TIMEOUT (usually 3s).
277 *
278 * @param req the command request
279 * @return the resulting event or nullptr on failure (timeout)
280 */
281 std::unique_ptr<MgmtEvent> sendWithReply(MgmtCommand &req) noexcept {
282 return sendWithReply(req, env.MGMT_COMMAND_REPLY_TIMEOUT);
283 }
284
285 bool send(MgmtCommand &req) noexcept;
286
287 /**
288 * Instantiate singleton.
289 */
290 BTManager() noexcept;
291 bool initialize(const std::shared_ptr<BTManager>& self) noexcept;
292
293 static const std::shared_ptr<BTManager> make_shared() noexcept {
294 try {
295 std::shared_ptr<BTManager> s( new BTManager() );
296 s->initialize(s);
297 return s;
298 } catch (const std::bad_alloc &e) {
299 ABORT("Error: bad_alloc: BTManager allocation failed");
300 return nullptr; // unreachable
301 }
302 }
303
304 std::unique_ptr<AdapterInfo> readAdapterInfo(const uint16_t dev_id) noexcept;
305
306 void processAdapterAdded(std::unique_ptr<MgmtEvent> e) noexcept;
307 void processAdapterRemoved(std::unique_ptr<MgmtEvent> e) noexcept;
308 void mgmtEvNewSettingsCB(const MgmtEvent& e) noexcept;
309 void mgmtEventAnyCB(const MgmtEvent& e) noexcept;
310
311 std::shared_ptr<BTAdapter> addAdapter(const AdapterInfo& ai) noexcept;
312
313 /**
314 * Removes the AdapterInfo with the given dev_id
315 * @return the removed instance or nullptr if not found.
316 */
317 std::shared_ptr<BTAdapter> removeAdapter(const uint16_t dev_id) noexcept;
318
319 /**
320 * Removal entry for DBTAdapter::~DBTAdapter
321 * @param adapter pointer to the dtor'ed adapter
322 * @return true if contained and removed, otherwise false
323 */
324 bool removeAdapter(BTAdapter* adapter) noexcept;
325
326 MgmtStatus handleCurrentSettingsReply(std::unique_ptr<MgmtEvent>&& reply, AdapterSetting& current_settings) noexcept;
327
328 public:
329 BTManager(const BTManager&) = delete;
330 void operator=(const BTManager&) = delete;
331
332 /**
333 * Retrieves the singleton instance.
334 * <p>
335 * First call will open and initialize the bluetooth kernel.
336 * </p>
337 * @return singleton instance.
338 */
339 static const std::shared_ptr<BTManager>& get() noexcept {
340 /**
341 * Thread safe starting with C++11 6.7:
342 *
343 * If control enters the declaration concurrently while the variable is being initialized,
344 * the concurrent execution shall wait for completion of the initialization.
345 *
346 * (Magic Statics)
347 *
348 * Avoiding non-working double checked locking.
349 */
350 static std::shared_ptr<BTManager> s = make_shared();
351 return s;
352 }
353
354 ~BTManager() noexcept override;
355
356 void close() noexcept;
357
358 std::string get_java_class() const noexcept override {
359 return java_class();
360 }
361 static std::string java_class() noexcept {
362 return std::string(JAVA_DBT_PACKAGE "DBTManager");
363 }
364
365 /** Returns true if this mgmt instance is open and hence valid, otherwise false */
366 bool isOpen() const noexcept {
367 return comm.is_open();
368 }
369
370 std::string toString() const noexcept override {
371 return "MgmtHandler["+std::to_string(adapters.size())+" adapter, "+javaObjectToString()+"]";
372 }
373
374 /** retrieve information gathered at startup */
375
376 /**
377 * Returns AdapterInfo count in list
378 */
379 size_type getAdapterCount() const noexcept { return adapters.size(); }
380
381 /**
382 * Returns a list of currently added DBTAdapter.
383 */
384 jau::darray<std::shared_ptr<BTAdapter>> getAdapters() { return *adapters.snapshot(); }
385
386 /**
387 * Returns the DBTAdapter with the given dev_id, or nullptr if not found.
388 */
389 std::shared_ptr<BTAdapter> getAdapter(const uint16_t dev_id) const noexcept;
390
391 /**
392 * Returns the default AdapterInfo.
393 * <p>
394 * The default adapter is either the first AdapterSetting::POWERED adapter,
395 * or function returns nullptr if none is AdapterSetting::POWERED.
396 * </p>
397 */
398 std::shared_ptr<BTAdapter> getDefaultAdapter() const noexcept;
399
400 bool setIOCapability(const uint16_t dev_id, const SMPIOCapability io_cap, SMPIOCapability& pre_io_cap) noexcept;
401 SMPIOCapability getIOCapability(const uint16_t dev_id) const noexcept;
402
403 bool setMode(const uint16_t dev_id, const MgmtCommand::Opcode opc, const uint8_t mode, AdapterSetting& current_settings) noexcept;
404 MgmtStatus setDiscoverable(const uint16_t dev_id, const uint8_t state, const uint16_t timeout, AdapterSetting& current_settings) noexcept;
405
406 /**
407 * Initialize the adapter with default values, including power-on.
408 * <p>
409 * Method shall be issued on the desired adapter found via ChangedAdapterSetFunc.
410 * </p>
411 * <p>
412 * While initialization, the adapter is first powered-off, setup and then powered-on.
413 * </p>
414 * @param adapterInfo reference for the AdapterInfo, updated to reflect the new initialized values.
415 * @param dev_id the adapter's device id
416 * @param btMode the desired adapter's BTMode
417 * @param powerOn true to leave adapter powered-on, otherwise leave it off
418 * @return HCIStatusCode::SUCCESS or an error state on failure (e.g. power-on)
419 * @since 3.2.0
420 */
421 HCIStatusCode initializeAdapter(AdapterInfo& adapterInfo, const uint16_t dev_id,
422 const BTMode btMode, const bool powerOn) noexcept;
423
424 HCIStatusCode setPrivacy(const uint16_t dev_id, const uint8_t privacy, const jau::uint128dp_t& irk, AdapterSetting& current_settings) noexcept;
425
426 /**
427 * Read default connection parameter for given adapter to the kernel.
428 *
429 * @param dev_id
430 * @return list of MgmtDefaultParam if successful, empty if command failed.
431 * @since 2.6.3
432 */
433 std::vector<MgmtDefaultParam> readDefaultSysParam(const uint16_t dev_id) noexcept;
434
435 /**
436 * Set default connection parameter for given adapter to the kernel.
437 *
438 * @param dev_id
439 * @param conn_interval_min in units of 1.25ms, default value 8 for 10ms; Value range [6 .. 3200] for [7.5ms .. 4000ms].
440 * @param conn_interval_max in units of 1.25ms, default value 40 for 50ms; Value range [6 .. 3200] for [7.5ms .. 4000ms]
441 * @param conn_latency slave latency in units of connection events, default value 0; Value range [0 .. 0x01F3].
442 * @param supervision_timeout in units of 10ms, default value 500ms >= 10 x conn_interval_max, we use HCIConstInt::LE_CONN_MIN_TIMEOUT_MS minimum; Value range [0xA-0x0C80] for [100ms - 32s].
443 * @return
444 * @since 2.5.3
445 */
446 HCIStatusCode setDefaultConnParam(const uint16_t dev_id,
447 const uint16_t conn_interval_min=8, const uint16_t conn_interval_max=40,
448 const uint16_t conn_latency=0, const uint16_t supervision_timeout=getHCIConnSupervisorTimeout(0, 50)) noexcept;
449
450 /**
451 * Uploads given connection parameter for given device to the kernel.
452 *
453 * @param dev_id
454 * @param address
455 * @param address_type
456 * @param conn_interval_min in units of 1.25ms, default value 12 for 15ms; Value range [6 .. 3200] for [7.5ms .. 4000ms]
457 * @param conn_interval_max in units of 1.25ms, default value 12 for 15ms; Value range [6 .. 3200] for [7.5ms .. 4000ms]
458 * @param conn_latency slave latency in units of connection events, default value 0; Value range [0 .. 0x01F3].
459 * @param supervision_timeout in units of 10ms, default value >= 10 x conn_interval_max, we use HCIConstInt::LE_CONN_MIN_TIMEOUT_MS minimum; Value range [0xA-0x0C80] for [100ms - 32s].
460 * @return
461 */
462 HCIStatusCode uploadConnParam(const uint16_t dev_id, const BDAddressAndType & addressAndType,
463 const uint16_t conn_interval_min=12, const uint16_t conn_interval_max=12,
464 const uint16_t conn_latency=0, const uint16_t supervision_timeout=getHCIConnSupervisorTimeout(0, 15)) noexcept;
465
466 /**
467 * Returns true, if the adapter's device is already whitelisted.
468 */
469 bool isDeviceWhitelisted(const uint16_t dev_id, const BDAddressAndType & addressAndType) noexcept;
470
471 /**
472 * Add the given device to the adapter's autoconnect whitelist.
473 * <p>
474 * Make sure {@link uploadConnParam(..)} is invoked first, otherwise performance will lack.
475 * </p>
476 * <p>
477 * Method will reject duplicate devices, in which case it should be removed first.
478 * </p>
479 */
480 bool addDeviceToWhitelist(const uint16_t dev_id, const BDAddressAndType & addressAndType, const HCIWhitelistConnectType ctype) noexcept;
481
482 /** Remove the given device from the adapter's autoconnect whitelist. */
483 bool removeDeviceFromWhitelist(const uint16_t dev_id, const BDAddressAndType & addressAndType) noexcept;
484
485 /** Remove all previously added devices from the autoconnect whitelist. Returns number of removed devices. */
487
488 std::shared_ptr<ConnectionInfo> getConnectionInfo(const uint16_t dev_id, const BDAddressAndType& addressAndType) noexcept;
489 std::shared_ptr<NameAndShortName> setLocalName(const uint16_t dev_id, const std::string & name, const std::string & short_name) noexcept;
490
491 /** Security commands */
492
493 /**
494 * Linux Kernel `load_long_term_keys(..)` (mgmt.c) require either `BDAddressType::BDADDR_LE_PUBLIC` or
495 * BDAddressType::BDADDR_LE_RANDOM and BLERandomAddressType::STATIC_PUBLIC in ltk_is_valid(..) (mgmt.c).
496 *
497 * The Linux kernel will reject unresolvable random addresses and resolvable random addresses.
498 *
499 * @return true if complying to above address-and-type requirements or if not using LINUX, otherwise false.
500 */
501 bool isValidLongTermKeyAddressAndType(const EUI48 &address, const BDAddressType &address_type) const noexcept;
502
503 HCIStatusCode uploadLongTermKey(const uint16_t dev_id, const jau::darray<MgmtLongTermKey> &keys) noexcept;
504 HCIStatusCode uploadLongTermKey(const BTRole adapterRole,
505 const uint16_t dev_id, const BDAddressAndType & addressAndType, const jau::darray<SMPLongTermKey>& ltks) noexcept;
506
507 HCIStatusCode uploadIdentityResolvingKey(const uint16_t dev_id, const jau::darray<MgmtIdentityResolvingKey> &keys) noexcept;
508 HCIStatusCode uploadIdentityResolvingKey(const uint16_t dev_id, const jau::darray<SMPIdentityResolvingKey>& irks) noexcept;
509 HCIStatusCode clearIdentityResolvingKeys(const uint16_t dev_id) noexcept;
510
511 HCIStatusCode uploadLinkKey(const uint16_t dev_id, const MgmtLinkKeyInfo &key) noexcept;
512 HCIStatusCode uploadLinkKey(const uint16_t dev_id, const BDAddressAndType & addressAndType, const SMPLinkKey& lk) noexcept;
513
514 MgmtStatus userPINCodeReply(const uint16_t dev_id, const BDAddressAndType & addressAndType, const std::string& pinCode) noexcept;
515 MgmtStatus userPINCodeNegativeReply(const uint16_t dev_id, const BDAddressAndType & addressAndType) noexcept;
516 MgmtStatus userPasskeyReply(const uint16_t dev_id, const BDAddressAndType & addressAndType, const uint32_t passkey) noexcept;
517 MgmtStatus userPasskeyNegativeReply(const uint16_t dev_id, const BDAddressAndType & addressAndType) noexcept;
518 MgmtStatus userConfirmReply(const uint16_t dev_id, const BDAddressAndType & addressAndType, const bool positive) noexcept;
519
520 HCIStatusCode unpairDevice(const uint16_t dev_id, const BDAddressAndType & addressAndType, const bool disconnect) noexcept;
521
522 /** MgmtEventCallback handling */
523
524 /**
525 * Appends the given MgmtEventCallback for the given adapter dev_id to the named MgmtEvent::Opcode list,
526 * if it is not present already (dev_id + opcode + callback).
527 * <p>
528 * The adapter dev_id allows filtering the events only directed to the given adapter.
529 * Use dev_id <code>-1</code> to receive the event for all adapter.
530 * </p>
531 * @param dev_id the associated adapter dev_id
532 * @param opc opcode index for callback list, the callback shall be added to
533 * @param cb the to be added callback
534 * @return true if newly added or already existing, false if given MgmtEvent::Opcode is out of supported range.
535 */
536 bool addMgmtEventCallback(const int dev_id, const MgmtEvent::Opcode opc, const MgmtEventCallback &cb) noexcept;
537 /** Returns count of removed given MgmtEventCallback from the named MgmtEvent::Opcode list. */
538 size_type removeMgmtEventCallback(const MgmtEvent::Opcode opc, const MgmtEventCallback &cb) noexcept;
539 /** Returns count of removed MgmtEventCallback from the named MgmtEvent::Opcode list matching the given adapter dev_id . */
540 size_type removeMgmtEventCallback(const int dev_id) noexcept;
541 /** Removes all MgmtEventCallbacks from the to the named MgmtEvent::Opcode list. */
542 void clearMgmtEventCallbacks(const MgmtEvent::Opcode opc) noexcept;
543 /** Removes all MgmtEventCallbacks from all MgmtEvent::Opcode lists. */
544 void clearAllCallbacks() noexcept;
545
546 /** Manually send a MgmtEvent to all of its listeners. */
547 void sendMgmtEvent(const MgmtEvent& event) noexcept;
548
549 /** ChangedAdapterSetCallback handling */
550
551 /**
552 * Adds the given ChangedAdapterSetCallback to this manager.
553 * <p>
554 * When a new callback is added, all available adapter's will be reported as added,
555 * this allows a fully event driven workflow.
556 * </p>
557 * <p>
558 * The callback is performed on a dedicated thread,
559 * allowing the user to perform complex operations.
560 * </p>
561 */
563
564 /**
565 * Remove the given ChangedAdapterSetCallback from this manager.
566 * @param l the to be removed element
567 * @return the number of removed elements
568 */
570
571 /**
572 * Adds the given ChangedAdapterSetFunc to this manager.
573 * <p>
574 * When a new callback is added, all available adapter's will be reported as added,
575 * this allows a fully event driven workflow.
576 * </p>
577 * <p>
578 * The callback is performed on a dedicated thread,
579 * allowing the user to perform complex operations.
580 * </p>
581 */
583
584 /**
585 * Remove the given ChangedAdapterSetFunc from this manager.
586 * @param l the to be removed element
587 * @return the number of removed elements
588 */
590
591 /**
592 * Remove all added ChangedAdapterSetCallback entries from this manager.
593 * @return the number of removed elements
594 * @since 2.7.0
595 */
597
598 };
599 typedef std::shared_ptr<BTManager> BTManagerRef;
600
601 /**@}*/
602
603} // namespace direct_bt
604
605#endif /* DBT_MANAGER_HPP_ */
606
#define JAVA_DBT_PACKAGE
Definition: BTTypes0.hpp:43
Unique Bluetooth EUI48 address and BDAddressType tuple.
Definition: BTAddress.hpp:175
BTAdapter represents one local Bluetooth Controller.
Definition: BTAdapter.hpp:324
A thread safe singleton handler of the BTAdapter manager, e.g.
Definition: BTManager.hpp:204
bool addDeviceToWhitelist(const uint16_t dev_id, const BDAddressAndType &addressAndType, const HCIWhitelistConnectType ctype) noexcept
Add the given device to the adapter's autoconnect whitelist.
Definition: BTManager.cpp:1046
HCIStatusCode uploadLinkKey(const uint16_t dev_id, const MgmtLinkKeyInfo &key) noexcept
Definition: BTManager.cpp:899
MgmtStatus userPINCodeNegativeReply(const uint16_t dev_id, const BDAddressAndType &addressAndType) noexcept
Definition: BTManager.cpp:953
BTManager(const BTManager &)=delete
std::shared_ptr< ConnectionInfo > getConnectionInfo(const uint16_t dev_id, const BDAddressAndType &addressAndType) noexcept
Definition: BTManager.cpp:1118
void clearAllCallbacks() noexcept
Removes all MgmtEventCallbacks from all MgmtEvent::Opcode lists.
Definition: BTManager.cpp:1200
~BTManager() noexcept override
Definition: BTManager.cpp:524
HCIStatusCode clearIdentityResolvingKeys(const uint16_t dev_id) noexcept
Definition: BTManager.cpp:888
void operator=(const BTManager &)=delete
void close() noexcept
Definition: BTManager.cpp:529
size_type removeMgmtEventCallback(const MgmtEvent::Opcode opc, const MgmtEventCallback &cb) noexcept
Returns count of removed given MgmtEventCallback from the named MgmtEvent::Opcode list.
Definition: BTManager.cpp:1172
HCIStatusCode setPrivacy(const uint16_t dev_id, const uint8_t privacy, const jau::uint128dp_t &irk, AdapterSetting &current_settings) noexcept
Definition: BTManager.cpp:733
MgmtStatus setDiscoverable(const uint16_t dev_id, const uint8_t state, const uint16_t timeout, AdapterSetting &current_settings) noexcept
Definition: BTManager.cpp:711
HCIStatusCode uploadConnParam(const uint16_t dev_id, const BDAddressAndType &addressAndType, const uint16_t conn_interval_min=12, const uint16_t conn_interval_max=12, const uint16_t conn_latency=0, const uint16_t supervision_timeout=getHCIConnSupervisorTimeout(0, 15)) noexcept
Uploads given connection parameter for given device to the kernel.
Definition: BTManager.cpp:762
HCIStatusCode unpairDevice(const uint16_t dev_id, const BDAddressAndType &addressAndType, const bool disconnect) noexcept
Definition: BTManager.cpp:1019
MgmtStatus userPasskeyReply(const uint16_t dev_id, const BDAddressAndType &addressAndType, const uint32_t passkey) noexcept
Definition: BTManager.cpp:968
bool setMode(const uint16_t dev_id, const MgmtCommand::Opcode opc, const uint8_t mode, AdapterSetting &current_settings) noexcept
Definition: BTManager.cpp:701
jau::nsize_t size_type
Definition: BTManager.hpp:211
std::shared_ptr< NameAndShortName > setLocalName(const uint16_t dev_id, const std::string &name, const std::string &short_name) noexcept
Definition: BTManager.cpp:1131
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:581
void sendMgmtEvent(const MgmtEvent &event) noexcept
Manually send a MgmtEvent to all of its listeners.
Definition: BTManager.cpp:139
MgmtStatus userPasskeyNegativeReply(const uint16_t dev_id, const BDAddressAndType &addressAndType) noexcept
Definition: BTManager.cpp:983
HCIStatusCode uploadIdentityResolvingKey(const uint16_t dev_id, const jau::darray< MgmtIdentityResolvingKey > &keys) noexcept
Definition: BTManager.cpp:846
size_type removeAllDevicesFromWhitelist() noexcept
Remove all previously added devices from the autoconnect whitelist.
Definition: BTManager.cpp:1065
bool isOpen() const noexcept
Returns true if this mgmt instance is open and hence valid, otherwise false.
Definition: BTManager.hpp:366
HCIStatusCode uploadLongTermKey(const uint16_t dev_id, const jau::darray< MgmtLongTermKey > &keys) noexcept
Definition: BTManager.cpp:798
MgmtStatus userPINCodeReply(const uint16_t dev_id, const BDAddressAndType &addressAndType, const std::string &pinCode) noexcept
Definition: BTManager.cpp:938
void addChangedAdapterSetCallback(const ChangedAdapterSetCallback &l)
ChangedAdapterSetCallback handling.
Definition: BTManager.cpp:1273
size_type removeAllChangedAdapterSetCallbacks() noexcept
Remove all added ChangedAdapterSetCallback entries from this manager.
Definition: BTManager.cpp:1294
HCIStatusCode initializeAdapter(AdapterInfo &adapterInfo, const uint16_t dev_id, const BTMode btMode, const bool powerOn) noexcept
Initialize the adapter with default values, including power-on.
Definition: BTManager.cpp:225
HCIStatusCode setDefaultConnParam(const uint16_t dev_id, const uint16_t conn_interval_min=8, const uint16_t conn_interval_max=40, const uint16_t conn_latency=0, const uint16_t supervision_timeout=getHCIConnSupervisorTimeout(0, 50)) noexcept
Set default connection parameter for given adapter to the kernel.
Definition: BTManager.cpp:741
bool isValidLongTermKeyAddressAndType(const EUI48 &address, const BDAddressType &address_type) const noexcept
Security commands.
Definition: BTManager.cpp:780
bool setIOCapability(const uint16_t dev_id, const SMPIOCapability io_cap, SMPIOCapability &pre_io_cap) noexcept
Definition: BTManager.cpp:648
std::string toString() const noexcept override
Definition: BTManager.hpp:370
static const std::shared_ptr< BTManager > & get() noexcept
Retrieves the singleton instance.
Definition: BTManager.hpp:339
SMPIOCapability getIOCapability(const uint16_t dev_id) const noexcept
Definition: BTManager.cpp:671
jau::darray< std::shared_ptr< BTAdapter > > getAdapters()
Returns a list of currently added DBTAdapter.
Definition: BTManager.hpp:384
std::vector< MgmtDefaultParam > readDefaultSysParam(const uint16_t dev_id) noexcept
Read default connection parameter for given adapter to the kernel.
Definition: BTManager.cpp:719
std::string get_java_class() const noexcept override
Definition: BTManager.hpp:358
std::shared_ptr< BTAdapter > getDefaultAdapter() const noexcept
Returns the default AdapterInfo.
Definition: BTManager.cpp:571
bool addMgmtEventCallback(const int dev_id, const MgmtEvent::Opcode opc, const MgmtEventCallback &cb) noexcept
MgmtEventCallback handling
Definition: BTManager.cpp:1163
bool isDeviceWhitelisted(const uint16_t dev_id, const BDAddressAndType &addressAndType) noexcept
Returns true, if the adapter's device is already whitelisted.
Definition: BTManager.cpp:1035
size_type removeChangedAdapterSetCallback(const ChangedAdapterSetCallback &l)
Remove the given ChangedAdapterSetCallback from this manager.
Definition: BTManager.cpp:1281
void clearMgmtEventCallbacks(const MgmtEvent::Opcode opc) noexcept
Removes all MgmtEventCallbacks from the to the named MgmtEvent::Opcode list.
Definition: BTManager.cpp:1193
static std::string java_class() noexcept
Definition: BTManager.hpp:361
size_type getAdapterCount() const noexcept
retrieve information gathered at startup
Definition: BTManager.hpp:379
bool removeDeviceFromWhitelist(const uint16_t dev_id, const BDAddressAndType &addressAndType) noexcept
Remove the given device from the adapter's autoconnect whitelist.
Definition: BTManager.cpp:1092
MgmtStatus userConfirmReply(const uint16_t dev_id, const BDAddressAndType &addressAndType, const bool positive) noexcept
Definition: BTManager.cpp:998
mgmt_addr_info { EUI48, uint8_t type }, int8_t rssi, int8_t tx_power, int8_t max_tx_power;
Definition: BTTypes1.hpp:83
Read/Write HCI communication channel.
Definition: HCIComm.hpp:61
bool is_open() const noexcept
Definition: HCIComm.hpp:91
Managment Singleton runtime environment properties.
Definition: BTManager.hpp:67
const jau::fraction_i64 MGMT_COMMAND_REPLY_TIMEOUT
Timeout for mgmt command replies, defaults to 3s.
Definition: BTManager.hpp:95
const jau::fraction_i64 MGMT_READER_THREAD_POLL_TIMEOUT
Poll timeout for mgmt reader thread, defaults to 10s.
Definition: BTManager.hpp:87
const bool DEBUG_EVENT
Debug all Mgmt event communication.
Definition: BTManager.hpp:119
const int32_t MGMT_EVT_RING_CAPACITY
Small ringbuffer capacity for synchronized commands, defaults to 64 messages.
Definition: BTManager.hpp:111
const bool DEBUG_GLOBAL
Global Debug flag, retrieved first to triggers DBTEnv initialization.
Definition: BTManager.hpp:75
const jau::fraction_i64 MGMT_SET_POWER_COMMAND_TIMEOUT
Timeout for mgmt SET_POWER command reply, defaults to max(MGMT_COMMAND_REPLY_TIMEOUT,...
Definition: BTManager.hpp:103
static MgmtEnv & get() noexcept
Definition: BTManager.hpp:126
uint16_t opcode, uint16_t dev-id, uint16_t param_size
Definition: MgmtTypes.hpp:1402
Persistent endian aware octet data, i.e.
Definition: octets.hpp:560
Implementation of a dynamic linear array storage, aka vector.
Definition: darray.hpp:148
Class template jau::function is a general-purpose static-polymorphic function wrapper.
Ring buffer implementation, a.k.a circular buffer, exposing lock-free get*(..) and put*(....
Definition: ringbuffer.hpp:182
Base jau environment class, merely to tag all environment settings by inheritance and hence documenta...
Definition: environment.hpp:57
Service runner, a reusable dedicated thread performing custom user services.
static BTMode btMode
#define ABORT(...)
Use for unconditional ::abort() call with given messages, prefix '[elapsed_time] ABORT @ file:line fu...
Definition: debug.hpp:101
std::string to_string(const alphabet &v) noexcept
Definition: base_codec.hpp:97
SMPIOCapability
Vol 3, Part H, 2.3.2 IO capabilities.
Definition: SMPTypes.hpp:209
constexpr const bool USE_LINUX_BT_SECURITY
Definition: DBTConst.hpp:60
@ UNSET
Denoting unset value, i.e.
@ NO_INPUT_NO_OUTPUT
No input not output, value 3.
void(* ChangedAdapterSetFunc)(bool added, std::shared_ptr< BTAdapter > &adapter)
Callback function to receive change events regarding the system's adapter set, e.g.
Definition: BTManager.hpp:166
std::shared_ptr< BTManager > BTManagerRef
Definition: BTAdapter.hpp:61
BTMode
Bluetooth adapter operating mode.
Definition: BTTypes0.hpp:112
HCIWhitelistConnectType
HCI Whitelist connection type.
Definition: BTTypes0.hpp:471
AdapterSetting
Adapter Setting Bits.
Definition: BTTypes1.hpp:144
BDAddressType
BT Core Spec v5.2: Vol 3, Part C Generic Access Profile (GAP): 15.1.1.1 Public Bluetooth address.
Definition: BTAddress.hpp:60
jau::function< void(bool, std::shared_ptr< BTAdapter > &)> ChangedAdapterSetCallback
Callback jau::function to receive change events regarding the system's adapter set,...
Definition: BTManager.hpp:192
BTRole
Bluetooth roles from the perspective of the link layer (connection initiator).
Definition: BTTypes0.hpp:69
jau::cow_darray< ChangedAdapterSetCallback > ChangedAdapterSetCallbackList
Definition: BTManager.hpp:193
constexpr uint16_t getHCIConnSupervisorTimeout(const uint16_t conn_latency, const uint16_t conn_interval_max_ms, const uint16_t min_result_ms=number(HCIConstInt::LE_CONN_MIN_TIMEOUT_MS), const uint16_t multiplier=10) noexcept
Defining the supervising timeout for LE connections to be a multiple of the maximum connection interv...
Definition: HCITypes.hpp:102
HCIStatusCode
BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes.
Definition: HCITypes.hpp:138
fraction< int64_t > fraction_i64
fraction using int64_t as integral type
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition: int_types.hpp:53
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
STL namespace.
Used in MgmtReadDefaultSysParamCmd and MgmtSetDefaultConnParamCmd.
Definition: MgmtTypes.hpp:1237
Used for MgmtLoadIdentityResolvingKeyCmd and MgmtEvtNewIdentityResolvingKey.
Definition: MgmtTypes.hpp:289
Used for MgmtLoadLinkKeyCmd and MgmtEvtNewLinkKey.
Definition: MgmtTypes.hpp:345
Used for MgmtLoadLongTermKeyCmd and MgmtEvtNewLongTermKey.
Definition: MgmtTypes.hpp:264
SMP Identity Resolving Key, used for platform agnostic persistence.
Definition: SMPTypes.hpp:636
Local SMP Link Key, used for platform agnostic persistence, mapping to platform specific MgmtLoadLink...
Definition: SMPTypes.hpp:824
SMP Long Term Key, used for platform agnostic persistence.
Definition: SMPTypes.hpp:552
A packed 48 bit EUI-48 identifier, formerly known as MAC-48 or simply network device MAC address (Med...
Definition: eui48.hpp:324