aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-05-02 03:15:31 +0200
committerSven Gothel <[email protected]>2020-05-02 03:15:31 +0200
commit6b7c067e29f8f81b80919c267beca1e05b098216 (patch)
treeccba74eb42652507d210368d06b3eff1d834d7f2
parent3df6239693ae0acdb0a067646fbacb99fcc2e5fe (diff)
DBTManager::disconnect(..): send explicit MgmtEvtDeviceDisconnected to listener
It has been recognized that our disconnect command will not result in a MgmtEvtDeviceDisconnected received from the BlueZ Kernel. Hence sending it out ourselves to listening clients.
-rw-r--r--api/direct_bt/DBTManager.hpp3
-rw-r--r--api/direct_bt/MgmtTypes.hpp29
-rw-r--r--src/direct_bt/DBTDevice.cpp2
-rw-r--r--src/direct_bt/DBTManager.cpp19
4 files changed, 49 insertions, 4 deletions
diff --git a/api/direct_bt/DBTManager.hpp b/api/direct_bt/DBTManager.hpp
index 27e6a561..812db1b1 100644
--- a/api/direct_bt/DBTManager.hpp
+++ b/api/direct_bt/DBTManager.hpp
@@ -110,6 +110,7 @@ namespace direct_bt {
bool mgmtEvNewConnectionParamCB(std::shared_ptr<MgmtEvent> e);
bool mgmtEvDeviceWhitelistAddedCB(std::shared_ptr<MgmtEvent> e);
bool mgmtEvDeviceWhilelistRemovedCB(std::shared_ptr<MgmtEvent> e);
+ void sendMgmtEvent(std::shared_ptr<MgmtEvent> event);
public:
/**
@@ -199,7 +200,7 @@ namespace direct_bt {
const uint16_t min_ce_length=0x0001, const uint16_t max_ce_length=0x0001,
const uint8_t initiator_filter=0);
- bool disconnect(const int dev_id, const EUI48 &peer_bdaddr, const BDAddressType peer_mac_type);
+ bool disconnect(const int dev_id, const EUI48 &peer_bdaddr, const BDAddressType peer_mac_type, const uint8_t reason=0);
/** MgmtEventCallback handling */
diff --git a/api/direct_bt/MgmtTypes.hpp b/api/direct_bt/MgmtTypes.hpp
index b99e9999..48dd38ae 100644
--- a/api/direct_bt/MgmtTypes.hpp
+++ b/api/direct_bt/MgmtTypes.hpp
@@ -324,6 +324,11 @@ namespace direct_bt {
}
};
+ /**
+ * uint16_t opcode,
+ * uint16_t dev-id,
+ * uint16_t param_size
+ */
class MgmtEvent
{
public:
@@ -417,6 +422,22 @@ namespace direct_bt {
pdu.check_range(0, MGMT_HEADER_SIZE+getParamSize());
checkOpcode(getOpcode(), CMD_COMPLETE, PHY_CONFIGURATION_CHANGED);
}
+ MgmtEvent(const Opcode opc, const uint16_t dev_id, const uint16_t param_size=0)
+ : pdu(MGMT_HEADER_SIZE+param_size), ts_creation(getCurrentMilliseconds())
+ {
+ // checkOpcode(opc, READ_VERSION, SET_BLOCKED_KEYS);
+
+ pdu.put_uint16(0, opc);
+ pdu.put_uint16(2, dev_id);
+ pdu.put_uint16(4, param_size);
+ }
+ MgmtEvent(const Opcode opc, const uint16_t dev_id, const uint16_t param_size, const uint8_t* param)
+ : MgmtEvent(opc, dev_id, param_size)
+ {
+ if( param_size > 0 ) {
+ memcpy(pdu.get_wptr(MGMT_HEADER_SIZE), param, param_size);
+ }
+ }
virtual ~MgmtEvent() {}
int getTotalSize() const { return pdu.getSize(); }
@@ -712,6 +733,14 @@ namespace direct_bt {
{
checkOpcode(getOpcode(), DEVICE_DISCONNECTED);
}
+ MgmtEvtDeviceDisconnected(const uint16_t dev_id, const EUI48 &address, const BDAddressType addressType, uint8_t reason)
+ : MgmtEvent(DEVICE_DISCONNECTED, dev_id, 6+1+1)
+ {
+ pdu.put_eui48(MGMT_HEADER_SIZE, address);
+ pdu.put_uint8(MGMT_HEADER_SIZE+6, addressType);
+ pdu.put_uint8(MGMT_HEADER_SIZE+6+1, reason);
+ }
+
const EUI48 getAddress() const { return EUI48(pdu.get_ptr(MGMT_HEADER_SIZE)); } // mgmt_addr_info
BDAddressType getAddressType() const { return static_cast<BDAddressType>(pdu.get_uint8(MGMT_HEADER_SIZE+6)); } // mgmt_addr_info
diff --git a/src/direct_bt/DBTDevice.cpp b/src/direct_bt/DBTDevice.cpp
index cb78fbc4..ccc534d6 100644
--- a/src/direct_bt/DBTDevice.cpp
+++ b/src/direct_bt/DBTDevice.cpp
@@ -244,7 +244,7 @@ void DBTDevice::disconnect(const uint8_t reason) {
{
// Actually issuing DISCONNECT post HCI
DBTManager & mngr = adapter.getManager();
- mngr.disconnect(adapter.dev_id, address, addressType);
+ mngr.disconnect(adapter.dev_id, address, addressType, reason);
}
std::shared_ptr<DBTDevice> thisDevice = getSharedInstance();
diff --git a/src/direct_bt/DBTManager.cpp b/src/direct_bt/DBTManager.cpp
index cad3100f..5a49ef2d 100644
--- a/src/direct_bt/DBTManager.cpp
+++ b/src/direct_bt/DBTManager.cpp
@@ -96,6 +96,16 @@ void DBTManager::mgmtReaderThreadImpl() {
mgmtReaderRunning = false;
}
+void DBTManager::sendMgmtEvent(std::shared_ptr<MgmtEvent> event) {
+ const MgmtEvent::Opcode opc = event->getOpcode();
+ MgmtEventCallbackList mgmtEventCallbackList = mgmtEventCallbackLists[opc];
+ DBG_PRINT("DBTManager::sendMgmtEvent: Event %s -> %zd callbacks", event->toString().c_str(), mgmtEventCallbackList.size());
+ for (auto it = mgmtEventCallbackList.begin(); it != mgmtEventCallbackList.end(); ++it) {
+ MgmtEventCallback callback = *it;
+ callback.invoke(event);
+ }
+}
+
static void mgmthandler_sigaction(int sig, siginfo_t *info, void *ucontext) {
INFO_PRINT("DBTManager.sigaction: sig %d, info[code %d, errno %d, signo %d, pid %d, uid %d, fd %d]",
sig, info->si_code, info->si_errno, info->si_signo,
@@ -486,7 +496,7 @@ uint16_t DBTManager::create_connection(const int dev_id,
return 0;
}
-bool DBTManager::disconnect(const int dev_id, const EUI48 &peer_bdaddr, const BDAddressType peer_mac_type) {
+bool DBTManager::disconnect(const int dev_id, const EUI48 &peer_bdaddr, const BDAddressType peer_mac_type, const uint8_t reason) {
MgmtDisconnectCmd req(dev_id, peer_bdaddr, peer_mac_type);
DBG_PRINT("DBTManager::disconnect: %s", req.toString().c_str());
std::shared_ptr<MgmtEvent> res = send(req);
@@ -497,7 +507,12 @@ bool DBTManager::disconnect(const int dev_id, const EUI48 &peer_bdaddr, const BD
DBG_PRINT("DBTManager::disconnect res: %s", res->toString().c_str());
if( res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) {
const MgmtEvtCmdComplete &res1 = *static_cast<const MgmtEvtCmdComplete *>(res.get());
- return MgmtStatus::SUCCESS == res1.getStatus();
+ if( MgmtStatus::SUCCESS == res1.getStatus() ) {
+ // explicit disconnected event
+ MgmtEvtDeviceDisconnected *e = new MgmtEvtDeviceDisconnected(dev_id, peer_bdaddr, peer_mac_type, reason);
+ sendMgmtEvent(std::shared_ptr<MgmtEvent>(e));
+ return true;
+ }
} else {
DBG_PRINT("DBTManager::disconnect res: NULL");
return false;