26#ifndef BT_ADAPTER_HPP_
27#define BT_ADAPTER_HPP_
101 return static_cast<uint8_t
>(rhs);
104 if( 1 <= v && v <= 4 ) {
161 (void)changedEnabled;
292 {
return this == &rhs; }
295 {
return !(*
this == rhs); }
328 const bool debug_event, debug_lock;
330 std::atomic_bool adapter_operational;
341 bool hci_uses_ext_scan;
343 bool hci_uses_ext_conn;
345 bool hci_uses_ext_adv;
376 const BTDevice* single_conn_device_ptr =
nullptr;
377 std::mutex mtx_single_conn_device;
378 std::condition_variable cv_single_conn_device;
395 struct StatusListenerPair {
399 std::weak_ptr<BTDevice> wbr_device;
401 bool match(
const BTDeviceRef& device)
const noexcept {
403 if(
nullptr != sda &&
nullptr != device ) {
404 return *sda == *device;
412 statusListenerList_t statusListenerList;
415 std::string key_path;
416 typedef std::shared_ptr<SMPKeyBin> SMPKeyBinRef;
424 mutable std::mutex mtx_discoveredDevices;
425 mutable std::mutex mtx_connectedDevices;
426 mutable std::mutex mtx_pausingDiscoveryDevices;
427 mutable std::mutex mtx_discovery;
428 mutable std::mutex mtx_sharedDevices;
429 mutable std::mutex mtx_keys;
432 bool updateDataFromHCI() noexcept;
433 bool updateDataFromAdapterInfo() noexcept;
434 bool initialSetup() noexcept;
435 bool enableListening(const
bool enable) noexcept;
438 static
BTDeviceRef findDevice(device_list_t & devices, BTDevice const & device) noexcept;
440 static
BTDeviceRef findWeakDevice(weak_device_list_t & devices, BTDevice const & device) noexcept;
441 static
void printDeviceList(const
std::
string& prefix, const
BTAdapter::device_list_t& list) noexcept;
442 static
void printWeakDeviceList(const
std::
string& prefix,
BTAdapter::weak_device_list_t& list) noexcept;
445 class ctor_cookie {
friend BTAdapter; ctor_cookie(
const uint16_t secret) { (void)secret; } };
448 static std::shared_ptr<BTAdapter> make_shared(
const BTManagerRef& mgmt_,
const AdapterInfo& adapterInfo_) {
449 return std::make_shared<BTAdapter>(BTAdapter::ctor_cookie(0), mgmt_, adapterInfo_);
463 void poweredOff(
bool active,
const std::string& msg)
noexcept;
473 uint16_t min_interval, uint16_t max_interval,
474 uint16_t latency, uint16_t supervision_timeout) noexcept;
475 friend
HCIStatusCode BTDevice::connectBREDR(const uint16_t pkt_type, const uint16_t clock_offset, const uint8_t role_switch) noexcept;
485 bool unlockConnect(const
BTDevice & device) noexcept;
486 bool unlockConnectAny() noexcept;
488 bool addDevicePausingDiscovery(const
BTDeviceRef & device) noexcept;
490 void clearDevicesPausingDiscovery() noexcept;
491 jau::
nsize_t getDevicesPausingDiscoveryCount() noexcept;
493 bool addConnectedDevice(const
BTDeviceRef & device) noexcept;
494 bool removeConnectedDevice(const
BTDevice & device) noexcept;
497 jau::
nsize_t getConnectedDeviceCount() const noexcept;
499 bool addDiscoveredDevice(
BTDeviceRef const &device) noexcept;
501 void removeDevice(
BTDevice & device) noexcept;
503 bool addSharedDevice(
BTDeviceRef const &device) noexcept;
505 void removeSharedDevice(const
BTDevice & device) noexcept;
508 static
bool removeSMPKeyBin(
key_list_t & keys,
BDAddressAndType const & remoteAddress, const
bool remove_file, const
std::
string& key_path_) noexcept;
509 SMPKeyBinRef findSMPKeyBin(
BDAddressAndType const & remoteAddress) noexcept;
511 bool addSMPKeyBin(const SMPKeyBinRef& key, const
bool write_file) noexcept;
512 bool removeSMPKeyBin(
BDAddressAndType const & remoteAddress, const
bool remove_file) noexcept;
515 jau::service_runner l2cap_service;
517 std::mutex mtx_l2cap_att;
518 std::condition_variable cv_l2cap_att;
519 void l2capServerWork(
jau::service_runner& sr) noexcept;
520 void l2capServerInit(
jau::service_runner& sr) noexcept;
521 void l2capServerEnd(
jau::service_runner& sr) noexcept;
524 void mgmtEvNewSettingsMgmt(const
MgmtEvent& e) noexcept;
525 void updateAdapterSettings(const
bool off_thread, const
AdapterSetting new_settings, const
bool sendEvent, const uint64_t timestamp) noexcept;
526 void mgmtEvDeviceDiscoveringMgmt(const
MgmtEvent& e) noexcept;
527 void mgmtEvLocalNameChangedMgmt(const
MgmtEvent& e) noexcept;
528 void mgmtEvDeviceFoundHCI(const
MgmtEvent& e) noexcept;
530 void mgmtEvPairDeviceCompleteMgmt(const
MgmtEvent& e) noexcept;
531 void mgmtEvNewLongTermKeyMgmt(const
MgmtEvent& e) noexcept;
532 void mgmtEvNewLinkKeyMgmt(const
MgmtEvent& e) noexcept;
533 void mgmtEvNewIdentityResolvingKeyMgmt(const
MgmtEvent& e) noexcept;
535 void mgmtEvHCIAnyHCI(const
MgmtEvent& e) noexcept;
536 void mgmtEvMgmtAnyMgmt(const
MgmtEvent& e) noexcept;
537 void mgmtEvDeviceDiscoveringHCI(const
MgmtEvent& e) noexcept;
538 void mgmtEvDeviceConnectedHCI(const
MgmtEvent& e) noexcept;
539 void mgmtEvDeviceConnectedMgmt(const
MgmtEvent& e) noexcept;
541 void mgmtEvConnectFailedHCI(const
MgmtEvent& e) noexcept;
542 void mgmtEvHCILERemoteUserFeaturesHCI(const
MgmtEvent& e) noexcept;
543 void mgmtEvHCILEPhyUpdateCompleteHCI(const
MgmtEvent& e) noexcept;
544 void mgmtEvDeviceDisconnectedHCI(const
MgmtEvent& e) noexcept;
547 void mgmtEvLELTKReqEventHCI(const
MgmtEvent& e) noexcept;
548 void mgmtEvLELTKReplyAckCmdHCI(const
MgmtEvent& e) noexcept;
549 void mgmtEvLELTKReplyRejCmdHCI(const
MgmtEvent& e) noexcept;
552 void mgmtEvLEEnableEncryptionCmdHCI(const
MgmtEvent& e) noexcept;
553 void mgmtEvHCIEncryptionChangedHCI(const
MgmtEvent& e) noexcept;
554 void mgmtEvHCIEncryptionKeyRefreshCompleteHCI(const
MgmtEvent& e) noexcept;
556 void updateDeviceDiscoveringState(const
ScanType eventScanType, const
bool eventEnabled) noexcept;
557 void mgmtEvDeviceDiscoveringAny(const
ScanType eventScanType, const
bool eventEnabled, const uint64_t eventTimestamp,
558 const
bool hciSourced) noexcept;
560 void mgmtEvPinCodeRequestMgmt(const
MgmtEvent& e) noexcept;
561 void mgmtEvUserConfirmRequestMgmt(const
MgmtEvent& e) noexcept;
562 void mgmtEvUserPasskeyRequestMgmt(const
MgmtEvent& e) noexcept;
563 void mgmtEvPasskeyNotifyMgmt(const
MgmtEvent& e) noexcept;
564 void mgmtEvAuthFailedMgmt(const
MgmtEvent& e) noexcept;
565 void mgmtEvDeviceUnpairedMgmt(const
MgmtEvent& e) noexcept;
570 void notifyPairingStageDone(const
BTDeviceRef& device, uint64_t timestamp) noexcept;
571 void sendDeviceReady(
BTDeviceRef device, uint64_t timestamp) noexcept;
573 jau::service_runner discovery_service;
574 void discoveryServerWork(
jau::service_runner& sr) noexcept;
575 void checkDiscoveryState() noexcept;
578 const uint64_t timestampMS) noexcept;
611 void close() noexcept;
657 constexpr uint16_t
getBTMajorVersion() const noexcept {
return ( hci_uses_ext_scan && hci_uses_ext_conn && hci_uses_ext_adv ) ? 5 : 4; }
754 bool setPowered(
const bool power_on)
noexcept;
964 const uint16_t conn_interval_min=12,
const uint16_t conn_interval_max=12,
1091 HCIStatusCode stopDiscoveryImpl(const
bool forceDiscoveringEvent, const
bool temporary) noexcept;
1138 return currentMetaScanType;
1332 std::string
toString(
bool includeDiscoveredDevices)
const noexcept;
1349 {
return lhs.getAddressAndType() == rhs.getAddressAndType(); }
1352 {
return !(lhs == rhs); }
#define JAVA_MAIN_PACKAGE
std::string getName() const noexcept
BTMode getCurrentBTMode() const noexcept
Map getCurrentSettingMask() to BTMode.
std::string getShortName() const noexcept
const BDAddressAndType addressAndType
The adapter's address initially reported by the system is always its public address,...
bool isCurrentSettingBitSet(const AdapterSetting bit) const noexcept
BTAdapter status listener for remote BTDevice discovery events: Added, updated and removed; as well a...
virtual void discoveringChanged(BTAdapter &adapter, const ScanType currentMeta, const ScanType changedType, const bool changedEnabled, const DiscoveryPolicy policy, const uint64_t timestamp)
BTAdapter's discovery state has changed, i.e.
virtual void deviceUpdated(const BTDeviceRef &device, const EIRDataType updateMask, const uint64_t timestamp)
An already discovered remote BTDevice has been updated.
virtual void adapterSettingsChanged(BTAdapter &adapter, const AdapterSetting oldmask, const AdapterSetting newmask, const AdapterSetting changedmask, const uint64_t timestamp)
BTAdapter setting(s) changed.
virtual void deviceDisconnected(const BTDeviceRef &device, const HCIStatusCode reason, const uint16_t handle, const uint64_t timestamp)
Remote BTDevice got disconnected.
std::string toString() const noexcept override
~AdapterStatusListener() noexcept override=default
std::string get_java_class() const noexcept override
bool operator!=(const AdapterStatusListener &rhs) const
virtual bool deviceFound(const BTDeviceRef &device, const uint64_t timestamp)
A remote BTDevice has been newly discovered.
virtual void devicePairingState(const BTDeviceRef &device, const SMPPairingState state, const PairingMode mode, const uint64_t timestamp)
An already connected remote BTDevice's SMPPairingState has changed.
static std::string java_class() noexcept
virtual void deviceReady(const BTDeviceRef &device, const uint64_t timestamp)
Remote BTDevice is ready for user (GATT) processing, i.e.
virtual void deviceConnected(const BTDeviceRef &device, const bool discovered, const uint64_t timestamp)
Remote BTDevice got connected.
virtual bool operator==(const AdapterStatusListener &rhs) const
Default comparison operator, merely testing for same memory reference.
Unique Bluetooth EUI48 address and BDAddressType tuple.
BTAdapter represents one local Bluetooth Controller.
BTMode getBTMode() const noexcept
Returns the current BTMode of this adapter.
HCIStatusCode setName(const std::string &name, const std::string &short_name) noexcept
Sets the name and short-name.
HCIStatusCode stopAdvertising() noexcept
Ends advertising.
std::string get_java_class() const noexcept override
constexpr LE_Features getLEFeatures() const noexcept
Return LE_Features for this controller.
std::string getShortName() const noexcept
Returns the short name.
HCIStatusCode setPrivacy(const bool enable) noexcept
Toggle adapter privacy address mode, i.e.
bool isInitialized() const noexcept
Returns true, if initialize() has already been called for this adapter, otherwise false.
BDAddressAndType const & getVisibleAddressAndType() const noexcept
Returns the adapter's currently visible BDAddressAndType, i.e.
bool isDiscovering() const noexcept
Returns true if the meta discovering state is not ScanType::NONE.
void setSMPKeyPath(const std::string path) noexcept
Set the adapter's persistent storage directory for SMPKeyBin files.
std::string toString() const noexcept override
HCIStatusCode setDefaultConnParam(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 of incoming connections for this adapter when in server mode,...
bool isAdvertising() const noexcept
Returns the adapter's current advertising state.
BTDeviceRef findSharedDevice(const EUI48 &address, const BDAddressType addressType) noexcept
Returns shared BTDevice if found, otherwise nullptr.
HCIHandler & getHCI() noexcept
Returns a reference to the aggregated HCIHandler instance.
HCIStatusCode reset() noexcept
Reset the adapter.
HCIStatusCode startDiscovery(const DBGattServerRef &gattServerData_=nullptr, const DiscoveryPolicy policy=DiscoveryPolicy::PAUSE_CONNECTED_UNTIL_READY, const bool le_scan_active=true, const uint16_t le_scan_interval=24, const uint16_t le_scan_window=24, const uint8_t filter_policy=0x00, const bool filter_dup=true) noexcept
Starts discovery.
bool isValid() const noexcept
Returns whether the adapter is valid, i.e.
bool isSuspended() const noexcept
Returns whether the adapter is suspended, i.e.
size_type removeDiscoveredDevices() noexcept
Discards all discovered devices.
void printStatusListenerList() noexcept
bool hasSecureSimplePairing() const noexcept
HCIStatusCode uploadKeys(SMPKeyBin &bin, const bool write) noexcept
Associate the given SMPKeyBin with the contained remote address, i.e.
ScanType getCurrentNativeScanType() const noexcept
Returns the adapter's current native discovering ScanType.
BTDeviceRef findDiscoveredDevice(const EUI48 &address, const BDAddressType addressType) noexcept
Returns shared BTDevice if found, otherwise nullptr.
bool getSecureConnectionsEnabled() const noexcept
Returns whether Secure Connections (SC) is enabled.
HCIStatusCode initialize(const BTMode btMode, const bool powerOn) noexcept
Initialize the adapter with default values, including power-on.
void setServerConnSecurity(const BTSecurityLevel sec_level, const SMPIOCapability io_cap) noexcept
Sets the given BTSecurityLevel and SMPIOCapability for connecting device when in server (peripheral) ...
HCIStatusCode stopDiscovery() noexcept
Ends discovery.
const uint16_t dev_id
Adapter's internal temporary device id.
DiscoveryPolicy getCurrentDiscoveryPolicy() const noexcept
Return the current DiscoveryPolicy, set via startDiscovery().
bool removeDeviceFromWhitelist(const BDAddressAndType &addressAndType)
Remove the given device from the adapter's autoconnect whitelist.
bool isPowered() const noexcept
Returns whether the adapter is valid, plugged in and powered.
bool isDeviceWhitelisted(const BDAddressAndType &addressAndType) noexcept
Returns true, if the adapter's device is already whitelisted.
BTRole getRole() const noexcept
Return the current BTRole of this adapter.
size_type removeAllStatusListener() noexcept
Remove all status listener from the list.
HCIStatusCode startAdvertising(const DBGattServerRef &gattServerData_, EInfoReport &eir, EIRDataType adv_mask=EIRDataType::FLAGS|EIRDataType::SERVICE_UUID, EIRDataType scanrsp_mask=EIRDataType::NAME|EIRDataType::CONN_IVAL, const uint16_t adv_interval_min=160, const uint16_t adv_interval_max=480, const AD_PDU_Type adv_type=AD_PDU_Type::ADV_IND, const uint8_t adv_chan_map=0x07, const uint8_t filter_policy=0x00) noexcept
Starts advertising.
BDAddressAndType const & getAddressAndType() const noexcept
Returns the adapter's public BDAddressAndType, i.e.
ScanType getCurrentScanType() const noexcept
Returns the current meta discovering ScanType.
bool removeStatusListener(const AdapterStatusListenerRef &l) noexcept
Remove the given listener from the list.
void printDeviceLists() noexcept
Print the internally maintained BTDevice lists to stderr:
HCIStatusCode setDefaultLE_PHY(const LE_PHYs Tx, const LE_PHYs Rx) noexcept
Sets default preference of LE_PHYs.
bool removeDevicePausingDiscovery(const BTDevice &device) noexcept
Manual DiscoveryPolicy intervention point, allowing user to remove the ready device from the queue of...
constexpr uint16_t getBTMajorVersion() const noexcept
Returns the Bluetooth major version of this adapter.
bool addDeviceToWhitelist(const BDAddressAndType &addressAndType, const HCIWhitelistConnectType ctype, 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))
Add the given device to the adapter's autoconnect whitelist.
std::string getName() const noexcept
Returns the name.
BTAdapter(const BTAdapter::ctor_cookie &cc, BTManagerRef mgmt_, AdapterInfo adapterInfo_) noexcept
Private ctor for private BTAdapter::make_shared() intended for friends.
static std::string java_class() noexcept
bool addStatusListener(const AdapterStatusListenerRef &l) noexcept
Add the given listener to the list if not already present.
const BTManagerRef & getManager() const noexcept
Returns a reference to the used singleton BTManager instance, used to create this adapter.
bool hasSecureConnections() const noexcept
HCIStatusCode setSecureConnections(const bool enable) noexcept
Enable or disable Secure Connections (SC) of the adapter.
jau::darray< BTDeviceRef > getDiscoveredDevices() const noexcept
Returns discovered devices from the last discovery.
bool setPowered(const bool power_on) noexcept
Set the power state of the adapter.
bool removeDiscoveredDevice(const BDAddressAndType &addressAndType) noexcept
Discards matching discovered devices.
void close() noexcept
Closes this instance, usually being called by destructor or when this adapter is being removed as rec...
DBGattServerRef getGATTServerData()
Return the user's DBGattServer shared reference if in BTRole::Slave mode as set via startAdvertising(...
BTDevice represents one remote Bluetooth device.
std::shared_ptr< BTDevice > getSharedInstance() const noexcept
Returns the shared pointer of this instance managed by the adapter.
A thread safe singleton handler of the BTAdapter manager, e.g.
bool isValidInstance() const noexcept
Returns whether the object's reference is valid and in a general operational state.
mgmt_addr_info { EUI48, uint8_t type }, int8_t rssi, int8_t tx_power, int8_t max_tx_power;
Collection of 'Extended Advertising Data' (EAD), 'Advertising Data' (AD) or 'Extended Inquiry Respons...
BT Core Spec v5.2: Vol 4, Part E HCI: 5.4.2 HCI ACL Data packets.
A thread safe singleton handler of the HCI control channel to one controller (BT adapter)
bool isOpen() const noexcept
Returns true if this mgmt instance is open, connected and hence valid, otherwise false.
bool isAdvertising() const noexcept
Advertising is enabled via le_start_adv() or le_enable_adv().
ScanType getCurrentScanType() const noexcept
L2CAP read/write communication channel to remote device.
L2CAP server socket to listen for connecting remote devices.
uint16_t opcode, uint16_t dev-id, uint16_t param_size
Storage for SMP keys including required connection parameter per local adapter and remote device.
Handles the Security Manager Protocol (SMP) using Protocol Data Unit (PDU) encoded messages over L2CA...
bool(* equal_comparator)(const value_type &a, const value_type &b)
Generic value_type equal comparator to be user defined for e.g.
Sharing the anonymous Java object (JavaAnon), i.e.
A simple timer for timeout and interval applications, using one dedicated service_runner thread per i...
static const uint8_t filter_policy
static const uint16_t le_scan_interval
static const uint16_t le_scan_window
static const bool filter_dup
static bool le_scan_active
static const uint16_t adv_interval_max
static const uint8_t adv_chan_map
static const uint16_t adv_interval_min
static const AD_PDU_Type adv_type
SMPPairingState
SMP Pairing Process state definition.
SMPIOCapability
Vol 3, Part H, 2.3.2 IO capabilities.
@ UNSET
Denoting unset value, i.e.
std::shared_ptr< BTManager > BTManagerRef
BTMode
Bluetooth adapter operating mode.
std::shared_ptr< AdapterStatusListener > AdapterStatusListenerRef
LE_Features
HCI Supported Commands.
HCIWhitelistConnectType
HCI Whitelist connection type.
DiscoveryPolicy
Discovery policy defines the BTAdapter discovery mode after connecting a remote BTDevice:
std::shared_ptr< BTDevice > BTDeviceRef
std::string to_string(const DiscoveryPolicy v) noexcept
std::shared_ptr< BTAdapter > BTAdapterRef
LE_PHYs
LE Transport PHY bit values.
ScanType
Meta ScanType as derived from BTMode, with defined value mask consisting of BDAddressType bits.
AdapterSetting
Adapter Setting Bits.
BDAddressType
BT Core Spec v5.2: Vol 3, Part C Generic Access Profile (GAP): 15.1.1.1 Public Bluetooth address.
BTRole
Bluetooth roles from the perspective of the link layer (connection initiator).
BTSecurityLevel
Bluetooth Security Level.
AD_PDU_Type
LE Advertising (AD) Protocol Data Unit (PDU) Types.
PairingMode
Bluetooth secure pairing mode.
bool operator!=(const BTAdapter &lhs, const BTAdapter &rhs) noexcept
constexpr DiscoveryPolicy to_DiscoveryPolicy(const uint8_t v) noexcept
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...
HCIStatusCode
BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes.
constexpr uint8_t number(const DiscoveryPolicy rhs) noexcept
EIRDataType
Bit mask of 'Extended Inquiry Response' (EIR) data fields, indicating a set of related data.
@ PAUSE_CONNECTED_UNTIL_PAIRED
Pause discovery until all connected BTDevice are optionally SMP paired (~120ms) without GATT service ...
@ PAUSE_CONNECTED_UNTIL_READY
Pause discovery until all connected BTDevice reach readiness inclusive optional SMP pairing (~120ms) ...
@ ALWAYS_ON
Always keep discovery enabled, i.e.
@ AUTO_OFF
Turn off discovery when connected and leave discovery disabled, if turned off by host system.
@ PAUSE_CONNECTED_UNTIL_DISCONNECTED
Pause discovery until all connected BTDevice become disconnected, effectively until AdapterStatusList...
@ UNSET
Security Level not set, value 0.
std::shared_ptr< BTGattService > BTGattServiceRef
std::shared_ptr< DBGattServer > DBGattServerRef
bool remove(const std::string &path, const traverse_options topts=traverse_options::none) noexcept
Remove the given path.
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Used for MgmtLoadIdentityResolvingKeyCmd and MgmtEvtNewIdentityResolvingKey.
A packed 48 bit EUI-48 identifier, formerly known as MAC-48 or simply network device MAC address (Med...
CXX_ALWAYS_INLINE _Tp load() const noexcept