summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-10-24 04:24:12 +0200
committerSven Gothel <[email protected]>2020-10-24 04:24:12 +0200
commit4a6d3ed80095045f72d7024362801e94b866549a (patch)
tree46a62df2318c7461d9497ae72cbdb79258c01463 /src
parentc7cc9acfe7fcce0df302de16497b3d730d337e36 (diff)
DBTManager: Add adapter add/remove support: Use cow_vector for adapterInfo-list, further drop index language for dev_id
Diffstat (limited to 'src')
-rw-r--r--src/direct_bt/DBTAdapter.cpp7
-rw-r--r--src/direct_bt/DBTManager.cpp114
2 files changed, 79 insertions, 42 deletions
diff --git a/src/direct_bt/DBTAdapter.cpp b/src/direct_bt/DBTAdapter.cpp
index b17d571a..70bc3711 100644
--- a/src/direct_bt/DBTAdapter.cpp
+++ b/src/direct_bt/DBTAdapter.cpp
@@ -148,6 +148,13 @@ bool DBTAdapter::validateDevInfo() noexcept {
}
adapterInfo = mgmt.getAdapterInfo(dev_id);
+ if( nullptr == adapterInfo ) {
+ // fill in a dummy AdapterInfo for the sake of de-referencing throughout this adapter instance
+ adapterInfo = std::shared_ptr<AdapterInfo>( new AdapterInfo(dev_id, EUI48_ANY_DEVICE, 0, 0,
+ AdapterSetting::NONE, AdapterSetting::NONE, 0, "invalid", "invalid"));
+ ERR_PRINT("DBTAdapter::validateDevInfo: Adapter[%d]: Not existent: %s", dev_id, adapterInfo->toString().c_str());
+ return false;
+ }
btMode = adapterInfo->getCurrentBTMode();
if( BTMode::NONE == btMode ) {
diff --git a/src/direct_bt/DBTManager.cpp b/src/direct_bt/DBTManager.cpp
index c865039f..2a4137e3 100644
--- a/src/direct_bt/DBTManager.cpp
+++ b/src/direct_bt/DBTManager.cpp
@@ -416,24 +416,23 @@ next1:
ERR_PRINT("Insufficient data for %d adapter indices: res %s", num_adapter, res->toString().c_str());
goto fail;
}
- adapterInfos.resize(num_adapter, nullptr);
- for(int i=0; ok && i < num_adapter; i++) {
- const uint16_t dev_id = jau::get_uint16(data, 2+i*2, true /* littleEndian */);
- if( dev_id >= num_adapter ) {
- ABORT("dev_id %d >= num_adapter %d", dev_id, num_adapter);
- }
- if( adapterInfos[dev_id] != nullptr ) {
- ABORT("adapters[dev_id=%d] != nullptr: %s", dev_id, adapterInfos[dev_id]->toString().c_str());
- }
- std::shared_ptr<AdapterInfo> adapterInfo = initAdapter(dev_id, defaultBTMode);
- adapterInfos[dev_id] = adapterInfo;
- if( nullptr != adapterInfo ) {
- DBG_PRINT("DBTManager::adapters %d/%d: dev_id %d: %s", i, num_adapter, dev_id, adapterInfo->toString().c_str());
- ok = true;
- } else {
- DBG_PRINT("DBTManager::adapters %d/%d: dev_id %d: FAILED", i, num_adapter, dev_id);
- ok = false;
+ {
+ // Not required: CTOR: const std::lock_guard<std::recursive_mutex> lock(adapterInfos.get_write_mutex());
+ std::shared_ptr<std::vector<std::shared_ptr<AdapterInfo>>> snapshot = adapterInfos.get_snapshot();
+
+ for(int i=0; ok && i < num_adapter; i++) {
+ const uint16_t dev_id = jau::get_uint16(data, 2+i*2, true /* littleEndian */);
+ std::shared_ptr<AdapterInfo> adapterInfo = initAdapter(dev_id, defaultBTMode);
+ if( nullptr != adapterInfo ) {
+ snapshot->push_back(adapterInfo);
+ DBG_PRINT("DBTManager::adapters %d/%d: dev_id %d: %s", i, num_adapter, dev_id, adapterInfo->toString().c_str());
+ ok = true;
+ } else {
+ DBG_PRINT("DBTManager::adapters %d/%d: dev_id %d: FAILED", i, num_adapter, dev_id);
+ ok = false;
+ }
}
+ // Not required: CTOR: adapterInfos.set_store(std::move(snapshot));
}
}
@@ -483,9 +482,9 @@ void DBTManager::close() noexcept {
removeAllDevicesFromWhitelist();
clearAllMgmtEventCallbacks();
- for (auto it = adapterInfos.begin(); it != adapterInfos.end(); it++) {
- shutdownAdapter((*it)->dev_id);
- }
+ jau::for_each_cow(adapterInfos, [&](std::shared_ptr<AdapterInfo> & a) {
+ shutdownAdapter(a->dev_id);
+ });
adapterInfos.clear();
// Interrupt DBTManager's HCIComm::read(..), avoiding prolonged hang
@@ -533,52 +532,62 @@ void DBTManager::close() noexcept {
}
int DBTManager::findAdapterInfoDevId(const EUI48 &mac) const noexcept {
- auto begin = adapterInfos.begin();
- auto it = std::find_if(begin, adapterInfos.end(), [&](std::shared_ptr<AdapterInfo> const& p) {
+ std::shared_ptr<std::vector<std::shared_ptr<AdapterInfo>>> snapshot = adapterInfos.get_snapshot();
+ auto begin = snapshot->begin();
+ auto it = std::find_if(begin, snapshot->end(), [&](std::shared_ptr<AdapterInfo> const& p) -> bool {
return p->address == mac;
});
- if ( it == std::end(adapterInfos) ) {
+ if ( it == std::end(*snapshot) ) {
return -1;
} else {
- return std::distance(begin, it);
+ return (*it)->dev_id;
}
}
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) {
+ std::shared_ptr<std::vector<std::shared_ptr<AdapterInfo>>> snapshot = adapterInfos.get_snapshot();
+ auto begin = snapshot->begin();
+ auto it = std::find_if(begin, snapshot->end(), [&](std::shared_ptr<AdapterInfo> const& p) -> bool {
return p->address == mac;
});
- if ( it == std::end(adapterInfos) ) {
+ if ( it == std::end(*snapshot) ) {
return nullptr;
} else {
return *it;
}
}
std::shared_ptr<AdapterInfo> DBTManager::getAdapterInfo(const uint16_t dev_id) const noexcept {
- if( 0 > idx || idx >= static_cast<int>(adapterInfos.size()) ) {
- throw jau::IndexOutOfBoundsException(idx, adapterInfos.size(), E_FILE_LINE);
+ std::shared_ptr<std::vector<std::shared_ptr<AdapterInfo>>> snapshot = adapterInfos.get_snapshot();
+ auto begin = snapshot->begin();
+ auto it = std::find_if(begin, snapshot->end(), [&](std::shared_ptr<AdapterInfo> const& p) -> bool {
+ return p->dev_id == dev_id;
+ });
+ if ( it == std::end(*snapshot) ) {
+ return nullptr;
+ } else {
+ return *it;
}
- std::shared_ptr<AdapterInfo> adapter = adapterInfos.at(idx);
- return adapter;
}
BTMode DBTManager::getCurrentBTMode(uint16_t dev_id) const noexcept {
- if( 0 > dev_id || dev_id >= static_cast<int>(adapterInfos.size()) ) {
- ERR_PRINT("dev_id %d out of bounds [0..%d[", dev_id, static_cast<int>(adapterInfos.size()));
+ std::shared_ptr<AdapterInfo> ai = getAdapterInfo(dev_id);
+ if( nullptr == ai ) {
+ ERR_PRINT("dev_id %d not found", dev_id);
return BTMode::NONE;
}
- return adapterInfos.at(dev_id)->getCurrentBTMode();
+ return ai->getCurrentBTMode();
}
std::shared_ptr<AdapterInfo> DBTManager::getDefaultAdapterInfo() const noexcept {
- auto begin = adapterInfos.begin();
- auto it = std::find_if(begin, adapterInfos.end(), [&](std::shared_ptr<AdapterInfo> const& p) {
+ std::shared_ptr<std::vector<std::shared_ptr<AdapterInfo>>> snapshot = adapterInfos.get_snapshot();
+ auto begin = snapshot->begin();
+ auto it = std::find_if(begin, snapshot->end(), [](std::shared_ptr<AdapterInfo> const& p) -> bool {
return p->isCurrentSettingBitSet(AdapterSetting::POWERED);
});
- if ( it != std::end(adapterInfos) ) {
- return *it; // the 1st POWERED adapter
+ if ( it == std::end(*snapshot) ) {
+ return nullptr;
+ } else {
+ return *it;
}
- return adapterInfos.size() > 0 ? getAdapterInfo(0) : nullptr; // first adapter or nullptr, if none.
}
int DBTManager::getDefaultAdapterDevId() const noexcept {
@@ -695,9 +704,9 @@ int DBTManager::removeAllDevicesFromWhitelist() noexcept {
int count = whitelist.size();
DBG_PRINT("DBTManager::removeAllDevicesFromWhitelist.B: Start %d elements", count);
whitelist.clear();
- for (auto it = adapterInfos.begin(); it != adapterInfos.end(); it++) {
- removeDeviceFromWhitelist((*it)->dev_id, EUI48_ANY_DEVICE, BDAddressType::BDADDR_BREDR); // flush whitelist!
- }
+ jau::for_each_cow(adapterInfos, [&](std::shared_ptr<AdapterInfo> & a) {
+ removeDeviceFromWhitelist(a->dev_id, EUI48_ANY_DEVICE, BDAddressType::BDADDR_BREDR); // flush whitelist!
+ });
#endif
DBG_PRINT("DBTManager::removeAllDevicesFromWhitelist: End: Removed %d elements, remaining %zd elements",
@@ -840,6 +849,27 @@ void DBTManager::clearAllMgmtEventCallbacks() noexcept {
}
}
+void DBTManager::processAdapterAdded(const uint16_t dev_id) noexcept {
+ std::shared_ptr<AdapterInfo> ai = initAdapter(dev_id, defaultBTMode);
+ if( nullptr != ai ) {
+ const bool added = addAdapterInfo(ai);
+ jau::PLAIN_PRINT("DBTManager::Adapter[%d] Added %d: %s", dev_id, added, ai->toString().c_str());
+ } else {
+ jau::PLAIN_PRINT("DBTManager::Adapter[%d] Added 0: Init failed", dev_id);
+ }
+}
+bool DBTManager::mgmtEvAdapterAddedCB(std::shared_ptr<MgmtEvent> e) noexcept {
+ jau::PLAIN_PRINT("DBTManager:mgmt:AdapterAdded: %s", e->toString().c_str());
+ std::thread adapterAddedThread(&DBTManager::processAdapterAdded, this, e->getDevID()); // @suppress("Invalid arguments")
+ adapterAddedThread.detach();
+ return true;
+}
+bool DBTManager::mgmtEvAdapterRemovedCB(std::shared_ptr<MgmtEvent> e) noexcept {
+ jau::PLAIN_PRINT("DBTManager:mgmt:AdapterRemoved: Start %s", e->toString().c_str());
+ std::shared_ptr<AdapterInfo> ai = removeAdapterInfo(e->getDevID());
+ jau::PLAIN_PRINT("DBTManager:mgmt:AdapterRemoved: End: Removed %s", (nullptr != ai ? ai->toString().c_str() : "none"));
+ return true;
+}
bool DBTManager::mgmtEvClassOfDeviceChangedCB(std::shared_ptr<MgmtEvent> e) noexcept {
jau::PLAIN_PRINT("DBTManager:mgmt:ClassOfDeviceChanged: %s", e->toString().c_str());
(void)e;