aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/direct_bt/DBTManager.cpp101
1 files changed, 55 insertions, 46 deletions
diff --git a/src/direct_bt/DBTManager.cpp b/src/direct_bt/DBTManager.cpp
index 9d39e34e..268ebacf 100644
--- a/src/direct_bt/DBTManager.cpp
+++ b/src/direct_bt/DBTManager.cpp
@@ -51,7 +51,7 @@ extern "C" {
using namespace direct_bt;
-MgmtEnv::MgmtEnv()
+MgmtEnv::MgmtEnv() noexcept
: DEBUG_GLOBAL( DBTEnv::get().DEBUG ),
exploding( DBTEnv::getExplodingProperties("direct_bt.mgmt") ),
MGMT_READER_THREAD_POLL_TIMEOUT( DBTEnv::getInt32Property("direct_bt.mgmt.reader.timeout", 10000, 1500 /* min */, INT32_MAX /* max */) ),
@@ -65,7 +65,7 @@ MgmtEnv::MgmtEnv()
const pid_t DBTManager::pidSelf = getpid();
std::mutex DBTManager::mtx_singleton;
-void DBTManager::mgmtReaderThreadImpl() {
+void DBTManager::mgmtReaderThreadImpl() noexcept {
{
const std::lock_guard<std::mutex> lock(mtx_mgmtReaderInit); // RAII-style acquire and relinquish via destructor
mgmtReaderShallStop = false;
@@ -115,7 +115,7 @@ void DBTManager::mgmtReaderThreadImpl() {
mgmtEventRing.clear();
}
-void DBTManager::sendMgmtEvent(std::shared_ptr<MgmtEvent> event) {
+void DBTManager::sendMgmtEvent(std::shared_ptr<MgmtEvent> event) noexcept {
const std::lock_guard<std::recursive_mutex> lock(mtx_callbackLists); // RAII-style acquire and relinquish via destructor
const int dev_id = event->getDevID();
MgmtAdapterEventCallbackList & mgmtEventCallbackList = mgmtAdapterEventCallbackLists[static_cast<uint16_t>(event->getOpcode())];
@@ -136,7 +136,7 @@ void DBTManager::sendMgmtEvent(std::shared_ptr<MgmtEvent> event) {
(void)invokeCount;
}
-static void mgmthandler_sigaction(int sig, siginfo_t *info, void *ucontext) {
+static void mgmthandler_sigaction(int sig, siginfo_t *info, void *ucontext) noexcept {
bool pidMatch = info->si_pid == DBTManager::pidSelf;
INFO_PRINT("DBTManager.sigaction: sig %d, info[code %d, errno %d, signo %d, pid %d, uid %d, fd %d], pid-self %d (match %d)",
sig, info->si_code, info->si_errno, info->si_signo,
@@ -163,7 +163,7 @@ static void mgmthandler_sigaction(int sig, siginfo_t *info, void *ucontext) {
#endif
}
-std::shared_ptr<MgmtEvent> DBTManager::sendWithReply(MgmtCommand &req) {
+std::shared_ptr<MgmtEvent> DBTManager::sendWithReply(MgmtCommand &req) noexcept {
const std::lock_guard<std::recursive_mutex> lock(mtx_sendReply); // RAII-style acquire and relinquish via destructor
{
COND_PRINT(env.DEBUG_EVENT, "DBTManager-IO SENT %s", req.toString().c_str());
@@ -197,7 +197,7 @@ std::shared_ptr<MgmtEvent> DBTManager::sendWithReply(MgmtCommand &req) {
return nullptr;
}
-void DBTManager::setAdapterMode(const uint16_t dev_id, const uint8_t ssp, const uint8_t bredr, const uint8_t le) {
+void DBTManager::setAdapterMode(const uint16_t dev_id, const uint8_t ssp, const uint8_t bredr, const uint8_t le) noexcept {
bool res;
res = setMode(dev_id, MgmtOpcode::SET_SSP, ssp);
DBG_PRINT("setAdapterMode[%d]: SET_SSP(%d): result %d", dev_id, ssp, res);
@@ -209,7 +209,7 @@ void DBTManager::setAdapterMode(const uint16_t dev_id, const uint8_t ssp, const
DBG_PRINT("setAdapterMode[%d]: SET_LE(%d): result %d", dev_id, le, res);
}
-std::shared_ptr<AdapterInfo> DBTManager::initAdapter(const uint16_t dev_id, const BTMode btMode) {
+std::shared_ptr<AdapterInfo> DBTManager::initAdapter(const uint16_t dev_id, const BTMode btMode) noexcept {
std::shared_ptr<AdapterInfo> adapterInfo = nullptr;
bool powered;
MgmtCommand req0(MgmtOpcode::READ_INFO, dev_id);
@@ -225,7 +225,8 @@ std::shared_ptr<AdapterInfo> DBTManager::initAdapter(const uint16_t dev_id, cons
const MgmtEvtAdapterInfo * res1 = static_cast<MgmtEvtAdapterInfo*>(res.get());
adapterInfo = res1->toAdapterInfo();
if( dev_id != adapterInfo->dev_id ) {
- throw InternalError("AdapterInfo dev_id="+std::to_string(adapterInfo->dev_id)+" != dev_id="+std::to_string(dev_id)+"]: "+adapterInfo->toString(), E_FILE_LINE);
+ ERR_PRINT("Internal-Error: AdapterInfo dev_id=%d != dev_id=%d: %s", adapterInfo->dev_id, dev_id, adapterInfo->toString().c_str());
+ abort();
}
}
DBG_PRINT("initAdapter[%d]: Start: %s", dev_id, adapterInfo->toString().c_str());
@@ -269,7 +270,8 @@ std::shared_ptr<AdapterInfo> DBTManager::initAdapter(const uint16_t dev_id, cons
const MgmtEvtAdapterInfo * res1 = static_cast<MgmtEvtAdapterInfo*>(res.get());
adapterInfo = res1->toAdapterInfo();
if( dev_id != adapterInfo->dev_id ) {
- throw InternalError("AdapterInfo dev_id="+std::to_string(adapterInfo->dev_id)+" != dev_id="+std::to_string(dev_id)+"]: "+adapterInfo->toString(), E_FILE_LINE);
+ ERR_PRINT("Internal-Error: AdapterInfo dev_id=%d != dev_id=%d: %s", adapterInfo->dev_id, dev_id, adapterInfo->toString().c_str());
+ abort();
}
}
DBG_PRINT("initAdapter[%d]: End: %s", dev_id, adapterInfo->toString().c_str());
@@ -278,14 +280,14 @@ fail:
return adapterInfo;
}
-void DBTManager::shutdownAdapter(const uint16_t dev_id) {
+void DBTManager::shutdownAdapter(const uint16_t dev_id) noexcept {
setMode(dev_id, MgmtOpcode::SET_CONNECTABLE, 0);
setMode(dev_id, MgmtOpcode::SET_FAST_CONNECTABLE, 0);
setMode(dev_id, MgmtOpcode::SET_DISCOVERABLE, 0);
setMode(dev_id, MgmtOpcode::SET_POWERED, 0);
}
-DBTManager::DBTManager(const BTMode _defaultBTMode)
+DBTManager::DBTManager(const BTMode _defaultBTMode) noexcept
: env(MgmtEnv::get()),
defaultBTMode(BTMode::NONE != _defaultBTMode ? _defaultBTMode : BTMode::LE),
rbuffer(ClientMaxMTU), comm(HCI_DEV_NONE, HCI_CHANNEL_CONTROL),
@@ -391,10 +393,12 @@ next1:
for(int i=0; ok && i < num_adapter; i++) {
const uint16_t dev_id = get_uint16(data, 2+i*2, true /* littleEndian */);
if( dev_id >= num_adapter ) {
- throw InternalError("dev_id "+std::to_string(dev_id)+" >= num_adapter "+std::to_string(num_adapter), E_FILE_LINE);
+ ERR_PRINT("Internal-Error: dev_id %d >= num_adapter %d", dev_id, num_adapter);
+ abort();
}
if( adapterInfos[dev_id] != nullptr ) {
- throw InternalError("adapters[dev_id="+std::to_string(dev_id)+"] != nullptr: "+adapterInfos[dev_id]->toString(), E_FILE_LINE);
+ ERR_PRINT("Internal-Error: adapters[dev_id=%d] != nullptr: %s", dev_id, adapterInfos[dev_id]->toString().c_str());
+ abort();
}
std::shared_ptr<AdapterInfo> adapterInfo = initAdapter(dev_id, defaultBTMode);
adapterInfos[dev_id] = adapterInfo;
@@ -435,7 +439,7 @@ fail:
return;
}
-void DBTManager::close() {
+void DBTManager::close() noexcept {
DBG_PRINT("DBTManager::close: Start");
removeAllDevicesFromWhitelist();
@@ -473,7 +477,7 @@ void DBTManager::close() {
DBG_PRINT("DBTManager::close: End");
}
-int DBTManager::findAdapterInfoIdx(const EUI48 &mac) const {
+int DBTManager::findAdapterInfoIdx(const EUI48 &mac) const noexcept {
auto begin = adapterInfos.begin();
auto it = std::find_if(begin, adapterInfos.end(), [&](std::shared_ptr<AdapterInfo> const& p) {
return p->address == mac;
@@ -484,7 +488,7 @@ int DBTManager::findAdapterInfoIdx(const EUI48 &mac) const {
return std::distance(begin, it);
}
}
-std::shared_ptr<AdapterInfo> DBTManager::findAdapterInfo(const EUI48 &mac) const {
+std::shared_ptr<AdapterInfo> DBTManager::findAdapterInfo(const EUI48 &mac) const noexcept {
auto begin = adapterInfos.begin();
auto it = std::find_if(begin, adapterInfos.end(), [&](std::shared_ptr<AdapterInfo> const& p) {
return p->address == mac;
@@ -503,7 +507,7 @@ std::shared_ptr<AdapterInfo> DBTManager::getAdapterInfo(const int idx) const {
return adapter;
}
-bool DBTManager::setMode(const int dev_id, const MgmtOpcode opc, const uint8_t mode) {
+bool DBTManager::setMode(const int dev_id, const MgmtOpcode opc, const uint8_t mode) noexcept {
MgmtUint8Cmd req(opc, dev_id, mode);
std::shared_ptr<MgmtEvent> res = sendWithReply(req);
if( nullptr != res ) {
@@ -518,11 +522,11 @@ bool DBTManager::setMode(const int dev_id, const MgmtOpcode opc, const uint8_t m
return false;
}
-ScanType DBTManager::startDiscovery(const int dev_id, const BTMode btMode) {
+ScanType DBTManager::startDiscovery(const int dev_id, const BTMode btMode) noexcept {
return startDiscovery(dev_id, getScanType(btMode));
}
-ScanType DBTManager::startDiscovery(const int dev_id, const ScanType scanType) {
+ScanType DBTManager::startDiscovery(const int dev_id, const ScanType scanType) noexcept {
MgmtUint8Cmd req(MgmtOpcode::START_DISCOVERY, dev_id, number(scanType));
std::shared_ptr<MgmtEvent> res = sendWithReply(req);
ScanType type = ScanType::NONE;
@@ -534,7 +538,7 @@ ScanType DBTManager::startDiscovery(const int dev_id, const ScanType scanType) {
}
return type;
}
-bool DBTManager::stopDiscovery(const int dev_id, const ScanType type) {
+bool DBTManager::stopDiscovery(const int dev_id, const ScanType type) noexcept {
MgmtUint8Cmd req(MgmtOpcode::STOP_DISCOVERY, dev_id, number(type));
std::shared_ptr<MgmtEvent> res = sendWithReply(req);
if( nullptr != res && res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) {
@@ -546,7 +550,7 @@ bool DBTManager::stopDiscovery(const int dev_id, const ScanType type) {
bool DBTManager::uploadConnParam(const int dev_id, const EUI48 &address, const BDAddressType address_type,
const uint16_t min_interval, const uint16_t max_interval,
- const uint16_t latency, const uint16_t timeout) {
+ const uint16_t latency, const uint16_t timeout) noexcept {
MgmtConnParam connParam{ address, address_type, min_interval, max_interval, latency, timeout };
MgmtLoadConnParamCmd req(dev_id, connParam);
std::shared_ptr<MgmtEvent> res = sendWithReply(req);
@@ -557,7 +561,7 @@ bool DBTManager::uploadConnParam(const int dev_id, const EUI48 &address, const B
return false;
}
-bool DBTManager::isDeviceWhitelisted(const int dev_id, const EUI48 &address) {
+bool DBTManager::isDeviceWhitelisted(const int dev_id, const EUI48 &address) noexcept {
for(auto it = whitelist.begin(); it != whitelist.end(); ) {
std::shared_ptr<WhitelistElem> wle = *it;
if( wle->dev_id == dev_id && wle->address == address ) {
@@ -569,7 +573,7 @@ bool DBTManager::isDeviceWhitelisted(const int dev_id, const EUI48 &address) {
return false;
}
-bool DBTManager::addDeviceToWhitelist(const int dev_id, const EUI48 &address, const BDAddressType address_type, const HCIWhitelistConnectType ctype) {
+bool DBTManager::addDeviceToWhitelist(const int dev_id, const EUI48 &address, const BDAddressType address_type, const HCIWhitelistConnectType ctype) noexcept {
MgmtAddDeviceToWhitelistCmd req(dev_id, address, address_type, ctype);
// Check if already exist in our local whitelist first, reject if so ..
@@ -589,7 +593,7 @@ bool DBTManager::addDeviceToWhitelist(const int dev_id, const EUI48 &address, co
return false;
}
-int DBTManager::removeAllDevicesFromWhitelist() {
+int DBTManager::removeAllDevicesFromWhitelist() noexcept {
#if 0
std::vector<std::shared_ptr<WhitelistElem>> whitelist_copy = whitelist;
int count = 0;
@@ -614,7 +618,7 @@ int DBTManager::removeAllDevicesFromWhitelist() {
return count;
}
-bool DBTManager::removeDeviceFromWhitelist(const int dev_id, const EUI48 &address, const BDAddressType address_type) {
+bool DBTManager::removeDeviceFromWhitelist(const int dev_id, const EUI48 &address, const BDAddressType address_type) noexcept {
// Remove from our local whitelist first
{
for(auto it = whitelist.begin(); it != whitelist.end(); ) {
@@ -641,10 +645,13 @@ bool DBTManager::removeDeviceFromWhitelist(const int dev_id, const EUI48 &addres
bool DBTManager::disconnect(const bool ioErrorCause,
const int dev_id, const EUI48 &peer_bdaddr, const BDAddressType peer_mac_type,
- const HCIStatusCode reason) {
+ const HCIStatusCode reason) noexcept {
bool bres = false;
- if( !ioErrorCause ) {
+ // Always issue DISCONNECT command, even in case of an ioError (lost-connection),
+ // see Issue #124 fast re-connect on CSR adapter.
+ // This will always notify the adapter of a disconnected device.
+ {
MgmtDisconnectCmd req(dev_id, peer_bdaddr, peer_mac_type);
std::shared_ptr<MgmtEvent> res = sendWithReply(req);
if( nullptr != res && res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) {
@@ -653,15 +660,17 @@ bool DBTManager::disconnect(const bool ioErrorCause,
bres = true;
}
}
- } else {
- // explicit disconnected event anyways
+ }
+ if( !ioErrorCause ) {
+ // In case of an ioError (lost-connection), don't wait for the lagging
+ // DISCONN_COMPLETE event but send it directly.
MgmtEvtDeviceDisconnected *e = new MgmtEvtDeviceDisconnected(dev_id, peer_bdaddr, peer_mac_type, reason, 0xffff);
sendMgmtEvent(std::shared_ptr<MgmtEvent>(e));
}
return bres;
}
-std::shared_ptr<ConnectionInfo> DBTManager::getConnectionInfo(const int dev_id, const EUI48 &address, const BDAddressType address_type) {
+std::shared_ptr<ConnectionInfo> DBTManager::getConnectionInfo(const int dev_id, const EUI48 &address, const BDAddressType address_type) noexcept {
MgmtGetConnectionInfoCmd req(dev_id, address, address_type);
std::shared_ptr<MgmtEvent> res = sendWithReply(req);
if( nullptr != res && res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) {
@@ -674,7 +683,7 @@ std::shared_ptr<ConnectionInfo> DBTManager::getConnectionInfo(const int dev_id,
return nullptr;
}
-std::shared_ptr<NameAndShortName> DBTManager::setLocalName(const int dev_id, const std::string & name, const std::string & short_name) {
+std::shared_ptr<NameAndShortName> DBTManager::setLocalName(const int dev_id, const std::string & name, const std::string & short_name) noexcept {
MgmtSetLocalNameCmd req (dev_id, name, short_name);
std::shared_ptr<MgmtEvent> res = sendWithReply(req);
if( nullptr != res && res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) {
@@ -745,91 +754,91 @@ void DBTManager::clearMgmtEventCallbacks(const MgmtEvent::Opcode opc) {
checkMgmtEventCallbackListsIndex(opc);
mgmtAdapterEventCallbackLists[static_cast<uint16_t>(opc)].clear();
}
-void DBTManager::clearAllMgmtEventCallbacks() {
+void DBTManager::clearAllMgmtEventCallbacks() noexcept {
const std::lock_guard<std::recursive_mutex> lock(mtx_callbackLists); // RAII-style acquire and relinquish via destructor
for(size_t i=0; i<mgmtAdapterEventCallbackLists.size(); i++) {
mgmtAdapterEventCallbackLists[i].clear();
}
}
-bool DBTManager::mgmtEvClassOfDeviceChangedCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvClassOfDeviceChangedCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:ClassOfDeviceChanged: %s", e->toString().c_str());
(void)e;
return true;
}
-bool DBTManager::mgmtEvDeviceDiscoveringCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvDeviceDiscoveringCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:DeviceDiscovering: %s", e->toString().c_str());
const MgmtEvtDiscovering &event = *static_cast<const MgmtEvtDiscovering *>(e.get());
(void)event;
return true;
}
-bool DBTManager::mgmtEvDeviceFoundCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvDeviceFoundCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:DeviceFound: %s", e->toString().c_str());
const MgmtEvtDeviceFound &event = *static_cast<const MgmtEvtDeviceFound *>(e.get());
(void)event;
return true;
}
-bool DBTManager::mgmtEvDeviceDisconnectedCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvDeviceDisconnectedCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:DeviceDisconnected: %s", e->toString().c_str());
const MgmtEvtDeviceDisconnected &event = *static_cast<const MgmtEvtDeviceDisconnected *>(e.get());
(void)event;
return true;
}
-bool DBTManager::mgmtEvDeviceConnectedCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvDeviceConnectedCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:DeviceConnected: %s", e->toString().c_str());
const MgmtEvtDeviceConnected &event = *static_cast<const MgmtEvtDeviceConnected *>(e.get());
(void)event;
return true;
}
-bool DBTManager::mgmtEvConnectFailedCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvConnectFailedCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:ConnectFailed: %s", e->toString().c_str());
const MgmtEvtDeviceConnectFailed &event = *static_cast<const MgmtEvtDeviceConnectFailed *>(e.get());
(void)event;
return true;
}
-bool DBTManager::mgmtEvDeviceBlockedCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvDeviceBlockedCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:DeviceBlocked: %s", e->toString().c_str());
const MgmtEvtDeviceBlocked &event = *static_cast<const MgmtEvtDeviceBlocked *>(e.get());
(void)event;
return true;
}
-bool DBTManager::mgmtEvDeviceUnblockedCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvDeviceUnblockedCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:DeviceUnblocked: %s", e->toString().c_str());
const MgmtEvtDeviceUnblocked &event = *static_cast<const MgmtEvtDeviceUnblocked *>(e.get());
(void)event;
return true;
}
-bool DBTManager::mgmtEvDeviceUnpairedCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvDeviceUnpairedCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:DeviceUnpaired: %s", e->toString().c_str());
const MgmtEvtDeviceUnpaired &event = *static_cast<const MgmtEvtDeviceUnpaired *>(e.get());
(void)event;
return true;
}
-bool DBTManager::mgmtEvNewConnectionParamCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvNewConnectionParamCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:NewConnectionParam: %s", e->toString().c_str());
const MgmtEvtNewConnectionParam &event = *static_cast<const MgmtEvtNewConnectionParam *>(e.get());
(void)event;
return true;
}
-bool DBTManager::mgmtEvDeviceWhitelistAddedCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvDeviceWhitelistAddedCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:DeviceWhitelistAdded: %s", e->toString().c_str());
const MgmtEvtDeviceWhitelistAdded &event = *static_cast<const MgmtEvtDeviceWhitelistAdded *>(e.get());
(void)event;
return true;
}
-bool DBTManager::mgmtEvDeviceWhilelistRemovedCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvDeviceWhilelistRemovedCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:DeviceWhitelistRemoved: %s", e->toString().c_str());
const MgmtEvtDeviceWhitelistRemoved &event = *static_cast<const MgmtEvtDeviceWhitelistRemoved *>(e.get());
(void)event;
return true;
}
-bool DBTManager::mgmtEvPinCodeRequestCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvPinCodeRequestCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:PinCodeRequest: %s", e->toString().c_str());
const MgmtEvtPinCodeRequest &event = *static_cast<const MgmtEvtPinCodeRequest *>(e.get());
(void)event;
return true;
}
-bool DBTManager::mgmtEvUserPasskeyRequestCB(std::shared_ptr<MgmtEvent> e) {
+bool DBTManager::mgmtEvUserPasskeyRequestCB(std::shared_ptr<MgmtEvent> e) noexcept {
PLAIN_PRINT("DBTManager::EventCB:UserPasskeyRequest: %s", e->toString().c_str());
const MgmtEvtUserPasskeyRequest &event = *static_cast<const MgmtEvtUserPasskeyRequest *>(e.get());
(void)event;