diff --git a/doc/settings-storage.txt b/doc/settings-storage.txt
index 178e7d0..4e9881e 100644
--- a/doc/settings-storage.txt
+++ b/doc/settings-storage.txt
strings remote in 128-bits UUID format,
separated by ";"
+ PreferredBearer String Preferred bearer for remote device
+
[DeviceID] group contains:
diff --git a/src/device.c b/src/device.c
index 0ab883d..57577e5 100644
--- a/src/device.c
+++ b/src/device.c
return NULL;
}
+static const char *device_prefer_bearer_str(struct btd_device *device)
+{
+ /* Check if both BR/EDR and LE bearer are supported */
+ if (!device->bredr || !device->le)
+ return NULL;
+
+ if (device->bredr_state.prefer)
+ return "bredr";
+ else if (device->le_state.prefer)
+ return "le";
+ else
+ return "last-seen";
+}
+
static void update_technologies(GKeyFile *file, struct btd_device *dev)
{
const char *list[2];
size_t len = 0;
+ const char *bearer;
if (dev->bredr)
list[len++] = "BR/EDR";
g_key_file_set_string_list(file, "General", "SupportedTechnologies",
list, len);
+
+ /* Store the PreferredBearer in case of dual-mode devices */
+ bearer = device_prefer_bearer_str(dev);
+ if (bearer)
+ g_key_file_set_string(file, "General", "PreferredBearer",
+ bearer);
}
static void store_csrk(struct csrk_info *csrk, GKeyFile *key_file,
static void device_set_auto_connect(struct btd_device *device, gboolean enable)
{
char addr[18];
+ const char *bearer;
if (!device || !device->le || device_address_is_private(device))
return;
return;
}
+ /* Inhibit auto connect if BR/EDR bearer is preferred */
+ bearer = device_prefer_bearer_str(device);
+ if (bearer && !strcasecmp(bearer, "bredr"))
+ return;
+
/* Enabling auto connect */
adapter_auto_connect_add(device->adapter, device);
{ }
};
-static const char *device_prefer_bearer_str(struct btd_device *device)
-{
- if (device->bredr_state.prefer)
- return "bredr";
- else if (device->le_state.prefer)
- return "le";
- else
- return "last-seen";
-}
-
static gboolean
dev_property_get_prefer_bearer(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data)
dbus_message_iter_get_basic(value, &str);
+ /* Check if current preferred bearer is the same */
if (!strcasecmp(device_prefer_bearer_str(device), str))
goto done;
return;
}
+ store_device_info(device);
+
g_dbus_emit_property_changed(dbus_conn, device->path,
DEVICE_INTERFACE, "PreferredBearer");
{
struct btd_device *device = data;
- /* Check if both BR/EDR and LE bearer are connected/bonded */
- if ((device->bredr_state.connected || device->bredr_state.bonded) &&
- (device->le_state.connected || device->le_state.bonded))
- return TRUE;
-
- /* Check if both BR/EDR and LE are connectable */
- return device->bredr_state.connectable && device->le_state.connectable;
+ return device_prefer_bearer_str(device) != NULL;
}
static const GDBusPropertyTable device_properties[] = {
g_strfreev(techno);
+ /* Load preferred bearer */
+ str = g_key_file_get_string(key_file, "General", "PreferredBearer",
+ NULL);
+ if (str) {
+ if (!strcasecmp(str, "last-seen")) {
+ device->bredr_state.prefer = false;
+ device->le_state.prefer = false;
+ } else if (!strcasecmp(str, "bredr")) {
+ device->bredr_state.prefer = true;
+ device->le_state.prefer = false;
+ } else if (!strcasecmp(str, "le")) {
+ device->le_state.prefer = true;
+ device->bredr_state.prefer = false;
+ }
+
+ g_free(str);
+ }
+
next:
/* Load trust */
device->trusted = g_key_file_get_boolean(key_file, "General",