diff options
-rw-r--r-- | api/direct_bt/BTTypes.hpp | 21 | ||||
-rw-r--r-- | api/direct_bt/DBTAdapter.hpp | 2 | ||||
-rw-r--r-- | api/direct_bt/DBTManager.hpp | 24 | ||||
-rw-r--r-- | api/direct_bt/DBTTypes.hpp | 6 | ||||
-rw-r--r-- | examples/direct_bt_scanner10/dbt_scanner10.cpp | 12 | ||||
-rw-r--r-- | examples/java/ScannerTinyB10.java | 5 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTManager.java | 4 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTManager.cxx | 5 | ||||
-rw-r--r-- | java/org/tinyb/BTMode.java | 78 | ||||
-rw-r--r-- | java/org/tinyb/BluetoothFactory.java | 28 | ||||
-rw-r--r-- | src/direct_bt/BTTypes.cpp | 14 | ||||
-rw-r--r-- | src/direct_bt/DBTAdapter.cpp | 13 | ||||
-rw-r--r-- | src/direct_bt/DBTManager.cpp | 62 | ||||
-rw-r--r-- | src/direct_bt/DBTTypes.cpp | 14 |
14 files changed, 250 insertions, 38 deletions
diff --git a/api/direct_bt/BTTypes.hpp b/api/direct_bt/BTTypes.hpp index c20feccb..43effd4e 100644 --- a/api/direct_bt/BTTypes.hpp +++ b/api/direct_bt/BTTypes.hpp @@ -38,10 +38,18 @@ namespace direct_bt { + /** + * Bluetooth adapter operating mode + */ enum class BTMode : uint8_t { - DUAL = 1, - BREDR = 2, - LE = 3 + /** Zero mode, neither DUAL, BREDR nor LE. Usually an error. */ + NONE = 0,/**< NONE */ + /** Dual Bluetooth mode, i.e. BREDR + LE. */ + DUAL = 1,/**< DUAL */ + /** BREDR only Bluetooth mode */ + BREDR = 2,/**< BREDR */ + /** LE only Bluetooth mode */ + LE = 3 /**< LE */ }; inline uint8_t number(const BTMode rhs) { return static_cast<uint8_t>(rhs); @@ -49,6 +57,13 @@ namespace direct_bt { std::string getBTModeString(const BTMode v); /** + * Maps the specified name to a constant of BTMode. + * @param name the string name to be mapped to a constant of this enum type. + * @return the corresponding constant of this enum type, using {@link BRMode#NONE} if not supported. + */ + BTMode getBTMode(const std::string & value); + + /** * Meta ScanType as derived from BTMode, * with defined value mask consisting of BDAddressType bits. * <p> diff --git a/api/direct_bt/DBTAdapter.hpp b/api/direct_bt/DBTAdapter.hpp index 36f3f62c..45034161 100644 --- a/api/direct_bt/DBTAdapter.hpp +++ b/api/direct_bt/DBTAdapter.hpp @@ -168,6 +168,7 @@ namespace direct_bt { const bool debug_event; DBTManager& mgmt; std::shared_ptr<AdapterInfo> adapterInfo; + BTMode btMode = BTMode::NONE; NameAndShortName localName; std::atomic<ScanType> currentMetaScanType; // = ScanType::NONE std::atomic<ScanType> currentNativeScanType; // = ScanType::NONE @@ -229,7 +230,6 @@ namespace direct_bt { void sendDeviceUpdated(std::string cause, std::shared_ptr<DBTDevice> device, uint64_t timestamp, EIRDataType updateMask); public: - const BTMode btMode; const int dev_id; /** diff --git a/api/direct_bt/DBTManager.hpp b/api/direct_bt/DBTManager.hpp index d7a7267b..6cb9e4b3 100644 --- a/api/direct_bt/DBTManager.hpp +++ b/api/direct_bt/DBTManager.hpp @@ -151,7 +151,7 @@ namespace direct_bt { std::vector<std::shared_ptr<WhitelistElem>> whitelist; const MgmtEnv & env; - const BTMode btMode; + const BTMode defaultBTMode; POctets rbuffer; HCIComm comm; @@ -181,10 +181,15 @@ namespace direct_bt { */ std::shared_ptr<MgmtEvent> sendWithReply(MgmtCommand &req); - DBTManager(const BTMode btMode); + /** + * Instantiate singleton. + * @param btMode default {@link BTMode}, adapters are tried to be initialized. + */ + DBTManager(const BTMode defaultBTMode); DBTManager(const DBTManager&) = delete; void operator=(const DBTManager&) = delete; + void setAdapterMode(const uint16_t dev_id, const uint8_t ssp, const uint8_t bredr, const uint8_t le); std::shared_ptr<AdapterInfo> initAdapter(const uint16_t dev_id, const BTMode btMode); void shutdownAdapter(const uint16_t dev_id); @@ -209,8 +214,10 @@ namespace direct_bt { * <p> * First call will open and initialize the bluetooth kernel. * </p> + * @param btMode default {@link BTMode}, adapters are tried to be initialized. + * @return singleton instance. */ - static DBTManager& get(const BTMode btMode) { + static DBTManager& get(const BTMode defaultBTMode) { const std::lock_guard<std::mutex> lock(mtx_singleton); // ensure thread safety /** * Thread safe starting with C++11 6.7: @@ -222,7 +229,7 @@ namespace direct_bt { * * Avoiding non-working double checked locking. */ - static DBTManager s(btMode); + static DBTManager s(defaultBTMode); return s; } ~DBTManager() { close(); } @@ -236,7 +243,8 @@ namespace direct_bt { return std::string(JAVA_DBT_PACKAGE "DBTManager"); } - BTMode getBTMode() { return btMode; } + /** Returns the default {@link BTMode}, adapters are tried to be initialized. */ + BTMode getDefaultBTMode() { return defaultBTMode; } /** Returns true if this mgmt instance is open and hence valid, otherwise false */ bool isOpen() const { @@ -244,7 +252,7 @@ namespace direct_bt { } std::string toString() const override { - return "MgmtHandler[BTMode "+getBTModeString(btMode)+", "+std::to_string(adapterInfos.size())+" adapter, "+javaObjectToString()+"]"; + return "MgmtHandler[BTMode "+getBTModeString(defaultBTMode)+", "+std::to_string(adapterInfos.size())+" adapter, "+javaObjectToString()+"]"; } /** retrieve information gathered at startup */ @@ -281,8 +289,8 @@ namespace direct_bt { bool setMode(const int dev_id, const MgmtOpcode opc, const uint8_t mode); - /** Start discovery on given adapter dev_id with a ScanType matching the used BTMode. Returns set ScanType. */ - ScanType startDiscovery(const int dev_id); + /** Start discovery on given adapter dev_id with a ScanType matching the given BTMode. Returns set ScanType. */ + ScanType startDiscovery(const int dev_id, const BTMode btMode); /** Start discovery on given adapter dev_id with given ScanType. Returns set ScanType. */ ScanType startDiscovery(const int dev_id, const ScanType type); /** Stop discovery on given adapter dev_id. */ diff --git a/api/direct_bt/DBTTypes.hpp b/api/direct_bt/DBTTypes.hpp index 8f5df905..a38e00f5 100644 --- a/api/direct_bt/DBTTypes.hpp +++ b/api/direct_bt/DBTTypes.hpp @@ -185,6 +185,9 @@ namespace direct_bt { std::string getAdapterSettingBitString(const AdapterSetting settingBit); std::string getAdapterSettingsString(const AdapterSetting settingBitMask); + /** Maps the given {@link AdapterSetting} to {@link BTMode} */ + BTMode getAdapterSettingsBTMode(const AdapterSetting settingMask); + class AdapterInfo { friend class DBTManager; // top manager @@ -238,6 +241,9 @@ namespace direct_bt { std::string getName() const { return name; } std::string getShortName() const { return short_name; } + /** Map {@link #getCurrentSetting()} to {@link BTMode} */ + BTMode getCurrentBTMode() const { return getAdapterSettingsBTMode(current_setting); } + std::string toString() const { return "Adapter[id "+std::to_string(dev_id)+", address "+address.toString()+", version "+std::to_string(version)+ ", manuf "+std::to_string(manufacturer)+ diff --git a/examples/direct_bt_scanner10/dbt_scanner10.cpp b/examples/direct_bt_scanner10/dbt_scanner10.cpp index 49e519f9..f5f405ae 100644 --- a/examples/direct_bt_scanner10/dbt_scanner10.cpp +++ b/examples/direct_bt_scanner10/dbt_scanner10.cpp @@ -416,6 +416,7 @@ void test(int dev_id) { int main(int argc, char *argv[]) { int dev_id = 0; // default + BTMode btMode = BTMode::LE; // default bool waitForEnter=false; for(int i=1; i<argc; i++) { @@ -425,6 +426,11 @@ int main(int argc, char *argv[]) SHOW_UPDATE_EVENTS = true; } else if( !strcmp("-dev_id", argv[i]) && argc > (i+1) ) { dev_id = atoi(argv[++i]); + } else if( !strcmp("-btmode", argv[i]) && argc > (i+1) ) { + BTMode v = getBTMode(argv[++i]); + if( BTMode::NONE != v ) { + btMode = v; + } } else if( !strcmp("-mac", argv[i]) && argc > (i+1) ) { std::string macstr = std::string(argv[++i]); waitForDevice = EUI48(macstr); @@ -446,15 +452,19 @@ int main(int argc, char *argv[]) } fprintf(stderr, "pid %d\n", getpid()); - fprintf(stderr, "Run with '[-dev_id <adapter-index>] [-mac <device_address>] [-disconnect] [-count <number>] [-single] (-wl <device_address>)* [-show_update_events]'\n"); + fprintf(stderr, "Run with '[-dev_id <adapter-index>] [-btmode <BT-MODE>] [-mac <device_address>] [-disconnect] [-count <number>] [-single] (-wl <device_address>)* [-show_update_events]'\n"); fprintf(stderr, "MULTI_MEASUREMENTS %d\n", MULTI_MEASUREMENTS); fprintf(stderr, "KEEP_CONNECTED %d\n", KEEP_CONNECTED); fprintf(stderr, "REMOVE_DEVICE %d\n", REMOVE_DEVICE); fprintf(stderr, "USE_WHITELIST %d\n", USE_WHITELIST); fprintf(stderr, "dev_id %d\n", dev_id); + fprintf(stderr, "btmode %s\n", getBTModeString(btMode).c_str()); fprintf(stderr, "waitForDevice: %s\n", waitForDevice.toString().c_str()); + // initialize manager with given default BTMode + DBTManager::get(btMode); + if( waitForEnter ) { fprintf(stderr, "Press ENTER to continue\n"); getchar(); diff --git a/examples/java/ScannerTinyB10.java b/examples/java/ScannerTinyB10.java index 50570456..57773d4a 100644 --- a/examples/java/ScannerTinyB10.java +++ b/examples/java/ScannerTinyB10.java @@ -37,6 +37,7 @@ import org.tinyb.BluetoothAddressType; import org.tinyb.BluetoothDevice; import org.tinyb.AdapterStatusListener; import org.tinyb.BLERandomAddressType; +import org.tinyb.BTMode; import org.tinyb.BluetoothException; import org.tinyb.BluetoothFactory; import org.tinyb.BluetoothGattCharacteristic; @@ -504,6 +505,10 @@ public class ScannerTinyB10 { 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()); + System.err.println("Setting 'org.tinyb.btmode' to "+btmode.toString()); } } // Drop BluetoothGattCharacteristic value cache and notification compatibility using direct_bt. diff --git a/java/direct_bt/tinyb/DBTManager.java b/java/direct_bt/tinyb/DBTManager.java index 5fdbfdb9..8874a2b3 100644 --- a/java/direct_bt/tinyb/DBTManager.java +++ b/java/direct_bt/tinyb/DBTManager.java @@ -269,11 +269,11 @@ public class DBTManager implements BluetoothManager private native List<BluetoothAdapter> getAdapterListImpl(); - private native void initImpl(final boolean unifyUUID128Bit) throws BluetoothException; + private native void initImpl(final boolean unifyUUID128Bit, final int btMode) throws BluetoothException; private native void deleteImpl(long nativeInstance); private DBTManager() { - initImpl(unifyUUID128Bit); + initImpl(unifyUUID128Bit, BluetoothFactory.DEFAULT_BTMODE.value); try { adapters.addAll(getAdapterListImpl()); } catch (final BluetoothException be) { diff --git a/java/jni/direct_bt/DBTManager.cxx b/java/jni/direct_bt/DBTManager.cxx index 71cbe591..40329abd 100644 --- a/java/jni/direct_bt/DBTManager.cxx +++ b/java/jni/direct_bt/DBTManager.cxx @@ -38,11 +38,12 @@ using namespace direct_bt; -void Java_direct_1bt_tinyb_DBTManager_initImpl(JNIEnv *env, jobject obj, jboolean unifyUUID128Bit) +void Java_direct_1bt_tinyb_DBTManager_initImpl(JNIEnv *env, jobject obj, jboolean unifyUUID128Bit, jint jbtMode) { directBTJNISettings.setUnifyUUID128Bit(unifyUUID128Bit); try { - DBTManager *manager = &DBTManager::get(BTMode::LE); // special: static singleton + BTMode btMode = static_cast<BTMode>(jbtMode); + DBTManager *manager = &DBTManager::get(btMode); // special: static singleton setInstance<DBTManager>(env, obj, manager); java_exception_check_and_throw(env, E_FILE_LINE); manager->setJavaObject( std::shared_ptr<JavaAnonObj>( new JavaGlobalObj(obj, nullptr) ) ); diff --git a/java/org/tinyb/BTMode.java b/java/org/tinyb/BTMode.java new file mode 100644 index 00000000..95d7cb83 --- /dev/null +++ b/java/org/tinyb/BTMode.java @@ -0,0 +1,78 @@ +/** + * Author: Sven Gothel <[email protected]> + * Copyright (c) 2020 Gothel Software e.K. + * Copyright (c) 2020 ZAFENA AB + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package org.tinyb; + +/** + * Bluetooth adapter operating mode + * <p> + * See {@link #get(int)} for its native integer mapping. + * </p> + * @since 2.0.0 + */ +public enum BTMode { + /** Zero mode, neither DUAL, BREDR nor LE. Usually an error. */ + NONE (0), + /** Dual Bluetooth mode, i.e. BREDR + LE. */ + DUAL (1), + /** BREDR only Bluetooth mode */ + BREDR (2), + /** LE only Bluetooth mode */ + LE (3); + + public final int value; + + /** + * Maps the specified name to a constant of BTMode. + * <p> + * Implementation simply returns {@link #valueOf(String)}. + * This maps the constant names itself to their respective constant. + * </p> + * @param name the string name to be mapped to a constant of this enum type. + * @return the corresponding constant of this enum type. + * @throws IllegalArgumentException if the specified name can't be mapped to a constant of this enum type + * as described above. + */ + public static BTMode get(final String name) throws IllegalArgumentException { + return valueOf(name); + } + + /** + * Maps the specified integer value to a constant of {@link BTMode}. + * @param value the integer value to be mapped to a constant of this enum type. + * @return the corresponding constant of this enum type, using {@link #NONE} if not supported. + */ + public static BTMode get(final int value) { + switch(value) { + case 0x01: return DUAL; + case 0x02: return BREDR; + case 0x03: return LE; + default: return NONE; + } + } + + BTMode(final int v) { + value = v; + } +} diff --git a/java/org/tinyb/BluetoothFactory.java b/java/org/tinyb/BluetoothFactory.java index 3cea0f1c..c7ae09a4 100644 --- a/java/org/tinyb/BluetoothFactory.java +++ b/java/org/tinyb/BluetoothFactory.java @@ -143,6 +143,7 @@ public class BluetoothFactory { * </p> */ public static final boolean VERBOSE; + /** * Debug logging enabled or disabled. * <p> @@ -150,6 +151,17 @@ public class BluetoothFactory { * </p> */ public static final boolean DEBUG; + + /** + * Default {@link BTMode} when initializing new adapter + * <p> + * System property {@code org.tinyb.btmode}, string, default {@code DUAL}. + * </p> + * @since 2.0.0 + * @implNote not implemented in tinyb.dbus. + */ + public static final BTMode DEFAULT_BTMODE; + /** * Have direct_bt provide compatibility to TinyB's {@link BluetoothGattCharacteristic} * API: {@link BluetoothGattCharacteristic#getValue() value cache} and @@ -170,6 +182,16 @@ public class BluetoothFactory { DEBUG = Boolean.valueOf(v); } { + final String v = System.getProperty("org.tinyb.btmode", "DUAL"); + BTMode btMode = BTMode.DUAL; + try { + btMode = BTMode.get(v); + } catch (final IllegalArgumentException ex) { + System.err.println("Invalid BTMode '"+v+"': "+ex.getMessage()); + } + DEFAULT_BTMODE = btMode; + } + { final String v = System.getProperty("direct_bt.tinyb.characteristic.compat", "true"); DIRECTBT_CHARACTERISTIC_VALUE_CACHE_NOTIFICATION_COMPAT = Boolean.valueOf(v); } @@ -442,15 +464,13 @@ public class BluetoothFactory { return getBluetoothManager(DirectBTImplementationID); } - private static final boolean debug = false; - private static final Manifest getManifest(final ClassLoader cl, final String[] extensions) { final Manifest[] extManifests = new Manifest[extensions.length]; try { final Enumeration<URL> resources = cl.getResources("META-INF/MANIFEST.MF"); while (resources.hasMoreElements()) { final URL resURL = resources.nextElement(); - if( debug ) { + if( DEBUG ) { System.err.println("resource: "+resURL); } final InputStream is = resURL.openStream(); @@ -465,7 +485,7 @@ public class BluetoothFactory { final Attributes attributes = manifest.getMainAttributes(); if(attributes != null) { final String attributesExtName = attributes.getValue( Attributes.Name.EXTENSION_NAME ); - if( debug ) { + if( DEBUG ) { System.err.println("resource: "+resURL+", attributes extName "+attributesExtName+", count "+attributes.size()); final Set<Object> keys = attributes.keySet(); for(final Iterator<Object> iter=keys.iterator(); iter.hasNext(); ) { diff --git a/src/direct_bt/BTTypes.cpp b/src/direct_bt/BTTypes.cpp index 9a1ccf92..e8ca71d2 100644 --- a/src/direct_bt/BTTypes.cpp +++ b/src/direct_bt/BTTypes.cpp @@ -196,6 +196,7 @@ static inline const int8_t * const_uint8_to_const_int8_ptr(const uint8_t* p) { std::string direct_bt::getBTModeString(const BTMode v) { switch(v) { + case BTMode::NONE: return "NONE"; case BTMode::DUAL: return "DUAL"; case BTMode::BREDR: return "BREDR"; case BTMode::LE: return "LE"; @@ -203,6 +204,19 @@ std::string direct_bt::getBTModeString(const BTMode v) { return "Unknown BTMode"; } +BTMode direct_bt::getBTMode(const std::string & value) { + if( "DUAL" == value ) { + return BTMode::DUAL; + } + if( "BREDR" == value ) { + return BTMode::BREDR; + } + if( "LE" == value ) { + return BTMode::LE; + } + return BTMode::NONE; +} + ScanType direct_bt::getScanType(BTMode btMode) { switch ( btMode ) { case BTMode::DUAL: diff --git a/src/direct_bt/DBTAdapter.cpp b/src/direct_bt/DBTAdapter.cpp index a52de5fe..ab4618b1 100644 --- a/src/direct_bt/DBTAdapter.cpp +++ b/src/direct_bt/DBTAdapter.cpp @@ -181,6 +181,12 @@ bool DBTAdapter::validateDevInfo() { adapterInfo = mgmt.getAdapterInfo(dev_id); + btMode = adapterInfo->getCurrentBTMode(); + if( BTMode::NONE == btMode ) { + ERR_PRINT("DBTAdapter::validateDevInfo: Adapter[%d] BTMode invalid, BREDR nor LE set: %s", dev_id, adapterInfo->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)); @@ -193,21 +199,21 @@ bool DBTAdapter::validateDevInfo() { DBTAdapter::DBTAdapter() : debug_event(DBTEnv::getBooleanProperty("direct_bt.debug.adapter.event", false)), - mgmt(DBTManager::get(BTMode::LE)), btMode(mgmt.getBTMode()), dev_id(nullptr != mgmt.getDefaultAdapterInfo() ? 0 : -1) + mgmt(DBTManager::get(BTMode::NONE /* already initialized */)), dev_id(nullptr != mgmt.getDefaultAdapterInfo() ? 0 : -1) { valid = validateDevInfo(); } DBTAdapter::DBTAdapter(EUI48 &mac) : debug_event(DBTEnv::getBooleanProperty("direct_bt.debug.adapter.event", false)), - mgmt(DBTManager::get(BTMode::LE)), btMode(mgmt.getBTMode()), dev_id(mgmt.findAdapterInfoIdx(mac)) + mgmt(DBTManager::get(BTMode::NONE /* already initialized */)), dev_id(mgmt.findAdapterInfoIdx(mac)) { valid = validateDevInfo(); } DBTAdapter::DBTAdapter(const int dev_id) : debug_event(DBTEnv::getBooleanProperty("direct_bt.debug.adapter.event", false)), - mgmt(DBTManager::get(BTMode::LE)), btMode(mgmt.getBTMode()), dev_id(dev_id) + mgmt(DBTManager::get(BTMode::NONE /* already initialized */)), dev_id(dev_id) { valid = validateDevInfo(); } @@ -593,6 +599,7 @@ std::shared_ptr<DBTDevice> DBTAdapter::findSharedDevice (EUI48 const & mac, cons std::string DBTAdapter::toString() const { std::string out("Adapter[BTMode "+getBTModeString(btMode)+", "+getAddressString()+", '"+getName()+"', id "+std::to_string(dev_id)+ + ", curSettings"+getAdapterSettingsString(adapterInfo->getCurrentSetting())+ ", scanType[native "+getScanTypeString(currentNativeScanType)+", meta "+getScanTypeString(currentMetaScanType)+"]" ", "+javaObjectToString()+"]"); std::vector<std::shared_ptr<DBTDevice>> devices = getDiscoveredDevices(); diff --git a/src/direct_bt/DBTManager.cpp b/src/direct_bt/DBTManager.cpp index a77b93c7..c678ea34 100644 --- a/src/direct_bt/DBTManager.cpp +++ b/src/direct_bt/DBTManager.cpp @@ -197,8 +197,21 @@ std::shared_ptr<MgmtEvent> DBTManager::sendWithReply(MgmtCommand &req) { return nullptr; } +void DBTManager::setAdapterMode(const uint16_t dev_id, const uint8_t ssp, const uint8_t bredr, const uint8_t le) { + bool res; + res = setMode(dev_id, MgmtOpcode::SET_SSP, ssp); + DBG_PRINT("setAdapterMode[%d]: SET_SSP(%d): result %d", dev_id, ssp, res); + + res = setMode(dev_id, MgmtOpcode::SET_BREDR, bredr); + DBG_PRINT("setAdapterMode[%d]: SET_BREDR(%d): result %d", dev_id, bredr, res); + + res = setMode(dev_id, MgmtOpcode::SET_LE, le); + DBG_PRINT("setAdapterMode[%d]: SET_LE(%d): result %d", dev_id, le, res); +} + std::shared_ptr<AdapterInfo> DBTManager::initAdapter(const uint16_t dev_id, const BTMode btMode) { std::shared_ptr<AdapterInfo> adapterInfo = nullptr; + bool powered; MgmtCommand req0(MgmtOpcode::READ_INFO, dev_id); { std::shared_ptr<MgmtEvent> res = sendWithReply(req0); @@ -215,22 +228,19 @@ std::shared_ptr<AdapterInfo> DBTManager::initAdapter(const uint16_t dev_id, cons throw InternalError("AdapterInfo dev_id="+std::to_string(adapterInfo->dev_id)+" != dev_id="+std::to_string(dev_id)+"]: "+adapterInfo->toString(), E_FILE_LINE); } } + DBG_PRINT("initAdapter[%d]: Start: %s", dev_id, adapterInfo->toString().c_str()); switch ( btMode ) { case BTMode::DUAL: - setMode(dev_id, MgmtOpcode::SET_SSP, 1); - setMode(dev_id, MgmtOpcode::SET_BREDR, 1); - setMode(dev_id, MgmtOpcode::SET_LE, 1); + setAdapterMode(dev_id, 1 /* ssp */, 1 /* bredr */, 1 /* le */); break; case BTMode::BREDR: - setMode(dev_id, MgmtOpcode::SET_SSP, 1); - setMode(dev_id, MgmtOpcode::SET_BREDR, 1); - setMode(dev_id, MgmtOpcode::SET_LE, 0); + setAdapterMode(dev_id, 1 /* ssp */, 1 /* bredr */, 0 /* le */); break; + case BTMode::NONE: + // fall through intended, map NONE -> LE case BTMode::LE: - setMode(dev_id, MgmtOpcode::SET_SSP, 0); - setMode(dev_id, MgmtOpcode::SET_BREDR, 0); - setMode(dev_id, MgmtOpcode::SET_LE, 1); + setAdapterMode(dev_id, 0 /* ssp */, 0 /* bredr */, 1 /* le */); break; } @@ -239,7 +249,30 @@ std::shared_ptr<AdapterInfo> DBTManager::initAdapter(const uint16_t dev_id, cons removeDeviceFromWhitelist(dev_id, EUI48_ANY_DEVICE, BDAddressType::BDADDR_BREDR); // flush whitelist! - setMode(dev_id, MgmtOpcode::SET_POWERED, 1); + powered = setMode(dev_id, MgmtOpcode::SET_POWERED, 1); + DBG_PRINT("setAdapterMode[%d]: SET_POWERED(1): result %d", dev_id, powered); + + /** + * Update AdapterSettings post settings + */ + { + adapterInfo = nullptr; // flush + + std::shared_ptr<MgmtEvent> res = sendWithReply(req0); + if( nullptr == res ) { + goto fail; + } + if( MgmtEvent::Opcode::CMD_COMPLETE != res->getOpcode() || res->getTotalSize() < MgmtEvtAdapterInfo::getRequiredSize()) { + ERR_PRINT("Insufficient data for adapter info: req %d, res %s", MgmtEvtAdapterInfo::getRequiredSize(), res->toString().c_str()); + goto fail; + } + const MgmtEvtAdapterInfo * res1 = static_cast<MgmtEvtAdapterInfo*>(res.get()); + adapterInfo = res1->toAdapterInfo(); + if( dev_id != adapterInfo->dev_id ) { + throw InternalError("AdapterInfo dev_id="+std::to_string(adapterInfo->dev_id)+" != dev_id="+std::to_string(dev_id)+"]: "+adapterInfo->toString(), E_FILE_LINE); + } + } + DBG_PRINT("initAdapter[%d]: End: %s", dev_id, adapterInfo->toString().c_str()); fail: return adapterInfo; @@ -252,9 +285,10 @@ void DBTManager::shutdownAdapter(const uint16_t dev_id) { setMode(dev_id, MgmtOpcode::SET_POWERED, 0); } -DBTManager::DBTManager(const BTMode btMode) +DBTManager::DBTManager(const BTMode _defaultBTMode) : env(MgmtEnv::get()), - btMode(btMode), rbuffer(ClientMaxMTU), comm(HCI_DEV_NONE, HCI_CHANNEL_CONTROL), + defaultBTMode(BTMode::NONE != _defaultBTMode ? _defaultBTMode : BTMode::LE), + rbuffer(ClientMaxMTU), comm(HCI_DEV_NONE, HCI_CHANNEL_CONTROL), mgmtEventRing(env.MGMT_EVT_RING_CAPACITY), mgmtReaderRunning(false), mgmtReaderShallStop(false) { INFO_PRINT("DBTManager.ctor: pid %d", DBTManager::pidSelf); @@ -362,7 +396,7 @@ next1: if( adapterInfos[dev_id] != nullptr ) { throw InternalError("adapters[dev_id="+std::to_string(dev_id)+"] != nullptr: "+adapterInfos[dev_id]->toString(), E_FILE_LINE); } - std::shared_ptr<AdapterInfo> adapterInfo = initAdapter(dev_id, btMode); + std::shared_ptr<AdapterInfo> adapterInfo = initAdapter(dev_id, defaultBTMode); adapterInfos[dev_id] = adapterInfo; if( nullptr != adapterInfo ) { DBG_PRINT("DBTManager::adapters %d/%d: dev_id %d: %s", i, num_adapter, dev_id, adapterInfo->toString().c_str()); @@ -484,7 +518,7 @@ bool DBTManager::setMode(const int dev_id, const MgmtOpcode opc, const uint8_t m return false; } -ScanType DBTManager::startDiscovery(const int dev_id) { +ScanType DBTManager::startDiscovery(const int dev_id, const BTMode btMode) { return startDiscovery(dev_id, getScanType(btMode)); } diff --git a/src/direct_bt/DBTTypes.cpp b/src/direct_bt/DBTTypes.cpp index 6b5db0e4..36b8efbf 100644 --- a/src/direct_bt/DBTTypes.cpp +++ b/src/direct_bt/DBTTypes.cpp @@ -95,3 +95,17 @@ std::string direct_bt::getAdapterSettingsString(const AdapterSetting settingMask out.append("]"); return out; } + +BTMode direct_bt::getAdapterSettingsBTMode(const AdapterSetting settingMask) { + const bool isBREDR = isAdapterSettingSet(settingMask, AdapterSetting::BREDR); + const bool isLE = isAdapterSettingSet(settingMask, AdapterSetting::LE); + if( isBREDR && isLE ) { + return BTMode::DUAL; + } else if( isBREDR ) { + return BTMode::BREDR; + } else if( isLE ) { + return BTMode::LE; + } else { + return BTMode::NONE; + } +} |