Skip to contentSkip to conversation

audio: Add ability to force CIS transport Links property

PATCH In review Frédéric Danis 2 participants 4 messages Apr 23 Bluetooth drivers

lore
Share & tools
lore
#0 lore raw

PATCH v3 1/3 audio: Add ability to force CIS transport Links property

If bluetoothd is started in testing mode the Links property for CIS is readwrite and can be used to force transport objects Links. This can used to unlink transport objects by sending an empty array.

For unlinked transport objects, each transports needs to be acquired separately.

This allows to pass PTS tests BAP/UCL/STR/BV-543-C and BV-546-C.
---
v1 -> v2:
- Add testing mode check in bap_connect_io_cb()
- Replace stream state check by checking that the stream is not linked before passing the connect event to all streams belonging to same CIG/CIS.
v2 -> v3: Fix Lint errors

 profiles/audio/bap.c       | 49 ++++++++++++++++++++++++++++++++
 profiles/audio/transport.c | 57 +++++++++++++++++++++++++++++++-------
 2 files changed, 96 insertions(+), 10 deletions(-)
profiles/audio/bap.c +49 -0
index 5333267f7..8a953d80f 100644
@@ -2655,13 +2655,62 @@ static void bap_connect_bcast_io_cb(GIOChannel *chan, GError *err,
 	iso_connect_bcast_cb(chan, err, setup->stream);
 }
 
+struct connect_io_data {
+	GIOChannel *chan;
+	GError *err;
+	uint8_t cig_id;
+	uint8_t cis_id;
+};
+
+static void connect_stream(void *data, void *user_data)
+{
+	struct bap_setup *setup = data;
+	struct connect_io_data *d = user_data;
+	uint8_t state;
+
+	/* Check stream state to only pass the connect event managed
+	 * by bap_stream_set_io()
+	 */
+	state = bt_bap_stream_get_state(setup->stream);
+	if ((state == BT_BAP_STREAM_STATE_ENABLING ||
+			state == BT_BAP_STREAM_STATE_DISABLING) &&
+			setup->qos.ucast.cig_id == d->cig_id &&
+			setup->qos.ucast.cis_id == d->cis_id)
+		iso_connect_cb(d->chan, d->err, setup->stream);
+}
+
+static void connect_ep(void *data, void *user_data)
+{
+	struct bap_ep *ep = data;
+
+	if (ep->setups)
+		queue_foreach(ep->setups, connect_stream, user_data);
+}
+
 static void bap_connect_io_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
 	struct bap_setup *setup = user_data;
+	struct connect_io_data data;
 
 	if (!setup->stream)
 		return;
 
+	if (queue_isempty(bt_bap_stream_io_get_links(setup->stream)) &&
+		btd_opts.testing) {
+		/* The stream may have manually been unliked for PTS tests,
+		 * e.g. BAP/UCL/STR/BV-543-C or BAP/UCL/STR/BV-546-C,
+		 * in this case send the connect event to all streams
+		 * belonging to the same CIG/CIS.
+		 */
+		data.chan = chan;
+		data.err = err;
+		data.cig_id = setup->qos.ucast.cig_id;
+		data.cis_id = setup->qos.ucast.cis_id;
+		queue_foreach(setup->ep->data->snks, connect_ep, &data);
+		queue_foreach(setup->ep->data->srcs, connect_ep, &data);
+		return;
+	}
+
 	iso_connect_cb(chan, err, setup->stream);
 }
 
profiles/audio/transport.c +47 -10

143 lines not on this page · raw message

Signature · 1 line
2.43.0
#1 lore raw

PATCH v3 2/3 doc: Add documentation for readwrite CIS transport Links property

This is only supported when bluetoothd is started in testing mode.

---
 doc/org.bluez.MediaTransport.rst | 5 +++++
 1 file changed, 5 insertions(+)
doc/org.bluez.MediaTransport.rst +5 -0
index 81cf9e4da..fe69f948b 100644
@@ -180,6 +180,11 @@ array{object} Links [readonly, optional, CIS only, experimental]
 
 Linked transport objects which the transport is associated with.
 
