summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-08-29 02:43:52 +0200
committerSven Gothel <[email protected]>2020-09-03 05:13:56 +0200
commitc1537236e116d7884eb3ff41e19bd95d92da9b13 (patch)
tree0771c58f085428df8dea59478d1aebba67b9268b
parentf2ae18d3c54b6500306ea7a6f690f469979f39b0 (diff)
Complete mapping of BTMode (C++, Java) and have Adapter recognize actual BTMode from AdapterInfo's AdapterSettings
Java property is 'org.tinyb.btmode' (not yet mapped to C++)
-rw-r--r--api/direct_bt/BTTypes.hpp21
-rw-r--r--api/direct_bt/DBTAdapter.hpp2
-rw-r--r--api/direct_bt/DBTManager.hpp24
-rw-r--r--api/direct_bt/DBTTypes.hpp6
-rw-r--r--examples/direct_bt_scanner10/dbt_scanner10.cpp12
-rw-r--r--examples/java/ScannerTinyB10.java5
-rw-r--r--java/direct_bt/tinyb/DBTManager.java4
-rw-r--r--java/jni/direct_bt/DBTManager.cxx5
-rw-r--r--java/org/tinyb/BTMode.java78
-rw-r--r--java/org/tinyb/BluetoothFactory.java28
-rw-r--r--src/direct_bt/BTTypes.cpp14
-rw-r--r--src/direct_bt/DBTAdapter.cpp13
-rw-r--r--src/direct_bt/DBTManager.cpp62
-rw-r--r--src/direct_bt/DBTTypes.cpp14
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;
+ }
+}