/*
* Author: Sven Gothel
* Copyright (c) 2020 Gothel Software e.K.
* Copyright (c) 2020 ZAFENA AB
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef HCI_HANDLER_HPP_
#define HCI_HANDLER_HPP_
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "BTTypes.hpp"
#include "BTIoctl.hpp"
#include "OctetTypes.hpp"
#include "HCIComm.hpp"
#include "HCITypes.hpp"
#include "MgmtTypes.hpp"
/**
* - - - - - - - - - - - - - - -
*
* Module HCIHandler:
*
* - BT Core Spec v5.2: Vol 4, Part E Host Controller Interface (HCI)
*/
namespace direct_bt {
class HCIHandler; // forward
/**
* HCI Singleton runtime environment properties
*
* Also see {@link DBTEnv::getExplodingProperties(const std::string & prefixDomain)}.
*
*/
class HCIEnv : public jau::root_environment {
friend class HCIHandler;
private:
HCIEnv() noexcept;
const bool exploding; // just to trigger exploding properties
public:
/**
* Poll timeout for HCI reader thread, defaults to 10s.
*
* Environment variable is 'direct_bt.hci.reader.timeout'.
*
*/
const int32_t HCI_READER_THREAD_POLL_TIMEOUT;
/**
* Timeout for HCI command status replies, excluding command complete, defaults to 3s.
*
* Environment variable is 'direct_bt.hci.cmd.status.timeout'.
*
*/
const int32_t HCI_COMMAND_STATUS_REPLY_TIMEOUT;
/**
* Timeout for HCI command complete replies, defaults to 10s.
* This timeout is rather longer, as it may include waiting for pending command complete.
*
* Environment variable is 'direct_bt.hci.cmd.complete.timeout'.
*
*/
const int32_t HCI_COMMAND_COMPLETE_REPLY_TIMEOUT;
/**
* Poll period for certain HCI commands actively waiting for clearance, defaults to 125ms.
*
* Used for LE_Create_Connection or Create_Connection
* when waiting for any pending connection commands or the addressed device's disconnect command to been completed
* up to HCI_COMMAND_COMPLETE_REPLY_TIMEOUT.
*
*
* Environment variable is 'direct_bt.hci.cmd.complete.timeout'.
*
*/
const int32_t HCI_COMMAND_POLL_PERIOD;
/**
* Small ringbuffer capacity for synchronized commands, defaults to 64 messages.
*
* Environment variable is 'direct_bt.hci.ringsize'.
*
*/
const int32_t HCI_EVT_RING_CAPACITY;
/**
* Debug all HCI event communication
*
* Environment variable is 'direct_bt.debug.hci.event'.
*
*/
const bool DEBUG_EVENT;
private:
/** Maximum number of packets to wait for until matching a sequential command. Won't block as timeout will limit. */
const int32_t HCI_READ_PACKET_MAX_RETRY;
public:
static HCIEnv& get() noexcept {
/**
* Thread safe starting with C++11 6.7:
*
* If control enters the declaration concurrently while the variable is being initialized,
* the concurrent execution shall wait for completion of the initialization.
*
* (Magic Statics)
*
* Avoiding non-working double checked locking.
*/
static HCIEnv e;
return e;
}
};
typedef jau::FunctionDef, const HCIACLData::l2cap_frame& /* source */> HCISMPMsgCallback;
typedef jau::cow_vector HCISMPMsgCallbackList;
/**
* A thread safe singleton handler of the HCI control channel to one controller (BT adapter)
*
* Implementation utilizes a lock free ringbuffer receiving data within its separate thread.
*
*
* Controlling Environment variables, see {@link HCIEnv}.
*
*/
class HCIHandler {
public:
enum DefaultsSizeT : jau::nsize_t {
HCI_MAX_MTU = static_cast(HCIConstSizeT::PACKET_MAX_SIZE)
};
static const pid_t pidSelf;
private:
class HCIConnection {
private:
EUI48 address; // immutable
BDAddressType addressType; // immutable
uint16_t handle; // mutable
public:
HCIConnection(const EUI48 &address_, const BDAddressType addressType_, const uint16_t handle_)
: address(address_), addressType(addressType_), handle(handle_) {}
HCIConnection(const HCIConnection &o) = default;
HCIConnection(HCIConnection &&o) = default;
HCIConnection& operator=(const HCIConnection &o) = default;
HCIConnection& operator=(HCIConnection &&o) = default;
const EUI48 & getAddress() const { return address; }
BDAddressType getAddressType() const { return addressType; }
uint16_t getHandle() const { return handle; }
void setHandle(uint16_t newHandle) { handle = newHandle; }
bool equals(const EUI48 & otherAddress, const BDAddressType otherAddressType) const
{ return address == otherAddress && addressType == otherAddressType; }
bool operator==(const HCIConnection& rhs) const
{ return address == rhs.address && addressType == rhs.addressType; }
bool operator!=(const HCIConnection& rhs) const
{ return !(*this == rhs); }
std::string toString() const {
return "HCIConnection[handle "+jau::uint16HexString(handle)+
", address="+address.toString()+", addressType "+getBDAddressTypeString(addressType)+"]";
}
};
typedef std::shared_ptr HCIConnectionRef;
static MgmtEvent::Opcode translate(HCIEventType evt, HCIMetaEventType met) noexcept;
const HCIEnv & env;
const uint16_t dev_id;
POctets rbuffer;
HCIComm comm;
hci_ufilter filter_mask;
std::atomic metaev_filter_mask;
std::atomic opcbit_filter_mask;
inline bool filter_test_metaev(HCIMetaEventType mec) noexcept { return 0 != jau::test_bit_uint32(number(mec)-1, metaev_filter_mask); }
inline void filter_put_metaevs(const uint32_t mask) noexcept { metaev_filter_mask=mask; }
constexpr static void filter_clear_metaevs(uint32_t &mask) noexcept { mask=0; }
constexpr static void filter_all_metaevs(uint32_t &mask) noexcept { mask=0xffffffffU; }
inline static void filter_set_metaev(HCIMetaEventType mec, uint32_t &mask) noexcept { jau::set_bit_uint32(number(mec)-1, mask); }
inline bool filter_test_opcbit(HCIOpcodeBit opcbit) noexcept { return 0 != jau::test_bit_uint64(number(opcbit), opcbit_filter_mask); }
inline void filter_put_opcbit(const uint64_t mask) noexcept { opcbit_filter_mask=mask; }
constexpr static void filter_clear_opcbit(uint64_t &mask) noexcept { mask=0; }
constexpr static void filter_all_opcbit(uint64_t &mask) noexcept { mask=0xffffffffffffffffUL; }
inline static void filter_set_opcbit(HCIOpcodeBit opcbit, uint64_t &mask) noexcept { jau::set_bit_uint64(number(opcbit), mask); }
jau::ringbuffer, nullptr, jau::nsize_t> hciEventRing;
jau::sc_atomic_bool hciReaderShallStop;
std::mutex mtx_hciReaderLifecycle;
std::condition_variable cv_hciReaderInit;
pthread_t hciReaderThreadId;
jau::relaxed_atomic_bool hciReaderRunning;
std::recursive_mutex mtx_sendReply; // for sendWith*Reply, process*Command, ..; Recurses from many..
jau::sc_atomic_bool allowClose;
std::atomic btMode;
std::atomic currentScanType;
std::vector connectionList;
std::vector disconnectCmdList;
std::recursive_mutex mtx_connectionList; // Recurses from disconnect -> findTrackerConnection, addOrUpdateTrackerConnection
/** Exclusive [le] connection command (status + pending completed) one at a time */
std::mutex mtx_connect_cmd;
/**
* Returns a newly added HCIConnectionRef tracker connection with given parameters, if not existing yet.
*
* In case the HCIConnectionRef tracker connection already exists,
* its handle will be updated (see below) and reference returned.
*
* Overwrite existing tracked connection handle with given _valid_ handle only, i.e. non zero!
*
* @param address key to matching connection
* @param addrType key to matching connection
* @param handle ignored for existing tracker _if_ invalid, i.e. zero.
*/
HCIConnectionRef addOrUpdateHCIConnection(std::vector &list,
const EUI48 & address, BDAddressType addrType, const uint16_t handle) noexcept;
HCIConnectionRef addOrUpdateTrackerConnection(const EUI48 & address, BDAddressType addrType, const uint16_t handle) noexcept {
return addOrUpdateHCIConnection(connectionList, address, addrType, handle);
}
HCIConnectionRef addOrUpdateDisconnectCmd(const EUI48 & address, BDAddressType addrType, const uint16_t handle) noexcept {
return addOrUpdateHCIConnection(disconnectCmdList, address, addrType, handle);
}
HCIConnectionRef findHCIConnection(std::vector &list, const EUI48 & address, BDAddressType addrType) noexcept;
HCIConnectionRef findTrackerConnection(const EUI48 & address, BDAddressType addrType) noexcept {
return findHCIConnection(connectionList, address, addrType);
}
HCIConnectionRef findDisconnectCmd(const EUI48 & address, BDAddressType addrType) noexcept {
return findHCIConnection(disconnectCmdList, address, addrType);
}
HCIConnectionRef findTrackerConnection(const uint16_t handle) noexcept;
HCIConnectionRef removeTrackerConnection(const HCIConnectionRef conn) noexcept;
int countPendingTrackerConnections() noexcept;
HCIConnectionRef removeHCIConnection(std::vector &list, const uint16_t handle) noexcept;
HCIConnectionRef removeTrackerConnection(const uint16_t handle) noexcept {
return removeHCIConnection(connectionList, handle);
}
HCIConnectionRef removeDisconnectCmd(const uint16_t handle) noexcept {
return removeHCIConnection(disconnectCmdList, handle);
}
/** One MgmtAdapterEventCallbackList per event type, allowing multiple callbacks to be invoked for each event */
std::array(MgmtEvent::Opcode::MGMT_EVENT_TYPE_COUNT)> mgmtEventCallbackLists;
inline bool isValidMgmtEventCallbackListsIndex(const MgmtEvent::Opcode opc) const noexcept {
return static_cast(opc) < mgmtEventCallbackLists.size();
}
HCISMPMsgCallbackList hciSMPMsgCallbackList;
std::shared_ptr translate(std::shared_ptr ev) noexcept;
void hciReaderThreadImpl() noexcept;
bool sendCommand(HCICommand &req) noexcept;
std::shared_ptr getNextReply(HCICommand &req, int32_t & retryCount, const int32_t replyTimeoutMS) noexcept;
std::shared_ptr getNextCmdCompleteReply(HCICommand &req, HCICommandCompleteEvent **res) noexcept;
std::shared_ptr processCommandStatus(HCICommand &req, HCIStatusCode *status) noexcept;
template
std::shared_ptr processCommandComplete(HCICommand &req,
const hci_cmd_event_struct **res, HCIStatusCode *status) noexcept;
template
std::shared_ptr receiveCommandComplete(HCICommand &req,
const hci_cmd_event_struct **res, HCIStatusCode *status) noexcept;
template
const hci_cmd_event_struct* getReplyStruct(std::shared_ptr event, HCIEventType evc, HCIStatusCode *status) noexcept;
template
const hci_cmd_event_struct* getMetaReplyStruct(std::shared_ptr event, HCIMetaEventType mec, HCIStatusCode *status) noexcept;
public:
HCIHandler(const uint16_t dev_id, const BTMode btMode=BTMode::NONE) noexcept;
HCIHandler(const HCIHandler&) = delete;
void operator=(const HCIHandler&) = delete;
/**
* Releases this instance after issuing {@link #close()}.
*/
~HCIHandler() noexcept { close(); }
void close() noexcept;
inline BTMode getBTMode() const noexcept { return btMode; }
inline void setBTMode(const BTMode mode) noexcept { btMode = mode; }
/** Returns true if this mgmt instance is open, connected and hence valid, otherwise false */
bool isOpen() const noexcept {
return true == allowClose.load() && comm.isOpen();
}
ScanType getCurrentScanType() const noexcept { return currentScanType.load(); }
void setCurrentScanType(const ScanType v) noexcept { currentScanType = v; }
std::string toString() const noexcept;
/**
* Bring up this adapter into a POWERED functional state.
*/
HCIStatusCode startAdapter();
/**
* Bring down this adapter into a non-POWERED non-functional state.
*
* All allocated resources should be freed and the internal state being reset
* in compliance to
*
* BT Core Spec v5.2: Vol 4, Part E HCI: 7.3.2 Reset command
*
*
*/
HCIStatusCode stopAdapter();
/**
* Reset the adapter.
*
* The semantics are specific to the HCI host implementation,
* however, it shall comply at least with the HCI Reset command
* and bring up the device from standby into a POWERED functional state afterwards.
*
*
* BT Core Spec v5.2: Vol 4, Part E HCI: 7.3.2 Reset command
*
*/
HCIStatusCode resetAdapter();
/**
* BT Core Spec v5.2: Vol 4, Part E HCI: 7.3.2 Reset command
*/
HCIStatusCode reset() noexcept;
HCIStatusCode getLocalVersion(HCILocalVersion &version) noexcept;
/**
* Sets LE scanning parameters.
*
* BT Core Spec v5.2: Vol 4 HCI, Part E HCI Functional: 7.8.10 LE Set Scan Parameters command
* BT Core Spec v5.2: Vol 6 LE, Part B Link Layer: 4.4.3 Scanning State
*
*
* Scan parameters control advertising (AD) Protocol Data Unit (PDU) delivery behavior.
*
*
* Should not be called while LE scanning is active, otherwise HCIStatusCode::COMMAND_DISALLOWED will be returned.
*
*
* @param own_mac_type HCILEOwnAddressType::PUBLIC (default) or random/private.
* @param le_scan_interval in units of 0.625ms, default value 24 for 15ms; Value range [4 .. 0x4000] for [2.5ms .. 10.24s]
* @param le_scan_window in units of 0.625ms, default value 24 for 15ms; Value range [4 .. 0x4000] for [2.5ms .. 10.24s]. Shall be <= le_scan_interval
* @param filter_policy 0x00 accepts all PDUs (default), 0x01 only of whitelisted, ...
* @param le_scan_active true enables delivery of active scanning PDUs, otherwise no scanning PDUs shall be sent (default)
*/
HCIStatusCode le_set_scan_param(const HCILEOwnAddressType own_mac_type=HCILEOwnAddressType::PUBLIC,
const uint16_t le_scan_interval=24, const uint16_t le_scan_window=24,
const uint8_t filter_policy=0x00, const bool le_scan_active=false) noexcept;
/**
* Starts or stops LE scanning.
*
* BT Core Spec v5.2: Vol 4, Part E HCI: 7.8.11 LE Set Scan Enable command
*
* @param enable true to enable discovery, otherwise false
* @param filter_dup true to filter out duplicate AD PDUs (default), otherwise all will be reported.
*/
HCIStatusCode le_enable_scan(const bool enable, const bool filter_dup=true) noexcept;
/**
* Start LE scanning, i.e. performs le_set_scan_param() and le_enable_scan() in one atomic operation.
*
* BT Core Spec v5.2: Vol 4 HCI, Part E HCI Functional: 7.8.10 LE Set Scan Parameters command
* BT Core Spec v5.2: Vol 4, Part E HCI: 7.8.11 LE Set Scan Enable command
*
*
* Scan parameters control advertising (AD) Protocol Data Unit (PDU) delivery behavior.
*
*
* Should not be called while LE scanning is active, otherwise HCIStatusCode::COMMAND_DISALLOWED will be returned.
*
*
* Method will report errors.
*
*
* @param filter_dup true to filter out duplicate AD PDUs (default), otherwise all will be reported.
* @param own_mac_type HCILEOwnAddressType::PUBLIC (default) or random/private.
* @param le_scan_interval in units of 0.625ms, default value 24 for 15ms; Value range [4 .. 0x4000] for [2.5ms .. 10.24s]
* @param le_scan_window in units of 0.625ms, default value 24 for 15ms; Value range [4 .. 0x4000] for [2.5ms .. 10.24s]. Shall be <= le_scan_interval
* @param filter_policy 0x00 accepts all PDUs (default), 0x01 only of whitelisted, ...
* @param le_scan_active true enables delivery of active scanning PDUs, otherwise no scanning PDUs shall be sent (default)
*/
HCIStatusCode le_start_scan(const bool filter_dup=true,
const HCILEOwnAddressType own_mac_type=HCILEOwnAddressType::PUBLIC,
const uint16_t le_scan_interval=24, const uint16_t le_scan_window=24,
const uint8_t filter_policy=0x00, const bool le_scan_active=false) noexcept;
/**
* Establish a connection to the given LE peer.
*
* BT Core Spec v5.2: Vol 4, Part E HCI: 7.8.12 LE Create Connection command
*
*
* Set window to the same value as the interval, enables continuous scanning.
*
*
* The supervising timeout period is the time it takes before a devices gives up on the link if no packets are received.
* Hence this parameter influences the responsiveness on a link loss.
* A too small number may render the link too unstable, it should be at least 6 times of the connection interval.
*
* To detect a link loss one can also send a regular ping to check whether the peripheral is still responding, see GATTHandler::ping().
*
*
* Implementation tries to mitigate HCIStatusCode::COMMAND_DISALLOWED failure due to any pending connection commands,
* waiting actively up to HCIEnv::HCI_COMMAND_COMPLETE_REPLY_TIMEOUT, testing every HCIEnv::HCI_COMMAND_POLL_PERIOD if resolved.
*
* In case of no resolution, i.e. another HCI_LE_Create_Connection command is pending,
* HCIStatusCode::COMMAND_DISALLOWED will be returned by the underlying HCI host implementation.
*
*
* Implementation tries to mitigate HCIStatusCode::CONNECTION_ALREADY_EXISTS failure due to a specific pending disconnect command,
* waiting actively up to HCIEnv::HCI_COMMAND_COMPLETE_REPLY_TIMEOUT, testing every HCIEnv::HCI_COMMAND_POLL_PERIOD if resolved.
*
* In case of no resolution, i.e. the connection persists,
* HCIStatusCode::CONNECTION_ALREADY_EXISTS will be returned by the underlying HCI host implementation.
*
* @param peer_bdaddr
* @param peer_mac_type
* @param own_mac_type
* @param le_scan_interval in units of 0.625ms, default value 24 for 15ms; Value range [4 .. 0x4000] for [2.5ms .. 10.24s]
* @param le_scan_window in units of 0.625ms, default value 24 for 15ms; Value range [4 .. 0x4000] for [2.5ms .. 10.24s]. Shall be <= le_scan_interval
* @param conn_interval_min in units of 1.25ms, default value 12 for 15ms; Value range [6 .. 3200] for [7.5ms .. 4000ms]
* @param conn_interval_max in units of 1.25ms, default value 12 for 15ms; Value range [6 .. 3200] for [7.5ms .. 4000ms]
* @param conn_latency slave latency in units of connection events, default value 0; Value range [0 .. 0x01F3].
* @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].
* @return
*/
HCIStatusCode le_create_conn(const EUI48 &peer_bdaddr,
const HCILEPeerAddressType peer_mac_type=HCILEPeerAddressType::PUBLIC,
const HCILEOwnAddressType own_mac_type=HCILEOwnAddressType::PUBLIC,
const uint16_t le_scan_interval=24, const uint16_t le_scan_window=24,
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;
/**
* Establish a connection to the given BREDR (non LE).
*
* BT Core Spec v5.2: Vol 4, Part E HCI: 7.1.5 Create Connection command
*
*
* Implementation tries to mitigate HCIStatusCode::COMMAND_DISALLOWED failure due to any pending connection commands,
* waiting actively up to HCIEnv::HCI_COMMAND_COMPLETE_REPLY_TIMEOUT, testing every HCIEnv::HCI_COMMAND_POLL_PERIOD if resolved.
*
* In case of no resolution, i.e. another HCI_Create_Connection command is pending,
* HCIStatusCode::COMMAND_DISALLOWED will be returned by the underlying HCI host implementation.
*
*
* Implementation tries to mitigate HCIStatusCode::CONNECTION_ALREADY_EXISTS failure due to a specific pending disconnect command,
* waiting actively up to HCIEnv::HCI_COMMAND_COMPLETE_REPLY_TIMEOUT, testing every HCIEnv::HCI_COMMAND_POLL_PERIOD if resolved.
*
* In case of no resolution, i.e. the connection persists,
* HCIStatusCode::CONNECTION_ALREADY_EXISTS will be returned by the underlying HCI host implementation.
*
*/
HCIStatusCode create_conn(const EUI48 &bdaddr,
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;
/**
* Disconnect an established connection.
*
* BT Core Spec v5.2: Vol 4, Part E HCI: 7.1.6 Disconnect command
*
*/
HCIStatusCode disconnect(const uint16_t conn_handle, const EUI48 &peer_bdaddr, const BDAddressType peer_mac_type,
const HCIStatusCode reason=HCIStatusCode::REMOTE_USER_TERMINATED_CONNECTION) noexcept;
/**
* Clear all internal states, i.e. connection and disconnect lists.
*/
void clearAllStates() noexcept;
/** MgmtEventCallback handling */
/**
* Appends the given MgmtEventCallback to the named MgmtEvent::Opcode list,
* if it is not present already (opcode + callback).
* @param opc opcode index for callback list, the callback shall be added to
* @param cb the to be added callback
* @return true if newly added or already existing, false if given MgmtEvent::Opcode is out of supported range.
*/
bool addMgmtEventCallback(const MgmtEvent::Opcode opc, const MgmtEventCallback &cb) noexcept;
/** Returns count of removed given MgmtEventCallback from the named MgmtEvent::Opcode list. */
int removeMgmtEventCallback(const MgmtEvent::Opcode opc, const MgmtEventCallback &cb) noexcept;
/** Removes all MgmtEventCallbacks from the to the named MgmtEvent::Opcode list. */
void clearMgmtEventCallbacks(const MgmtEvent::Opcode opc) noexcept;
void addSMPMsgCallback(const HCISMPMsgCallback & l);
int removeSMPMsgCallback(const HCISMPMsgCallback & l);
/** Removes all MgmtEventCallbacks from all MgmtEvent::Opcode lists and all SMPSecurityReqCallbacks. */
void clearAllCallbacks() noexcept;
/** Manually send a MgmtEvent to all of its listeners. */
void sendMgmtEvent(std::shared_ptr event) noexcept;
/**
* FIXME / TODO: Privacy Mode / Pairing / Bonding
*
* LE Secure Connections:
*
* BT Core Spec v5.2: Vol 1, Part A Architecture: 5.4 LE Security
* BT Core Spec v5.2: Vol 3, Part C GAP: 10.2 LE SECURITY MODES
* BT Core Spec v5.2: Vol 3, Part H SM: 2 Security Manager
* BT Core Spec v5.2: Vol 3, Part H SM: 2.3.5 Pairing: 2.3.5.6 LE Secure Connections pairing phase 2
* BT Core Spec v5.2: Vol 3, Part H SM: 2.3.5 Pairing: 2.3.5.6.3 LE Authentication stage 1 – Passkey Entry
* BT Core Spec v5.2: Vol 3, Part H SM: 3 Security Manager Protocol (SMP) fixed channel over L2CAP
*
*
* LE Legacy Pairing** similar to BREDR like: Secure Simple Pairing (SSP)
* LE Secure Connections functional equivalent to SSP, using 128 bit Long Term Key (LTK)
*
*
*
* BT Core Spec v5.2: Vol 1, Part A Architecture: 5 Security architecture
* BT Core Spec v5.2: Vol 1, Part A Architecture: 5.4 LE Security
* BT Core Spec v5.2: Vol 1, Part A Architecture: 5.4.5 LE Privacy feature
* - device privacy mode (mixed mode, also accept other peer address)
* - network privacy mode (only private address - default!)
* -> add device to resolving list, implying being added to device white list!
*
* BT Core Spec v5.2: Vol 3, Part C GAP: 10.2 LE SECURITY MODES
*
* BT Core Spec v5.2: Vol 4, Part E HCI: 7.8.77 LE Set Privacy Mode command
* BT Core Spec v5.2: Vol 6 LE Adapter, Part B Link Layer Spec: 4.7 Resolving List
*
* FIXME: TODO
*
* @return
* HCIStatusCode le_set_privacy_mode();
*
* Fills buffer with random bytes, usually 16 bytes for 128 bit key.
* FIXME: TODO
* static bool generateIRK(uint8_t *buffer, int size);
*/
};
} // namespace direct_bt
#endif /* DBT_HANDLER_HPP_ */