diff options
author | Sven Gothel <[email protected]> | 2020-10-25 02:19:34 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-10-25 02:19:34 +0100 |
commit | 2565b396380f1dc0c30161439c2dde30df083a0d (patch) | |
tree | da80840edca85529b8eb5d546c2da35f2a07debb | |
parent | 5d3d7df23b1f499e27f1956e885f1a40d7a0de3b (diff) |
Refine/add state queries in [DBT|Bluetooth]Adapter, BluetoothManager
[DBT|Bluetooth]Adapter: C++ and Java: Redefine/add state queries:
- isValid(): true if this adapter references are valid and hasn't been DBTAdapter::close() 'ed
- isPowered(): true if DBTAdapter::isValid(), HCIHandler::isOpen() and AdapterSetting::POWERED state is set
- isSuspended(): true if DBTAdapter::isValid(), HCIHandler::isOpen() and AdapterSetting::POWERED state is not set
- dev_id / getDevID(): Added definition, added method + implementation to Java
BluetoothAdapter: Java
- getPowered() -> getPoweredState() - to differentiate with isPowered()
BluetoothManager: Java
- getAdapter(dev_id) added
- setDefaultAdapter(..) implementation removed in DBTManager -> nonsense
- getDefaultAdapter(): DBT: Return 1st isPowered() adapter (redfinition, aligned with C++)
25 files changed, 281 insertions, 192 deletions
diff --git a/api/direct_bt/DBTAdapter.hpp b/api/direct_bt/DBTAdapter.hpp index 4c819192..0a487b65 100644 --- a/api/direct_bt/DBTAdapter.hpp +++ b/api/direct_bt/DBTAdapter.hpp @@ -181,6 +181,12 @@ namespace direct_bt { DBTManager& mgmt; public: + /** + * Adapter's internal temporary device id. + * <p> + * The internal device id is constant across the adapter lifecycle, + * but may change after its destruction. + */ const int dev_id; private: @@ -303,7 +309,10 @@ namespace direct_bt { ~DBTAdapter() noexcept; /** - * Closes this instance, usually being called by destructor. + * Closes this instance, usually being called by destructor or when this adapter is being removed. + * <p> + * Renders this adapter's DBTAdapter#isValid() state to false. + * </p> */ void close() noexcept; @@ -314,27 +323,37 @@ namespace direct_bt { return std::string(JAVA_DBT_PACKAGE "DBTAdapter"); } + bool hasDevId() const noexcept { return 0 <= dev_id; } + /** - * Throws an IllegalStateException if isValid() == false + * Returns whether the adapter is valid, plugged in and powered. + * @return true if DBTAdapter::isValid(), HCIHandler::isOpen() and AdapterSetting::POWERED state is set. + * @see #isSuspended() + * @see #isValid() */ - inline void checkValidAdapter() const { - if( !isValid() ) { - throw jau::IllegalStateException("Adapter state invalid: "+jau::aptrHexString(this)+", "+toString(), E_FILE_LINE); - } + bool isPowered() const noexcept { + return isValid() && hci.isOpen() && adapterInfo->isCurrentSettingBitSet(AdapterSetting::POWERED); } - bool hasDevId() const noexcept { return 0 <= dev_id; } - /** - * Returns true if the device is powered. + * Returns whether the adapter is suspended, i.e. valid and plugged in, but not powered. + * @return true if DBTAdapter::isValid(), HCIHandler::isOpen() and AdapterSetting::POWERED state is not set. + * @see #isPowered() + * @see #isValid() */ - bool isPowered() noexcept { return adapterInfo->isCurrentSettingBitSet(AdapterSetting::POWERED); } + bool isSuspended() const noexcept { + return isValid() && hci.isOpen() && !adapterInfo->isCurrentSettingBitSet(AdapterSetting::POWERED); + } /** - * Returns true if DBTAdapter::isValid() and HCIHandler::isOpen() and DBTAdapter::isPowered(). + * Returns whether the adapter is valid, i.e. reference is valid, plugged in and generally operational, + * but not necessarily DBTAdapter::isPowered() powered. + * @return true if this adapter references are valid and hasn't been DBTAdapter::close() 'ed + * @see #isPowered() + * @see #isSuspended() */ - bool isEnabled() noexcept { - return isValid() && hci.isOpen() && isPowered(); + bool isValid() const noexcept { + return DBTObject::isValid(); } EUI48 const & getAddress() const noexcept { return adapterInfo->address; } diff --git a/api/direct_bt/DBTManager.hpp b/api/direct_bt/DBTManager.hpp index 5a230cab..99dd6c70 100644 --- a/api/direct_bt/DBTManager.hpp +++ b/api/direct_bt/DBTManager.hpp @@ -313,9 +313,8 @@ namespace direct_bt { /** * Returns the default AdapterInfo. * <p> - * The default adapter is either the first POWERED adapter, - * or the one with index == dev_id == 0, - * or nullptr if no adapter is available. + * The default adapter is either the first AdapterSetting::POWERED adapter, + * or function returns nullptr if none is AdapterSetting::POWERED. * </p> */ std::shared_ptr<AdapterInfo> getDefaultAdapterInfo() const noexcept; @@ -323,12 +322,11 @@ namespace direct_bt { /** * Returns the default adapter dev_id (index). * <p> - * The default adapter is either the first POWERED adapter, - * or the one with index == dev_id == 0, - * or function returns -1 if no adapter is available. + * The default adapter is either the first AdapterSetting::POWERED adapter, + * or function returns -1 if none is AdapterSetting::POWERED. * </p> */ - int getDefaultAdapterDevId() const noexcept; + int getDefaultAdapterDevID() const noexcept; bool setMode(const uint16_t dev_id, const MgmtOpcode opc, const uint8_t mode) noexcept; diff --git a/api/direct_bt/DBTTypes.hpp b/api/direct_bt/DBTTypes.hpp index bec4bd41..f65688bd 100644 --- a/api/direct_bt/DBTTypes.hpp +++ b/api/direct_bt/DBTTypes.hpp @@ -48,23 +48,9 @@ namespace direct_bt { { protected: std::atomic_bool valid; - std::mutex lk; DBTObject() noexcept : valid(true) {} - bool lock() noexcept { - if (valid) { - lk.lock(); - return true; - } else { - return false; - } - } - - void unlock() noexcept { - lk.unlock(); - } - public: virtual std::string toString() const noexcept override { return "DBTObject["+aptrHexString(this)+"]"; } @@ -72,16 +58,10 @@ namespace direct_bt { valid = false; } - inline bool isValid() const noexcept { return valid.load(); } - /** - * Throws an IllegalStateException if isValid() == false + * Returns whether the object's reference is valid and in a general operational state. */ - void checkValid() const override { - if( !isValid() ) { - throw jau::IllegalStateException("DBTObject state invalid: "+aptrHexString(this), E_FILE_LINE); - } - } + inline bool isValid() const noexcept { return valid.load(); } }; /** diff --git a/api/direct_bt/MgmtTypes.hpp b/api/direct_bt/MgmtTypes.hpp index a2429553..8fe1e630 100644 --- a/api/direct_bt/MgmtTypes.hpp +++ b/api/direct_bt/MgmtTypes.hpp @@ -1281,12 +1281,14 @@ namespace direct_bt { private: /** Unique adapter index filter or <code>-1</code> to listen for all adapter. */ int dev_id; + /** Documented the related callback Opcode . */ + MgmtEvent::Opcode opc; /** MgmtEventCallback instance */ MgmtEventCallback callback; public: - MgmtAdapterEventCallback(int _dev_id, const MgmtEventCallback & _callback) noexcept - : dev_id(_dev_id), callback(_callback) {} + MgmtAdapterEventCallback(const int _dev_id, const MgmtEvent::Opcode _opc, const MgmtEventCallback & _callback) noexcept + : dev_id(_dev_id), opc(_opc), callback(_callback) {} MgmtAdapterEventCallback(const MgmtAdapterEventCallback &o) noexcept = default; MgmtAdapterEventCallback(MgmtAdapterEventCallback &&o) noexcept = default; @@ -1309,7 +1311,7 @@ namespace direct_bt { { return !(*this == rhs); } std::string toString() const { - return "MgmtAdapterEventCallback[dev_id "+std::to_string(dev_id)+", "+callback.toString()+"]"; + return "MgmtAdapterEventCallback[dev_id "+std::to_string(dev_id)+", "+MgmtEvent::getOpcodeString(opc)+", "+callback.toString()+"]"; } }; diff --git a/examples/direct_bt_scanner00/dbt_scanner00.cpp b/examples/direct_bt_scanner00/dbt_scanner00.cpp index ede0ea95..be56e35d 100644 --- a/examples/direct_bt_scanner00/dbt_scanner00.cpp +++ b/examples/direct_bt_scanner00/dbt_scanner00.cpp @@ -194,8 +194,8 @@ int main(int argc, char *argv[]) fprintf(stderr, "Adapter invalid.\n"); exit(1); } - if( !adapter.isEnabled() ) { - fprintf(stderr, "Adapter not enabled: device %s, address %s: %s\n", + if( !adapter.isPowered() ) { + fprintf(stderr, "Adapter not powered: device %s, address %s: %s\n", adapter.getName().c_str(), adapter.getAddressString().c_str(), adapter.toString().c_str()); exit(1); } diff --git a/examples/direct_bt_scanner01/dbt_scanner01.cpp b/examples/direct_bt_scanner01/dbt_scanner01.cpp index 9759faa6..e7933ad2 100644 --- a/examples/direct_bt_scanner01/dbt_scanner01.cpp +++ b/examples/direct_bt_scanner01/dbt_scanner01.cpp @@ -192,8 +192,8 @@ int main(int argc, char *argv[]) fprintf(stderr, "Adapter invalid.\n"); exit(1); } - if( !adapter.isEnabled() ) { - fprintf(stderr, "Adapter not enabled: device %s, address %s: %s\n", + if( !adapter.isPowered() ) { + fprintf(stderr, "Adapter not powered: device %s, address %s: %s\n", adapter.getName().c_str(), adapter.getAddressString().c_str(), adapter.toString().c_str()); exit(1); } diff --git a/examples/java/DBTScanner10.java b/examples/java/DBTScanner10.java index 59affe46..5988f5d6 100644 --- a/examples/java/DBTScanner10.java +++ b/examples/java/DBTScanner10.java @@ -615,12 +615,6 @@ public class DBTScanner10 { System.setProperty("direct_bt.hci", args[++i]); } else if( arg.equals("-dbt_mgmt") && args.length > (i+1) ) { System.setProperty("direct_bt.mgmt", args[++i]); - } else if( arg.equals("-default_dev_id") && args.length > (i+1) ) { - final int default_dev_id = Integer.valueOf(args[++i]).intValue(); - if( 0 <= default_dev_id ) { - System.setProperty("org.tinyb.default_adapter", String.valueOf(default_dev_id)); - System.err.println("Setting 'org.tinyb.default_adapter' to "+default_dev_id); - } } else if( arg.equals("-btmode") && args.length > (i+1) ) { final BTMode btmode = BTMode.get(args[++i]); System.setProperty("org.tinyb.btmode", btmode.toString()); diff --git a/examples/java/ScannerTinyB00.java b/examples/java/ScannerTinyB00.java index fe7f2475..ec088670 100644 --- a/examples/java/ScannerTinyB00.java +++ b/examples/java/ScannerTinyB00.java @@ -125,7 +125,7 @@ public class ScannerTinyB00 { System.exit(-1); } adapter = adapters.get(dev_id); - if( !adapter.isEnabled() ) { + if( !adapter.isPowered() ) { System.err.println("Adapter not enabled: device "+adapter.getName()+", address "+adapter.getAddress()+": "+adapter.toString()); System.exit(-1); } diff --git a/examples/java/ScannerTinyB01.java b/examples/java/ScannerTinyB01.java index e431f610..b1266a9e 100644 --- a/examples/java/ScannerTinyB01.java +++ b/examples/java/ScannerTinyB01.java @@ -150,7 +150,7 @@ public class ScannerTinyB01 { System.exit(-1); } adapter = adapters.get(dev_id); - if( !adapter.isEnabled() ) { + if( !adapter.isPowered() ) { System.err.println("Adapter not enabled: device "+adapter.getName()+", address "+adapter.getAddress()+": "+adapter.toString()); System.exit(-1); } diff --git a/examples/java/ScannerTinyB02.java b/examples/java/ScannerTinyB02.java index e40052a9..c300431a 100644 --- a/examples/java/ScannerTinyB02.java +++ b/examples/java/ScannerTinyB02.java @@ -130,7 +130,7 @@ public class ScannerTinyB02 { System.exit(-1); } adapter = adapters.get(dev_id); - if( !adapter.isEnabled() ) { + if( !adapter.isPowered() ) { System.err.println("Adapter not enabled: device "+adapter.getName()+", address "+adapter.getAddress()+": "+adapter.toString()); System.exit(-1); } diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java index 402175bd..62e92930 100644 --- a/java/direct_bt/tinyb/DBTAdapter.java +++ b/java/direct_bt/tinyb/DBTAdapter.java @@ -62,6 +62,7 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter private final String address; private final String name; + private final int dev_id; private final Object discoveryLock = new Object(); private final Object discoveredDevicesLock = new Object(); @@ -69,7 +70,7 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter private final AtomicBoolean isClosing = new AtomicBoolean(false); - private final AtomicBoolean isPowered = new AtomicBoolean(false); // AdapterSettings + private final AtomicBoolean powered_state = new AtomicBoolean(false); // AdapterSettings private BluetoothNotification<Boolean> userPairableNotificationCB = null; private final AtomicBoolean isDiscoverable = new AtomicBoolean(false); // AdapterSettings private BluetoothNotification<Boolean> userDiscoverableNotificationCB = null; @@ -81,11 +82,12 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter private final List<BluetoothDevice> discoveredDevices = new ArrayList<BluetoothDevice>(); - /* pp */ DBTAdapter(final long nativeInstance, final String address, final String name) + /* pp */ DBTAdapter(final long nativeInstance, final String address, final String name, final int dev_id) { super(nativeInstance, compHash(address, name)); this.address = address; this.name = name; + this.dev_id = dev_id; addStatusListener(this.statusListener, null); } @@ -123,7 +125,7 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter } private final void poweredOff() { - isPowered.set(false); + powered_state.set(false); currentMetaScanType.set(ScanType.NONE); } @@ -144,6 +146,9 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter public String getName() { return name; } @Override + public int getDevID() { return dev_id; } + + @Override public BluetoothType getBluetoothType() { return class_type(); } static BluetoothType class_type() { return BluetoothType.ADAPTER; } @@ -219,9 +224,6 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter /* Java callbacks */ @Override - public boolean getPowered() { return isPowered.get(); } - - @Override public void enablePoweredNotifications(final BluetoothNotification<Boolean> callback) { synchronized(userCallbackLock) { userPoweredNotificationCB = callback; @@ -332,7 +334,19 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter public native boolean setPairable(boolean value); @Override - public native boolean isEnabled(); + public boolean getPoweredState() { return powered_state.get(); } + + @Override + public final boolean isPowered() { return isValid() && isPoweredImpl(); } + public native boolean isPoweredImpl(); + + @Override + public final boolean isSuspended() { return isValid() && isSuspendedImpl(); } + public native boolean isSuspendedImpl(); + + @Override + public final boolean isValid() { return super.isValid() && isValidImpl(); } + public native boolean isValidImpl(); /* internal */ @@ -447,14 +461,14 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter } } if( initialSetting ) { - isPowered.set( newmask.isSet(AdapterSettings.SettingType.POWERED) ); + powered_state.set( newmask.isSet(AdapterSettings.SettingType.POWERED) ); isDiscoverable.set( newmask.isSet(AdapterSettings.SettingType.DISCOVERABLE) ); isPairable.set( newmask.isSet(AdapterSettings.SettingType.BONDABLE) ); return; } if( changedmask.isSet(AdapterSettings.SettingType.POWERED) ) { final boolean _isPowered = newmask.isSet(AdapterSettings.SettingType.POWERED); - if( isPowered.compareAndSet(!_isPowered, _isPowered) ) { + if( powered_state.compareAndSet(!_isPowered, _isPowered) ) { if( !_isPowered ) { poweredOff(); } @@ -515,7 +529,9 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter @Override public void deviceUpdated(final BluetoothDevice device, final EIRDataTypeSet updateMask, final long timestamp) { - if( DEBUG ) { + final boolean rssiUpdated = updateMask.isSet( EIRDataTypeSet.DataType.RSSI ); + final boolean mdUpdated = updateMask.isSet( EIRDataTypeSet.DataType.MANUF_DATA ); + if( DEBUG && !rssiUpdated && !mdUpdated) { System.err.println("Adapter.StatusListener.UPDATED: "+updateMask+" of "+device+" on "+device.getAdapter()); } // nop on discoveredDevices diff --git a/java/direct_bt/tinyb/DBTDevice.java b/java/direct_bt/tinyb/DBTDevice.java index 6d3d2b7d..eeed3f68 100644 --- a/java/direct_bt/tinyb/DBTDevice.java +++ b/java/direct_bt/tinyb/DBTDevice.java @@ -92,9 +92,6 @@ public class DBTDevice extends DBTObject implements BluetoothDevice final AdapterStatusListener statusListener = new AdapterStatusListener() { @Override public void deviceUpdated(final BluetoothDevice device, final EIRDataTypeSet updateMask, final long timestamp) { - if( DEBUG ) { - System.err.println("Device.StatusListener.UPDATED: "+updateMask+" of "+device); - } final boolean nameUpdated = updateMask.isSet( EIRDataTypeSet.DataType.NAME ); final boolean rssiUpdated = updateMask.isSet( EIRDataTypeSet.DataType.RSSI ); final boolean mdUpdated = updateMask.isSet( EIRDataTypeSet.DataType.MANUF_DATA ); diff --git a/java/direct_bt/tinyb/DBTManager.java b/java/direct_bt/tinyb/DBTManager.java index 3dd83c2f..436764a7 100644 --- a/java/direct_bt/tinyb/DBTManager.java +++ b/java/direct_bt/tinyb/DBTManager.java @@ -51,7 +51,6 @@ public class DBTManager implements BluetoothManager private static volatile boolean isJVMShuttingDown = false; private static final List<Runnable> userShutdownHooks = new ArrayList<Runnable>(); private static boolean unifyUUID128Bit = true; - private static final int DefaultAdapterIndex; static { AccessController.doPrivileged(new PrivilegedAction<Object>() { @@ -65,10 +64,6 @@ public class DBTManager implements BluetoothManager } }, "DBTManager_ShutdownHook" ) ) ; return null; } } ) ; - { - final String v = System.getProperty("org.tinyb.default_adapter", "-1"); - DefaultAdapterIndex = Integer.valueOf(v); - } } @@ -156,7 +151,6 @@ public class DBTManager implements BluetoothManager private long nativeInstance; private final List<BluetoothAdapter> adapters = new ArrayList<BluetoothAdapter>(); - private int defaultAdapterIndex = 0; private final Settings settings; @Override @@ -210,6 +204,17 @@ public class DBTManager implements BluetoothManager public List<BluetoothAdapter> getAdapters() { return adapters; } @Override + public BluetoothAdapter getAdapter(final int dev_id) { + for( int i=0; i<adapters.size(); i++) { + final BluetoothAdapter a = adapters.get(i); + if( dev_id == a.getDevID() ) { + return a; + } + } + return null; + } + + @Override public List<BluetoothDevice> getDevices() { return getDefaultAdapter().getDevices(); } /** @@ -245,17 +250,19 @@ public class DBTManager implements BluetoothManager @Override public boolean setDefaultAdapter(final BluetoothAdapter adapter) { - final int idx = adapters.indexOf(adapter); - if( 0 <= idx ) { - defaultAdapterIndex = idx; - return true; - } return false; } - @Override - public BluetoothAdapter getDefaultAdapter() { return adapters.get(defaultAdapterIndex); } + public BluetoothAdapter getDefaultAdapter() { + for( int i=0; i<adapters.size(); i++) { + final BluetoothAdapter a = adapters.get(i); + if( a.isPowered() ) { + return a; + } + } + return null; + } @Override public boolean startDiscovery() throws BluetoothException { return HCIStatusCode.SUCCESS == startDiscovery(true); } @@ -266,6 +273,7 @@ public class DBTManager implements BluetoothManager @Override public HCIStatusCode stopDiscovery() throws BluetoothException { return getDefaultAdapter().stopDiscovery(); } + @SuppressWarnings("deprecation") @Override public boolean getDiscovering() throws BluetoothException { return getDefaultAdapter().getDiscovering(); } @@ -281,24 +289,6 @@ public class DBTManager implements BluetoothManager } catch (final BluetoothException be) { be.printStackTrace(); } - boolean isDefaultAdapterEnabled = false; - if( 0 <= DefaultAdapterIndex && - adapters.size() > DefaultAdapterIndex - ) - { - // User chosen default adapter index, ignoring enabled state - defaultAdapterIndex = DefaultAdapterIndex; - isDefaultAdapterEnabled = adapters.get(defaultAdapterIndex).isEnabled(); - } else { - // Seek 1st enabled default adapter - for( int i=0; i<adapters.size(); i++) { - if( adapters.get(i).isEnabled() ) { - defaultAdapterIndex = i; - isDefaultAdapterEnabled = true; - break; // done - } - } - } final boolean supCharValCacheNotify; { final String v = System.getProperty("direct_bt.tinyb.characteristic.compat", "false"); @@ -323,8 +313,6 @@ public class DBTManager implements BluetoothManager } }; System.err.println("DBTManager: Using "+settings.toString()); - System.err.println("DBTManager: Using default adapter index "+defaultAdapterIndex+", user choice "+DefaultAdapterIndex+", isEnabled "+isDefaultAdapterEnabled); - System.err.println("DBTManager: Using default adapter "+adapters.get(defaultAdapterIndex).toString()); } /** Returns an instance of BluetoothManager, to be used instead of constructor. diff --git a/java/direct_bt/tinyb/DBTNativeDownlink.java b/java/direct_bt/tinyb/DBTNativeDownlink.java index c45bdb23..d9039db3 100644 --- a/java/direct_bt/tinyb/DBTNativeDownlink.java +++ b/java/direct_bt/tinyb/DBTNativeDownlink.java @@ -46,7 +46,7 @@ public abstract class DBTNativeDownlink initNativeJavaObject(nativeInstance); } - protected final boolean isValid() { return isValid.get(); } + protected boolean isValid() { return isValid.get(); } @Override protected void finalize() diff --git a/java/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx index 3eed0121..6e85b7ae 100644 --- a/java/jni/direct_bt/DBTAdapter.cxx +++ b/java/jni/direct_bt/DBTAdapter.cxx @@ -563,11 +563,33 @@ void Java_direct_1bt_tinyb_DBTAdapter_deleteImpl(JNIEnv *env, jobject obj, jlong } } -jboolean Java_direct_1bt_tinyb_DBTAdapter_isEnabled(JNIEnv *env, jobject obj) +jboolean Java_direct_1bt_tinyb_DBTAdapter_isPoweredImpl(JNIEnv *env, jobject obj) { try { DBTAdapter *adapter = jau::getJavaUplinkObject<DBTAdapter>(env, obj); - return adapter->isEnabled(); + return adapter->isPowered(); + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return JNI_FALSE; +} + +jboolean Java_direct_1bt_tinyb_DBTAdapter_isSuspendedImpl(JNIEnv *env, jobject obj) +{ + try { + DBTAdapter *adapter = jau::getJavaUplinkObject<DBTAdapter>(env, obj); + return adapter->isSuspended(); + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return JNI_FALSE; +} + +jboolean Java_direct_1bt_tinyb_DBTAdapter_isValidImpl(JNIEnv *env, jobject obj) +{ + try { + DBTAdapter *adapter = jau::getJavaUplinkObject<DBTAdapter>(env, obj); + return adapter->isValid(); } catch(...) { rethrow_and_raise_java_exception(env); } diff --git a/java/jni/direct_bt/DBTManager.cxx b/java/jni/direct_bt/DBTManager.cxx index 8734b9f3..7306cb5c 100644 --- a/java/jni/direct_bt/DBTManager.cxx +++ b/java/jni/direct_bt/DBTManager.cxx @@ -67,7 +67,24 @@ void Java_direct_1bt_tinyb_DBTManager_deleteImpl(JNIEnv *env, jobject obj, jlong } } -static const std::string _adapterClazzCtorArgs("(JLjava/lang/String;Ljava/lang/String;)V"); +static const std::string _adapterClazzCtorArgs("(JLjava/lang/String;Ljava/lang/String;I)V"); +static jobject _createJavaAdapter(JNIEnv *env_, jclass clazz, jmethodID clazz_ctor, DBTAdapter* adapter) { + // prepare adapter ctor + const jstring addr = from_string_to_jstring(env_, adapter->getAddressString()); + const jstring name = from_string_to_jstring(env_, adapter->getName()); + java_exception_check_and_throw(env_, E_FILE_LINE); + jobject jAdapter = env_->NewObject(clazz, clazz_ctor, (jlong)adapter, addr, name, adapter->dev_id); + java_exception_check_and_throw(env_, E_FILE_LINE); + JNIGlobalRef::check(jAdapter, E_FILE_LINE); + std::shared_ptr<JavaAnon> jAdapterRef = adapter->getJavaObject(); // GlobalRef + JavaGlobalObj::check(jAdapterRef, E_FILE_LINE); + env_->DeleteLocalRef(addr); + env_->DeleteLocalRef(name); + env_->DeleteLocalRef(jAdapter); + + DBG_PRINT("Java_direct_1bt_tinyb_DBTManager_createJavaAdapter: New Adapter %p %s", adapter, adapter->toString().c_str()); + return JavaGlobalObj::GetObject(jAdapterRef); +}; jobject Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl(JNIEnv *env, jobject obj) { @@ -75,41 +92,26 @@ jobject Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl(JNIEnv *env, jobject DBTManager *manager = getInstance<DBTManager>(env, obj); DBG_PRINT("Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl: Manager %s", manager->toString().c_str()); - // index == dev_id std::vector<std::unique_ptr<DBTAdapter>> adapters; const int adapterCount = manager->getAdapterCount(); - for(int idx = 0; idx < adapterCount; idx++) { - std::unique_ptr<DBTAdapter> adapter(new DBTAdapter( idx ) ); + for(int dev_id = 0; dev_id < adapterCount; dev_id++) { + if( nullptr == manager->getAdapterInfo(dev_id) ) { + ERR_PRINT("DBTManager::getAdapterListImpl: Adapter dev_id %d: Not found", dev_id); + continue; + } + std::unique_ptr<DBTAdapter> adapter(new DBTAdapter( dev_id ) ); if( !adapter->isValid() ) { - throw BluetoothException("Invalid adapter @ idx "+std::to_string( idx ), E_FILE_LINE); + throw BluetoothException("Invalid adapter @ dev_id "+std::to_string( dev_id ), E_FILE_LINE); } if( !adapter->hasDevId() ) { - throw BluetoothException("Invalid adapter dev-id @ idx "+std::to_string( idx ), E_FILE_LINE); + throw BluetoothException("Invalid adapter dev-id @ dev_id "+std::to_string( dev_id ), E_FILE_LINE); } - if( idx != adapter->dev_id ) { // just make sure idx == dev_id - throw BluetoothException("Invalid adapter dev-id "+std::to_string( adapter->dev_id )+" != index "+std::to_string( idx ), E_FILE_LINE); + if( dev_id != adapter->dev_id ) { // just make sure idx == dev_id + throw BluetoothException("Invalid adapter dev-id "+std::to_string( adapter->dev_id )+" != dev_id "+std::to_string( dev_id ), E_FILE_LINE); } adapters.push_back(std::move(adapter)); } - std::function<jobject(JNIEnv*, jclass, jmethodID, DBTAdapter*)> ctor_adapter = - [](JNIEnv *env_, jclass clazz, jmethodID clazz_ctor, DBTAdapter* adapter)->jobject { - // prepare adapter ctor - const jstring addr = from_string_to_jstring(env_, adapter->getAddressString()); - const jstring name = from_string_to_jstring(env_, adapter->getName()); - java_exception_check_and_throw(env_, E_FILE_LINE); - jobject jAdapter = env_->NewObject(clazz, clazz_ctor, (jlong)adapter, addr, name); - java_exception_check_and_throw(env_, E_FILE_LINE); - JNIGlobalRef::check(jAdapter, E_FILE_LINE); - std::shared_ptr<JavaAnon> jAdapterRef = adapter->getJavaObject(); // GlobalRef - JavaGlobalObj::check(jAdapterRef, E_FILE_LINE); - env_->DeleteLocalRef(addr); - env_->DeleteLocalRef(name); - env_->DeleteLocalRef(jAdapter); - - DBG_PRINT("Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl: New Adapter %p %s", adapter, adapter->toString().c_str()); - return JavaGlobalObj::GetObject(jAdapterRef); - }; - return convert_vector_uniqueptr_to_jarraylist<DBTAdapter>(env, adapters, _adapterClazzCtorArgs.c_str(), ctor_adapter); + return convert_vector_uniqueptr_to_jarraylist<DBTAdapter>(env, adapters, _adapterClazzCtorArgs.c_str(), _createJavaAdapter); } catch(...) { rethrow_and_raise_java_exception(env); } diff --git a/java/jni/tinyb/DBusAdapter.cxx b/java/jni/tinyb/DBusAdapter.cxx index f221d33a..435b4c39 100644 --- a/java/jni/tinyb/DBusAdapter.cxx +++ b/java/jni/tinyb/DBusAdapter.cxx @@ -180,7 +180,7 @@ jlong Java_tinyb_dbus_DBusAdapter_getBluetoothClass(JNIEnv *env, jobject obj) return 0; } -jboolean Java_tinyb_dbus_DBusAdapter_getPowered(JNIEnv *env, jobject obj) +jboolean Java_tinyb_dbus_DBusAdapter_getPoweredState(JNIEnv *env, jobject obj) { try { BluetoothAdapter *obj_adapter = getInstance<BluetoothAdapter>(env, obj); diff --git a/java/org/tinyb/BluetoothAdapter.java b/java/org/tinyb/BluetoothAdapter.java index 95f3e77c..3980c90f 100644 --- a/java/org/tinyb/BluetoothAdapter.java +++ b/java/org/tinyb/BluetoothAdapter.java @@ -208,6 +208,17 @@ public interface BluetoothAdapter extends BluetoothObject */ public String getName(); + /** + * Returns the BluetoothAdapter's internal temporary device id + * <p> + * The internal device id is constant across the adapter lifecycle, + * but may change after its destruction. + * </p> + * @since 2.0.0 + * @implNote Not implemented on tinyb.dbus + */ + public int getDevID(); + /** Returns the friendly name of this adapter. * @return The friendly name of this adapter, or NULL if not set. */ @@ -222,20 +233,46 @@ public interface BluetoothAdapter extends BluetoothObject */ public long getBluetoothClass(); + /** - * Returns whether this adapter is enabled and usable. - * <p> - * An inactive adapter could be blocked or rfkill'ed. - * </p> - * @return {@code true} if this adapter is enabled and usable, otherwise {@code false}. + * Returns whether the adapter is valid, plugged in and powered. + * @return true if {@link #isValid()}, HCI channel open and {@link AdapterSettings.SettingType#POWERED POWERED} state is set. + * @see #isSuspended() + * @see #isValid() * @since 2.0.0 */ - public boolean isEnabled(); + public boolean isPowered(); - /** Returns the power state the adapter. - * @return The power state of the adapter. - */ - public boolean getPowered(); + /** + * Returns whether the adapter is suspended, i.e. valid and plugged in, but not powered. + * @return true if {@link #isValid()}, HCI channel open and {@link AdapterSettings.SettingType#POWERED POWERED} state is not set. + * @see #isPowered() + * @see #isValid() + */ + public boolean isSuspended(); + + /** + * Returns whether the adapter is valid, i.e. reference is valid, plugged in and generally operational, + * but not necessarily {@link #isPowered()}. + * @return true if this adapter references are valid and hadn't been {@link #close()}'ed + * @see #isPowered() + * @see #isSuspended() + * @since 2.0.0 + */ + public boolean isValid(); + + /** + * Returns the power state the adapter. + * <p> + * Consider using {@link #isPowered()} + * </p> + * @return The power state of the adapter. + * @since 2.0.0 Renamed from getPowered() to getPoweredState() + * @see #isPowered() + * @see #isSuspended() + * @see #isValid() + */ + public boolean getPoweredState(); /** * Enables notifications for the powered property and calls run function of the diff --git a/java/org/tinyb/BluetoothManager.java b/java/org/tinyb/BluetoothManager.java index 5c7eba23..b8754303 100644 --- a/java/org/tinyb/BluetoothManager.java +++ b/java/org/tinyb/BluetoothManager.java @@ -192,6 +192,18 @@ public interface BluetoothManager */ public List<BluetoothAdapter> getAdapters(); + /** + * Returns the BluetoothAdapter matching the given dev_id or null if not found. + * <p> + * The adapters internal device id is constant across the adapter lifecycle, + * but may change after its destruction. + * </p> + * @param dev_id the internal temporary adapter device id + * @since 2.0.0 + * @implNote Not implemented on tinyb.dbus + */ + public BluetoothAdapter getAdapter(final int dev_id); + /** Returns a list of discovered BluetoothDevices * @return A list of discovered BluetoothDevices */ @@ -202,17 +214,24 @@ public interface BluetoothManager */ public List<BluetoothGattService> getServices(); - /** Sets a default adapter to use for discovery. - * @return TRUE if the device was set - */ + /** + * Sets a default adapter to use for discovery. + * @return TRUE if the device was set + * @implNote not implemented for direct_bt.tinyb + */ public boolean setDefaultAdapter(BluetoothAdapter adapter); - /** Gets the default adapter to use for discovery. - * <p> - * System default is the last detected adapter at initialisation. - * </p> - * @return the used default adapter - */ + /** + * Gets the default adapter to use for discovery. + * <p> + * <i>direct_bt.tinyb</i>: The default adapter is either the first {@link BluetoothAdapter#isPowered() powered} {@link BluetoothAdapter}, + * or function returns nullptr if none is enabled. + * </p> + * <p> + * <i>tinyb.dbus</i>: System default is the last detected adapter at initialization. + * </p> + * @return the used default adapter + */ public BluetoothAdapter getDefaultAdapter(); /** Turns on device discovery on the default adapter if it is disabled. diff --git a/java/tinyb/dbus/DBusAdapter.java b/java/tinyb/dbus/DBusAdapter.java index 3d8a1d89..17cbb7d1 100644 --- a/java/tinyb/dbus/DBusAdapter.java +++ b/java/tinyb/dbus/DBusAdapter.java @@ -68,9 +68,13 @@ public class DBusAdapter extends DBusObject implements BluetoothAdapter } @Override - public boolean isEnabled() { - return true; // FIXME - } + public boolean isPowered() { return isValid() && getPoweredState(); } + + @Override + public final boolean isSuspended() { return isValid() && !getPoweredState(); } + + @Override + public final boolean isValid() { return super.isValid(); } @Override public boolean isDeviceWhitelisted(final String address) { @@ -131,6 +135,9 @@ public class DBusAdapter extends DBusObject implements BluetoothAdapter public native String getName(); @Override + public int getDevID() { return 0; } // FIXME + + @Override public native String getAlias(); @Override @@ -140,7 +147,7 @@ public class DBusAdapter extends DBusObject implements BluetoothAdapter public native long getBluetoothClass(); @Override - public native boolean getPowered(); + public native boolean getPoweredState(); @Override public native void enablePoweredNotifications(BluetoothNotification<Boolean> callback); diff --git a/java/tinyb/dbus/DBusManager.java b/java/tinyb/dbus/DBusManager.java index e815aeec..0c87ba49 100644 --- a/java/tinyb/dbus/DBusManager.java +++ b/java/tinyb/dbus/DBusManager.java @@ -95,6 +95,9 @@ public class DBusManager implements BluetoothManager public native List<BluetoothAdapter> getAdapters(); @Override + public BluetoothAdapter getAdapter(final int dev_id) { return null; } // FIXME + + @Override public native List<BluetoothDevice> getDevices(); @Override diff --git a/java/tinyb/dbus/DBusObject.java b/java/tinyb/dbus/DBusObject.java index b714d4c2..4e336261 100644 --- a/java/tinyb/dbus/DBusObject.java +++ b/java/tinyb/dbus/DBusObject.java @@ -80,6 +80,8 @@ public class DBusObject implements BluetoothObject return objectPath.hashCode(); } + protected synchronized boolean isValid() { return isValid; } + @Override public synchronized void close() { if (!isValid) diff --git a/src/direct_bt/DBTAdapter.cpp b/src/direct_bt/DBTAdapter.cpp index caf09a28..776a508c 100644 --- a/src/direct_bt/DBTAdapter.cpp +++ b/src/direct_bt/DBTAdapter.cpp @@ -164,7 +164,7 @@ bool DBTAdapter::validateDevInfo() noexcept { } hci.setBTMode(btMode); - if( isPowered() ) { + if( adapterInfo->isCurrentSettingBitSet(AdapterSetting::POWERED) ) { HCILocalVersion version; HCIStatusCode status = hci.getLocalVersion(version); if( HCIStatusCode::SUCCESS != status ) { @@ -206,7 +206,7 @@ bool DBTAdapter::validateDevInfo() noexcept { DBTAdapter::DBTAdapter() noexcept : debug_event(jau::environment::getBooleanProperty("direct_bt.debug.adapter.event", false)), mgmt( DBTManager::get(BTMode::NONE /* use env default */) ), - dev_id( mgmt.getDefaultAdapterDevId() ), + dev_id( mgmt.getDefaultAdapterDevID() ), hci( dev_id ) { valid = validateDevInfo(); @@ -224,7 +224,7 @@ DBTAdapter::DBTAdapter(EUI48 &mac) noexcept DBTAdapter::DBTAdapter(const int _dev_id) noexcept : debug_event(jau::environment::getBooleanProperty("direct_bt.debug.adapter.event", false)), mgmt( DBTManager::get(BTMode::NONE /* use env default */) ), - dev_id( 0 <= _dev_id ? _dev_id : mgmt.getDefaultAdapterDevId() ), + dev_id( 0 <= _dev_id ? _dev_id : mgmt.getDefaultAdapterDevID() ), hci( dev_id ) { valid = validateDevInfo(); @@ -239,10 +239,11 @@ DBTAdapter::~DBTAdapter() noexcept { void DBTAdapter::close() noexcept { DBG_PRINT("DBTAdapter::close: ... %p %s", this, toString().c_str()); keep_le_scan_alive = false; + // mute all listener first { int count = mgmt.removeMgmtEventCallback(dev_id); - DBG_PRINT("DBTAdapter removeMgmtEventCallback(DISCOVERING): %d callbacks", count); + DBG_PRINT("DBTAdapter::close removeMgmtEventCallback: %d callbacks", count); } statusListenerList.clear(); @@ -350,8 +351,8 @@ bool DBTAdapter::isDeviceWhitelisted(const EUI48 &address) noexcept { bool DBTAdapter::addDeviceToWhitelist(const EUI48 &address, const BDAddressType address_type, const HCIWhitelistConnectType ctype, const uint16_t conn_interval_min, const uint16_t conn_interval_max, const uint16_t conn_latency, const uint16_t timeout) { - if( !isEnabled() ) { - ERR_PRINT("DBTAdapter::startDiscovery: Adapter not enabled/powered: %s", toString().c_str()); + if( !isPowered() ) { + ERR_PRINT("DBTAdapter::startDiscovery: Adapter not powered: %s", toString().c_str()); return false; } if( mgmt.isDeviceWhitelisted(dev_id, address) ) { @@ -367,7 +368,6 @@ bool DBTAdapter::addDeviceToWhitelist(const EUI48 &address, const BDAddressType } bool DBTAdapter::removeDeviceFromWhitelist(const EUI48 &address, const BDAddressType address_type) { - checkValidAdapter(); return mgmt.removeDeviceFromWhitelist(dev_id, address, address_type); } @@ -375,7 +375,6 @@ static jau::cow_vector<std::shared_ptr<AdapterStatusListener>>::equal_comparator [](const std::shared_ptr<AdapterStatusListener> &a, const std::shared_ptr<AdapterStatusListener> &b) -> bool { return *a == *b; }; bool DBTAdapter::addStatusListener(std::shared_ptr<AdapterStatusListener> l) { - checkValidAdapter(); if( nullptr == l ) { throw jau::IllegalArgumentException("DBTAdapterStatusListener ref is null", E_FILE_LINE); } @@ -387,7 +386,6 @@ bool DBTAdapter::addStatusListener(std::shared_ptr<AdapterStatusListener> l) { } bool DBTAdapter::removeStatusListener(std::shared_ptr<AdapterStatusListener> l) { - checkValidAdapter(); if( nullptr == l ) { throw jau::IllegalArgumentException("DBTAdapterStatusListener ref is null", E_FILE_LINE); } @@ -396,7 +394,6 @@ bool DBTAdapter::removeStatusListener(std::shared_ptr<AdapterStatusListener> l) } bool DBTAdapter::removeStatusListener(const AdapterStatusListener * l) { - checkValidAdapter(); if( nullptr == l ) { throw jau::IllegalArgumentException("DBTAdapterStatusListener ref is null", E_FILE_LINE); } @@ -420,7 +417,6 @@ bool DBTAdapter::removeStatusListener(const AdapterStatusListener * l) { } int DBTAdapter::removeAllStatusListener() { - checkValidAdapter(); int count = statusListenerList.size(); statusListenerList.clear(); return count; @@ -457,8 +453,8 @@ HCIStatusCode DBTAdapter::startDiscovery(const bool keepAlive, const HCILEOwnAdd // ERR_PRINT("Test"); // throw jau::RuntimeException("Test", E_FILE_LINE); - if( !isEnabled() ) { - WARN_PRINT("DBTAdapter::startDiscovery: Adapter not enabled/powered: %s", toString().c_str()); + if( !isPowered() ) { + WARN_PRINT("DBTAdapter::startDiscovery: Adapter not powered: %s", toString().c_str()); return HCIStatusCode::UNSPECIFIED_ERROR; } const std::lock_guard<std::mutex> lock(mtx_discovery); // RAII-style acquire and relinquish via destructor @@ -502,8 +498,8 @@ HCIStatusCode DBTAdapter::startDiscovery(const bool keepAlive, const HCILEOwnAdd void DBTAdapter::startDiscoveryBackground() noexcept { // FIXME: Respect DBTAdapter::btMode, i.e. BTMode::BREDR, BTMode::LE or BTMode::DUAL to setup BREDR, LE or DUAL scanning! - if( !isEnabled() ) { - WARN_PRINT("DBTAdapter::startDiscoveryBackground: Adapter not enabled/powered: %s", toString().c_str()); + if( !isPowered() ) { + WARN_PRINT("DBTAdapter::startDiscoveryBackground: Adapter not powered: %s", toString().c_str()); return; } const std::lock_guard<std::mutex> lock(mtx_discovery); // RAII-style acquire and relinquish via destructor @@ -556,7 +552,7 @@ HCIStatusCode DBTAdapter::stopDiscovery() noexcept { } HCIStatusCode status; - if( !isPowered() ) { + if( !adapterInfo->isCurrentSettingBitSet(AdapterSetting::POWERED) ) { WARN_PRINT("DBTAdapter::stopDiscovery: Powered off: %s", toString().c_str()); hci.setCurrentScanType(ScanType::NONE); currentMetaScanType = ScanType::NONE; diff --git a/src/direct_bt/DBTDevice.cpp b/src/direct_bt/DBTDevice.cpp index 13cc837d..931e8a46 100644 --- a/src/direct_bt/DBTDevice.cpp +++ b/src/direct_bt/DBTDevice.cpp @@ -261,8 +261,10 @@ HCIStatusCode DBTDevice::connectLE(uint16_t le_scan_interval, uint16_t le_scan_w uint16_t conn_latency, uint16_t supervision_timeout) { const std::lock_guard<std::recursive_mutex> lock_conn(mtx_connect); // RAII-style acquire and relinquish via destructor - adapter.checkValid(); - + if( !adapter.isPowered() ) { + WARN_PRINT("DBTDevice::connectLE: Adapter not powered: %s", adapter.toString().c_str()); + return HCIStatusCode::UNSPECIFIED_ERROR; + } HCILEOwnAddressType hci_own_mac_type; HCILEPeerAddressType hci_peer_mac_type; @@ -339,7 +341,10 @@ HCIStatusCode DBTDevice::connectLE(uint16_t le_scan_interval, uint16_t le_scan_w HCIStatusCode DBTDevice::connectBREDR(const uint16_t pkt_type, const uint16_t clock_offset, const uint8_t role_switch) { const std::lock_guard<std::recursive_mutex> lock_conn(mtx_connect); // RAII-style acquire and relinquish via destructor - adapter.checkValid(); + if( !adapter.isPowered() ) { + WARN_PRINT("DBTDevice::connectBREDR: Adapter not powered: %s", adapter.toString().c_str()); + return HCIStatusCode::UNSPECIFIED_ERROR; + } if( isConnected ) { ERR_PRINT("DBTDevice::connectBREDR: Already connected: %s", toString().c_str()); @@ -451,15 +456,10 @@ HCIStatusCode DBTDevice::disconnect(const HCIStatusCode reason) noexcept { } if( !adapter.isPowered() ) { - WARN_PRINT("DBTDevice::disconnect: Powered off: %s", toString().c_str()); + WARN_PRINT("DBTDevice::disconnect: Adapter not powered: %s", toString().c_str()); res = HCIStatusCode::UNSPECIFIED_ERROR; // powered-off goto exit; } - if( !hci.isOpen() ) { - ERR_PRINT("DBTDevice::disconnect: HCI closed: %s", toString().c_str()); - res = HCIStatusCode::UNSPECIFIED_ERROR; - goto exit; - } res = hci.disconnect(hciConnHandle.load(), address, addressType, reason); if( HCIStatusCode::SUCCESS != res ) { diff --git a/src/direct_bt/DBTManager.cpp b/src/direct_bt/DBTManager.cpp index c7a74572..fa5513f1 100644 --- a/src/direct_bt/DBTManager.cpp +++ b/src/direct_bt/DBTManager.cpp @@ -346,7 +346,6 @@ DBTManager::DBTManager(const BTMode _defaultBTMode) noexcept PERF_TS_T0(); - bool ok = true; // Mandatory { MgmtCommand req0(MgmtOpcode::READ_VERSION, MgmtConstU16::MGMT_INDEX_NONE); @@ -420,16 +419,14 @@ next1: // 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++) { + for(int i=0; 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)); @@ -457,10 +454,14 @@ next1: PERF_TS_TD("DBTManager::open.ok"); return; } + PERF_TS_TD("DBTManager::ctor.ok"); + DBG_PRINT("DBTManager::ctor: OK"); + return; fail: close(); - PERF_TS_TD("DBTManager::open.fail"); + PERF_TS_TD("DBTManager::ctor.fail"); + DBG_PRINT("DBTManager::ctor: FAIL"); return; } @@ -591,7 +592,7 @@ std::shared_ptr<AdapterInfo> DBTManager::getDefaultAdapterInfo() const noexcept } } -int DBTManager::getDefaultAdapterDevId() const noexcept { +int DBTManager::getDefaultAdapterDevID() const noexcept { std::shared_ptr<AdapterInfo> ai = getDefaultAdapterInfo(); if( nullptr == ai ) { return -1; @@ -818,7 +819,7 @@ bool DBTManager::addMgmtEventCallback(const int dev_id, const MgmtEvent::Opcode return false; } MgmtAdapterEventCallbackList &l = mgmtAdapterEventCallbackLists[static_cast<uint16_t>(opc)]; - /* const bool added = */ l.push_back_unique(MgmtAdapterEventCallback(dev_id, cb), _mgmtAdapterEventCallbackEqComp_ID_CB); + /* const bool added = */ l.push_back_unique(MgmtAdapterEventCallback(dev_id, opc, cb), _mgmtAdapterEventCallbackEqComp_ID_CB); return true; } int DBTManager::removeMgmtEventCallback(const MgmtEvent::Opcode opc, const MgmtEventCallback &cb) noexcept { @@ -827,13 +828,19 @@ int DBTManager::removeMgmtEventCallback(const MgmtEvent::Opcode opc, const MgmtE return 0; } MgmtAdapterEventCallbackList &l = mgmtAdapterEventCallbackLists[static_cast<uint16_t>(opc)]; - return l.erase_matching(MgmtAdapterEventCallback(0, cb), true /* all_matching */, _mgmtAdapterEventCallbackEqComp_CB); + return l.erase_matching( MgmtAdapterEventCallback( 0, MgmtEvent::Opcode::INVALID, cb ), + true /* all_matching */, _mgmtAdapterEventCallbackEqComp_CB); } int DBTManager::removeMgmtEventCallback(const int dev_id) noexcept { + if( 0 > dev_id ) { + // skip dev_id -1 case, use clearAllMgmtEventCallbacks() here + return 0; + } int count = 0; for(size_t i=0; i<mgmtAdapterEventCallbackLists.size(); i++) { MgmtAdapterEventCallbackList &l = mgmtAdapterEventCallbackLists[i]; - count += l.erase_matching(MgmtAdapterEventCallback(dev_id, MgmtEventCallback()), true /* all_matching */, _mgmtAdapterEventCallbackEqComp_ID); + count += l.erase_matching( MgmtAdapterEventCallback( dev_id, MgmtEvent::Opcode::INVALID, MgmtEventCallback() ), + true /* all_matching */, _mgmtAdapterEventCallbackEqComp_ID); } return count; } |