+If D-Bus testing interfaces as been enabled this property is readwrite.
+
+This can be used to manually unlink transport objects by sending empty array.
+Then, each link needs be acquired separately.
+
 array{object} Links [readwrite, BIS only, experimental]
 ```````````````````````````````````````````````````````
 
Signature · 1 line
2.43.0
#2 lore raw

PATCH v3 3/3 client/player: Add support to unlink transports

In reply to Frédéric Danis

This is used to pass PTS tests BAP/UCL/STR/BV-543-C and BV-546-C.

---
 client/player.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)
client/player.c +56 -1
index 1444e939d..e3bd28fea 100644
@@ -5003,6 +5003,9 @@ static bool transport_recv(struct io *io, void *user_data)
 static void transport_new(GDBusProxy *proxy, int sk, uint16_t mtu[2])
 {
 	struct transport *transport;
+	DBusMessageIter iter;
+	const char *uuid;
+	bool reader = true;
 
 	transport = new0(struct transport, 1);
 	transport->proxy = proxy;
@@ -5014,7 +5017,23 @@ static void transport_new(GDBusProxy *proxy, int sk, uint16_t mtu[2])
 
 	io_set_disconnect_handler(transport->io, transport_disconnected,
 							transport, NULL);
-	io_set_read_handler(transport->io, transport_recv, transport, NULL);
+
+	if (!g_dbus_proxy_get_property(proxy, "UUID", &iter))
+		return;
+
+	dbus_message_iter_get_basic(&iter, &uuid);
+
+	/* For BAP testing, streams may have been manually unlinked.
+	 * In this case source and sink streams are acquired separately and
+	 * read handler should not be started for source local endpoint.
+	 */
+	if (!g_dbus_proxy_get_property(proxy, "Links", &iter) &&
+			!strcmp(uuid, PAC_SOURCE_UUID))
+		reader = false;
+
+	if (reader)
+		io_set_read_handler(transport->io, transport_recv, transport,
+									NULL);
 
 	if (!ios)
 		ios = queue_new();
@@ -6091,6 +6110,39 @@ static void cmd_metadata_transport(int argc, char *argv[])
 	}
 }
 
+static void unlink_cb(const DBusError *error, void *user_data)
+{
+	if (dbus_error_is_set(error)) {
+		bt_shell_printf("Failed to unlink: %s\n", error->name);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
+	}
+
+	bt_shell_printf("Unlink succeeded\n");
+
+	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_unlink_transport(int argc, char *argv[])
+{
+	GDBusProxy *proxy;
+	char *value[0];
+
+	proxy = g_dbus_proxy_lookup(transports, NULL, argv[1],
+					BLUEZ_MEDIA_TRANSPORT_INTERFACE);
+	if (!proxy) {
+		bt_shell_printf("Transport %s not found\n", argv[1]);
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
+	}
+
+	if (g_dbus_proxy_set_property_array(proxy, "Links",
+				DBUS_TYPE_OBJECT_PATH,
+				value, 0, unlink_cb,
+				NULL, NULL) == FALSE) {
+		bt_shell_printf("Failed to unlink transport\n");
+		return bt_shell_noninteractive_quit(EXIT_FAILURE);
+	}
+}
+
 static const struct bt_shell_menu transport_menu = {
 	.name = "transport",
 	.desc = "Media Transport Submenu",
@@ -6126,6 +6178,9 @@ static const struct bt_shell_menu transport_menu = {
 	{ "metadata",    "<transport> [value...]", cmd_metadata_transport,
 						"Get/Set Transport Metadata",
 						transport_generator },
+	{ "unlink",      "<transport>", cmd_unlink_transport,
+						"Unlink Transport",
+						transport_generator },
 	{} },
 };
 
Signature · 1 line
2.43.0
#3 lore raw
In reply to Frédéric Danis

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1084652

---Test result---

Test Summary:

CheckPatch                    PASS      1.62 seconds
GitLint                       PASS      0.99 seconds
BuildEll                      PASS      20.07 seconds
BluezMake                     PASS      607.25 seconds
MakeCheck                     PASS      19.20 seconds
MakeDistcheck                 PASS      235.07 seconds
CheckValgrind                 PASS      274.62 seconds
CheckSmatch                   PASS      321.53 seconds
bluezmakeextell               PASS      165.35 seconds
IncrementalBuild              PASS      619.37 seconds
ScanBuild                     PASS      926.27 seconds

https://github.com/bluez/bluez/pull/2065

---
Regards,
Linux Bluetooth