Hi Luiz, On Mon, 26 Oct 2020 at 21:15, Luiz Augusto von Dentz <luiz.dentz@xxxxxxxxx> wrote: > > Hi Marijn, > > On Sun, Oct 25, 2020 at 9:27 AM Marijn Suijten <marijns95@xxxxxxxxx> wrote: > > > > a2dp_channel keeps a reference to an avdtp session without incrementing > > its refcount. Not only does this appear wrong, it causes unexpected > > disconnections when the remote SEP responds with rejections. > > > > During testing with an audio application disconnections are observed > > when a codec config change through MediaEndpoint1.SetConfiguration > > fails. As soon as BlueZ receives this failure from the peer the > > corresponding a2dp_setup object is cleaned up which holds the last > > refcount to an avdtp session, in turn starting the disconnect process. > > An eventual open sink/source and transport have already closed by that > > time and released their refcounts. > > > > Adding refcounting semantics around a2dp_channel resolves the > > disconnections and allows future calls on MediaEndpoint1 to safely > > access the sesion stored within this channel. > > --- > > profiles/audio/a2dp.c | 7 ++++++- > > 1 file changed, 6 insertions(+), 1 deletion(-) > > > > diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c > > index cc4866b5b..0eac0135f 100644 > > --- a/profiles/audio/a2dp.c > > +++ b/profiles/audio/a2dp.c > > @@ -1507,6 +1507,9 @@ static void channel_free(void *data) > > > > avdtp_remove_state_cb(chan->state_id); > > > > + if (chan->session) > > + avdtp_unref(chan->session); > > + > > queue_destroy(chan->seps, remove_remote_sep); > > free(chan->last_used); > > g_free(chan); > > @@ -2065,7 +2068,7 @@ static void avdtp_state_cb(struct btd_device *dev, struct avdtp *session, > > break; > > case AVDTP_SESSION_STATE_CONNECTED: > > if (!chan->session) > > - chan->session = session; > > + chan->session = avdtp_ref(session); > > Afaik this was done on purpose since we only need a weak reference as > taking a reference would prevent the session to be disconnected when > there is no setup in place, so I pretty sure this will cause > regressions, instead we should probably add a reference when > reconfiguring is in place and have a grace period for switching to > another codec. Allright, so it's either an in-progress setup or ongoing transport keeping the session alive, nothing else? I guess this is as simple as setting a higher dc_timeout when calling set_disconnect_timer in avdtp_unref? > > > load_remote_seps(chan); > > break; > > } > > @@ -2145,6 +2148,7 @@ found: > > channel_remove(chan); > > return NULL; > > } > > + avdtp_ref(chan->session); > > > > return avdtp_ref(chan->session); > > } > > @@ -2165,6 +2169,7 @@ static void connect_cb(GIOChannel *io, GError *err, gpointer user_data) > > error("Unable to create AVDTP session"); > > goto fail; > > } > > + avdtp_ref(chan->session); > > } > > > > g_io_channel_unref(chan->io); > > -- > > 2.29.1 > > > > Marijn Suijten > > > > -- > Luiz Augusto von Dentz Marijn Suijten