aboutsummaryrefslogtreecommitdiffstats
path: root/api/direct_bt
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-06-27 12:21:13 +0200
committerSven Gothel <[email protected]>2020-06-27 12:21:13 +0200
commitaeb0f54cc1e622324ce06edff342180500e4ccd1 (patch)
treedeb2459793c461294994210fe720ab6dbb12df1d /api/direct_bt
parent0d4ce1aa1b5f8fccd1fa8457c0957119269e7f71 (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.hpp39
-rw-r--r--api/direct_bt/HCITypes.hpp2
-rw-r--r--api/direct_bt/MgmtTypes.hpp39
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; }