diff options
author | Sven Gothel <[email protected]> | 2020-06-27 12:21:13 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-06-27 12:21:13 +0200 |
commit | aeb0f54cc1e622324ce06edff342180500e4ccd1 (patch) | |
tree | deb2459793c461294994210fe720ab6dbb12df1d /api/direct_bt | |
parent | 0d4ce1aa1b5f8fccd1fa8457c0957119269e7f71 (diff) |
HCIHandler: Complete HCIConnection Tracker for full *connect* and disconnect support incl HCI connection handle
We move *connect* and disconnect from DBTManager to HCIHandler,
as we need full control of the connection tracker due to:
- expose HCI connection handle to match actual session for disconnect
- control the disconnect on IOError (no command, purge tracker element and send event)
DBTManager::disconnect:
- no more used
- still aligned the 'send event' on ioerror code path
HCIHandler, DBTManager:
- Own callbacks for verbose mode only added in VERBOSE_ON compilation
Diffstat (limited to 'api/direct_bt')
-rw-r--r-- | api/direct_bt/HCIHandler.hpp | 39 | ||||
-rw-r--r-- | api/direct_bt/HCITypes.hpp | 2 | ||||
-rw-r--r-- | api/direct_bt/MgmtTypes.hpp | 39 |
3 files changed, 46 insertions, 34 deletions
diff --git a/api/direct_bt/HCIHandler.hpp b/api/direct_bt/HCIHandler.hpp index f259bf20..a2f70308 100644 --- a/api/direct_bt/HCIHandler.hpp +++ b/api/direct_bt/HCIHandler.hpp @@ -53,32 +53,33 @@ */ namespace direct_bt { - class HCIHandleBDAddr { + class HCIConnection { public: uint16_t handle; EUI48 address; BDAddressType addressType; public: - HCIHandleBDAddr(const uint16_t handle, const EUI48 &address, const BDAddressType addressType) + HCIConnection(const uint16_t handle, const EUI48 &address, const BDAddressType addressType) : handle(handle), address(address), addressType(addressType) {} - HCIHandleBDAddr(const HCIHandleBDAddr &o) = default; - HCIHandleBDAddr(HCIHandleBDAddr &&o) = default; - HCIHandleBDAddr& operator=(const HCIHandleBDAddr &o) = default; - HCIHandleBDAddr& operator=(HCIHandleBDAddr &&o) = default; + HCIConnection(const HCIConnection &o) = default; + HCIConnection(HCIConnection &&o) = default; + HCIConnection& operator=(const HCIConnection &o) = default; + HCIConnection& operator=(HCIConnection &&o) = default; - bool operator==(const HCIHandleBDAddr& rhs) const - { return handle == rhs.handle; } + bool operator==(const HCIConnection& rhs) const + { return handle == rhs.handle && address == rhs.address; } - bool operator!=(const HCIHandleBDAddr& rhs) const + bool operator!=(const HCIConnection& rhs) const { return !(*this == rhs); } std::string toString() const { - return "HCIHandleBDAddr[handle "+uint16HexString(handle)+ + return "HCIConnection[handle "+uint16HexString(handle)+ ", address="+address.toString()+", addressType "+getBDAddressTypeString(addressType)+"]"; } }; + typedef std::shared_ptr<HCIConnection> HCIConnectionRef; /** * A thread safe singleton handler of the HCI control channel to one controller (BT adapter) @@ -102,10 +103,10 @@ namespace direct_bt { }; static const pid_t pidSelf; - static MgmtEvent::Opcode translate(HCIEventType evt, HCIMetaEventType met); - std::shared_ptr<MgmtEvent> translate(std::shared_ptr<HCIEvent> ev); private: + static MgmtEvent::Opcode translate(HCIEventType evt, HCIMetaEventType met); + const BTMode btMode; const uint16_t dev_id; POctets rbuffer; @@ -130,8 +131,14 @@ namespace direct_bt { std::condition_variable cv_hciReaderInit; std::recursive_mutex mtx_sendReply; // for sendWith*Reply, process*Command, .. - std::vector<HCIHandleBDAddr> disconnectHandleAddrList; - std::recursive_mutex mtx_disconnectHandleAddrList; + std::vector<HCIConnectionRef> connectionList; + std::recursive_mutex mtx_connectionList; + void addTrackerConnection(const EUI48 & address, BDAddressType addrType, const uint16_t handle); + HCIConnectionRef setTrackerConnectionHandle(const EUI48 & address, const uint16_t handle); + HCIConnectionRef findTrackerConnection(const EUI48 & address); + HCIConnectionRef findTrackerConnection(const uint16_t handle); + HCIConnectionRef removeTrackerConnection(const uint16_t handle); + bool removeTrackerConnection(const EUI48 & address); /** One MgmtAdapterEventCallbackList per event type, allowing multiple callbacks to be invoked for each event */ std::array<MgmtEventCallbackList, static_cast<uint16_t>(MgmtEvent::Opcode::MGMT_EVENT_TYPE_COUNT)> mgmtEventCallbackLists; @@ -141,6 +148,7 @@ namespace direct_bt { throw IndexOutOfBoundsException(static_cast<uint16_t>(opc), 1, mgmtEventCallbackLists.size(), E_FILE_LINE); } } + std::shared_ptr<MgmtEvent> translate(std::shared_ptr<HCIEvent> ev); void hciReaderThreadImpl(); @@ -240,7 +248,8 @@ namespace direct_bt { * BT Core Spec v5.2: Vol 4, Part E HCI: 7.1.6 Disconnect command * </p> */ - HCIStatusCode disconnect(const uint16_t conn_handle, const EUI48 &peer_bdaddr, const BDAddressType peer_mac_type, + HCIStatusCode disconnect(const bool ioErrorCause, + const uint16_t conn_handle, const EUI48 &peer_bdaddr, const BDAddressType peer_mac_type, const HCIStatusCode reason=HCIStatusCode::REMOTE_USER_TERMINATED_CONNECTION); /** MgmtEventCallback handling */ diff --git a/api/direct_bt/HCITypes.hpp b/api/direct_bt/HCITypes.hpp index c6b23b9e..9b3e640f 100644 --- a/api/direct_bt/HCITypes.hpp +++ b/api/direct_bt/HCITypes.hpp @@ -659,7 +659,7 @@ namespace direct_bt { std::string baseString() const override { return HCIEvent::baseString()+ ", status "+uint8HexString(static_cast<uint8_t>(getStatus()), true)+" "+getHCIStatusCodeString(getStatus())+ - ", handle "+std::to_string(getHandle())+ + ", handle "+uint16HexString(getHandle())+ ", reason "+uint8HexString(static_cast<uint8_t>(getReason()), true)+" "+getHCIStatusCodeString(getReason()); } diff --git a/api/direct_bt/MgmtTypes.hpp b/api/direct_bt/MgmtTypes.hpp index eb90d0f0..10481378 100644 --- a/api/direct_bt/MgmtTypes.hpp +++ b/api/direct_bt/MgmtTypes.hpp @@ -866,7 +866,7 @@ namespace direct_bt { public: MgmtEvtDeviceConnected(const uint8_t* buffer, const int buffer_len) - : MgmtEvent(buffer, buffer_len), hci_conn_handle(0) + : MgmtEvent(buffer, buffer_len), hci_conn_handle(0xffff) { checkOpcode(getOpcode(), Opcode::DEVICE_CONNECTED); } @@ -900,24 +900,24 @@ namespace direct_bt { class MgmtEvtDeviceConnectFailed : public MgmtEvent { private: - const HCIStatusCode hciRootStatus; + const HCIStatusCode hciStatus; protected: std::string baseString() const override { return MgmtEvent::baseString()+", address="+getAddress().toString()+ ", addressType "+getBDAddressTypeString(getAddressType())+ ", status[mgmt["+uint8HexString(static_cast<uint8_t>(getStatus()))+" ("+getMgmtStatusString(getStatus())+")]"+ - ", hci["+uint8HexString(static_cast<uint8_t>(hciRootStatus))+" ("+getHCIStatusCodeString(hciRootStatus)+")]]"; + ", hci["+uint8HexString(static_cast<uint8_t>(hciStatus))+" ("+getHCIStatusCodeString(hciStatus)+")]]"; } public: MgmtEvtDeviceConnectFailed(const uint8_t* buffer, const int buffer_len) - : MgmtEvent(buffer, buffer_len), hciRootStatus(HCIStatusCode::UNKNOWN) + : MgmtEvent(buffer, buffer_len), hciStatus(HCIStatusCode::UNKNOWN) { checkOpcode(getOpcode(), Opcode::CONNECT_FAILED); } MgmtEvtDeviceConnectFailed(const uint16_t dev_id, const EUI48 &address, const BDAddressType addressType, const HCIStatusCode status) - : MgmtEvent(Opcode::DEVICE_CONNECTED, dev_id, 6+1+1), hciRootStatus(status) + : MgmtEvent(Opcode::CONNECT_FAILED, dev_id, 6+1+1), hciStatus(status) { pdu.put_eui48(MGMT_HEADER_SIZE, address); pdu.put_uint8(MGMT_HEADER_SIZE+6, addressType); @@ -929,7 +929,7 @@ namespace direct_bt { MgmtStatus getStatus() const { return static_cast<MgmtStatus>( pdu.get_uint8(MGMT_HEADER_SIZE+7) ); } /** Return the root reason in non reduced HCIStatusCode space, if available. Otherwise this value will be HCIStatusCode::UNKNOWN. */ - HCIStatusCode getHCIRootStatus() const { return hciRootStatus; } + HCIStatusCode getHCIStatus() const { return hciStatus; } int getDataOffset() const override { return MGMT_HEADER_SIZE+8; } int getDataSize() const override { return getParamSize()-8; } @@ -967,7 +967,8 @@ namespace direct_bt { static DisconnectReason getDisconnectReason(HCIStatusCode hciReason); private: - const HCIStatusCode hciRootReason; + const HCIStatusCode hciReason; + const uint16_t hci_conn_handle; protected: std::string baseString() const override { @@ -976,19 +977,21 @@ namespace direct_bt { return MgmtEvent::baseString()+", address="+getAddress().toString()+ ", addressType "+getBDAddressTypeString(getAddressType())+ ", reason[mgmt["+uint8HexString(static_cast<uint8_t>(reason1))+" ("+getDisconnectReasonString(reason1)+")]"+ - ", hci["+uint8HexString(static_cast<uint8_t>(reason2))+" ("+getHCIStatusCodeString(reason2)+")]]"; + ", hci["+uint8HexString(static_cast<uint8_t>(reason2))+" ("+getHCIStatusCodeString(reason2)+")]]"+ + ", hci_handle "+uint16HexString(hci_conn_handle); } public: MgmtEvtDeviceDisconnected(const uint8_t* buffer, const int buffer_len) - : MgmtEvent(buffer, buffer_len), hciRootReason(HCIStatusCode::UNKNOWN) + : MgmtEvent(buffer, buffer_len), hciReason(HCIStatusCode::UNKNOWN), hci_conn_handle(0xffff) { checkOpcode(getOpcode(), Opcode::DEVICE_DISCONNECTED); } - MgmtEvtDeviceDisconnected(const uint16_t dev_id, const EUI48 &address, const BDAddressType addressType, HCIStatusCode hciRootReason) - : MgmtEvent(Opcode::DEVICE_DISCONNECTED, dev_id, 6+1+1), hciRootReason(hciRootReason) + MgmtEvtDeviceDisconnected(const uint16_t dev_id, const EUI48 &address, const BDAddressType addressType, + HCIStatusCode hciReason, const uint16_t hci_conn_handle) + : MgmtEvent(Opcode::DEVICE_DISCONNECTED, dev_id, 6+1+1), hciReason(hciReason), hci_conn_handle(hci_conn_handle) { - DisconnectReason disconnectReason = getDisconnectReason(hciRootReason); + DisconnectReason disconnectReason = getDisconnectReason(hciReason); pdu.put_eui48(MGMT_HEADER_SIZE, address); pdu.put_uint8(MGMT_HEADER_SIZE+6, addressType); pdu.put_uint8(MGMT_HEADER_SIZE+6+1, static_cast<uint8_t>(disconnectReason)); @@ -999,17 +1002,17 @@ namespace direct_bt { DisconnectReason getReason() const { return static_cast<DisconnectReason>(pdu.get_uint8(MGMT_HEADER_SIZE+7)); } - /** Return the root reason in non reduced HCIStatusCode space, if available. Otherwise this value will be HCIStatusCode::UNKNOWN. */ - HCIStatusCode getHCIRootReason() const { return hciRootReason; } - - /** Returns either the getHCIRootReason() if not HCIStatusCode::UNKNOWN, or the translated DisconnectReason. */ + /** Returns either the HCI reason if given, or the translated DisconnectReason. */ HCIStatusCode getHCIReason() const { - if( HCIStatusCode::UNKNOWN != hciRootReason ) { - return hciRootReason; + if( HCIStatusCode::UNKNOWN != hciReason ) { + return hciReason; } return getHCIReason(getReason()); } + /** Returns the disconnected HCI connection handle, assuming creation occurred via HCIHandler */ + uint16_t getHCIHandle() const { return hci_conn_handle; } + int getDataOffset() const override { return MGMT_HEADER_SIZE+8; } int getDataSize() const override { return getParamSize()-8; } const uint8_t* getData() const override { return getDataSize()>0 ? pdu.get_ptr(getDataOffset()) : nullptr; } |