aboutsummaryrefslogtreecommitdiffstats
path: root/api
Commit message (Collapse)AuthorAgeFilesLines
* AdapterStatusListener::deviceFound: Resolve sharedDevices persistence of ↵Sven Gothel2021-01-172-11/+24
| | | | | | | | | | found device via return value While we keep the device instance temporarily alive within discoveredDevices until next removeDiscoveredDevices() eg at startDiscover(), we only keep it within persistent sharedDevices list if at least one deviceFound implementation returns true. This allows user to minimize the sharedDevices footprint when rejecting the device w/o being required to call device.remove().
* DBTAdapter: USe pre-incr, use typedef device_list_t (shorten shared device ↵Sven Gothel2021-01-151-5/+6
| | | | darray)
* Replace std::vector w/ jau::darray and jau::cow_vector with jau::cow_darray ↵Sven Gothel2021-01-1115-57/+55
| | | | | | | | | | | | | | | | | | | | | (performance and CoW correctness) Merging jaulib's darray and cow_darray into direct_bt. As explained in jaulib, motivation behing darray + cow_darray is to allow fine grained controll over the CoW's storage to have certain guarantess on its operation. Iterator and push_back() enhancments are a few of these. Fixes performed while replacing: - DBTDevice getGATTServices(): Take the copy as it will be returned. - GATTHandler removeAllAssociatedCharacteristicListener(): Try to delete all matching! Don't stop loop after found and erased first, continue. Also return number of erased elements, not just true. - DBTManager ctor: Don't work on CoW snapshot, work on CoW - Simplified many loops / iterations
* Replace jau::cow_vector with jau::cow_darray (simple type replacement, ↵Sven Gothel2021-01-066-13/+13
| | | | compatible API)
* TinyB: Handle no RTTI in BluetoothManager: Removing the 'find' method ↵Sven Gothel2021-01-051-0/+10
| | | | implementation w/o RTTI
* Fix operator==(const EUI48& lhs, const EUI48& rhs): Sloppy typo lhs -> rhs ↵Sven Gothel2020-12-251-4/+1
| | | | for 2nd argument; Remove operator<(..)
* smart_ptr-5: Use std::make_shared<T>(..) where possible, reducing two memory ↵Sven Gothel2020-12-141-0/+3
| | | | | | | | | allocations to one smart_ptr change series, commit #5 This series started with commit cafd8d1f3689135eae36854a9cca4def690045fd, see for details.
* smart_ptr-4: Pass GATTCharacteristic TROOctets notification and indication ↵Sven Gothel2020-12-141-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | as const reference instead of std::shared_ptr to GATTCharacteristicListener No extra (shared POctets) copy is needed nor desired here. +++ smart_ptr change series, commit #4 This series started with commit cafd8d1f3689135eae36854a9cca4def690045fd, see for details. +++ Contemplated whether to even drop the 'AttPDUMsg::getSpecialized(rbuffer.get_ptr(), static_cast<jau::nsize_t>(len))' for these callbacks, as a copy is not needed. However, the ATTPDUMsg constructor validate data consistency, which would need to be replaced (-> more work). Hence keep this portion as is, may revisit for very tight resources on certain embedded devices. Note: The GATTCharacteristicListener for Native -> Java also perform one copy into a new byte array. This can't be avoided w/o some NIO rework. However, let's have all these thoughts noted here .. just in case.
* smart_ptr-3: Handle HCIEvent + SMPPDUMsg instances via std::unique_ptr ↵Sven Gothel2020-12-147-55/+69
| | | | | | | | | | | | | | | | | | | | | | | | | instead of shared_ptr; Callbacks use 'const <T> &' now. smart_ptr change series, commit #2 This series started with commit cafd8d1f3689135eae36854a9cca4def690045fd, see for details. Refined MgmtMsg clone template and added same to HCIPacket and SMPPDUMsg. Notable: To have this clone template to work, the default copy-constructor should not be deleted. Hence removing the const qualifier from timestamp and manual default/deleted directives. +++ At this point, all high frequent objects (ATT, HCI w/ SMP, Mgmt events) use std::unique_ptr and therefor reduce a certain overhead. Further, this constraint also removes a potential 'build in' leaks, in case a callback method keeps the shared_ptr instance. Now, callbacks only received the const reference and if so desired, need to create a copy themselves.
* smart_ptr-2: Handle MgmtEvent instances via std::unique_ptr instead of ↵Sven Gothel2020-12-144-24/+45
| | | | | | | | | | | | | | | shared_ptr; MgmtEvent Callbacks use 'const MgmtEvent&' now. smart_ptr change series, commit #2 This series started with commit cafd8d1f3689135eae36854a9cca4def690045fd, see for details. Due to using unique_ptr<MgmtEvent>, we cannot pass them to the user (loss of ownership via std::move). Hence it must be enough to pass a reference to the direct constant type. In case a user needs to cache the event for later, a copy must be created, see 'template<class T> MgmtMsg::clone(const T& source) noexcept' for this purpose.
* smart_ptr-1: Handle AttPDUMsg instances via std::unique_ptr instead of ↵Sven Gothel2020-12-137-20/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | std::shared_ptr for more efficancy; Use std::make_unique where possible smart_ptr change series, commit #1 For high frequent objects, it is desired to reduce resources and overhead as much as possible. unique_ptr has zero overhead, while shared_ptr own a little storage for the reference counter. Using unique_ptr forces us to move the instance from the receiving reading thread to the ringbuffer and moving it out later. Hence the changes in jau::ringbuffer earlier. Using std::make_unique is not really required, as unique_ptr has no resource overhead, hence 'unique_ptr( new Something() )' is only one allocation. However, this smart_ptr change series will review all smart pointer use cases and in case a shared_ptr is required like DBTDevice of GATTCharacteristic elements of GATTServices etc, we shall use std::make_shared to fold two allocations into one. Note: 'shared_ptr( new Something() )' implies two allocations. Current implementation state allows these optimizations, as the use cases for these data types are well understood. Earlier it was not feasible to undertake constraining efforts, as it was not clear whether other actors like to share a resource, like a uuid_t for example.
* Adopt new BDAddressAndType key value across projectSven Gothel2020-12-126-127/+122
| | | | See commit bc9d1c0d2942ce24019b432198f2d4c0d00aee19
* Revamp native + java types: EUI48 and add BDAddressAndTypeSven Gothel2020-12-121-22/+200
| | | | | | | | | | | | | | | | EUI48: add hash-code, fast compare, include static const ANY_*DEVICE) - added Hash specialization in namespace std for hash-map (C++) BDAddressAndType: Added, to be utilizes as actual unique device address having EUI48 + BDAddressType - fully self sufficient w/ comparison, hash and matching methods - added Hash specialization in namespace std for hash-map (C++) Goal for BDAddressAndType is to replace separate EUI48 + BDAddressType, providing BluetoothDevice / DBTDevice with a unique single key entry. This will allow us to properly use a hash-map (new for our C++ code) Further we emphasize on the unique key contract, which requires the BDAddressAndType, as EUI48 is not enough.
* Added support for SMPSignatureResolvingKeyInfo and SMPKeyType querySven Gothel2020-12-102-35/+51
| | | | | | | - Added SMPSignatureResolvingKeyInfo (native + Java) key retrieval - Rename SMPKeyDist -> SMPKeyType: For general use, e.g. new query 'SMPKeyType getAvailableSMPKeys(const bool responder)' - Added SMPKeyType.java - Added DBTDevice::getAvailableSMPKeys(const bool responder): Allowing user to act upon specific keys when available (native + java)
* SMPTypes: Add SMPSignatureResolvingKeyInfo (WIP..)Sven Gothel2020-12-101-0/+74
|
* Process MgmtEvent::Opcode::NEW_LONG_TERM_KEY: Allowing updatePairingState() ↵Sven Gothel2020-12-102-3/+5
| | | | | | | | | | | if SMPKeyDist::ENC_KEY not done yet MgmtEvent::Opcode::NEW_LONG_TERM_KEY shall become handy when using Secure Connections (SC), as the generated / derived LTKs will not be transported via SMP. Also: - DBTDevice::clearSMPStates(): Clear keys - Extract checkPairingKeyDistributionComplete(..) for hciSMPMsgCallback() and updatePairingState()
* DBTDevice::setLongTermKeyInfo(): Only allowed if not yet connectedSven Gothel2020-12-101-0/+3
|
* MgmtLongTermKeyInfo: Add toSMPLongTermKeyInfo() conversionSven Gothel2020-12-101-1/+38
|
* SMPLongTermKeyInfo: Encode RESPONDER (or INITIATOR) within its Property bit ↵Sven Gothel2020-12-104-12/+15
| | | | | | | mask, determining key role; ... DBTDevice::setLongTermKeyInfo() writes given key to pairing_data.ltk_resp or pairing_data.ltk_init to reflect proper state.
* BluetoothDevice: Support SMPLongTermKeyInfo via ↵Sven Gothel2020-12-101-1/+1
| | | | | | | | | | | | [get/set]LongTermKeyInfo(..), tested with DBTScanner10.java Java + Native test are now on par, may share the LTK binary file in example. On loading a pre-existing key when device found and before connecting, BlueZ/Kernel will try the uploaded key and no pairing procedure is being performed. This tested with explicit unpair before uploading the LTK, to ensure the pre-existing keys have been deleted.
* Add SMPLongTermKeyInfo::isValid()Sven Gothel2020-12-101-1/+3
|
* SMPLongTermKeyInfo: Use Property enum class bitfield instead of single ↵Sven Gothel2020-12-092-6/+58
| | | | boolean; Add Java implementation for SMPLongTermKeyInfo
* DBTManager::uploadLongTermKey(..): Return HCIStatusCode (platform agnostic; ↵Sven Gothel2020-12-091-1/+1
| | | | TODO: Use it everywhere possible)
* DBTDevice: Add get/set methods for SMPLongTermKeyInfo (tested); TODO: JavaSven Gothel2020-12-091-0/+17
|
* DBTDevice::address: Earmark (FIXME) to become mutable for resolvable -> ↵Sven Gothel2020-12-091-3/+3
| | | | identity during pairing
* DBTDevice::PairingState: Drop atomic fields for sc_atomic_critical sync(); ↵Sven Gothel2020-12-091-15/+21
| | | | Use SMPLongTermKeyInfo; Add IRK and CSRK state.
* DBTManager: Added platform agnostic uploadLongTermKeyInfo(..)Sven Gothel2020-12-091-2/+6
|
* SMPTypes.hpp: Add platform agnostic SMPLongTermKeyInfoSven Gothel2020-12-091-0/+27
|
* MgmtTypes: Complete Key Info Types incl. Mgmt*KeyType deduction from ↵Sven Gothel2020-12-091-117/+230
| | | | | | | | | | | | | | | | | | platform agnostic setting (auth + sc) New Mgmt*KeyType: - MgmtLinkKeyType for MgmtLinkKeyInfo - MgmtLTKType (incl deduction from boolean use_auth and use_sc) for MgmtLongTermKeyInfo - MgmtCSRKType for MgmtSignatureResolvingKeyInfo New/Updated Mgmt*KeyInfo: - MgmtLinkKeyInfo for MgmtLoadLinkKeyCmd, MgmtEvtNewLinkKey - MgmtLongTermKeyInfo for MgmtLoadLongTermKeyCmd (added to DBTManager and tested), MgmtEvtNewLongTermKey - MgmtIdentityResolvingKeyInfo for MgmtLoadIdentityResolvingKeyCmd, MgmtEvtNewIdentityResolvingKey - MgmtSignatureResolvingKeyInfo for MgmtEvtNewSignatureResolvingKey New Event Types: - MgmtEvtNewSignatureResolvingKey
* SMPPairingState::COMPLETED + AdapterStatusListener::deviceReady(): Refine ↵Sven Gothel2020-12-093-6/+9
| | | | API doc
* DBTDevice::hciSMPMsgCallback: Cache ENC_KEY (ltk, ediv + rand) for ↵Sven Gothel2020-12-041-0/+6
| | | | processing (next step)
* MgmtLongTermKey + MgmtLinkKey: Add note that POD struct denotes a byte ↵Sven Gothel2020-12-041-10/+26
| | | | | | | | stream w/o endian conversion, ... MgmtLongTermKey: Also add note about master field (confusion, IMHO inverted logic from mgmt), as well as using more natural field names and apply same data representation as SMP types aligned w/ btmon's SMP types (not btmon's MGMT types).
* SMPTypes: Inject a tag type SMPEncKeyByteStream, denoting encryption key(s) ↵Sven Gothel2020-12-041-44/+103
| | | | | | byte stream w/o endian conversion, ... hence implement all put/get method of its implementations using non-endian conversion 1:1 read/write operations.
* OctetTypes: Add put_bytes[_nc](..) as a variation to conveniently memcpy ↵Sven Gothel2020-12-041-0/+8
| | | | into the buffer w/o TROctets
* DBTAdapter::[un]lockConnect[Any](..): New single device connect-command impl ↵Sven Gothel2020-12-032-73/+46
| | | | | | | | | | | | | | | | | | | | | | using mutex + condition-wait; Lock-free DBTDevice::setConn*Security*(..) .. DBTAdapter::[un]lockConnect[Any](..): New single device connect-command impl using mutex + condition-wait; - previous atomic use was too complicated - only provide lockConnect(.., SMPIOCapability) and unlockConnect[Any](), the former gets called at connect with cached SMPIOCapability user value and the latter gets called ASAP after successful connection and L2CAP config or at failure / power-off. - to debug locking, set direct_bt.debug.adapter.lock environment variable, e.g. setenv("direct_bt.debug", "true,adapter.lock", 1 /* overwrite */); Lock-free DBTDevice::setConn*Security*(..) .. - check constrains (already connected etc) - cache SMPIOCapability for lockConnect() @ connect*() command - cache BTSecurityLevel for L2CAP config when connected Provide [DBT|Bluetooth]Device::setConnSecurityBest(..) for convenience.
* DBTAdapter: One Connect Command at a time due to SMPIOCapability (1/2 WIP)Sven Gothel2020-12-031-20/+5
| | | | | | | | | | | | | | We need to lock all Connect Commands starting with [1] - connectLE or connectBREDR, or [2] - setConn*Security* for SMPIOCapability (FIXME) The release ASAP on - success after connect from within DBTDevice::processL2CAPSetup(..) - disconnect or connect-failure or power-off TODO: Above [2] locking at setConn* shall be remove by cashing the attribute and locking at [1] connect* command. This shall give a more natural API and expected behavior.
* MgmtTypes: Support PAIR_DEVICE (async - pending reply), CANCEL_PAIR_DEVICE ↵Sven Gothel2020-12-034-15/+149
| | | | | | | | | | | | | | | | | | and UNPAIR_DEVICE: DBTManager <-> DBTDevice PAIR_DEVICE's COMMAND_COMPLETE reply -> Synthetic pending event PAIR_DEVICE_COMPLETE (MgmtEvtPairDeviceComplete) - Testing disclosed that Mgmt's pairDevice(..) is not suitable nor stable - within our workflow: SCAN - FOUND - *CONNECT or PAIR* .. - Can't call adapter.stopDiscovery() after FOUND, otherwise pairDevice() fails - Not able to set all scan params (even though connection params can be frontloaded) - Not producing proper PRE_PAIRED behavior (ALREADY_PAIRED doesn't allow us to GATT process) The above despite the very usable way of setting SMPIOCapability per connection w/o our hacky blocked per adapter setting (one connect command at one time). However, having it supported for testing, allowed us to compare with our workflow and just using connect.
* Add Mapping from MgmtStatus -> HCIStatusCode, include value subset of former ↵Sven Gothel2020-12-032-0/+24
| | | | within latter (general HCIStatusCode use)
* SMPTypes.hpp: Complete Phase 3 SMPPDUMsg types (Fix arg names + API doc + ↵Sven Gothel2020-12-031-34/+80
| | | | string representation)
* SMPTypes.hpp: Move SMPPairingMsg::KeyDistFormat -> SMPKeyDist (top-level) ↵Sven Gothel2020-12-031-85/+106
| | | | and add bit-operator
* Fix SMPPairingState (Phase 3); Add PairingMode::PRE_PAIRED;Sven Gothel2020-12-034-7/+25
| | | | | | | | | | | | | | | | | | | | | | | HCIEventType::ENCRYPT_CHANGE: mgmtEvHCIEncryptionChangedHCI / DBTDevice::updatePairingState(..): - BT Core Spec v5.2: Vol 4, Part E HCI: 7.7.8 HCIEventType::ENCRYPT_CHANGE - Allow HCIEventType::ENCRYPT_CHANGE to toggle state to COMPLETED if no SMP pairing in process (maybe REQUESTED_BY_RESPONDER at maximum). This indicates: PairingMode::PRE_PAIRED (new). DBTDevice::processL2CAPSetup(): - Directly process processDeviceReady(..) if !l2cap_auth, skipping AUTH_FAILURE having no security. DBTDevice::processDeviceReady(..): - sleep 100ms if in PairingMode::PRE_PAIRED mode (magic) - upair() if connectGATT() fails _and_ in PairingMode::PRE_PAIRED mode DBTDevice::hciSMPMsgCallback - Better DBG_PRINT alternative (use multiline) - Track SMPKeyDist from initiator and responder to identify end of Phase 3 (distribution) - Complete Phase 3: SMP Key & Value Distribution phase -> COMPLETED - TODO: Facility to have keys persisting.
* PairingMode getPairingMode(..): Simplify argument name le_sc_pairing -> use_scSven Gothel2020-12-031-4/+4
|
* DBTManager: Use mgmtEventAnyCB() for all debug output, added if ↵Sven Gothel2020-12-011-20/+0
| | | | jau::environment::get().debug
* DBTDevice::clearSMPStates(): Shall not clear pairing_data.sec_level_user on ↵v2.1.34Sven Gothel2020-11-251-3/+3
| | | | connected as used for security setup @ connect
* DBTDevice: Clarify setConn* Security parameter API: Provide more versatile ↵Sven Gothel2020-11-242-33/+129
| | | | | | overloaded variant and simplified API entries. setConnSecurityLevel(..) no more sets SMPIOCapability, only advise in API doc to avoid complexity.
* Have doxygen produce links to enum class type using ::EnumClassType ↵Sven Gothel2020-11-245-46/+46
| | | | | | | (however, link to its value fails) Note: I had no success to have doxygen produce links to 'enum class' values, i.e. '::BTSecurityLevel::NONE' and all permutations of '::' and '#' did not succeed.
* Documentation: Add notes re 'LE Secure Connections and LE legacy pairing'Sven Gothel2020-11-241-0/+4
|
* Security: Re-enable auth-failure (try w/o security); Resolve ↵Sven Gothel2020-11-231-4/+3
| | | | | | | | | | | | | | | | | | | L2CAPComm::open() BT_SECURITY deadlock Re-enable auth-failure (try w/o security) from hciSMPMsgCallback() Resolve L2CAPComm::open() BT_SECURITY deadlock - set sec_level after connect() within L2CAPComm::open() - see macro SET_BT_SECURITY_POST_CONNECT in L2CAPComm.cpp - L2CAPComm::setBTSecurityLevel() ignores unchanged BT_SECURITY value. Otherwise it fails on BTSecurityLevel::NONE, don't ask - don't know, even after BlueZ/Kernel review. Working w/ DBTScanner10: - Device w/o security: No special settings in commandline - Device w/ Secure Connection SMP: Only set passkey in commandline - Device w/ legacy encryption only (no auth): Set BTSecurityLevel::ENC_ONLY or SMPIOCapabilities::NO_INPUT_NO_OUTPUT or both.
* Enc/Auth: Allow full PairingMode modulation via BTSecurityLevel and ↵Sven Gothel2020-11-232-9/+91
| | | | | | | | | | | | | | | | | | | | SMPIOCapability: Like force JUST_WORKS by BTSecurityLevel::ENC_ONLY or SMPIOCapability::NO_INPUT_NO_OUTPUT To allow non-auth encryption mode, user _must_ set BTSecurityLevel, SMPIOCapability or both appropriately. Otherwise BlueZ/Kernel will chose authenticated SMP negotiation. - DBTDevice::setConnSecurityLevel(): Will adjust SMPIOCapability automatically, if not yet set - DBTDevice::setConnIOCapability() and DBTDevice::setConnSecurity(): Perform plain setting - DBTDevice::processL2CAPSetup(): Sets BTSecurityLevel appropriately either if no-auth SMPIOCapability::NO_INPUT_NO_OUTPUT is chosen, or based on LE_Enc feature bit and/or SC capability. Using new HCI ENCRYPT_CHANGE and ENCRYPT_KEY_REFRESH_COMPLETE, for non-auth BTSecurityLevel::ENC_ONLY endpoint to set SMPPairingState::PROCESS_COMPLETED + PairingMode::JUST_WORKS. Note: In the non-auth legacy mode, the SMP (ACL.SMP) is not being used. ....
* DBTManager: Support configurable SMPIOCapability per adapter, default is ↵Sven Gothel2020-11-231-0/+17
| | | | | | | | still SMPIOCapability::KEYBOARD_ONLY for PairingMode::PASSKEY_ENTRY Use the following methods to read/write SMPIOCapability per adapter (dev_id): + bool setIOCapability(const uint16_t dev_id, const SMPIOCapability io_cap, SMPIOCapability& pre_io_cap) noexcept; + SMPIOCapability getIOCapability(const uint16_t dev_id) const noexcept;