Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ 0/8] client/btpclient: Add BAP/ASCS/PACS support for auto-pts BAP tests
@ 2026-09-04 13:51 Frédéric Danis
  2026-09-04 13:51 ` [PATCH BlueZ 1/8] client/btpclient: Add BTP_EV_BAP_ASE_FOUND support Frédéric Danis
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Frédéric Danis @ 2026-09-04 13:51 UTC (permalink / raw)
  To: linux-bluetooth

This series extends btpclient with support for the BAP, ASCS, and PACS
BTP services required to pass the auto-pts Basic Audio Profile test
suites (BAP/UCL/*, BAP/USR/*).

- Patch 1 adds BTP_EV_BAP_ASE_FOUND, needed by BAP/UCL/SCC/BV-004-C
  and BAP/UCL/SCC/BV-019-C.
- Patch 2 fetches Codec capabilities when replying to an ASE.
- Patch 3 introduces ASCS BTP support: audio endpoints are registered
  via the VENDOR service's ASCS setup command, and the
  SelectProperties() D-Bus reply is postponed until auto-pts has
  requested the ASE and PACS characteristic values, allowing
  BAP/UCL/SCC/* tests to pass.
- Patch 4 adds BTP_OP_PACS_SET_LOCATION support to store the expected
  location for a local endpoint.
- Patch 5 adds BTP_OP_BAP_SEND support.
- Patch 6 extends ASCS support to cover the BAP/UCL/STR/* tests.
- Patch 7 fixes CIG/CIS id assignment to be deferred and based on the
  Unicast Client/Server role, matching what auto-pts expects (0/0 for
  Client tests, 1/1 for Server tests) instead of eagerly assigning
  CIG 0 to every discovered ASE.
- Patch 8 adds automatic stream acquisition and data sending for the
  BAP/USR/STR/* tests.

Together these patches allow btpclient to pass the BAP/UCL and
BAP/USR auto-pts test suites.

Frédéric Danis (8):
  client/btpclient: Add BTP_EV_BAP_ASE_FOUND support
  client/btpclient: Get Codec capabilities on ASE reply
  client/btpclient: Add ASCS BTP support
  client/btpclient: Add BTP_OP_PACS_SET_LOCATION support
  client/btpclient: Add BTP_OP_BAP_SEND support
  client/btpclient: Add ASCS support for BAP/UCL/STR/* tests
  client/btpclient: Defer CIG/CIS assignment based on Client/Server role
  client/btpclient: Add stream auto acquire for BAP/USR/STR/* tests

 Makefile.tools               |    7 +-
 client/btpclient/ascs.c      | 1641 ++++++++++++++++++++++++++++++++++
 client/btpclient/ascs.h      |   21 +
 client/btpclient/bap.c       |  381 ++++++++
 client/btpclient/bap.h       |    4 +
 client/btpclient/btpclient.c |  194 +++-
 client/btpclient/btpclient.h |   36 +
 client/btpclient/core.c      |   75 +-
 client/btpclient/gap.c       |    3 -
 client/btpclient/pacs.c      |  107 +++
 client/btpclient/pacs.h      |   13 +
 client/btpclient/vendor.c    |  103 +++
 client/btpclient/vendor.h    |   13 +
 src/shared/btp.h             |  156 ++++
 14 files changed, 2744 insertions(+), 10 deletions(-)
 create mode 100644 client/btpclient/ascs.c
 create mode 100644 client/btpclient/ascs.h
 create mode 100644 client/btpclient/pacs.c
 create mode 100644 client/btpclient/pacs.h
 create mode 100644 client/btpclient/vendor.c
 create mode 100644 client/btpclient/vendor.h

-- 
2.43.0


^ permalink raw reply	[flat|nested] 11+ messages in thread
* [PATCH BlueZ v2 1/8] client/btpclient: Add BTP_EV_BAP_ASE_FOUND support
@ 2026-09-08 17:06 Frédéric Danis
  2026-09-08 17:59 ` client/btpclient: Add BAP/ASCS/PACS support for auto-pts BAP tests bluez.test.bot
  0 siblings, 1 reply; 11+ messages in thread
From: Frédéric Danis @ 2026-09-08 17:06 UTC (permalink / raw)
  To: linux-bluetooth

This is used at least for BAP/UCL/SCC/BV-004-C and BAP/UCL/SCC/BV-019-C
tests.
---
 client/btpclient/bap.c       | 109 +++++++++++++++++++++++++++++++++++
 client/btpclient/bap.h       |   2 +
 client/btpclient/btpclient.c |   6 ++
 client/btpclient/btpclient.h |   8 +++
 src/shared/btp.h             |  11 ++++
 5 files changed, 136 insertions(+)

diff --git a/client/btpclient/bap.c b/client/btpclient/bap.c
index 0302fc1c0..cdbae4ac2 100644
--- a/client/btpclient/bap.c
+++ b/client/btpclient/bap.c
@@ -96,6 +96,115 @@ failed:
 	btp_send_error(btp, BTP_BAP_SERVICE, index, status);
 }
 
