diff mbox series

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

Message ID 20241004123523.1012743-5-vlad.pruteanu@nxp.com
State New
Headers show
Series Allow syncing to multiple BISes from the same BIG | expand

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