diff mbox series

[BlueZ,4/9] transport: Trigger transport release when syncing to multiple BISes

Message ID 20241004123523.1012743-5-vlad.pruteanu@nxp.com (mailing list archive)
State New, archived
Headers show
Series Allow syncing to multiple BISes from the same BIG | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch success CheckPatch PASS
tedd_an/GitLint success Gitlint PASS

Commit Message

Vlad Pruteanu Oct. 4, 2024, 12:35 p.m. UTC
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(+)

Comments

Luiz Augusto von Dentz Oct. 4, 2024, 3:01 p.m. UTC | #1
Hi Vlad,

On Fri, Oct 4, 2024 at 8:35 AM Vlad Pruteanu <vlad.pruteanu@nxp.com> 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
>
diff mbox series

Patch

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);
+			}
+		}
+
 		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;