On Friday 03 May 2019 13:18:10 Luiz Augusto von Dentz wrote: > Hi Pali, > > On Fri, May 3, 2019 at 1:07 PM Pali Rohár <pali.rohar@xxxxxxxxx> wrote: > > > > On Wednesday 24 April 2019 18:57:21 Pali Rohár wrote: > > > On Wednesday 24 April 2019 12:42:22 Luiz Augusto von Dentz wrote: > > > > Hi Pali, > > > > > > > > On Wed, Apr 24, 2019 at 11:39 AM Luiz Augusto von Dentz > > > > <luiz.dentz@xxxxxxxxx> wrote: > > > > > > > > > > From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> > > > > > > > > > > This stores the last used endpoint whenever it is considered open and > > > > > then prefer to use it when attempting to reconnect. > > > > > --- > > > > > profiles/audio/a2dp.c | 104 ++++++++++++++++++++++++++++++++++++------ > > > > > 1 file changed, 91 insertions(+), 13 deletions(-) > > > > > > > > > > diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c > > > > > index 8f141739c..78b02dc84 100644 > > > > > --- a/profiles/audio/a2dp.c > > > > > +++ b/profiles/audio/a2dp.c > > > > > @@ -147,6 +147,7 @@ struct a2dp_channel { > > > > > unsigned int auth_id; > > > > > struct avdtp *session; > > > > > struct queue *seps; > > > > > + struct a2dp_remote_sep *last_used; > > > > > }; > > > > > > > > > > static GSList *servers = NULL; > > > > > @@ -860,6 +861,60 @@ static gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep, > > > > > return TRUE; > > > > > } > > > > > > > > > > +static bool match_remote_sep(const void *data, const void *user_data) > > > > > +{ > > > > > + const struct a2dp_remote_sep *sep = data; > > > > > + const struct avdtp_remote_sep *rsep = user_data; > > > > > + > > > > > + return sep->sep == rsep; > > > > > +} > > > > > + > > > > > +static void store_last_used(struct a2dp_channel *chan, > > > > > + struct avdtp_remote_sep *rsep) > > > > > +{ > > > > > + GKeyFile *key_file; > > > > > + char filename[PATH_MAX]; > > > > > + char dst_addr[18]; > > > > > + char value[4]; > > > > > + char *data; > > > > > + size_t len = 0; > > > > > + > > > > > + ba2str(device_get_address(chan->device), dst_addr); > > > > > + > > > > > + snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", > > > > > + btd_adapter_get_storage_dir(device_get_adapter(chan->device)), > > > > > + dst_addr); > > > > > + key_file = g_key_file_new(); > > > > > + g_key_file_load_from_file(key_file, filename, 0, NULL); > > > > > + > > > > > + sprintf(value, "%02hhx", avdtp_get_seid(rsep)); > > > > > + > > > > > + g_key_file_set_string(key_file, "Endpoints", "LastUsed", value); > > > > > + > > > > > + data = g_key_file_to_data(key_file, &len, NULL); > > > > > + g_file_set_contents(filename, data, len, NULL); > > > > > + > > > > > + g_free(data); > > > > > + g_key_file_free(key_file); > > > > > +} > > > > > + > > > > > +static void update_last_used(struct a2dp_channel *chan, > > > > > + struct avdtp_stream *stream) > > > > > +{ > > > > > + struct avdtp_remote_sep *rsep; > > > > > + struct a2dp_remote_sep *sep; > > > > > + > > > > > + rsep = avdtp_stream_get_remote_sep(stream); > > > > > + > > > > > + /* Update last used */ > > > > > + sep = queue_find(chan->seps, match_remote_sep, rsep); > > > > > + if (chan->last_used == sep) > > > > > + return; > > > > > + > > > > > + chan->last_used = sep; > > > > > + store_last_used(chan, rsep); > > > > > +} > > > > > + > > > > > static void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep, > > > > > struct avdtp_stream *stream, struct avdtp_error *err, > > > > > void *user_data) > > > > > @@ -884,7 +939,8 @@ static void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep, > > > > > setup->err = err; > > > > > if (setup->start) > > > > > finalize_resume(setup); > > > > > - } > > > > > + } else if (setup->chan) > > > > > + update_last_used(setup->chan, stream); > > > > > > > > > > finalize_config(setup); > > > > > > > > > > @@ -1077,14 +1133,6 @@ static gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep, > > > > > return TRUE; > > > > > } > > > > > > > > > > -static bool match_remote_sep(const void *data, const void *user_data) > > > > > -{ > > > > > - const struct a2dp_remote_sep *sep = data; > > > > > - const struct avdtp_remote_sep *rsep = user_data; > > > > > - > > > > > - return sep->sep == rsep; > > > > > -} > > > > > - > > > > > static struct a2dp_remote_sep *find_remote_sep(struct a2dp_channel *chan, > > > > > struct a2dp_sep *sep) > > > > > { > > > > > @@ -1791,19 +1839,28 @@ done: > > > > > queue_push_tail(chan->seps, sep); > > > > > } > > > > > > > > > > +static bool match_seid(const void *data, const void *user_data) > > > > > +{ > > > > > + const struct a2dp_remote_sep *sep = data; > > > > > + const uint8_t *seid = user_data; > > > > > + > > > > > + return avdtp_get_seid(sep->sep) == *seid; > > > > > +} > > > > > + > > > > > static void load_remote_sep(struct a2dp_channel *chan, GKeyFile *key_file, > > > > > char **seids) > > > > > { > > > > > struct avdtp_remote_sep *sep; > > > > > + uint8_t seid; > > > > > + char *value; > > > > > > > > > > if (!seids) > > > > > return; > > > > > > > > > > for (; *seids; seids++) { > > > > > - uint8_t seid; > > > > > uint8_t type; > > > > > uint8_t codec; > > > > > - char *value, caps[256]; > > > > > + char caps[256]; > > > > > uint8_t data[128]; > > > > > int i, size; > > > > > GSList *l = NULL; > > > > > @@ -1847,6 +1904,15 @@ static void load_remote_sep(struct a2dp_channel *chan, GKeyFile *key_file, > > > > > > > > > > register_remote_sep(sep, chan); > > > > > } > > > > > + > > > > > + value = g_key_file_get_string(key_file, "Endpoints", "LastUsed", NULL); > > > > > + if (!value) > > > > > + return; > > > > > + > > > > > + if (sscanf(value, "%02hhx", &seid) != 1) > > > > > + return; > > > > > + > > > > > + chan->last_used = queue_find(chan->seps, match_seid, &seid); > > > > > } > > > > > > > > > > static void load_remote_seps(struct a2dp_channel *chan) > > > > > @@ -2355,8 +2421,12 @@ done: > > > > > static struct a2dp_sep *a2dp_find_sep(struct avdtp *session, GSList *list, > > > > > const char *sender) > > > > > { > > > > > + struct a2dp_sep *first = NULL; > > > > > + struct a2dp_channel *chan = find_channel(session); > > > > > + > > > > > for (; list; list = list->next) { > > > > > struct a2dp_sep *sep = list->data; > > > > > + struct avdtp_remote_sep *rsep; > > > > > > > > > > /* Use sender's endpoint if available */ > > > > > if (sender) { > > > > > @@ -2370,14 +2440,22 @@ static struct a2dp_sep *a2dp_find_sep(struct avdtp *session, GSList *list, > > > > > continue; > > > > > } > > > > > > > > > > - if (avdtp_find_remote_sep(session, sep->lsep) == NULL) > > > > > + rsep = avdtp_find_remote_sep(session, sep->lsep); > > > > > + if (!rsep) > > > > > continue; > > > > > > > > > > + /* Locate last used if set */ > > > > > + if (chan->last_used) { > > > > > + if (chan->last_used->sep == rsep) > > > > > + return sep; > > > > > + first = sep; > > > > > + } > > > > > + > > > > > return sep; > > > > > > > > > > } > > > > > > > > > > - return NULL; > > > > > + return first; > > > > > } > > > > > > > > > > static struct a2dp_sep *a2dp_select_sep(struct avdtp *session, uint8_t type, > > > > > -- > > > > > 2.20.1 > > > > > > > > Can you give this a try, it should make the daemon remember what was > > > > the last endpoint used (locally the remote selection we cannot really > > > > control). > > > > > > Great, I will try it. > > > > Now I run 'sudo grep LastUsed -r /var/lib/bluetooth/' and see that this > > properly is stored only for one device. So seems that bluetoothd does > > not always stores LastUsed information. > > > > E.g. when I called and successfully connected device via command > > > > $ qdbus --system org.bluez /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX org.bluez.Device1.ConnectProfile 0000110a-0000-1000-8000-00805f9b34fb > > > > and later disconnected, I have not found anything via above grep. > > Is this with the latest set? git master + wget -q 'https://lore.kernel.org/linux-bluetooth/20190503084547.15743-1-luiz.dentz@xxxxxxxxx/t.mbox.gz' -O - | gunzip | git am > Were there any failures in the configuration? No, at least do not see it in console. > (note that you need su/root to list /var/lib/bluetooth/) I know, that is why sudo grep > /var/lib/bluetooth/B8:8A:60:D8:17:D7/cache/08:DF:1F:D9:2A:93:43:LastUsed=01 > /var/lib/bluetooth/B8:8A:60:D8:17:D7/cache/B4:CD:27:F0:8D:0A:60:LastUsed=04 > /var/lib/bluetooth/B8:8A:60:D8:17:D7/cache/94:20:53:2E:08:CE:24:LastUsed=05 > -- Pali Rohár pali.rohar@xxxxxxxxx
Attachment:
signature.asc
Description: PGP signature