Thread (10 messages) flat view 10 messages, 2 authors, 4d ago
COOLING4d

Revision v3 of 3 in this series.

Revisions (3)
  1. v1 [diff vs current]
  2. v2 [diff vs current]
  3. v3 current

[PATCH BlueZ v3 2/8] client/btpclient: Get Codec capabilities on ASE reply

From: Frédéric Danis <hidden>
Date: 2026-09-10 08:49:25
Subsystem: the rest · Maintainer: Linus Torvalds

---
 Makefile.tools         |  2 +-
 client/btpclient/bap.c | 94 ++++++++++++++++++++++++++++++++++++++++--
 src/shared/btp.h       | 12 ++++++
 3 files changed, 104 insertions(+), 4 deletions(-)
diff --git a/Makefile.tools b/Makefile.tools
index 4c97d990a..41473d63f 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -567,7 +567,7 @@ noinst_PROGRAMS += client/btpclient/btpclient client/btpclient/btpclientctl
 
 client_btpclient_btpclient_SOURCES = client/btpclient/btpclient.c \
 				client/btpclient/btpclient.h \
-				src/shared/btp.c src/shared/btp.h \
+				src/shared/btp.c src/shared/btp.h src/shared/bap-defs.h \
 				client/btpclient/bap.c client/btpclient/bap.h \
 				client/btpclient/core.c client/btpclient/core.h \
 				client/btpclient/gap.c client/btpclient/gap.h \
diff --git a/client/btpclient/bap.c b/client/btpclient/bap.c
index cdbae4ac2..d30d931f1 100644
--- a/client/btpclient/bap.c
+++ b/client/btpclient/bap.c
@@ -17,6 +17,7 @@
 
 #include "bluetooth/bluetooth.h"
 #include "bluetooth/uuid.h"
+#include "src/shared/bap-defs.h"
 #include "src/shared/btp.h"
 #include "btpclient.h"
 #include "bap.h"
@@ -59,6 +60,13 @@ failed:
 	btp_send_error(btp, BTP_BAP_SERVICE, index, BTP_ERROR_FAIL);
 }
 
+static bool match_attribute_uuid(const void *attr, const void *uuid)
+{
+	const struct gatt_attribute *attribute = attr;
+
+	return !bt_uuid_cmp(&attribute->uuid, uuid);
+}
+
 static void btp_bap_discover(uint8_t index, const void *param, uint16_t length,
 								void *user_data)
 {
@@ -110,17 +118,17 @@ static void bap_charac_read_setup(struct l_dbus_message *message,
 	l_dbus_message_builder_destroy(builder);
 }
 
-static void bap_read_ase_reply(struct l_dbus_proxy *proxy,
+static void bap_read_pac_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 btp_bap_codec_cap_found_ev *rp;
 	struct l_dbus_message_iter iter;
 	uint8_t *data;
-	uint32_t n;
+	uint32_t n, i, capa_length;
 
 	if (l_dbus_message_is_error(result)) {
 		const char *name, *desc;
@@ -141,6 +149,73 @@ static void bap_read_ase_reply(struct l_dbus_proxy *proxy,
 		goto failed;
 	}
 
+	rp = l_new(struct btp_bap_codec_cap_found_ev, 1);
+	rp->address_type = device->address_type;
+	rp->address = device->address;
+	rp->dir = ase->dir;
+	rp->coding_format = data[1];
+	capa_length = data[6];
+	i = 0;
+	while (i < capa_length) {
+		struct bt_ltv *ltv = (struct bt_ltv *)(data + i + 7);
+
+		if ((i + ltv->len >= capa_length) || (!ltv->len))
+			goto failed;
+
+		if (ltv->type == 0x01)
+			rp->frequencies = bt_get_le16(ltv->value);
+		else if (ltv->type == 0x02)
+			rp->frame_durations = ltv->value[0];
+		else if (ltv->type == 0x03)
+			rp->channel_counts = ltv->value[0];
+		else if (ltv->type == 0x04)
+			rp->octets_per_frame = bt_get_le32(ltv->value);
+
+		i += ltv->len + 1;
+	}
+
+	btp_send(btp, BTP_BAP_SERVICE, BTP_BAP_EV_CODEC_CAP_FOUND,
+		adapter->index, sizeof(struct btp_bap_codec_cap_found_ev), rp);
+
+	free(rp);
+
+	return;
+
+failed:
+	btp_send_error(btp, BTP_BAP_SERVICE, adapter->index, BTP_ERROR_FAIL);
+}
+
+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;
+	bt_uuid_t uuid;
+	struct gatt_attribute *attribute;
+
+	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);
+
+		goto failed;
+	}
+
+	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);
@@ -154,6 +229,19 @@ static void bap_read_ase_reply(struct l_dbus_proxy *proxy,
 
 	free(rp);
 
+	if (bt_uuid16_cmp(&ase->uuid, ASE_SINK_UUID))
+		bt_uuid16_create(&uuid, PAC_SINK_CHRC_UUID);
+	else
+		bt_uuid16_create(&uuid, PAC_SOURCE_CHRC_UUID);
+	attribute = l_queue_find(device->characteristics,
+						match_attribute_uuid, &uuid);
+	if (!attribute)
+		goto failed;
+
+	l_dbus_proxy_method_call(attribute->proxy, "ReadValue",
+				bap_charac_read_setup, bap_read_pac_reply,
+				ase, NULL);
+
 	return;
 
 failed:
diff --git a/src/shared/btp.h b/src/shared/btp.h
index 9757301f2..100308de1 100644
--- a/src/shared/btp.h
+++ b/src/shared/btp.h
@@ -443,6 +443,18 @@ struct btp_bap_discovery_completed_ev {
 	uint8_t status;
 } __packed;
 
+#define BTP_BAP_EV_CODEC_CAP_FOUND		0x81
+struct btp_bap_codec_cap_found_ev {
+	uint8_t address_type;
+	bdaddr_t address;
+	uint8_t dir;
+	uint8_t coding_format;
+	uint16_t frequencies;
+	uint8_t frame_durations;
+	uint32_t octets_per_frame;
+	uint8_t channel_counts;
+} __packed;
+
 #define BTP_EV_BAP_ASE_FOUND			0x82
 struct btp_bap_ase_found_ev {
 	uint8_t address_type;
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help