40#include "HCIIoctl.hpp"
60 class AdapterStatusListener;
88 std::unique_ptr<L2CAPClient> l2cap_att;
89 uint64_t ts_last_discovery;
90 uint64_t ts_last_update;
93 int8_t tx_power = 127;
94 std::shared_ptr<EInfoReport> eir;
95 std::shared_ptr<EInfoReport> eir_ind;
96 std::shared_ptr<EInfoReport> eir_scan_rsp;
101 std::shared_ptr<SMPHandler> smpHandler =
nullptr;
102 std::recursive_mutex mtx_smpHandler;
103 std::shared_ptr<BTGattHandler> gattHandler =
nullptr;
104 mutable std::recursive_mutex mtx_gattHandler;
105 mutable std::recursive_mutex mtx_connect;
106 mutable std::mutex mtx_eir;
113 bool is_pre_paired =
false;
122 bool res_requested_sec;
124 bool encryption_enabled;
126 std::uint32_t passKey_resp;
131 uint8_t maxEncsz_init, maxEncsz_resp;
157 PairingData pairing_data;
158 mutable std::recursive_mutex mtx_pairing;
159 std::condition_variable_any cv_pairing_state_changed;
163 class ctor_cookie {
friend BTDevice; ctor_cookie(
const uint16_t secret) { (void)secret; } };
167 return std::make_shared<BTDevice>(BTDevice::ctor_cookie(0), adapter, r);
170 void clearData()
noexcept;
172 bool updateIdentityAddress(
BDAddressAndType const & identityAddress,
bool sendEvent)
noexcept;
173 bool updateVisibleAddress(
BDAddressAndType const & randomPrivateAddress)
noexcept;
177 void notifyDisconnected()
noexcept;
178 void notifyConnected(
const std::shared_ptr<BTDevice>& sthis,
const uint16_t handle,
const SMPIOCapability io_cap_has)
noexcept;
179 void notifyLEFeatures(
const std::shared_ptr<BTDevice>& sthis,
const LE_Features features)
noexcept;
189 void processL2CAPSetup(std::shared_ptr<BTDevice> sthis);
252 bool connectSMP(std::shared_ptr<BTDevice> sthis,
const BTSecurityLevel sec_level)
noexcept;
254 bool checkPairingKeyDistributionComplete()
const noexcept;
266 void getSMPEncStatus(
bool& enc_done,
bool& using_auth,
bool& is_pre_paired);
276 void processDeviceReady(std::shared_ptr<BTDevice> sthis,
const uint64_t timestamp);
287 bool connectGATT(
const std::shared_ptr<BTDevice>& sthis)
noexcept;
292 void disconnectGATT(
const int caller)
noexcept;
297 void disconnectSMP(
const int caller)
noexcept;
299 void clearSMPStates(
const bool connected)
noexcept;
301 void sendMgmtEvDeviceDisconnected(std::unique_ptr<MgmtEvent> evt)
noexcept;
377 uint64_t
getLastUpdateAge(
const uint64_t ts_now)
const noexcept {
return ts_now - ts_last_update; }
421 int8_t
getRSSI() const noexcept {
return rssi; }
444 std::string
const getName() const noexcept;
472 std::string
toString(
bool includeDiscoveredServices)
const noexcept;
566 const uint16_t conn_interval_min=8,
const uint16_t conn_interval_max=12,
593 const uint16_t clock_offset=0x0000, const uint8_t role_switch=0x01) noexcept;
718 bool isPrePaired() const noexcept {
return pairing_data.is_pre_paired; }
801 if( bin.isValid() && bin.getSecLevel() >= req_min_level &&
setSMPKeyBin(bin) ) {
1254 bool sendNotification(const uint16_t char_value_handle, const
jau::TROOctets & value) noexcept;
1268 bool sendIndication(const uint16_t char_value_handle, const
jau::TROOctets & value) noexcept;
1339 return lhs.getAddressAndType() == rhs.getAddressAndType() ||
1340 lhs.getVisibleAddressAndType() == rhs.getVisibleAddressAndType()
1345 {
return !(lhs == rhs); }
Unique Bluetooth EUI48 address and BDAddressType tuple.
BTAdapter represents one local Bluetooth Controller.
BTDevice represents one remote Bluetooth device.
BDAddressAndType addressAndType
Device's unique mac address and type tuple, might be its initially reported (resolvable) random addre...
std::shared_ptr< GattGenericAccessSvc > getGattGenericAccess()
Returns the shared GenericAccess instance, retrieved by getGattServices() or nullptr if not available...
HCIStatusCode setPairingPINCodeNegative() noexcept
bool removeCharListener(const BTGattCharListenerRef &l) noexcept
Remove the given BTGattCharListener from the listener list.
bool setConnSecurity(const BTSecurityLevel sec_level, const SMPIOCapability io_cap=SMPIOCapability::UNSET) noexcept
Sets the given BTSecurityLevel and SMPIOCapability used to connect to this device on the upcoming con...
const uint64_t ts_creation
bool isConnSecurityAutoEnabled() const noexcept
Returns true if automatic security negotiation has been enabled via setConnSecurityAuto(),...
SMPLongTermKey getLongTermKey(const bool responder) const noexcept
Returns a copy of the Long Term Key (LTK), valid after connection and SMP pairing has been completed.
bool pingGATT() noexcept
Issues a GATT ping to the device, validating whether it is still reachable.
uint64_t getCreationTimestamp() const noexcept
Returns the timestamp in monotonic milliseconds when this device instance has been created,...
void remove() noexcept
Disconnects this device via disconnect(..) if getConnected()==true and explicitly removes its shared ...
BTRole getRole() const noexcept
Return the fixed BTRole of this remote BTDevice.
SMPSignatureResolvingKey getSignatureResolvingKey(const bool responder) const noexcept
Returns a copy of the Signature Resolving Key (CSRK), valid after connection and SMP pairing has been...
EInfoReportRef getEIRInd() noexcept
Return the latest advertised EInfoReport AD_IND variant for this remote device.
LE_PHYs getTxPhys() const noexcept
Return the Tx LE_PHYs as notified via HCIMetaEventType::LE_PHY_UPDATE_COMPLETE or retrieved via getCo...
constexpr BDAddressAndType const & getAddressAndType() const noexcept
Returns the devices' unique EUI48 address and type tuple, might be its initially reported (resolvable...
HCIStatusCode setPairingPasskeyNegative() noexcept
Method replies with a negative passkey response, i.e.
static void validateSecParam(const BTSecurityLevel sec_level, const SMPIOCapability io_cap, BTSecurityLevel &res_sec_level, SMPIOCapability &res_io_cap) noexcept
Returns the validated security parameter BTSecurityLevel and SMPIOCapability in the designated refere...
bool setSMPKeyBin(const SMPKeyBin &bin) noexcept
Copy all keys from the given SMPKeyBin into this BTDevice.
uint64_t getLastUpdateAge(const uint64_t ts_now) const noexcept
HCIStatusCode connectBREDR(const uint16_t pkt_type=HCI_DM1|HCI_DM3|HCI_DM5|HCI_DH1|HCI_DH3|HCI_DH5, const uint16_t clock_offset=0x0000, const uint8_t role_switch=0x01) noexcept
Establish a HCI BDADDR_BREDR connection to this device.
uint64_t getLastDiscoveryTimestamp() const noexcept
Returns the timestamp in monotonic milliseconds when this device instance has discovered or connected...
HCIStatusCode unpair() noexcept
Unpair this device from the adapter while staying connected.
std::string getResponderSMPPassKeyString() const noexcept
Returns getResponderSMPPassKey() as a canonical string, e.g.
static std::string java_class() noexcept
bool removeStatusListener(const AdapterStatusListenerRef &l) noexcept
Remove the given listener from the list.
SMPPairingState getPairingState() const noexcept
Returns the current SMPPairingState.
SMPIdentityResolvingKey getIdentityResolvingKey(const bool responder) const noexcept
Returns a copy of the Identity Resolving Key (IRK), valid after connection and SMP pairing has been c...
std::shared_ptr< ConnectionInfo > getConnectionInfo() noexcept
Retrieves the current connection info for this device and returns the ConnectionInfo reference if suc...
bool setConnSecurityAuto(const SMPIOCapability iocap_auto) noexcept
Set automatic security negotiation of BTSecurityLevel and SMPIOCapability pairing mode.
HCIStatusCode connectLE(const uint16_t le_scan_interval=24, const uint16_t le_scan_window=24, const uint16_t conn_interval_min=8, const uint16_t conn_interval_max=12, const uint16_t conn_latency=0, const uint16_t conn_supervision_timeout=getHCIConnSupervisorTimeout(0, 15)) noexcept
Establish a HCI BDADDR_LE_PUBLIC or BDADDR_LE_RANDOM connection to this device.
uint16_t getConnectionHandle() const noexcept
Return the HCI connection handle to the LE or BREDR peer, zero if not connected.
PairingMode getPairingMode() const noexcept
Returns the current PairingMode used by the device.
LE_PHYs getRxPhys() const noexcept
Return the Rx LE_PHYs as notified via HCIMetaEventType::LE_PHY_UPDATE_COMPLETE or retrieved via getCo...
BTDevice(const BTDevice &)=delete
BDAddressAndType const & getVisibleAddressAndType() const noexcept
Returns the devices' visible BDAddressAndType, i.e.
HCIStatusCode setConnectedLE_PHY(const LE_PHYs Tx, const LE_PHYs Rx) noexcept
Sets preference of used LE_PHYs for the given connection.
int8_t getTxPower() const noexcept
Return Tx Power Level in dBm with ±6 dB accuracy of device as recognized at discovery and connect.
std::string const getName() const noexcept
Returns the remote device name.
uint64_t getLastUpdateTimestamp() const noexcept
Returns the timestamp in monotonic milliseconds when this device instance underlying data has been up...
EInfoReportRef getEIR() noexcept
Return the merged advertised EInfoReport for this remote device.
HCIStatusCode getConnectedLE_PHY(LE_PHYs &resTx, LE_PHYs &resRx) noexcept
Request and return LE_PHYs bit for the given connection.
void setSignatureResolvingKey(const SMPSignatureResolvingKey &csrk) noexcept
Sets the Signature Resolving Key (CSRK) of this device for pre-paired encryption.
size_type removeAllAssociatedCharListener(const BTGattCharRef &associatedCharacteristic) noexcept
Remove all BTGattCharListener from the list, which are associated to the given BTGattChar.
EInfoReportRef getEIRScanRsp() noexcept
Return the latest advertised EInfoReport AD_SCAN_RSP for this remote device.
std::shared_ptr< BTDevice > getSharedInstance() const noexcept
Returns the shared pointer of this instance managed by the adapter.
bool sendIndication(const uint16_t char_value_handle, const jau::TROOctets &value) noexcept
Send an indication event consisting out of the given value representing the given characteristic valu...
BTSecurityLevel getConnSecurityLevel() const noexcept
Return the BTSecurityLevel, determined when the connection is established.
SMPKeyType getAvailableSMPKeys(const bool responder) const noexcept
Returns the available SMPKeyType mask for the responder (LL slave) or initiator (LL master).
void operator=(const BTDevice &)=delete
GattServiceList_t getGattServices() noexcept
Returns a complete list of shared BTGattService available on this device, initially retrieved via GAT...
void setIdentityResolvingKey(const SMPIdentityResolvingKey &irk) noexcept
Sets the Identity Resolving Key (IRK) of this device for pre-paired encryption.
void setLinkKey(const SMPLinkKey &lk) noexcept
Sets the Link Key (LK) of this device for pre-paired encryption.
~BTDevice() noexcept override
Releases this instance after calling remove().
HCIStatusCode connectDefault() noexcept
Establish a default HCI connection to this device, using certain default parameter.
std::uint32_t getResponderSMPPassKey() const noexcept
Returns the responder SMP passkey, ranging from [0..999999].
std::shared_ptr< BTGattHandler > getGattHandler() noexcept
Returns the connected GATTHandler or nullptr, see connectGATT(), getGattServices() and disconnect().
BTGattServiceRef findGattService(const jau::uuid_t &service_uuid) noexcept
Find a BTGattService by its service_uuid.
BTAdapter & getAdapter() const
Returns the managing adapter.
HCIStatusCode disconnect(const HCIStatusCode reason=HCIStatusCode::REMOTE_USER_TERMINATED_CONNECTION) noexcept
Disconnect the LE or BREDR peer's GATT and HCI connection.
HCIStatusCode uploadKeys(const std::string &smp_key_bin_path, const BTSecurityLevel req_min_level, const bool verbose_) noexcept
Convenient combination of SMPKeyBin::read(), setSMPKeyBin() and uploadKeys() after validating given S...
bool matches_irk(const BDAddressAndType &rpa) noexcept
Returns true if this remote device's IRK matches the given random private address (rpa)
SMPIOCapability getConnIOCapability() const noexcept
Return the set SMPIOCapability value, determined when the connection is established.
std::string get_java_class() const noexcept override
SMPLinkKey getLinkKey(const bool responder) const noexcept
Returns a copy of the Link Key (LK), valid after connection and SMP pairing has been completed.
BTDevice(const BTDevice::ctor_cookie &cc, BTAdapter &adapter, EInfoReport const &r)
Private ctor for private BTDevice::make_shared() intended for friends.
BTGattCharRef findGattChar(const jau::uuid_t &service_uuid, const jau::uuid_t &char_uuid) noexcept
Find a BTGattChar by its service_uuid and char_uuid.
bool addCharListener(const BTGattCharListenerRef &l) noexcept
Add the given BTGattCharListener to the listener list if not already present.
HCIStatusCode setPairingNumericComparison(const bool equal) noexcept
Method sets the numeric comparison result, see PairingMode::NUMERIC_COMPARE_ini.
bool addStatusListener(const AdapterStatusListenerRef &l) noexcept
Add the given AdapterStatusListener to the list if not already present, intended to listen only for e...
HCIStatusCode uploadKeys() noexcept
Upload all set keys to the adapter for pre-pairing.
bool getConnected() noexcept
Return true if the device has been successfully connected, otherwise false.
BDAddressAndType visibleAddressAndType
Either the remote devices' initially reported (resolvable) random address or its (static) public iden...
GATTRole getLocalGATTRole() const noexcept
Return the local GATTRole operating for the remote BTDevice.
int8_t getRSSI() const noexcept
Returns Received Signal Strength Indicator (RSSI) in dBm with ±6 dB accuracy of device as recognized ...
bool isPrePaired() const noexcept
Returns true if this device has completed SMP pairing or keys are set via uploadKeys()
void setLongTermKey(const SMPLongTermKey <k) noexcept
Sets the Long Term Key (LTK) of this device for pre-paired encryption.
std::string toString() const noexcept override
HCIStatusCode setPairingPasskey(const uint32_t passkey) noexcept
Method sets the given passkey entry, see PairingMode::PASSKEY_ENTRY_ini.
bool sendNotification(const uint16_t char_value_handle, const jau::TROOctets &value) noexcept
Send a notification event consisting out of the given value representing the given characteristic val...
size_type removeAllCharListener() noexcept
Remove all BTGattCharListener from the list.
HCIStatusCode setPairingPINCode(const std::string &pinCode) noexcept
Representing a Gatt Characteristic object from the GATTRole::Client perspective.
A thread safe GATT handler associated to one device via one L2CAP connection.
Collection of 'Extended Advertising Data' (EAD), 'Advertising Data' (AD) or 'Extended Inquiry Respons...
Generic Access Service is a mandatory GATT service all peripherals are required to implement.
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.
static SMPKeyBin read(const std::string &fname, const bool verbose_)
Create a new SMPKeyBin instance based upon stored file denoted by fname.
Handles the Security Manager Protocol (SMP) using Protocol Data Unit (PDU) encoded messages over L2CA...
static const uint16_t le_scan_interval
static const uint16_t le_scan_window
SMPAuthReqs
SMP Authentication Requirements Bits, denotes specific bits or whole protocol uint8_t bit-mask.
SMPPairingState
SMP Pairing Process state definition.
SMPKeyType
SMP Key Type for Distribution, indicates keys distributed in the Transport Specific Key Distribution ...
std::string toPassKeyString(const std::uint32_t passKey) noexcept
Returns given passKey ranging [0..999999] as a canonical string, e.g.
SMPOOBDataFlag
Vol 3, Part H, 2.3.3 OOB authentication data.
SMPIOCapability
Vol 3, Part H, 2.3.2 IO capabilities.
@ UNSET
Denoting unset value, i.e.
std::shared_ptr< AdapterStatusListener > AdapterStatusListenerRef
LE_Features
HCI Supported Commands.
std::shared_ptr< BTDevice > BTDeviceRef
LE_PHYs
LE Transport PHY bit values.
std::shared_ptr< EInfoReport > EInfoReportRef
GATTRole
Bluetooth GATT roles.
BTRole
Bluetooth roles from the perspective of the link layer (connection initiator).
BTSecurityLevel
Bluetooth Security Level.
PairingMode
Bluetooth secure pairing mode.
bool operator!=(const BTAdapter &lhs, const BTAdapter &rhs) 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.
EIRDataType
Bit mask of 'Extended Inquiry Response' (EIR) data fields, indicating a set of related data.
@ UNSET
Security Level not set, value 0.
@ REMOTE_USER_TERMINATED_CONNECTION
std::shared_ptr< BTGattCharListener > BTGattCharListenerRef
std::shared_ptr< BTGattChar > BTGattCharRef
std::shared_ptr< BTGattService > BTGattServiceRef
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
int_fast32_t snsize_t
Natural 'ssize_t' alternative using int_fast32_t as its natural sized type.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Representing ACL Datas' L2CAP Frame.
SMP Identity Resolving Key, used for platform agnostic persistence.
Local SMP Link Key, used for platform agnostic persistence, mapping to platform specific MgmtLoadLink...
SMP Long Term Key, used for platform agnostic persistence.
SMP Signature Resolving Key, used for platform agnostic persistence.
std::atomic<T> type with predefined fixed std::memory_order, not allowing changing the memory model o...