+static void bap_charac_read_setup(struct l_dbus_message *message,
+							void *user_data)
+{
+	struct l_dbus_message_builder *builder;
+
+	builder = l_dbus_message_builder_new(message);
+	l_dbus_message_builder_enter_array(builder, "{sv}");
+	l_dbus_message_builder_enter_dict(builder, "sv");
+	l_dbus_message_builder_leave_dict(builder);
+	l_dbus_message_builder_leave_array(builder);
+	l_dbus_message_builder_finalize(builder);
+	l_dbus_message_builder_destroy(builder);
+}
+
+static void bap_read_ase_reply(struct l_dbus_proxy *proxy,
+						struct l_dbus_message *result,
+						void *user_data)
+{
+	struct btp_ase *ase = user_data;
+	struct btp_device *device = ase->device;
+	struct btp_adapter *adapter = find_adapter_by_device(device);
+	struct btp_bap_ase_found_ev *rp;
+	struct l_dbus_message_iter iter;
+	uint8_t *data;
+	uint32_t n;
+
+	if (l_dbus_message_is_error(result)) {
+		const char *name, *desc;
+
+		l_dbus_message_get_error(result, &name, &desc);
+		l_error("Failed to read value (%s), %s", name, desc);
+
+		btp_send_error(btp, BTP_BAP_SERVICE, adapter->index,
+							BTP_ERROR_FAIL);
+		return;
+	}
+
+	if (!l_dbus_message_get_arguments(result, "ay", &iter))
+		goto failed;
+
+	if (!l_dbus_message_iter_get_fixed_array(&iter, &data, &n)) {
+		l_debug("Cannot read value");
+		goto failed;
+	}
+
+	ase->ase_id = data[0];
+
+	rp = l_new(struct btp_bap_ase_found_ev, 1);
+	rp->address_type = device->address_type;
+	rp->address = device->address;
+	rp->dir = ase->dir;
+	rp->ase_id = data[0];
+
+	btp_send(btp, BTP_BAP_SERVICE, BTP_EV_BAP_ASE_FOUND, adapter->index,
+				sizeof(struct btp_bap_ase_found_ev), rp);
+
+	free(rp);
+
+	return;
+
+failed:
+	btp_send_error(btp, BTP_BAP_SERVICE, adapter->index, BTP_ERROR_FAIL);
+}
+
+void bap_proxy_added(struct l_dbus_proxy *proxy, void *user_data)
+{
+	struct btp_device *device = user_data;
+	const char *interface = l_dbus_proxy_get_interface(proxy);
+
+	if (!strcmp(interface, "org.bluez.GattCharacteristic1")) {
+		char *str, str_uuid[MAX_LEN_UUID_STR];
+		bt_uuid_t uuid;
+		struct btp_ase *ase;
+
+		if (!l_dbus_proxy_get_property(proxy, "UUID", "s", &str))
+			return;
+
+		bt_uuid16_create(&uuid, ASE_SINK_UUID);
+		bt_uuid_to_string(&uuid, str_uuid, MAX_LEN_UUID_STR);
+		if (!bt_uuid_strcmp(str, str_uuid)) {
+			ase = l_new(struct btp_ase, 1);
+			ase->device = device;
+			ase->dir = BTP_BAP_DIR_SINK;
+			ase->uuid = uuid;
+			l_queue_push_tail(device->ases, ase);
+
+			l_dbus_proxy_method_call(proxy, "ReadValue",
+						bap_charac_read_setup,
+						bap_read_ase_reply,
+						ase, NULL);
+		}
+
+		bt_uuid16_create(&uuid, ASE_SOURCE_UUID);
+		bt_uuid_to_string(&uuid, str_uuid, MAX_LEN_UUID_STR);
+		if (!bt_uuid_strcmp(str, str_uuid)) {
+			ase = l_new(struct btp_ase, 1);
+			ase->device = device;
+			ase->dir = BTP_BAP_DIR_SOURCE;
+			ase->uuid = uuid;
+			l_queue_push_tail(device->ases, ase);
+
+			l_dbus_proxy_method_call(proxy, "ReadValue",
+						bap_charac_read_setup,
+						bap_read_ase_reply,
+						ase, NULL);
+		}
+	}
+}
+
 bool bap_register_service(struct btp *btp_, struct l_dbus *dbus_,
 					struct l_dbus_client *client)
 {
diff --git a/client/btpclient/bap.h b/client/btpclient/bap.h
index 2b7a218b5..7fea19f8b 100644
--- a/client/btpclient/bap.h
+++ b/client/btpclient/bap.h
@@ -11,3 +11,5 @@ bool bap_register_service(struct btp *btp_, struct l_dbus *dbus_,
 					struct l_dbus_client *client);
 void bap_unregister_service(struct btp *btp);
 bool bap_is_service_registered(void);
+
+void bap_proxy_added(struct l_dbus_proxy *proxy, void *user_data);
diff --git a/client/btpclient/btpclient.c b/client/btpclient/btpclient.c
index 0d124bc7a..c0aa13287 100644
--- a/client/btpclient/btpclient.c
+++ b/client/btpclient/btpclient.c
@@ -25,6 +25,7 @@
 #include "bluetooth/uuid.h"
 #include "src/shared/btp.h"
 #include "btpclient.h"
+#include "bap.h"
 #include "core.h"
 #include "gap.h"
 #include "gatt.h"
@@ -347,6 +348,7 @@ static void signal_handler(uint32_t signo, void *user_data)
 
 static void btp_device_free(struct btp_device *device)
 {
+	l_queue_destroy(device->ases, l_free);
 	l_queue_destroy(device->services, l_free);
 	l_queue_destroy(device->characteristics, l_free);
 	l_queue_destroy(device->descriptors, l_free);
@@ -444,6 +446,7 @@ static void proxy_added(struct l_dbus_proxy *proxy, void *user_data)
 		device->services = l_queue_new();
 		device->characteristics = l_queue_new();
 		device->descriptors = l_queue_new();
+		device->ases = l_queue_new();
 
 		l_queue_push_tail(adapter->devices, device);
 
@@ -545,6 +548,9 @@ static void proxy_added(struct l_dbus_proxy *proxy, void *user_data)
 		}
 
 		l_queue_push_tail(device->characteristics, attribute);
+
+		if (bap_is_service_registered())
+			bap_proxy_added(proxy, device);
 	}
 
 	if (!strcmp(interface, "org.bluez.GattDescriptor1")) {
diff --git a/client/btpclient/btpclient.h b/client/btpclient/btpclient.h
index 8a5ea2172..74ca7278c 100644
--- a/client/btpclient/btpclient.h
+++ b/client/btpclient/btpclient.h
@@ -26,6 +26,14 @@ struct btp_device {
 	struct l_queue *services;
 	struct l_queue *characteristics;
 	struct l_queue *descriptors;
+	struct l_queue *ases;
+};
+
+struct btp_ase {
+	struct btp_device *device;
+	bt_uuid_t uuid;
+	uint8_t dir;
+	uint8_t ase_id;
 };
 
 struct btp_agent {
diff --git a/src/shared/btp.h b/src/shared/btp.h
index 5590bb51f..9757301f2 100644
--- a/src/shared/btp.h
+++ b/src/shared/btp.h
@@ -425,6 +425,9 @@ struct btp_gatt_write_rp {
 	uint8_t att_response;
 } __packed;
 
+#define BTP_BAP_DIR_SINK			0x01
+#define BTP_BAP_DIR_SOURCE			0x02
+
 #define BTP_OP_BAP_READ_SUPPORTED_COMMANDS	0x01
 
 #define BTP_OP_BAP_DISCOVER			0x02
@@ -440,6 +443,14 @@ struct btp_bap_discovery_completed_ev {
 	uint8_t status;
 } __packed;
 
+#define BTP_EV_BAP_ASE_FOUND			0x82
+struct btp_bap_ase_found_ev {
+	uint8_t address_type;
+	bdaddr_t address;
+	uint8_t dir;
+	uint8_t ase_id;
+} __packed;
+
 struct btp;
 
 typedef void (*btp_destroy_func_t)(void *user_data);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-09-08 17:59 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04 13:51 [PATCH BlueZ 0/8] client/btpclient: Add BAP/ASCS/PACS support for auto-pts BAP tests Frédéric Danis
2026-09-04 13:51 ` [PATCH BlueZ 1/8] client/btpclient: Add BTP_EV_BAP_ASE_FOUND support Frédéric Danis
2026-09-04 17:38   ` client/btpclient: Add BAP/ASCS/PACS support for auto-pts BAP tests bluez.test.bot
2026-09-04 13:51 ` [PATCH BlueZ 2/8] client/btpclient: Get Codec capabilities on ASE reply Frédéric Danis
2026-09-04 13:51 ` [PATCH BlueZ 3/8] client/btpclient: Add ASCS BTP support Frédéric Danis
2026-09-04 13:51 ` [PATCH BlueZ 4/8] client/btpclient: Add BTP_OP_PACS_SET_LOCATION support Frédéric Danis
2026-09-04 13:51 ` [PATCH BlueZ 5/8] client/btpclient: Add BTP_OP_BAP_SEND support Frédéric Danis
2026-09-04 13:51 ` [PATCH BlueZ 6/8] client/btpclient: Add ASCS support for BAP/UCL/STR/* tests Frédéric Danis
2026-09-04 13:51 ` [PATCH BlueZ 7/8] client/btpclient: Defer CIG/CIS assignment based on Client/Server role Frédéric Danis
2026-09-04 13:51 ` [PATCH BlueZ 8/8] client/btpclient: Add stream auto acquire for BAP/USR/STR/* tests Frédéric Danis
  -- strict thread matches above, loose matches on Subject: below --
2026-09-08 17:06 [PATCH BlueZ v2 1/8] client/btpclient: Add BTP_EV_BAP_ASE_FOUND support Frédéric Danis
2026-09-08 17:59 ` client/btpclient: Add BAP/ASCS/PACS support for auto-pts BAP tests bluez.test.bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox