diff options
author | Sven Gothel <[email protected]> | 2021-01-17 18:56:02 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2021-01-17 18:56:02 +0100 |
commit | 30b4e5f0c1f62c92c40a6ccceda8878f88a9521a (patch) | |
tree | f932f2366a47d847ef4b4813c3a49d685c2351a1 | |
parent | a93f3bd05b075095eebe44ec7784c1664dc68700 (diff) |
AdapterStatusListener::deviceFound: Resolve sharedDevices persistence of found device via return value
While we keep the device instance temporarily alive within discoveredDevices until next removeDiscoveredDevices() eg at startDiscover(),
we only keep it within persistent sharedDevices list if at least one deviceFound implementation returns true.
This allows user to minimize the sharedDevices footprint when rejecting the device
w/o being required to call device.remove().
-rw-r--r-- | api/direct_bt/DBTAdapter.hpp | 32 | ||||
-rw-r--r-- | api/direct_bt/DBTDevice.hpp | 3 | ||||
-rw-r--r-- | examples/direct_bt_scanner00/dbt_scanner00.cpp | 3 | ||||
-rw-r--r-- | examples/direct_bt_scanner01/dbt_scanner01.cpp | 3 | ||||
-rw-r--r-- | examples/direct_bt_scanner10/dbt_scanner10.cpp | 6 | ||||
-rw-r--r-- | examples/java/DBTScanner10.java | 6 | ||||
-rw-r--r-- | examples/java/ScannerTinyB01.java | 5 | ||||
-rw-r--r-- | examples/java/ScannerTinyB02.java | 5 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTAdapter.java | 3 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTAdapter.cxx | 12 | ||||
-rw-r--r-- | java/org/tinyb/AdapterStatusListener.java | 11 | ||||
-rw-r--r-- | src/direct_bt/DBTAdapter.cpp | 50 |
12 files changed, 93 insertions, 46 deletions
diff --git a/api/direct_bt/DBTAdapter.hpp b/api/direct_bt/DBTAdapter.hpp index c23d3809..10735eb6 100644 --- a/api/direct_bt/DBTAdapter.hpp +++ b/api/direct_bt/DBTAdapter.hpp @@ -108,10 +108,19 @@ namespace direct_bt { /** * A DBTDevice has been newly discovered. + * <p> + * The boolean return value informs the adapter whether the device shall be made persistent for connection {@code true}, + * or that it can be discarded {@code false}.<br> + * If no registered AdapterStatusListener::deviceFound() implementation returns {@code true}, + * the device instance will be removed from all internal lists and can no longer being used.<br> + * If any registered AdapterStatusListener::deviceFound() implementation returns {@code true}, + * the device will be made persistent, is ready to connect and DBTDevice::remove() shall be called after usage. + * </p> * @param device the found device * @param timestamp the time in monotonic milliseconds when this event occurred. See BasicTypes::getCurrentMilliseconds(). + * @return true if the device shall be made persistent and DBTDevice::remove() issued later. Otherwise false to remove device right away. */ - virtual void deviceFound(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) = 0; + virtual bool deviceFound(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) = 0; /** * An already discovered DBTDevice has been updated. @@ -221,15 +230,18 @@ namespace direct_bt { std::condition_variable cv_single_conn_device; typedef jau::darray<std::shared_ptr<DBTDevice>> device_list_t; + /** All discovered devices: Transient until removeDiscoveredDevices(), startDiscovery(). */ + device_list_t discoveredDevices; + /** All connected devices: Transient until disconnect or removal. */ device_list_t connectedDevices; - device_list_t discoveredDevices; // all discovered devices + /** All persistent shared devices: Persistent until removal. */ device_list_t sharedDevices; // All active shared devices. Final holder of DBTDevice lifecycle! typedef jau::cow_darray<std::shared_ptr<AdapterStatusListener>> statusListenerList_t; statusListenerList_t statusListenerList; - std::mutex mtx_discoveredDevices; - std::mutex mtx_connectedDevices; - std::mutex mtx_discovery; - std::mutex mtx_sharedDevices; // final mutex of all DBTDevice lifecycle + mutable std::mutex mtx_discoveredDevices; + mutable std::mutex mtx_connectedDevices; + mutable std::mutex mtx_discovery; + mutable std::mutex mtx_sharedDevices; // final mutex of all DBTDevice lifecycle bool validateDevInfo() noexcept; @@ -269,14 +281,12 @@ namespace direct_bt { std::shared_ptr<DBTDevice> findConnectedDevice (const EUI48 & address, const BDAddressType & addressType) noexcept; bool addDiscoveredDevice(std::shared_ptr<DBTDevice> const &device) noexcept; - bool removeDiscoveredDevice(const DBTDevice & device) noexcept; void removeDevice(DBTDevice & device) noexcept; bool addSharedDevice(std::shared_ptr<DBTDevice> const &device) noexcept; std::shared_ptr<DBTDevice> getSharedDevice(const DBTDevice & device) noexcept; void removeSharedDevice(const DBTDevice & device) noexcept; - std::shared_ptr<DBTDevice> findSharedDevice (const EUI48 & address, const BDAddressType addressType) noexcept; bool mgmtEvNewSettingsMgmt(const MgmtEvent& e) noexcept; bool mgmtEvDeviceDiscoveringMgmt(const MgmtEvent& e) noexcept; @@ -658,9 +668,15 @@ namespace direct_bt { /** Discards all discovered devices. Returns number of removed discovered devices. */ int removeDiscoveredDevices() noexcept; + /** Discards matching discovered devices. Returns {@code true} if found and removed, otherwise false. */ + bool removeDiscoveredDevice(const BDAddressAndType & addressAndType) noexcept; + /** Returns shared DBTDevice if found, otherwise nullptr */ std::shared_ptr<DBTDevice> findDiscoveredDevice (const EUI48 & address, const BDAddressType addressType) noexcept; + /** Returns shared DBTDevice if found, otherwise nullptr */ + std::shared_ptr<DBTDevice> findSharedDevice (const EUI48 & address, const BDAddressType addressType) noexcept; + std::string toString() const noexcept override { return toString(true); } std::string toString(bool includeDiscoveredDevices) const noexcept; diff --git a/api/direct_bt/DBTDevice.hpp b/api/direct_bt/DBTDevice.hpp index b1b111d4..fe0c6d2b 100644 --- a/api/direct_bt/DBTDevice.hpp +++ b/api/direct_bt/DBTDevice.hpp @@ -712,9 +712,6 @@ namespace direct_bt { * After calling this method, this instance is destroyed and shall not be used anymore! * </p> * <p> - * This method is automatically called @ destructor. - * </p> - * <p> * This method is an atomic operation. * </p> * <p> diff --git a/examples/direct_bt_scanner00/dbt_scanner00.cpp b/examples/direct_bt_scanner00/dbt_scanner00.cpp index 9d6d5b81..23a4e4fe 100644 --- a/examples/direct_bt_scanner00/dbt_scanner00.cpp +++ b/examples/direct_bt_scanner00/dbt_scanner00.cpp @@ -70,7 +70,7 @@ class MyAdapterStatusListener : public AdapterStatusListener { (void)timestamp; } - void deviceFound(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) override { + bool deviceFound(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) override { fprintf(stderr, "****** FOUND__: %s\n", device->toString(true).c_str()); fprintf(stderr, "Status Adapter:\n"); fprintf(stderr, "%s\n", device->getAdapter().toString().c_str()); @@ -78,6 +78,7 @@ class MyAdapterStatusListener : public AdapterStatusListener { std::unique_lock<std::mutex> lockRead(mtxDeviceFound); // RAII-style acquire and relinquish via destructor ::deviceFound = device; cvDeviceFound.notify_all(); // notify waiting getter + return true; } (void)timestamp; } diff --git a/examples/direct_bt_scanner01/dbt_scanner01.cpp b/examples/direct_bt_scanner01/dbt_scanner01.cpp index 86bb2627..5a036a00 100644 --- a/examples/direct_bt_scanner01/dbt_scanner01.cpp +++ b/examples/direct_bt_scanner01/dbt_scanner01.cpp @@ -69,7 +69,7 @@ class MyAdapterStatusListener : public AdapterStatusListener { (void)timestamp; } - void deviceFound(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) override { + bool deviceFound(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) override { fprintf(stderr, "****** FOUND__: %s\n", device->toString(true).c_str()); fprintf(stderr, "Status Adapter:\n"); fprintf(stderr, "%s\n", device->getAdapter().toString().c_str()); @@ -77,6 +77,7 @@ class MyAdapterStatusListener : public AdapterStatusListener { std::unique_lock<std::mutex> lockRead(mtxDeviceFound); // RAII-style acquire and relinquish via destructor ::deviceFound = device; cvDeviceFound.notify_all(); // notify waiting getter + return true; } (void)timestamp; } diff --git a/examples/direct_bt_scanner10/dbt_scanner10.cpp b/examples/direct_bt_scanner10/dbt_scanner10.cpp index 6e5b0ba0..c640072c 100644 --- a/examples/direct_bt_scanner10/dbt_scanner10.cpp +++ b/examples/direct_bt_scanner10/dbt_scanner10.cpp @@ -281,14 +281,14 @@ class MyAdapterStatusListener : public AdapterStatusListener { (void)timestamp; } - void deviceFound(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) override { + bool deviceFound(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) override { (void)timestamp; if( BDAddressType::BDADDR_LE_PUBLIC != device->getAddressAndType().type && BLERandomAddressType::STATIC_PUBLIC != device->getAddressAndType().getBLERandomAddressType() ) { // Requires BREDR or LE Secure Connection support: WIP fprintf(stderr, "****** FOUND__-2: Skip non 'public LE' and non 'random static public LE' %s\n", device->toString(true).c_str()); - return; + return false; } if( !isDeviceProcessing( device->getAddressAndType() ) && ( waitForDevices.empty() || @@ -305,8 +305,10 @@ class MyAdapterStatusListener : public AdapterStatusListener { } std::thread dc(::connectDiscoveredDevice, device); // @suppress("Invalid arguments") dc.detach(); + return true; } else { fprintf(stderr, "****** FOUND__-1: NOP %s\n", device->toString(true).c_str()); + return false; } } diff --git a/examples/java/DBTScanner10.java b/examples/java/DBTScanner10.java index 037c6ce8..0141e1b6 100644 --- a/examples/java/DBTScanner10.java +++ b/examples/java/DBTScanner10.java @@ -316,14 +316,14 @@ public class DBTScanner10 { } @Override - public void deviceFound(final BluetoothDevice device, final long timestamp) { + public boolean deviceFound(final BluetoothDevice device, final long timestamp) { println("****** FOUND__: "+device.toString()); if( BDAddressType.BDADDR_LE_PUBLIC != device.getAddressAndType().type && BLERandomAddressType.STATIC_PUBLIC != device.getAddressAndType().getBLERandomAddressType() ) { // Requires BREDR or LE Secure Connection support: WIP println("****** FOUND__-2: Skip non 'public LE' and non 'random static public LE' "+device.toString()); - return; + return false; } if( !devicesInProcessing.contains( device.getAddressAndType() ) && ( waitForDevices.isEmpty() || @@ -340,8 +340,10 @@ public class DBTScanner10 { } executeOffThread( () -> { connectDiscoveredDevice(device); }, "DBT-Connect-"+device.getAddressAndType(), true /* detach */); + return true; } else { println("****** FOUND__-1: NOP "+device.toString()); + return false; } } diff --git a/examples/java/ScannerTinyB01.java b/examples/java/ScannerTinyB01.java index c0fa198d..e24c1e3c 100644 --- a/examples/java/ScannerTinyB01.java +++ b/examples/java/ScannerTinyB01.java @@ -177,7 +177,7 @@ public class ScannerTinyB01 { } @Override - public void deviceFound(final BluetoothDevice device, final long timestamp) { + public boolean deviceFound(final BluetoothDevice device, final long timestamp) { final boolean matches = BDAddressAndType.ANY_DEVICE.matches(waitForDevice) || device.getAddressAndType().matches(waitForDevice); System.err.println("****** FOUND__: "+device.toString()+" - match "+matches); System.err.println("Status Adapter:"); @@ -188,6 +188,9 @@ public class ScannerTinyB01 { matchingDiscoveredDeviceBucket[0] = device; matchingDiscoveredDeviceBucket.notifyAll(); } + return true; + } else { + return false; } } diff --git a/examples/java/ScannerTinyB02.java b/examples/java/ScannerTinyB02.java index 261467f9..dde7b5d2 100644 --- a/examples/java/ScannerTinyB02.java +++ b/examples/java/ScannerTinyB02.java @@ -153,7 +153,7 @@ public class ScannerTinyB02 { } @Override - public void deviceFound(final BluetoothDevice device, final long timestamp) { + public boolean deviceFound(final BluetoothDevice device, final long timestamp) { final boolean matches = BDAddressAndType.ANY_DEVICE.matches(waitForDevice) || device.getAddressAndType().equals(waitForDevice); System.err.println("****** FOUND__: "+device.toString()+" - match "+matches); System.err.println("Status Adapter:"); @@ -164,6 +164,9 @@ public class ScannerTinyB02 { matchingDiscoveredDeviceBucket[0] = device; matchingDiscoveredDeviceBucket.notifyAll(); } + return true; + } else { + return false; } } diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java index b8ae955d..ab1d25fd 100644 --- a/java/direct_bt/tinyb/DBTAdapter.java +++ b/java/direct_bt/tinyb/DBTAdapter.java @@ -537,13 +537,14 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter } } @Override - public void deviceFound(final BluetoothDevice device, final long timestamp) { + public boolean deviceFound(final BluetoothDevice device, final long timestamp) { if( DEBUG ) { System.err.println("Adapter.FOUND: "+device+" on "+device.getAdapter()); } synchronized(discoveredDevicesLock) { discoveredDevices.add(device); } + return false; } @Override diff --git a/java/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx index 38674b6d..9d83bb3b 100644 --- a/java/jni/direct_bt/DBTAdapter.cxx +++ b/java/jni/direct_bt/DBTAdapter.cxx @@ -51,7 +51,7 @@ static const std::string _deviceClazzCtorArgs("(JLdirect_bt/tinyb/DBTAdapter;[BB static const std::string _adapterSettingsChangedMethodArgs("(Lorg/tinyb/BluetoothAdapter;Lorg/tinyb/AdapterSettings;Lorg/tinyb/AdapterSettings;Lorg/tinyb/AdapterSettings;J)V"); static const std::string _discoveringChangedMethodArgs("(Lorg/tinyb/BluetoothAdapter;Lorg/tinyb/ScanType;Lorg/tinyb/ScanType;ZZJ)V"); -static const std::string _deviceFoundMethodArgs("(Lorg/tinyb/BluetoothDevice;J)V"); +static const std::string _deviceFoundMethodArgs("(Lorg/tinyb/BluetoothDevice;J)Z"); static const std::string _deviceUpdatedMethodArgs("(Lorg/tinyb/BluetoothDevice;Lorg/tinyb/EIRDataTypeSet;J)V"); static const std::string _deviceConnectedMethodArgs("(Lorg/tinyb/BluetoothDevice;SJ)V"); static const std::string _devicePairingStateMethodArgs("(Lorg/tinyb/BluetoothDevice;Lorg/tinyb/SMPPairingState;Lorg/tinyb/PairingMode;J)V"); @@ -348,7 +348,7 @@ class JNIAdapterStatusListener : public AdapterStatusListener { jau::java_exception_check_and_throw(env, E_FILE_LINE); } - void deviceFound(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) override { + bool deviceFound(std::shared_ptr<DBTDevice> device, const uint64_t timestamp) override { JNIEnv *env = *jni_env; jobject jdevice; std::shared_ptr<jau::JavaAnon> jDeviceRef0 = device->getJavaObject(); @@ -378,8 +378,9 @@ class JNIAdapterStatusListener : public AdapterStatusListener { } env->SetLongField(jdevice, deviceClazzTSLastDiscoveryField, (jlong)device->getLastDiscoveryTimestamp()); jau::java_exception_check_and_throw(env, E_FILE_LINE); - env->CallVoidMethod(listenerObjRef.getObject(), mDeviceFound, jdevice, (jlong)timestamp); + jboolean res = env->CallBooleanMethod(listenerObjRef.getObject(), mDeviceFound, jdevice, (jlong)timestamp); jau::java_exception_check_and_throw(env, E_FILE_LINE); + return JNI_TRUE == res; } void deviceUpdated(std::shared_ptr<DBTDevice> device, const EIRDataType updateMask, const uint64_t timestamp) override { @@ -890,7 +891,10 @@ jobject Java_direct_1bt_tinyb_DBTAdapter_connectDeviceImpl(JNIEnv *env, jobject const EUI48& address = *reinterpret_cast<EUI48 *>(address_ptr); const BDAddressType addressType = static_cast<BDAddressType>( jaddressType ); - std::shared_ptr<DBTDevice> device = adapter->findDiscoveredDevice(address, addressType); + std::shared_ptr<DBTDevice> device = adapter->findSharedDevice(address, addressType); + if( nullptr == device ) { + device = adapter->findDiscoveredDevice(address, addressType); + } if( nullptr != device ) { direct_bt::HCIHandler & hci = adapter->getHCI(); if( !hci.isOpen() ) { diff --git a/java/org/tinyb/AdapterStatusListener.java b/java/org/tinyb/AdapterStatusListener.java index 8b19416c..2bd0be7b 100644 --- a/java/org/tinyb/AdapterStatusListener.java +++ b/java/org/tinyb/AdapterStatusListener.java @@ -93,10 +93,19 @@ public abstract class AdapterStatusListener { /** * A {@link BluetoothDevice} has been newly discovered. + * <p> + * The boolean return value informs the adapter whether the device shall be made persistent for connection {@code true}, + * or that it can be discarded {@code false}.<br> + * If no registered {@link AdapterStatusListener#deviceFound(BluetoothDevice, long) deviceFound(..)} implementation returns {@code true}, + * the device instance will be removed from all internal lists and can no longer being used.<br> + * If any registered {@link AdapterStatusListener#deviceFound(BluetoothDevice, long) deviceFound(..)} implementation returns {@code true}, + * the device will be made persistent, is ready to connect and {@link BluetoothDevice#remove() remove} shall be called after usage. + * </p> * @param device the found device * @param timestamp the time in monotonic milliseconds when this event occurred. See {@link BluetoothUtils#currentTimeMillis()}. + * @return true if the device shall be made persistent and {@link BluetoothDevice#remove() remove} issued later. Otherwise false to remove device right away. */ - public void deviceFound(final BluetoothDevice device, final long timestamp) { } + public boolean deviceFound(final BluetoothDevice device, final long timestamp) { return false; } /** * An already discovered {@link BluetoothDevice} has been updated. 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; } |