* [PATCH BlueZ 0/3] Add ability to desynchronized transports for PTS tests
@ 2026-04-27 17:20 Frédéric Danis
2026-04-27 17:20 ` [PATCH BlueZ 1/3] audio: Add ability to desynchronized linked transport Frédéric Danis
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Frédéric Danis @ 2026-04-27 17:20 UTC (permalink / raw)
To: linux-bluetooth
If bluetoothd is started in testing mode a new Desynchronized property
is added to org.bluez.MediaTransport1, allowing to prevent automatic
acquire of linked transport objects.
When desynchronized, each transports needs to be acquired separately.
This allows to pass PTS tests BAP/UCL/STR/BV-543-C and BV-546-C which
requires to connect the ISO streams with one ASE in "Enable" state
while the other is in "Config QoS" state.
Frédéric Danis (3):
audio: Add ability to desynchronized linked transport
doc: Add documentation for CIS transport Desynchronized property
client/player: Add support to desynchronize linked transports
client/player.c | 76 ++++++++++++++++++++-
doc/org.bluez.MediaTransport.rst | 14 ++++
profiles/audio/transport.c | 113 +++++++++++++++++++++++++++----
3 files changed, 189 insertions(+), 14 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH BlueZ 1/3] audio: Add ability to desynchronized linked transport
2026-04-27 17:20 [PATCH BlueZ 0/3] Add ability to desynchronized transports for PTS tests Frédéric Danis
@ 2026-04-27 17:20 ` Frédéric Danis
2026-04-27 18:02 ` Luiz Augusto von Dentz
2026-04-27 18:56 ` Add ability to desynchronized transports for PTS tests bluez.test.bot
2026-04-27 17:20 ` [PATCH BlueZ 2/3] doc: Add documentation for CIS transport Desynchronized property Frédéric Danis
2026-04-27 17:20 ` [PATCH BlueZ 3/3] client/player: Add support to desynchronize linked transports Frédéric Danis
2 siblings, 2 replies; 6+ messages in thread
From: Frédéric Danis @ 2026-04-27 17:20 UTC (permalink / raw)
To: linux-bluetooth
If bluetoothd is started in testing mode a new Desynchronized property
is added, allowing to prevent automatic acquire of linked transport
objects.
When desynchronized, each transports needs to be acquired separately.
This allows to pass PTS tests BAP/UCL/STR/BV-543-C and BV-546-C.
---
profiles/audio/transport.c | 113 ++++++++++++++++++++++++++++++++-----
1 file changed, 100 insertions(+), 13 deletions(-)
diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
index 5c2a2777e..f8f68737d 100644
--- a/profiles/audio/transport.c
+++ b/profiles/audio/transport.c
@@ -37,6 +37,7 @@
#include "src/shared/bap.h"
#include "src/shared/bass.h"
#include "src/shared/io.h"
+#include "src/btd.h"
#ifdef HAVE_A2DP
#include "avdtp.h"
@@ -109,11 +110,13 @@ struct bap_transport {
guint resume_id;
struct iovec *meta;
guint chan_id;
+ bool desynchronized;
};
struct media_transport_ops {
const char *uuid;
const GDBusPropertyTable *properties;
+ const GDBusPropertyTable *test_properties;
void (*set_owner)(struct media_transport *transport,
struct media_owner *owner);
void (*remove_owner)(struct media_transport *transport,
@@ -351,7 +354,7 @@ static void transport_bap_remove_owner(struct media_transport *transport,
{
struct bap_transport *bap = transport->data;
- if (bap && bap->linked)
+ if (bap && bap->linked && !bap->desynchronized)
queue_foreach(bt_bap_stream_io_get_links(bap->stream),
linked_transport_remove_owner, owner);
}
@@ -729,7 +732,7 @@ static void transport_bap_set_owner(struct media_transport *transport,
{
struct bap_transport *bap = transport->data;
- if (bap && bap->linked)
+ if (bap && bap->linked && !bap->desynchronized)
queue_foreach(bt_bap_stream_io_get_links(bap->stream),
linked_transport_set_owner, owner);
}
@@ -1463,6 +1466,60 @@ static void set_links(const GDBusPropertyTable *property,
g_dbus_pending_property_success(id);
}
+static gboolean get_desynchronized(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct media_transport *transport = data;
+ struct bap_transport *bap = transport->data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
+ &bap->desynchronized);
+
+ return TRUE;
+}
+
+static void transport_desynchronize(void *data, void *user_data)
+{
+ struct bt_bap_stream *link = data;
+ bool desynchronized = PTR_TO_UINT(user_data);
+ struct media_transport *transport;
+ struct bap_transport *bap;
+
+ transport = find_transport_by_bap_stream(link);
+ bap = transport->data;
+ bap->desynchronized = desynchronized;
+ g_dbus_emit_property_changed(btd_get_dbus_connection(), transport->path,
+ MEDIA_TRANSPORT_INTERFACE,
+ "Desynchronized");
+}
+
+static void set_desynchronized(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, GDBusPendingPropertySet id,
+ void *data)
+{
+ struct media_transport *transport = data;
+ struct bap_transport *bap = transport->data;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN) {
+ g_dbus_pending_property_error(id,
+ ERROR_INTERFACE ".InvalidArguments",
+ "Expected BOOLEAN");
+ return;
+ }
+
+ dbus_message_iter_get_basic(iter, &bap->desynchronized);
+ g_dbus_emit_property_changed(btd_get_dbus_connection(), transport->path,
+ MEDIA_TRANSPORT_INTERFACE,
+ "Desynchronized");
+
+ /* Set desynchronized for all the links */
+ queue_foreach(bt_bap_stream_io_get_links(bap->stream),
+ transport_desynchronize,
+ UINT_TO_PTR(bap->desynchronized));
+
+ g_dbus_pending_property_success(id);
+}
+
static gboolean qos_ucast_exists(const GDBusPropertyTable *property, void *data)
{
struct media_transport *transport = data;
@@ -1486,6 +1543,23 @@ static const GDBusPropertyTable transport_bap_uc_properties[] = {
{ }
};
+static const GDBusPropertyTable transport_bap_uc_test_properties[] = {
+ { "Device", "o", get_device },
+ { "UUID", "s", get_uuid },
+ { "Codec", "y", get_codec },
+ { "Configuration", "ay", get_configuration },
+ { "State", "s", get_state },
+ { "QoS", "a{sv}", get_ucast_qos, NULL, qos_ucast_exists },
+ { "Endpoint", "o", get_endpoint, NULL, endpoint_exists },
+ { "Location", "u", get_location },
+ { "Metadata", "ay", get_metadata, set_metadata },
+ { "Links", "ao", get_links, NULL, links_exists },
+ { "Volume", "q", get_volume, set_volume, volume_exists },
+ { "Desynchronized", "b", get_desynchronized, set_desynchronized,
+ links_exists},
+ { }
+};
+
static gboolean get_bcast_qos(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data)
{
@@ -1920,6 +1994,9 @@ static void transport_bap_update_links_uc(
g_dbus_emit_property_changed(btd_get_dbus_connection(), transport->path,
MEDIA_TRANSPORT_INTERFACE,
"Links");
+ g_dbus_emit_property_changed(btd_get_dbus_connection(), transport->path,
+ MEDIA_TRANSPORT_INTERFACE,
+ "Desynchronized");
DBG("stream %p linked %s", bap->stream, bap->linked ? "true" : "false");
}
@@ -2037,8 +2114,9 @@ static guint transport_bap_resume(struct media_transport *transport,
return bap->resume_id;
}
- id = bt_bap_stream_enable(bap->stream, bap->linked, NULL,
- bap_enable_complete, owner);
+ id = bt_bap_stream_enable(bap->stream,
+ bap->desynchronized ? false : bap->linked,
+ NULL, bap_enable_complete, owner);
if (!id)
return 0;
@@ -2161,7 +2239,7 @@ static void transport_bap_set_state(struct media_transport *transport,
{
struct bap_transport *bap = transport->data;
- if (!bap->linked)
+ if (!bap->linked || bap->desynchronized)
return;
/* Update links */
@@ -2540,10 +2618,11 @@ static void *transport_asha_init(struct media_transport *transport, void *data)
#define TRANSPORT_OPS(_uuid, _props, _set_owner, _remove_owner, _init, \
_resume, _suspend, _cancel, _set_state, _get_stream, \
_get_volume, _set_volume, _set_delay, _update_links, \
- _destroy) \
+ _destroy, _test_props) \
{ \
.uuid = _uuid, \
.properties = _props, \
+ .test_properties = _test_props, \
.set_owner = _set_owner, \
.remove_owner = _remove_owner, \
.init = _init, \
@@ -2565,26 +2644,28 @@ static void *transport_asha_init(struct media_transport *transport, void *data)
transport_a2dp_resume, transport_a2dp_suspend, \
transport_a2dp_cancel, NULL, \
transport_a2dp_get_stream, transport_a2dp_get_volume, \
- _set_volume, _set_delay, NULL, _destroy)
+ _set_volume, _set_delay, NULL, _destroy, NULL)
#define BAP_OPS(_uuid, _props, _set_owner, _remove_owner, _update_links, \
- _set_state) \
+ _set_state, _test_props) \
TRANSPORT_OPS(_uuid, _props, _set_owner, _remove_owner,\
transport_bap_init, \
transport_bap_resume, transport_bap_suspend, \
transport_bap_cancel, _set_state, \
transport_bap_get_stream, transport_bap_get_volume, \
transport_bap_set_volume, NULL, \
- _update_links, transport_bap_destroy)
+ _update_links, transport_bap_destroy, _test_props)
#define BAP_UC_OPS(_uuid) \
BAP_OPS(_uuid, transport_bap_uc_properties, \
transport_bap_set_owner, transport_bap_remove_owner, \
- transport_bap_update_links_uc, transport_bap_set_state)
+ transport_bap_update_links_uc, \
+ transport_bap_set_state, \
+ transport_bap_uc_test_properties)
#define BAP_BC_OPS(_uuid) \
BAP_OPS(_uuid, transport_bap_bc_properties, NULL, NULL, \
- transport_bap_update_links_bc, NULL)
+ transport_bap_update_links_bc, NULL, NULL)
#define ASHA_OPS(_uuid) \
TRANSPORT_OPS(_uuid, transport_asha_properties, NULL, NULL, \
@@ -2592,7 +2673,7 @@ static void *transport_asha_init(struct media_transport *transport, void *data)
transport_asha_resume, transport_asha_suspend, \
transport_asha_cancel, NULL, NULL, \
transport_asha_get_volume, transport_asha_set_volume, \
- NULL, NULL, NULL)
+ NULL, NULL, NULL, NULL)
static const struct media_transport_ops transport_ops[] = {
#ifdef HAVE_A2DP
@@ -2647,6 +2728,7 @@ struct media_transport *media_transport_create(struct btd_device *device,
struct media_transport *transport;
const struct media_transport_ops *ops;
int fd;
+ const GDBusPropertyTable *properties;
transport = g_new0(struct media_transport, 1);
if (device)
@@ -2701,9 +2783,14 @@ struct media_transport *media_transport_create(struct btd_device *device,
goto fail;
}
+ if (btd_opts.testing && ops->test_properties)
+ properties = ops->test_properties;
+ else
+ properties = ops->properties;
+
if (g_dbus_register_interface(btd_get_dbus_connection(),
transport->path, MEDIA_TRANSPORT_INTERFACE,
- transport_methods, NULL, ops->properties,
+ transport_methods, NULL, properties,
transport, media_transport_free) == FALSE) {
error("Could not register transport %s", transport->path);
goto fail;
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH BlueZ 2/3] doc: Add documentation for CIS transport Desynchronized property
2026-04-27 17:20 [PATCH BlueZ 0/3] Add ability to desynchronized transports for PTS tests Frédéric Danis
2026-04-27 17:20 ` [PATCH BlueZ 1/3] audio: Add ability to desynchronized linked transport Frédéric Danis
@ 2026-04-27 17:20 ` Frédéric Danis
2026-04-27 17:20 ` [PATCH BlueZ 3/3] client/player: Add support to desynchronize linked transports Frédéric Danis
2 siblings, 0 replies; 6+ messages in thread
From: Frédéric Danis @ 2026-04-27 17:20 UTC (permalink / raw)
To: linux-bluetooth
This is only supported when bluetoothd is started in testing mode.
Assisted-by: GPT:GPT-5.3-Codex
---
doc/org.bluez.MediaTransport.rst | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/doc/org.bluez.MediaTransport.rst b/doc/org.bluez.MediaTransport.rst
index 81cf9e4da..e50ec3f20 100644
--- a/doc/org.bluez.MediaTransport.rst
+++ b/doc/org.bluez.MediaTransport.rst
@@ -357,3 +357,17 @@ Possible values for both Unicast and Broadcast:
:byte Retransmissions:
Indicates configured retransmissions.
+
+boolean Desynchronized [readwrite, optional, CIS only, testing, experimental]
+`````````````````````````````````````````````````````````````````````````````
+
+Available only when D-Bus testing interfaces are enabled and the transport has
+the **Links** property.
+
+Controls whether linked transports are acquired together.
+
+When set to False (default), acquiring one linked transport automatically
+acquires all links.
+
+When set to True, links are not acquired automatically and each link must be
+acquired separately.
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH BlueZ 3/3] client/player: Add support to desynchronize linked transports
2026-04-27 17:20 [PATCH BlueZ 0/3] Add ability to desynchronized transports for PTS tests Frédéric Danis
2026-04-27 17:20 ` [PATCH BlueZ 1/3] audio: Add ability to desynchronized linked transport Frédéric Danis
2026-04-27 17:20 ` [PATCH BlueZ 2/3] doc: Add documentation for CIS transport Desynchronized property Frédéric Danis
@ 2026-04-27 17:20 ` Frédéric Danis
2 siblings, 0 replies; 6+ messages in thread
From: Frédéric Danis @ 2026-04-27 17:20 UTC (permalink / raw)
To: linux-bluetooth
After linked transports has been desynchronized, they should be acquired
separately and read handler should only be started for source local
endpoint.
This is used to pass PTS tests BAP/UCL/STR/BV-543-C and BV-546-C.
---
client/player.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 75 insertions(+), 1 deletion(-)
diff --git a/client/player.c b/client/player.c
index 1444e939d..c5e4beef0 100644
--- a/client/player.c
+++ b/client/player.c
@@ -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,27 @@ 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 desynchronized.
+ * 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, "Desynchronized", &iter)) {
+ dbus_bool_t desync;
+
+ dbus_message_iter_get_basic(&iter, &desync);
+ if (desync && !strcmp(uuid, PAC_SOURCE_UUID))
+ reader = false;
+ }
+
+ if (reader)
+ io_set_read_handler(transport->io, transport_recv, transport,
+ NULL);
if (!ios)
ios = queue_new();
@@ -5325,6 +5348,7 @@ static void print_transport_properties(GDBusProxy *proxy)
print_property(proxy, "QoS");
print_property(proxy, "Location");
print_property(proxy, "Links");
+ print_property(proxy, "Desynchronized");
}
static void print_transports(void *data, void *user_data)
@@ -6091,6 +6115,53 @@ static void cmd_metadata_transport(int argc, char *argv[])
}
}
+static void desync_cb(const DBusError *error, void *user_data)
+{
+ if (dbus_error_is_set(error)) {
+ bt_shell_printf("Failed to desynchronize: %s\n", error->name);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ bt_shell_printf("Desynchronize succeeded\n");
+
+ return bt_shell_noninteractive_quit(EXIT_SUCCESS);
+}
+
+static void cmd_desync_transport(int argc, char *argv[])
+{
+ dbus_bool_t desync;
+ GDBusProxy *proxy;
+
+ if (argc < 3) {
+ bt_shell_printf("Missing argument to %s\n", argv[0]);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ 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 (!strcmp(argv[2], "on") || !strcmp(argv[2], "yes")) {
+ desync = TRUE;
+ } else if (!strcmp(argv[2], "off") || !strcmp(argv[2], "no")) {
+ desync = FALSE;
+ } else {
+ bt_shell_printf("Invalid argument %s\n", argv[2]);
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ if (!g_dbus_proxy_set_property_basic(proxy, "Desynchronized",
+ DBUS_TYPE_BOOLEAN,
+ &desync, desync_cb,
+ NULL, NULL)) {
+ bt_shell_printf("Failed to desynchronize 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 +6197,9 @@ static const struct bt_shell_menu transport_menu = {
{ "metadata", "<transport> [value...]", cmd_metadata_transport,
"Get/Set Transport Metadata",
transport_generator },
+ { "desync", "<transport> <on/off>", cmd_desync_transport,
+ "Desynchronize Transport",
+ transport_generator },
{} },
};
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH BlueZ 1/3] audio: Add ability to desynchronized linked transport
2026-04-27 17:20 ` [PATCH BlueZ 1/3] audio: Add ability to desynchronized linked transport Frédéric Danis
@ 2026-04-27 18:02 ` Luiz Augusto von Dentz
2026-04-27 18:56 ` Add ability to desynchronized transports for PTS tests bluez.test.bot
1 sibling, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2026-04-27 18:02 UTC (permalink / raw)
To: Frédéric Danis; +Cc: linux-bluetooth
Hi Frédéric,
On Mon, Apr 27, 2026 at 1:26 PM Frédéric Danis
<frederic.danis@collabora.com> wrote:
>
> If bluetoothd is started in testing mode a new Desynchronized property
> is added, allowing to prevent automatic acquire of linked transport
> objects.
>
> When desynchronized, each transports needs to be acquired separately.
>
> This allows to pass PTS tests BAP/UCL/STR/BV-543-C and BV-546-C.
> ---
> profiles/audio/transport.c | 113 ++++++++++++++++++++++++++++++++-----
> 1 file changed, 100 insertions(+), 13 deletions(-)
>
> diff --git a/profiles/audio/transport.c b/profiles/audio/transport.c
> index 5c2a2777e..f8f68737d 100644
> --- a/profiles/audio/transport.c
> +++ b/profiles/audio/transport.c
> @@ -37,6 +37,7 @@
> #include "src/shared/bap.h"
> #include "src/shared/bass.h"
> #include "src/shared/io.h"
> +#include "src/btd.h"
>
> #ifdef HAVE_A2DP
> #include "avdtp.h"
> @@ -109,11 +110,13 @@ struct bap_transport {
> guint resume_id;
> struct iovec *meta;
> guint chan_id;
> + bool desynchronized;
Let's call it 'desync' for short. Also, add a comment stating that
this is only writable when testing is enabled; otherwise, it defaults
to false, meaning the Enable/Acquire operations synchronize
input/output directions that share the same ISO socket CID/CIG.
> };
>
> struct media_transport_ops {
> const char *uuid;
> const GDBusPropertyTable *properties;
> + const GDBusPropertyTable *test_properties;
> void (*set_owner)(struct media_transport *transport,
> struct media_owner *owner);
> void (*remove_owner)(struct media_transport *transport,
> @@ -351,7 +354,7 @@ static void transport_bap_remove_owner(struct media_transport *transport,
> {
> struct bap_transport *bap = transport->data;
>
> - if (bap && bap->linked)
> + if (bap && bap->linked && !bap->desynchronized)
> queue_foreach(bt_bap_stream_io_get_links(bap->stream),
> linked_transport_remove_owner, owner);
> }
> @@ -729,7 +732,7 @@ static void transport_bap_set_owner(struct media_transport *transport,
> {
> struct bap_transport *bap = transport->data;
>
> - if (bap && bap->linked)
> + if (bap && bap->linked && !bap->desynchronized)
> queue_foreach(bt_bap_stream_io_get_links(bap->stream),
> linked_transport_set_owner, owner);
> }
> @@ -1463,6 +1466,60 @@ static void set_links(const GDBusPropertyTable *property,
> g_dbus_pending_property_success(id);
> }
>
> +static gboolean get_desynchronized(const GDBusPropertyTable *property,
> + DBusMessageIter *iter, void *data)
> +{
> + struct media_transport *transport = data;
> + struct bap_transport *bap = transport->data;
> +
> + dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
> + &bap->desynchronized);
> +
> + return TRUE;
> +}
> +
> +static void transport_desynchronize(void *data, void *user_data)
> +{
> + struct bt_bap_stream *link = data;
> + bool desynchronized = PTR_TO_UINT(user_data);
> + struct media_transport *transport;
> + struct bap_transport *bap;
> +
> + transport = find_transport_by_bap_stream(link);
> + bap = transport->data;
> + bap->desynchronized = desynchronized;
> + g_dbus_emit_property_changed(btd_get_dbus_connection(), transport->path,
> + MEDIA_TRANSPORT_INTERFACE,
> + "Desynchronized");
> +}
> +
> +static void set_desynchronized(const GDBusPropertyTable *property,
> + DBusMessageIter *iter, GDBusPendingPropertySet id,
> + void *data)
> +{
> + struct media_transport *transport = data;
> + struct bap_transport *bap = transport->data;
> +
> + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_BOOLEAN) {
> + g_dbus_pending_property_error(id,
> + ERROR_INTERFACE ".InvalidArguments",
> + "Expected BOOLEAN");
> + return;
> + }
> +
> + dbus_message_iter_get_basic(iter, &bap->desynchronized);
> + g_dbus_emit_property_changed(btd_get_dbus_connection(), transport->path,
> + MEDIA_TRANSPORT_INTERFACE,
> + "Desynchronized");
> +
> + /* Set desynchronized for all the links */
> + queue_foreach(bt_bap_stream_io_get_links(bap->stream),
> + transport_desynchronize,
> + UINT_TO_PTR(bap->desynchronized));
> +
> + g_dbus_pending_property_success(id);
> +}
> +
> static gboolean qos_ucast_exists(const GDBusPropertyTable *property, void *data)
> {
> struct media_transport *transport = data;
> @@ -1486,6 +1543,23 @@ static const GDBusPropertyTable transport_bap_uc_properties[] = {
> { }
> };
>
> +static const GDBusPropertyTable transport_bap_uc_test_properties[] = {
> + { "Device", "o", get_device },
> + { "UUID", "s", get_uuid },
> + { "Codec", "y", get_codec },
> + { "Configuration", "ay", get_configuration },
> + { "State", "s", get_state },
> + { "QoS", "a{sv}", get_ucast_qos, NULL, qos_ucast_exists },
> + { "Endpoint", "o", get_endpoint, NULL, endpoint_exists },
> + { "Location", "u", get_location },
> + { "Metadata", "ay", get_metadata, set_metadata },
> + { "Links", "ao", get_links, NULL, links_exists },
> + { "Volume", "q", get_volume, set_volume, volume_exists },
> + { "Desynchronized", "b", get_desynchronized, set_desynchronized,
> + links_exists},
> + { }
> +};
> +
> static gboolean get_bcast_qos(const GDBusPropertyTable *property,
> DBusMessageIter *iter, void *data)
> {
> @@ -1920,6 +1994,9 @@ static void transport_bap_update_links_uc(
> g_dbus_emit_property_changed(btd_get_dbus_connection(), transport->path,
> MEDIA_TRANSPORT_INTERFACE,
> "Links");
> + g_dbus_emit_property_changed(btd_get_dbus_connection(), transport->path,
> + MEDIA_TRANSPORT_INTERFACE,
> + "Desynchronized");
>
> DBG("stream %p linked %s", bap->stream, bap->linked ? "true" : "false");
> }
> @@ -2037,8 +2114,9 @@ static guint transport_bap_resume(struct media_transport *transport,
> return bap->resume_id;
> }
>
> - id = bt_bap_stream_enable(bap->stream, bap->linked, NULL,
> - bap_enable_complete, owner);
> + id = bt_bap_stream_enable(bap->stream,
> + bap->desynchronized ? false : bap->linked,
> + NULL, bap_enable_complete, owner);
I guess this is the main change that makes everything work together.
We do have a single user `bt_bap_stream_enable(stream, false)` in
test-bap but that doesn't seem to match this test case. Perhaps we
should add a test case for it under test-bap, doesn't need to be in
this set though.
> if (!id)
> return 0;
>
> @@ -2161,7 +2239,7 @@ static void transport_bap_set_state(struct media_transport *transport,
> {
> struct bap_transport *bap = transport->data;
>
> - if (!bap->linked)
> + if (!bap->linked || bap->desynchronized)
> return;
>
> /* Update links */
> @@ -2540,10 +2618,11 @@ static void *transport_asha_init(struct media_transport *transport, void *data)
> #define TRANSPORT_OPS(_uuid, _props, _set_owner, _remove_owner, _init, \
> _resume, _suspend, _cancel, _set_state, _get_stream, \
> _get_volume, _set_volume, _set_delay, _update_links, \
> - _destroy) \
> + _destroy, _test_props) \
> { \
> .uuid = _uuid, \
> .properties = _props, \
> + .test_properties = _test_props, \
> .set_owner = _set_owner, \
> .remove_owner = _remove_owner, \
> .init = _init, \
> @@ -2565,26 +2644,28 @@ static void *transport_asha_init(struct media_transport *transport, void *data)
> transport_a2dp_resume, transport_a2dp_suspend, \
> transport_a2dp_cancel, NULL, \
> transport_a2dp_get_stream, transport_a2dp_get_volume, \
> - _set_volume, _set_delay, NULL, _destroy)
> + _set_volume, _set_delay, NULL, _destroy, NULL)
>
> #define BAP_OPS(_uuid, _props, _set_owner, _remove_owner, _update_links, \
> - _set_state) \
> + _set_state, _test_props) \
> TRANSPORT_OPS(_uuid, _props, _set_owner, _remove_owner,\
> transport_bap_init, \
> transport_bap_resume, transport_bap_suspend, \
> transport_bap_cancel, _set_state, \
> transport_bap_get_stream, transport_bap_get_volume, \
> transport_bap_set_volume, NULL, \
> - _update_links, transport_bap_destroy)
> + _update_links, transport_bap_destroy, _test_props)
>
> #define BAP_UC_OPS(_uuid) \
> BAP_OPS(_uuid, transport_bap_uc_properties, \
> transport_bap_set_owner, transport_bap_remove_owner, \
> - transport_bap_update_links_uc, transport_bap_set_state)
> + transport_bap_update_links_uc, \
> + transport_bap_set_state, \
> + transport_bap_uc_test_properties)
>
> #define BAP_BC_OPS(_uuid) \
> BAP_OPS(_uuid, transport_bap_bc_properties, NULL, NULL, \
> - transport_bap_update_links_bc, NULL)
> + transport_bap_update_links_bc, NULL, NULL)
>
> #define ASHA_OPS(_uuid) \
> TRANSPORT_OPS(_uuid, transport_asha_properties, NULL, NULL, \
> @@ -2592,7 +2673,7 @@ static void *transport_asha_init(struct media_transport *transport, void *data)
> transport_asha_resume, transport_asha_suspend, \
> transport_asha_cancel, NULL, NULL, \
> transport_asha_get_volume, transport_asha_set_volume, \
> - NULL, NULL, NULL)
> + NULL, NULL, NULL, NULL)
>
> static const struct media_transport_ops transport_ops[] = {
> #ifdef HAVE_A2DP
> @@ -2647,6 +2728,7 @@ struct media_transport *media_transport_create(struct btd_device *device,
> struct media_transport *transport;
> const struct media_transport_ops *ops;
> int fd;
> + const GDBusPropertyTable *properties;
>
> transport = g_new0(struct media_transport, 1);
> if (device)
> @@ -2701,9 +2783,14 @@ struct media_transport *media_transport_create(struct btd_device *device,
> goto fail;
> }
>
> + if (btd_opts.testing && ops->test_properties)
> + properties = ops->test_properties;
> + else
> + properties = ops->properties;
> +
> if (g_dbus_register_interface(btd_get_dbus_connection(),
> transport->path, MEDIA_TRANSPORT_INTERFACE,
> - transport_methods, NULL, ops->properties,
> + transport_methods, NULL, properties,
> transport, media_transport_free) == FALSE) {
> error("Could not register transport %s", transport->path);
> goto fail;
> --
> 2.43.0
>
>
--
Luiz Augusto von Dentz
^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: Add ability to desynchronized transports for PTS tests
2026-04-27 17:20 ` [PATCH BlueZ 1/3] audio: Add ability to desynchronized linked transport Frédéric Danis
2026-04-27 18:02 ` Luiz Augusto von Dentz
@ 2026-04-27 18:56 ` bluez.test.bot
1 sibling, 0 replies; 6+ messages in thread
From: bluez.test.bot @ 2026-04-27 18:56 UTC (permalink / raw)
To: linux-bluetooth, frederic.danis
[-- Attachment #1: Type: text/plain, Size: 1979 bytes --]
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=1086318
---Test result---
Test Summary:
CheckPatch FAIL 1.69 seconds
GitLint PASS 1.04 seconds
BuildEll PASS 20.25 seconds
BluezMake PASS 658.00 seconds
MakeCheck PASS 19.23 seconds
MakeDistcheck PASS 248.35 seconds
CheckValgrind PASS 297.60 seconds
CheckSmatch PASS 349.62 seconds
bluezmakeextell PASS 181.86 seconds
IncrementalBuild PASS 647.13 seconds
ScanBuild PASS 1011.48 seconds
Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,2/3] doc: Add documentation for CIS transport Desynchronized property
WARNING:BAD_SIGN_OFF: Non-standard signature: Assisted-by:
#73:
Assisted-by: GPT:GPT-5.3-Codex
ERROR:BAD_SIGN_OFF: Unrecognized email address: 'GPT:GPT-5.3-Codex'
#73:
Assisted-by: GPT:GPT-5.3-Codex
/github/workspace/src/patch/14541954.patch total: 1 errors, 1 warnings, 17 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
/github/workspace/src/patch/14541954.patch has style problems, please review.
NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
https://github.com/bluez/bluez/pull/2077
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-04-27 18:56 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-27 17:20 [PATCH BlueZ 0/3] Add ability to desynchronized transports for PTS tests Frédéric Danis
2026-04-27 17:20 ` [PATCH BlueZ 1/3] audio: Add ability to desynchronized linked transport Frédéric Danis
2026-04-27 18:02 ` Luiz Augusto von Dentz
2026-04-27 18:56 ` Add ability to desynchronized transports for PTS tests bluez.test.bot
2026-04-27 17:20 ` [PATCH BlueZ 2/3] doc: Add documentation for CIS transport Desynchronized property Frédéric Danis
2026-04-27 17:20 ` [PATCH BlueZ 3/3] client/player: Add support to desynchronize linked transports Frédéric Danis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox