diff options
author | Sven Gothel <[email protected]> | 2020-08-22 18:32:18 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-08-22 18:32:18 +0200 |
commit | 1f39f6c21c84e466d2563d4ead1470c3c5b5143b (patch) | |
tree | 7166631a4f0081a6370d06488daad82130d88bb5 | |
parent | 536975dd325723593e38efecde061d8c7c95c707 (diff) |
DBTAdapter: Have non-enabled adapter to be valid, use lazy HCI initialization; DBTManager: Validate enabled for non-user default adapter.
DBTAdapter: Have non-enabled adapter to be valid, use lazy HCI initialization
In a multi adapter setting, it is possible to have one adapter not being enabled,
i.e. blocked from operations (e.g. rfkill).
HCI communication is not possible in such cases and 'openHCI()' will fail.
We still need to treat such adapter as valid, as they are,
and distinguish the states: 'valid' and 'enabled'.
This allows 'delivery' of all adapters to a manager
and allows querying whether they are enabled.
Therefor, the native DBTAdapter will not issue an aggregated 'openHCI()'
at construction and initial validation, but treat the HCI instance as a singleton
to be lazily created via 'getHCI()' if not yet existing.
Here the required listener are also attached to the instance.
In the future, this shall also allow dynamically adding/removing
and enabling/disabling adapters.
Hence before using a chosen adapter, one should query its enabled state
via 'isEnabled()', which will also potentially initializing HCI.
+++
DBTManager: Validate enabled for non-user default adapter.
On the Java side, we can chose a default adapter via the property 'org.tinyb.default_adapter'.
If so chosen, it shall be the default adapter, regardless of its 'enabled' state.
Otherwise, the default adapter shall be the first enabled adapter in the list.
-rw-r--r-- | api/direct_bt/DBTAdapter.hpp | 19 | ||||
-rw-r--r-- | examples/direct_bt_scanner00/dbt_scanner00.cpp | 5 | ||||
-rw-r--r-- | examples/direct_bt_scanner01/dbt_scanner01.cpp | 5 | ||||
-rw-r--r-- | examples/direct_bt_scanner10/dbt_scanner10.cpp | 6 | ||||
-rw-r--r-- | examples/java/ScannerTinyB00.java | 4 | ||||
-rw-r--r-- | examples/java/ScannerTinyB01.java | 4 | ||||
-rw-r--r-- | examples/java/ScannerTinyB02.java | 4 | ||||
-rw-r--r-- | examples/java/ScannerTinyB10.java | 20 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTAdapter.java | 3 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTManager.java | 23 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTAdapter.cxx | 11 | ||||
-rw-r--r-- | java/org/tinyb/BluetoothAdapter.java | 10 | ||||
-rw-r--r-- | java/tinyb/dbus/DBusAdapter.java | 5 | ||||
-rw-r--r-- | src/direct_bt/DBTAdapter.cpp | 34 | ||||
-rw-r--r-- | src/direct_bt/DBTDevice.cpp | 23 |
15 files changed, 144 insertions, 32 deletions
diff --git a/api/direct_bt/DBTAdapter.hpp b/api/direct_bt/DBTAdapter.hpp index 08364a7b..d24c287b 100644 --- a/api/direct_bt/DBTAdapter.hpp +++ b/api/direct_bt/DBTAdapter.hpp @@ -168,6 +168,7 @@ namespace direct_bt { std::vector<std::shared_ptr<DBTDevice>> discoveredDevices; // all discovered devices std::vector<std::shared_ptr<DBTDevice>> sharedDevices; // all active shared devices std::vector<std::shared_ptr<AdapterStatusListener>> statusListenerList; + std::recursive_mutex mtx_hci; std::recursive_mutex mtx_connectedDevices; std::recursive_mutex mtx_discoveredDevices; std::recursive_mutex mtx_sharedDevices; @@ -175,7 +176,6 @@ namespace direct_bt { std::recursive_mutex mtx_discovery; bool validateDevInfo(); - bool openHCI(); bool closeHCI(); friend std::shared_ptr<DBTDevice> DBTDevice::getSharedInstance() const; @@ -257,8 +257,21 @@ namespace direct_bt { } } + /** + * Throws an IllegalStateException if isValid() == false or getHCI() == nullptr + */ + inline void checkValidEnabledAdapter() { + if( nullptr == getHCI() ) { // implies 'checkValidAdapter()' + throw IllegalStateException("Adapter HCI not enabled: "+aptrHexString(this)+", "+toString(), E_FILE_LINE); + } + } + bool hasDevId() const { return 0 <= dev_id; } + bool isEnabled() { + return nullptr != getHCI(); // implies 'checkValidAdapter()' + } + EUI48 const & getAddress() const { return adapterInfo->address; } std::string getAddressString() const { return adapterInfo->address.toString(); } @@ -310,9 +323,9 @@ namespace direct_bt { DBTManager& getManager() const { return mgmt; } /** - * Returns the {@link #openHCI()} HCIHandler or {@code nullptr} if closed. + * Returns the already open or newly opened HCIHandler or {@code nullptr} if not available. */ - std::shared_ptr<HCIHandler> getHCI() const { return hci; } + std::shared_ptr<HCIHandler> getHCI(); /** * Returns true, if the adapter's device is already whitelisted. diff --git a/examples/direct_bt_scanner00/dbt_scanner00.cpp b/examples/direct_bt_scanner00/dbt_scanner00.cpp index 48939bdc..e7348b30 100644 --- a/examples/direct_bt_scanner00/dbt_scanner00.cpp +++ b/examples/direct_bt_scanner00/dbt_scanner00.cpp @@ -185,6 +185,11 @@ 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", + adapter.getName().c_str(), adapter.getAddressString().c_str(), adapter.toString().c_str()); + exit(1); + } fprintf(stderr, "Using adapter: device %s, address %s: %s\n", adapter.getName().c_str(), adapter.getAddressString().c_str(), adapter.toString().c_str()); diff --git a/examples/direct_bt_scanner01/dbt_scanner01.cpp b/examples/direct_bt_scanner01/dbt_scanner01.cpp index 5f57f3ee..ee1f0c39 100644 --- a/examples/direct_bt_scanner01/dbt_scanner01.cpp +++ b/examples/direct_bt_scanner01/dbt_scanner01.cpp @@ -181,6 +181,11 @@ 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", + adapter.getName().c_str(), adapter.getAddressString().c_str(), adapter.toString().c_str()); + exit(1); + } fprintf(stderr, "Using adapter: device %s, address %s: %s\n", adapter.getName().c_str(), adapter.getAddressString().c_str(), adapter.toString().c_str()); diff --git a/examples/direct_bt_scanner10/dbt_scanner10.cpp b/examples/direct_bt_scanner10/dbt_scanner10.cpp index 929d5d49..f1490d23 100644 --- a/examples/direct_bt_scanner10/dbt_scanner10.cpp +++ b/examples/direct_bt_scanner10/dbt_scanner10.cpp @@ -158,6 +158,7 @@ class MyAdapterStatusListener : public AdapterStatusListener { } void deviceConnected(std::shared_ptr<DBTDevice> device, const uint16_t handle, const uint64_t timestamp) override { + (void)handle; (void)timestamp; if( !isDeviceProcessing( device->getAddress() ) && @@ -371,6 +372,11 @@ void test(int dev_id) { fprintf(stderr, "Adapter invalid.\n"); exit(1); } + if( !adapter.isEnabled() ) { + fprintf(stderr, "Adapter not enabled: device %s, address %s: %s\n", + adapter.getName().c_str(), adapter.getAddressString().c_str(), adapter.toString().c_str()); + exit(1); + } fprintf(stderr, "Using adapter: device %s, address %s: %s\n", adapter.getName().c_str(), adapter.getAddressString().c_str(), adapter.toString().c_str()); diff --git a/examples/java/ScannerTinyB00.java b/examples/java/ScannerTinyB00.java index e3b00648..286375ca 100644 --- a/examples/java/ScannerTinyB00.java +++ b/examples/java/ScannerTinyB00.java @@ -116,6 +116,10 @@ public class ScannerTinyB00 { System.exit(-1); } adapter = adapters.get(dev_id); + if( !adapter.isEnabled() ) { + System.err.println("Adapter not enabled: device "+adapter.getName()+", address "+adapter.getAddress()+": "+adapter.toString()); + System.exit(-1); + } } do { diff --git a/examples/java/ScannerTinyB01.java b/examples/java/ScannerTinyB01.java index 8e294561..94f75611 100644 --- a/examples/java/ScannerTinyB01.java +++ b/examples/java/ScannerTinyB01.java @@ -139,6 +139,10 @@ public class ScannerTinyB01 { System.exit(-1); } adapter = adapters.get(dev_id); + if( !adapter.isEnabled() ) { + System.err.println("Adapter not enabled: device "+adapter.getName()+", address "+adapter.getAddress()+": "+adapter.toString()); + System.exit(-1); + } } final BluetoothDevice[] matchingDiscoveredDeviceBucket = { null }; diff --git a/examples/java/ScannerTinyB02.java b/examples/java/ScannerTinyB02.java index 9ccfceec..75245920 100644 --- a/examples/java/ScannerTinyB02.java +++ b/examples/java/ScannerTinyB02.java @@ -129,6 +129,10 @@ public class ScannerTinyB02 { System.exit(-1); } adapter = adapters.get(dev_id); + if( !adapter.isEnabled() ) { + System.err.println("Adapter not enabled: device "+adapter.getName()+", address "+adapter.getAddress()+": "+adapter.toString()); + System.exit(-1); + } } final BluetoothDevice[] matchingDiscoveredDeviceBucket = { null }; diff --git a/examples/java/ScannerTinyB10.java b/examples/java/ScannerTinyB10.java index af57e867..844f169f 100644 --- a/examples/java/ScannerTinyB10.java +++ b/examples/java/ScannerTinyB10.java @@ -70,7 +70,7 @@ public class ScannerTinyB10 { boolean SHOW_UPDATE_EVENTS = false; - int dev_id = 0; // default + int dev_id = -1; // use default int shutdownTest = 0; @@ -407,7 +407,15 @@ public class ScannerTinyB10 { println("No adapter dev_id "+dev_id+" available, adapter count "+adapters.size()); System.exit(-1); } - adapter = adapters.get(dev_id); + if( 0 > dev_id ) { + adapter = manager.getDefaultAdapter(); + } else { + adapter = adapters.get(dev_id); + } + if( !adapter.isEnabled() ) { + println("Adapter not enabled: device "+adapter.getName()+", address "+adapter.getAddress()+": "+adapter.toString()); + System.exit(-1); + } } timestamp_t0 = BluetoothUtils.getCurrentMilliseconds(); @@ -470,6 +478,12 @@ public class ScannerTinyB10 { System.setProperty("org.tinyb.debug", "true"); } else if( arg.equals("-verbose") ) { System.setProperty("org.tinyb.verbose", "true"); + } 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); + } } } // Drop BluetoothGattCharacteristic value cache and notification compatibility using direct_bt. @@ -512,7 +526,7 @@ public class ScannerTinyB10 { test.MULTI_MEASUREMENTS = -1; } } - println("Run with '[-dev_id <adapter-index>] (-mac <device_address>)* [-disconnect] [-count <number>] [-single] (-wl <device_address>)* (-char <uuid>)* [-show_update_events] [-bluetoothManager <BluetoothManager-Implementation-Class-Name>] [-verbose] [-debug] [-shutdown <int>]'"); + println("Run with '[-default_dev_id <adapter-index>] [-dev_id <adapter-index>] (-mac <device_address>)* [-disconnect] [-count <number>] [-single] (-wl <device_address>)* (-char <uuid>)* [-show_update_events] [-bluetoothManager <BluetoothManager-Implementation-Class-Name>] [-verbose] [-debug] [-shutdown <int>]'"); } println("BluetoothManager "+bluetoothManagerClazzName); diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java index 0fe7ba3b..717fd697 100644 --- a/java/direct_bt/tinyb/DBTAdapter.java +++ b/java/direct_bt/tinyb/DBTAdapter.java @@ -304,6 +304,9 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter @Override public native void setPairable(boolean value); + @Override + public native boolean isEnabled(); + /* internal */ @Override diff --git a/java/direct_bt/tinyb/DBTManager.java b/java/direct_bt/tinyb/DBTManager.java index 6874da74..5fdbfdb9 100644 --- a/java/direct_bt/tinyb/DBTManager.java +++ b/java/direct_bt/tinyb/DBTManager.java @@ -50,7 +50,7 @@ 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 int DefaultAdapterIndex = 0; + private static final int DefaultAdapterIndex; static { AccessController.doPrivileged(new PrivilegedAction<Object>() { @@ -65,7 +65,7 @@ public class DBTManager implements BluetoothManager return null; } } ) ; { - final String v = System.getProperty("org.tinyb.default_adapter", "0"); + final String v = System.getProperty("org.tinyb.default_adapter", "-1"); DefaultAdapterIndex = Integer.valueOf(v); } @@ -279,9 +279,26 @@ public class DBTManager implements BluetoothManager } catch (final BluetoothException be) { be.printStackTrace(); } - if( adapters.size() >= DefaultAdapterIndex+1 ) { + 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 + } + } } + 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/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx index d1ca6a2d..7a4ddaad 100644 --- a/java/jni/direct_bt/DBTAdapter.cxx +++ b/java/jni/direct_bt/DBTAdapter.cxx @@ -537,6 +537,17 @@ void Java_direct_1bt_tinyb_DBTAdapter_deleteImpl(JNIEnv *env, jobject obj, jlong } } +jboolean Java_direct_1bt_tinyb_DBTAdapter_isEnabled(JNIEnv *env, jobject obj) +{ + try { + DBTAdapter *adapter = getDBTObject<DBTAdapter>(env, obj); + return adapter->isEnabled(); + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return JNI_FALSE; +} + jboolean Java_direct_1bt_tinyb_DBTAdapter_startDiscoveryImpl(JNIEnv *env, jobject obj, jboolean keepAlive) { try { diff --git a/java/org/tinyb/BluetoothAdapter.java b/java/org/tinyb/BluetoothAdapter.java index a7be8d95..c7b19e81 100644 --- a/java/org/tinyb/BluetoothAdapter.java +++ b/java/org/tinyb/BluetoothAdapter.java @@ -214,6 +214,16 @@ 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}. + * @since 2.0.0 + */ + public boolean isEnabled(); + /** Returns the power state the adapter. * @return The power state of the adapter. */ diff --git a/java/tinyb/dbus/DBusAdapter.java b/java/tinyb/dbus/DBusAdapter.java index 5a3760c1..4b71ef8a 100644 --- a/java/tinyb/dbus/DBusAdapter.java +++ b/java/tinyb/dbus/DBusAdapter.java @@ -66,6 +66,11 @@ public class DBusAdapter extends DBusObject implements BluetoothAdapter } @Override + public boolean isEnabled() { + return true; // FIXME + } + + @Override public boolean isDeviceWhitelisted(final String address) { return false; // FIXME } diff --git a/src/direct_bt/DBTAdapter.cpp b/src/direct_bt/DBTAdapter.cpp index 3e51c153..937948fb 100644 --- a/src/direct_bt/DBTAdapter.cpp +++ b/src/direct_bt/DBTAdapter.cpp @@ -131,18 +131,27 @@ std::shared_ptr<DBTDevice> DBTAdapter::findConnectedDevice (EUI48 const & mac, c // ************************************************* // ************************************************* -bool DBTAdapter::openHCI() +std::shared_ptr<HCIHandler> DBTAdapter::getHCI() { - hci = std::shared_ptr<HCIHandler>( new HCIHandler(btMode, dev_id, HCIHandler::Defaults::HCI_COMMAND_REPLY_TIMEOUT) ); - if( !hci->isOpen() ) { - ERR_PRINT("Could not open HCIHandler: %s of %s", hci->toString().c_str(), toString().c_str()); - return false; + checkValidAdapter(); + const std::lock_guard<std::recursive_mutex> lock(mtx_hci); // RAII-style acquire and relinquish via destructor + if( nullptr == hci ) { + hci = std::shared_ptr<HCIHandler>( new HCIHandler(btMode, dev_id, HCIHandler::Defaults::HCI_COMMAND_REPLY_TIMEOUT) ); + if( !hci->isOpen() ) { + ERR_PRINT("Could not open HCIHandler: %s of %s", hci->toString().c_str(), toString().c_str()); + hci = nullptr; + } else { + hci->addMgmtEventCallback(MgmtEvent::Opcode::DEVICE_CONNECTED, bindMemberFunc(this, &DBTAdapter::mgmtEvDeviceConnectedHCI)); + hci->addMgmtEventCallback(MgmtEvent::Opcode::CONNECT_FAILED, bindMemberFunc(this, &DBTAdapter::mgmtEvConnectFailedHCI)); + hci->addMgmtEventCallback(MgmtEvent::Opcode::DEVICE_DISCONNECTED, bindMemberFunc(this, &DBTAdapter::mgmtEvDeviceDisconnectedHCI)); + } } - return true; + return hci; } bool DBTAdapter::closeHCI() { + const std::lock_guard<std::recursive_mutex> lock(mtx_hci); // RAII-style acquire and relinquish via destructor DBG_PRINT("DBTAdapter::closeHCI: ..."); if( nullptr == hci ) { DBG_PRINT("DBTAdapter::closeHCI: HCI null"); @@ -170,20 +179,11 @@ bool DBTAdapter::validateDevInfo() { adapterInfo = mgmt.getAdapterInfo(dev_id); - if( !openHCI() ) { - ERR_PRINT("DBTAdapter::validateDevInfo: Opening adapter's HCI failed: %s", toString().c_str()); - return false; - } - mgmt.addMgmtEventCallback(dev_id, MgmtEvent::Opcode::DISCOVERING, bindMemberFunc(this, &DBTAdapter::mgmtEvDeviceDiscoveringMgmt)); mgmt.addMgmtEventCallback(dev_id, MgmtEvent::Opcode::NEW_SETTINGS, bindMemberFunc(this, &DBTAdapter::mgmtEvNewSettingsMgmt)); mgmt.addMgmtEventCallback(dev_id, MgmtEvent::Opcode::LOCAL_NAME_CHANGED, bindMemberFunc(this, &DBTAdapter::mgmtEvLocalNameChangedMgmt)); mgmt.addMgmtEventCallback(dev_id, MgmtEvent::Opcode::DEVICE_FOUND, bindMemberFunc(this, &DBTAdapter::mgmtEvDeviceFoundMgmt)); - hci->addMgmtEventCallback(MgmtEvent::Opcode::DEVICE_CONNECTED, bindMemberFunc(this, &DBTAdapter::mgmtEvDeviceConnectedHCI)); - hci->addMgmtEventCallback(MgmtEvent::Opcode::CONNECT_FAILED, bindMemberFunc(this, &DBTAdapter::mgmtEvConnectFailedHCI)); - hci->addMgmtEventCallback(MgmtEvent::Opcode::DEVICE_DISCONNECTED, bindMemberFunc(this, &DBTAdapter::mgmtEvDeviceDisconnectedHCI)); - #ifdef VERBOSE_ON mgmt.addMgmtEventCallback(dev_id, MgmtEvent::Opcode::DEVICE_DISCONNECTED, bindMemberFunc(this, &DBTAdapter::mgmtEvDeviceDisconnectedMgmt)); #endif @@ -265,7 +265,7 @@ bool DBTAdapter::isDeviceWhitelisted(const EUI48 &address) { 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) { - checkValidAdapter(); + checkValidEnabledAdapter(); if( mgmt.isDeviceWhitelisted(dev_id, address) ) { ERR_PRINT("DBTAdapter::addDeviceToWhitelist: device already listed: dev_id %d, address %s", dev_id, address.toString().c_str()); return true; @@ -367,7 +367,7 @@ void DBTAdapter::checkDiscoveryState() { bool DBTAdapter::startDiscovery(const bool keepAlive, const HCILEOwnAddressType own_mac_type, const uint16_t le_scan_interval, const uint16_t le_scan_window) { - checkValidAdapter(); + checkValidEnabledAdapter(); const std::lock_guard<std::recursive_mutex> lock(mtx_discovery); // RAII-style acquire and relinquish via destructor if( ScanType::NONE != currentMetaScanType ) { removeDiscoveredDevices(); diff --git a/src/direct_bt/DBTDevice.cpp b/src/direct_bt/DBTDevice.cpp index e60fa2d4..1a07eca5 100644 --- a/src/direct_bt/DBTDevice.cpp +++ b/src/direct_bt/DBTDevice.cpp @@ -314,10 +314,15 @@ HCIStatusCode DBTDevice::connectLE(uint16_t le_scan_interval, uint16_t le_scan_w return HCIStatusCode::CONNECTION_ALREADY_EXISTS; } - HCIStatusCode status = adapter.getHCI()->le_create_conn(address, - hci_peer_mac_type, hci_own_mac_type, - le_scan_interval, le_scan_window, conn_interval_min, conn_interval_max, - conn_latency, supervision_timeout); + std::shared_ptr<HCIHandler> hci = adapter.getHCI(); + if( nullptr == hci ) { + ERR_PRINT("DBTDevice::connectLE: HCI not available: %s", toString().c_str()); + return HCIStatusCode::INTERNAL_FAILURE; + } + HCIStatusCode status = hci->le_create_conn(address, + hci_peer_mac_type, hci_own_mac_type, + le_scan_interval, le_scan_window, conn_interval_min, conn_interval_max, + conn_latency, supervision_timeout); allowDisconnect = true; #if 0 if( HCIStatusCode::CONNECTION_ALREADY_EXISTS == status ) { @@ -361,7 +366,12 @@ HCIStatusCode DBTDevice::connectBREDR(const uint16_t pkt_type, const uint16_t cl return HCIStatusCode::UNACCEPTABLE_CONNECTION_PARAM; } - HCIStatusCode status = adapter.getHCI()->create_conn(address, pkt_type, clock_offset, role_switch); + std::shared_ptr<HCIHandler> hci = adapter.getHCI(); + if( nullptr == hci ) { + ERR_PRINT("DBTDevice::connectBREDR: HCI not available: %s", toString().c_str()); + return HCIStatusCode::INTERNAL_FAILURE; + } + HCIStatusCode status = hci->create_conn(address, pkt_type, clock_offset, role_switch); allowDisconnect = true; if ( HCIStatusCode::SUCCESS != status ) { ERR_PRINT("DBTDevice::connectBREDR: Could not create connection: status 0x%2.2X (%s), errno %d %s on %s", @@ -440,7 +450,8 @@ HCIStatusCode DBTDevice::disconnect(const bool fromDisconnectCB, const bool ioEr } if( nullptr == hci ) { - DBG_PRINT("DBTDevice::disconnect: Skip disconnect: HCI is null: %s", toString().c_str()); + DBG_PRINT("DBTDevice::disconnect: Skip disconnect: HCI not available: %s", toString().c_str()); + res = HCIStatusCode::INTERNAL_FAILURE; goto exit; } |