diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/direct_bt/DBTAdapter.cpp | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/src/direct_bt/DBTAdapter.cpp b/src/direct_bt/DBTAdapter.cpp index 49a67a0d..389e55ee 100644 --- a/src/direct_bt/DBTAdapter.cpp +++ b/src/direct_bt/DBTAdapter.cpp @@ -745,7 +745,7 @@ exit: // ************************************************* std::shared_ptr<DBTDevice> DBTAdapter::findDiscoveredDevice (const EUI48 & address, const BDAddressType addressType) noexcept { - const std::lock_guard<std::mutex> lock(const_cast<DBTAdapter*>(this)->mtx_discoveredDevices); // RAII-style acquire and relinquish via destructor + const std::lock_guard<std::mutex> lock(mtx_discoveredDevices); // RAII-style acquire and relinquish via destructor return findDevice(discoveredDevices, address, addressType); } @@ -759,10 +759,10 @@ bool DBTAdapter::addDiscoveredDevice(std::shared_ptr<DBTDevice> const &device) n return true; } -bool DBTAdapter::removeDiscoveredDevice(const DBTDevice & device) noexcept { +bool DBTAdapter::removeDiscoveredDevice(const BDAddressAndType & addressAndType) noexcept { const std::lock_guard<std::mutex> lock(mtx_discoveredDevices); // RAII-style acquire and relinquish via destructor for (auto it = discoveredDevices.begin(); it != discoveredDevices.end(); ) { - if ( nullptr != *it && device == **it ) { + if ( nullptr != *it && addressAndType == (*it)->addressAndType ) { it = discoveredDevices.erase(it); return true; } else { @@ -824,7 +824,7 @@ void DBTAdapter::removeDevice(DBTDevice & device) noexcept { WORDY_PRINT("DBTAdapter::removeDevice: disconnect %s, %s", getHCIStatusCodeString(status).c_str(), toString(false).c_str()); unlockConnect(device); removeConnectedDevice(device); // usually done in DBTAdapter::mgmtEvDeviceDisconnectedHCI - removeDiscoveredDevice(device); // usually done in DBTAdapter::mgmtEvDeviceDisconnectedHCI + removeDiscoveredDevice(device.addressAndType); // usually done in DBTAdapter::mgmtEvDeviceDisconnectedHCI WORDY_PRINT("DBTAdapter::removeDevice: End %s", toString(false).c_str()); removeSharedDevice(device); } @@ -1049,12 +1049,15 @@ bool DBTAdapter::mgmtEvDeviceConnectedHCI(const MgmtEvent& e) noexcept { std::shared_ptr<DBTDevice> device = findConnectedDevice(event.getAddress(), event.getAddressType()); if( nullptr == device ) { device = findDiscoveredDevice(event.getAddress(), event.getAddressType()); - new_connect = nullptr != device ? 1 : 0; + if( nullptr != device ) { + addSharedDevice(device); // connected devices must be in shared + discovered list + new_connect = 1; + } } if( nullptr == device ) { device = findSharedDevice(event.getAddress(), event.getAddressType()); if( nullptr != device ) { - addDiscoveredDevice(device); + addDiscoveredDevice(device); // connected devices must be in shared + discovered list new_connect = 2; } } @@ -1070,14 +1073,6 @@ bool DBTAdapter::mgmtEvDeviceConnectedHCI(const MgmtEvent& e) noexcept { const SMPIOCapability io_cap_conn = mgmt.getIOCapability(dev_id); EIRDataType updateMask = device->update(ad_report); - if( addConnectedDevice(device) ) { // track device, if not done yet - if( 0 == new_connect ) { - new_connect = 4; // unknown reason... - } - } - if( 2 <= new_connect ) { - device->ts_last_discovery = ad_report.getTimestamp(); - } if( 0 == new_connect ) { WARN_PRINT("DBTAdapter::EventHCI:DeviceConnected(dev_id %d, already connected, updated %s): %s, handle %s -> %s,\n %s,\n -> %s", dev_id, getEIRDataMaskString(updateMask).c_str(), event.toString().c_str(), @@ -1085,13 +1080,16 @@ bool DBTAdapter::mgmtEvDeviceConnectedHCI(const MgmtEvent& e) noexcept { ad_report.toString().c_str(), device->toString().c_str()); } else { + addConnectedDevice(device); // track device, if not done yet + if( 2 <= new_connect ) { + device->ts_last_discovery = ad_report.getTimestamp(); + } COND_PRINT(debug_event, "DBTAdapter::EventHCI:DeviceConnected(dev_id %d, new_connect %d, updated %s): %s, handle %s -> %s,\n %s,\n -> %s", dev_id, new_connect, getEIRDataMaskString(updateMask).c_str(), event.toString().c_str(), jau::uint16HexString(device->getConnectionHandle()).c_str(), jau::uint16HexString(event.getHCIHandle()).c_str(), ad_report.toString().c_str(), device->toString().c_str()); } - device->notifyConnected(device, event.getHCIHandle(), io_cap_conn); int i=0; @@ -1143,7 +1141,7 @@ bool DBTAdapter::mgmtEvConnectFailedHCI(const MgmtEvent& e) noexcept { } i++; }); - removeDiscoveredDevice(*device); // ensure device will cause a deviceFound event after disconnect + removeDiscoveredDevice(device->addressAndType); // ensure device will cause a deviceFound event after disconnect } else { WORDY_PRINT("DBTAdapter::EventHCI:DeviceDisconnected(dev_id %d): Device not tracked: %s", dev_id, event.toString().c_str()); @@ -1233,7 +1231,7 @@ bool DBTAdapter::mgmtEvDeviceDisconnectedHCI(const MgmtEvent& e) noexcept { } i++; }); - removeDiscoveredDevice(*device); // ensure device will cause a deviceFound event after disconnect + removeDiscoveredDevice(device->addressAndType); // ensure device will cause a deviceFound event after disconnect } else { WORDY_PRINT("DBTAdapter::EventHCI:DeviceDisconnected(dev_id %d): Device not tracked: %s", dev_id, event.toString().c_str()); @@ -1329,10 +1327,11 @@ bool DBTAdapter::mgmtEvDeviceFoundHCI(const MgmtEvent& e) noexcept { dev->getAddressAndType().toString().c_str(), eir->toString().c_str()); int i=0; + bool device_used = false; jau::for_each_fidelity(statusListenerList, [&](std::shared_ptr<AdapterStatusListener> &l) { try { if( l->matchDevice(*dev) ) { - l->deviceFound(dev, eir->getTimestamp()); + device_used = l->deviceFound(dev, eir->getTimestamp()) || device_used; } } catch (std::exception &except) { ERR_PRINT("DBTAdapter:hci:DeviceFound: %d/%zd: %s of %s: Caught exception %s", @@ -1341,7 +1340,11 @@ bool DBTAdapter::mgmtEvDeviceFoundHCI(const MgmtEvent& e) noexcept { } i++; }); - if( EIRDataType::NONE != updateMask ) { + if( !device_used ) { + // keep to avoid duplicate finds: removeDiscoveredDevice(dev->addressAndType); + // and still allowing usage, as connecting will re-add to shared list + removeSharedDevice(*dev); // pending dtor if discovered is flushed + } else if( EIRDataType::NONE != updateMask ) { sendDeviceUpdated("SharedDeviceFound", dev, eir->getTimestamp(), updateMask); } return true; @@ -1358,10 +1361,11 @@ bool DBTAdapter::mgmtEvDeviceFoundHCI(const MgmtEvent& e) noexcept { dev->getAddressAndType().toString().c_str(), eir->toString().c_str()); int i=0; + bool device_used = false; jau::for_each_fidelity(statusListenerList, [&](std::shared_ptr<AdapterStatusListener> &l) { try { if( l->matchDevice(*dev) ) { - l->deviceFound(dev, eir->getTimestamp()); + device_used = l->deviceFound(dev, eir->getTimestamp()) || device_used; } } catch (std::exception &except) { ERR_PRINT("DBTAdapter:hci:DeviceFound-CBs %d/%zd: %s of %s: Caught exception %s", @@ -1370,7 +1374,11 @@ bool DBTAdapter::mgmtEvDeviceFoundHCI(const MgmtEvent& e) noexcept { } i++; }); - + if( !device_used ) { + // keep to avoid duplicate finds: removeDiscoveredDevice(dev->addressAndType); + // and still allowing usage, as connecting will re-add to shared list + removeSharedDevice(*dev); // pending dtor if discovered is flushed + } return true; } |