From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> This adds support for storing PreferredBearer into device info file. --- doc/settings-storage.txt | 2 ++ src/device.c | 66 +++++++++++++++++++++++++++++----------- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/doc/settings-storage.txt b/doc/settings-storage.txt index 178e7d07bf11..4e9881eedf02 100644 --- a/doc/settings-storage.txt +++ b/doc/settings-storage.txt @@ -293,6 +293,8 @@ Long term key) related to a remote device. 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 de92e68d2780..9219eb674f87 100644 --- a/src/device.c +++ b/src/device.c @@ -368,10 +368,25 @@ static GSList *find_service_with_uuid(GSList *list, char *uuid) 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"; @@ -391,6 +406,12 @@ static void update_technologies(GKeyFile *file, struct btd_device *dev) 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, @@ -2080,6 +2101,7 @@ bool btd_device_add_set(struct btd_device *device, bool encrypted, 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; @@ -2100,6 +2122,11 @@ static void device_set_auto_connect(struct btd_device *device, gboolean enable) 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); @@ -3343,16 +3370,6 @@ static const GDBusMethodTable device_methods[] = { { } }; -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) @@ -3382,6 +3399,7 @@ dev_property_set_prefer_bearer(const GDBusPropertyTable *property, 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; @@ -3407,6 +3425,8 @@ dev_property_set_prefer_bearer(const GDBusPropertyTable *property, return; } + store_device_info(device); + g_dbus_emit_property_changed(dbus_conn, device->path, DEVICE_INTERFACE, "PreferredBearer"); @@ -3420,13 +3440,7 @@ dev_property_prefer_bearer_exists(const GDBusPropertyTable *property, { 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[] = { @@ -3996,6 +4010,24 @@ static void load_info(struct btd_device *device, const char *local, 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", -- 2.48.1