diff --git a/src/adapter.c b/src/adapter.c
index 92ee1a0..4e28c61 100644
--- a/src/adapter.c
+++ b/src/adapter.c
{
struct btd_adapter *adapter = user_data;
const struct mgmt_rp_read_info *rp = param;
+ uint32_t missing_settings;
int err;
DBG("index %u status 0x%02x", adapter->dev_id, status);
clear_uuids(adapter);
clear_devices(adapter);
+ missing_settings = adapter->current_settings ^
+ adapter->supported_settings;
+
+ switch (main_opts.mode) {
+ case BT_MODE_DUAL:
+ if (missing_settings & MGMT_SETTING_SSP)
+ set_mode(adapter, MGMT_OP_SET_SSP, 0x01);
+ if (missing_settings & MGMT_SETTING_LE)
+ set_mode(adapter, MGMT_OP_SET_LE, 0x01);
+ if (missing_settings & MGMT_SETTING_BREDR)
+ set_mode(adapter, MGMT_OP_SET_BREDR, 0x01);
+ break;
+ case BT_MODE_BREDR:
+ if (missing_settings & MGMT_SETTING_SSP)
+ set_mode(adapter, MGMT_OP_SET_SSP, 0x01);
+ if (missing_settings & MGMT_SETTING_BREDR)
+ set_mode(adapter, MGMT_OP_SET_BREDR, 0x01);
+ if (adapter->current_settings & MGMT_SETTING_LE)
+ set_mode(adapter, MGMT_OP_SET_LE, 0x00);
+ break;
+ case BT_MODE_LE:
+ if (missing_settings & MGMT_SETTING_LE)
+ set_mode(adapter, MGMT_OP_SET_LE, 0x01);
+ if (adapter->current_settings & MGMT_SETTING_BREDR)
+ set_mode(adapter, MGMT_OP_SET_BREDR, 0x00);
+ break;
+ }
+
err = adapter_register(adapter);
if (err < 0) {
error("Unable to register new adapter");
set_name(adapter, btd_adapter_get_name(adapter));
- if ((adapter->supported_settings & MGMT_SETTING_SSP) &&
- !(adapter->current_settings & MGMT_SETTING_SSP))
- set_mode(adapter, MGMT_OP_SET_SSP, 0x01);
-
- if ((adapter->supported_settings & MGMT_SETTING_LE) &&
- !(adapter->current_settings & MGMT_SETTING_LE))
- set_mode(adapter, MGMT_OP_SET_LE, 0x01);
-
if (!(adapter->current_settings & MGMT_SETTING_BONDABLE))
set_mode(adapter, MGMT_OP_SET_BONDABLE, 0x01);
diff --git a/src/hcid.h b/src/hcid.h
index 6040c71..0c91292 100644
--- a/src/hcid.h
+++ b/src/hcid.h
*
*/
+typedef enum {
+ BT_MODE_DUAL,
+ BT_MODE_BREDR,
+ BT_MODE_LE,
+} bt_mode_t;
+
struct main_opts {
char *name;
uint32_t class;
uint16_t did_vendor;
uint16_t did_product;
uint16_t did_version;
+
+ bt_mode_t mode;
};
extern struct main_opts main_opts;
diff --git a/src/main.c b/src/main.c
index e6bac6e..191dc11 100644
--- a/src/main.c
+++ b/src/main.c
g_strfreev(keys);
}
+static int get_mode(const char *str)
+{
+ if (strcmp(str, "dual") == 0)
+ return BT_MODE_DUAL;
+ else if (strcmp(str, "bredr") == 0)
+ return BT_MODE_BREDR;
+ else if (strcmp(str, "le") == 0)
+ return BT_MODE_LE;
+
+ error("Unknown controller mode \"%s\"", str);
+
+ return BT_MODE_DUAL;
+}
+
static void parse_config(GKeyFile *config)
{
GError *err = NULL;
g_clear_error(&err);
else
main_opts.debug_keys = boolean;
+
+ str = g_key_file_get_string(config, "General", "ControllerMode", &err);
+ if (err) {
+ g_clear_error(&err);
+ } else {
+ DBG("ControllerMode=%s", str);
+ main_opts.mode = get_mode(str);
+ g_free(str);
+ }
}
static void init_defaults(void)
diff --git a/src/main.conf b/src/main.conf
index 3ebadde..ea0a2bd 100644
--- a/src/main.conf
+++ b/src/main.conf
# that they were created for.
#DebugKeys = false
+# Restricts all controllers to the specified transport. Default vallue
+# is "dual", i.e. both BR/EDR and LE enabled (when supported by the HW).
+# Possible values: "dual", "bredr", "le"
+#ControllerMode = dual
+
#[Policy]
#
# The ReconnectUUIDs defines the set of remote services that should try