Hi Vlad, On Fri, Oct 4, 2024 at 8:35 AM Vlad Pruteanu <vlad.pruteanu@xxxxxxx> wrote: > > In order to sync to multiple BISes from the same BIG, the existing > sync must be destroyed and a new one created. This is accomplished > by prompting the audio server to release the existing, active, > transports (by moving them to the IDLE state). They will later be > identified by the RELEASING state of their streams and the process > for reacquirement (along with the new transport) will begin. > --- > profiles/audio/transport.c | 41 ++++++++++++++++++++++++++++++++++++++ > 1 file changed, 41 insertions(+) > > diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c > index caa7287db..e68695c39 100644 > --- a/profiles/audio/transport.c > +++ b/profiles/audio/transport.c > @@ -1366,6 +1366,7 @@ static DBusMessage *select_transport(DBusConnection *conn, DBusMessage *msg, > void *data) > { > struct media_transport *transport = data; > + GSList *l; > > if (transport->owner != NULL) > return btd_error_not_authorized(msg); > @@ -1375,6 +1376,29 @@ static DBusMessage *select_transport(DBusConnection *conn, DBusMessage *msg, > > if (!strcmp(media_endpoint_get_uuid(transport->endpoint), > BAA_SERVICE_UUID)) { > + /* Check if there are any ACTIVE transports, from the same > + * device. If there are, it means that this is a request to add > + * a new BIS to the active BIG sync. This is done by releasing > + * the ACTIVE transports, and then reaquiring them along with > + * the new transport that needs to be added to the sync. To > + * release the transports, bt_bap_stream_release is called, > + * which will set the stream's state to > + * BT_BAP_STREAM_STATE_RELEASING. On bap_state_changed, this > + * will be detected and transport_update_playing will be called, > + * with playing set to FALSE. This will move the transport to > + * IDLE, prompting the audio server to release it. > + */ > + for (l = transports; l; l = g_slist_next(l)) { > + struct media_transport *tr = l->data; > + struct bap_transport *bap_temp = tr->data; > + > + if (tr->device == transport->device && > + tr->state == TRANSPORT_STATE_ACTIVE) { > + bt_bap_stream_release(bap_temp->stream, > + NULL, NULL); > + } > + } This seems a little counter intuitive, I don't think we should allow, at least not by default, to sync BIS(s) one by one otherwise on every select we would then need to do the release/reacquire logic that you are proposing, instead what we should probably be doing is to list the BIS(s) of the same BIG as Links: https://github.com/bluez/bluez/blob/master/doc/org.bluez.MediaTransport.rst#arrayobject-links-readonly-optional-iso-only-experimental > transport_update_playing(transport, TRUE); > } > > @@ -1385,9 +1409,22 @@ static DBusMessage *unselect_transport(DBusConnection *conn, DBusMessage *msg, > void *data) > { > struct media_transport *transport = data; > + GSList *l; > > if (!strcmp(media_endpoint_get_uuid(transport->endpoint), > BAA_SERVICE_UUID)) { > + for (l = transports; l; l = g_slist_next(l)) { > + struct media_transport *tr = l->data; > + struct bap_transport *bap_temp = tr->data; > + > + if (tr->device == transport->device && > + tr->state == TRANSPORT_STATE_ACTIVE && > + tr != transport) { > + bt_bap_stream_release(bap_temp->stream, > + NULL, NULL); > + } > + } > + > transport_update_playing(transport, FALSE); > } > > @@ -1768,6 +1805,10 @@ static void bap_state_changed(struct bt_bap_stream *stream, uint8_t old_state, > bap_update_bcast_qos(transport); > break; > case BT_BAP_STREAM_STATE_RELEASING: > + if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SOURCE) { > + transport_update_playing(transport, FALSE); > + return; > + } > if (bt_bap_stream_io_dir(stream) == BT_BAP_BCAST_SINK) > return; > break; > -- > 2.40.1 > -- Luiz Augusto von Dentz