Linux bluetooth development
 help / color / mirror / Atom feed
From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ v1 2/3] shared/bap: Move LTV type defines to bap-defs.h
Date: Wed, 28 Oct 2026 09:55:16 -0400	[thread overview]
Message-ID: <20261028135517.2395290-2-luiz.dentz@gmail.com> (raw)
In-Reply-To: <20261028135517.2395290-1-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Replace the BAP_*_LTV_TYPE defines private to bap.c with BT_BAP_CAP_*,
BT_BAP_CC_* and BT_BAP_META_* in bap-defs.h, covering every type in
Assigned Numbers 6.12.4, 6.12.5 and 6.12.6, and use them in the
bap-debug.c LTV tables.

Add bap-debug.c decoders for the metadata types that had none: CCID_List,
Parental_Rating, Program_Info_URI, Audio_Active_State,
Broadcast_Audio_Immediate_Rendering_Flag, Assisted_Listening_Stream,
Broadcast_Name, Extended_Metadata and Vendor_Specific.

Assisted-by: OpenCode:claude-opus-5.5
---
 src/shared/bap-debug.c | 209 ++++++++++++++++++++++++++++++++++++++---
 src/shared/bap-defs.h  |  52 ++++++++++
 src/shared/bap.c       |  33 +++----
 3 files changed, 259 insertions(+), 35 deletions(-)

diff --git a/src/shared/bap-debug.c b/src/shared/bap-debug.c
index 495a22c44126..47a574d41d6c 100644
--- a/src/shared/bap-debug.c
+++ b/src/shared/bap-debug.c
@@ -15,6 +15,7 @@
 #include <errno.h>
 
 #include "src/shared/util.h"
+#include "src/shared/bap-defs.h"
 #include "src/shared/bap-debug.h"
 
 static const struct util_bit_debugger pac_freq_table[] = {
@@ -185,11 +186,11 @@ done:
 }
 
 static const struct util_ltv_debugger pac_cap_table[] = {
-	UTIL_LTV_DEBUG(0x01, pac_debug_freq),
-	UTIL_LTV_DEBUG(0x02, pac_debug_duration),
-	UTIL_LTV_DEBUG(0x03, pac_debug_channels),
-	UTIL_LTV_DEBUG(0x04, pac_debug_frame_length),
-	UTIL_LTV_DEBUG(0x05, pac_debug_sdu)
+	UTIL_LTV_DEBUG(BT_BAP_CAP_FREQ, pac_debug_freq),
+	UTIL_LTV_DEBUG(BT_BAP_CAP_DURATION, pac_debug_duration),
+	UTIL_LTV_DEBUG(BT_BAP_CAP_CHANNELS, pac_debug_channels),
+	UTIL_LTV_DEBUG(BT_BAP_CAP_FRAME_LENGTH, pac_debug_frame_length),
+	UTIL_LTV_DEBUG(BT_BAP_CAP_SDU, pac_debug_sdu)
 };
 
 bool bt_bap_debug_caps(void *data, size_t len, util_debug_func_t func,
@@ -414,11 +415,11 @@ done:
 }
 
 static const struct util_ltv_debugger ase_cc_table[] = {
-	UTIL_LTV_DEBUG(0x01, ase_debug_freq),
-	UTIL_LTV_DEBUG(0x02, ase_debug_duration),
-	UTIL_LTV_DEBUG(0x03, ase_debug_location),
-	UTIL_LTV_DEBUG(0x04, ase_debug_frame_length),
-	UTIL_LTV_DEBUG(0x05, ase_debug_blocks)
+	UTIL_LTV_DEBUG(BT_BAP_CC_FREQ, ase_debug_freq),
+	UTIL_LTV_DEBUG(BT_BAP_CC_DURATION, ase_debug_duration),
+	UTIL_LTV_DEBUG(BT_BAP_CC_LOCATION, ase_debug_location),
+	UTIL_LTV_DEBUG(BT_BAP_CC_FRAME_LENGTH, ase_debug_frame_length),
+	UTIL_LTV_DEBUG(BT_BAP_CC_SDU, ase_debug_blocks)
 };
 
 bool bt_bap_debug_config(void *data, size_t len, util_debug_func_t func,
@@ -527,11 +528,191 @@ done:
 				user_data);
 }
 
+static void debug_string(const char *label, const uint8_t *data,
+				uint8_t len, util_debug_func_t func,
+				void *user_data)
+{
+	util_debug(func, user_data, "%s: %.*s", label, len, (const char *)data);
+}
+
+static void ase_debug_ccid_list(const uint8_t *data, uint8_t len,
+				util_debug_func_t func, void *user_data)
+{
+	uint8_t i;
+
+	util_debug(func, user_data, "CCID List: %u entries", len);
+
+	for (i = 0; i < len; i++)
+		util_debug(func, user_data, "\tCCID: %u", data[i]);
+}
+
+static void ase_debug_parental_rating(const uint8_t *data, uint8_t len,
+				util_debug_func_t func, void *user_data)
+{
+	struct iovec frame = { (void *)data, len };
+	uint8_t value;
+
+	if (!util_iov_pull_u8(&frame, &value)) {
+		util_debug(func, user_data, "value: invalid size");
+		goto done;
+	}
+
+	switch (value & 0x0f) {
+	case 0x00:
+		util_debug(func, user_data,
+				"Parental Rating: No rating (0x%2.2x)", value);
+		break;
+	case 0x01:
+		util_debug(func, user_data,
+				"Parental Rating: Any age (0x%2.2x)", value);
+		break;
+	default:
+		util_debug(func, user_data,
+				"Parental Rating: Age %u or older (0x%2.2x)",
+				(value & 0x0f) + 3, value);
+		break;
+	}
+
+done:
+	if (frame.iov_len)
+		util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+				user_data);
+}
+
+static void ase_debug_program_info_uri(const uint8_t *data, uint8_t len,
+				util_debug_func_t func, void *user_data)
+{
+	debug_string("Program Info URI", data, len, func, user_data);
+}
+
+static void ase_debug_audio_active_state(const uint8_t *data, uint8_t len,
+				util_debug_func_t func, void *user_data)
+{
+	struct iovec frame = { (void *)data, len };
+	uint8_t value;
+
+	if (!util_iov_pull_u8(&frame, &value)) {
+		util_debug(func, user_data, "value: invalid size");
+		goto done;
+	}
+
+	switch (value) {
+	case 0x00:
+		util_debug(func, user_data,
+				"Audio Active State: No audio data (0x00)");
+		break;
+	case 0x01:
+		util_debug(func, user_data,
+				"Audio Active State: Audio data (0x01)");
+		break;
+	default:
+		util_debug(func, user_data,
+				"Audio Active State: RFU (0x%2.2x)", value);
+		break;
+	}
+
+done:
+	if (frame.iov_len)
+		util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+				user_data);
+}
+
+static void ase_debug_bcast_immediate(const uint8_t *data, uint8_t len,
+				util_debug_func_t func, void *user_data)
+{
+	util_debug(func, user_data, "Broadcast Audio Immediate Rendering");
+
+	if (len)
+		util_hexdump(' ', data, len, func, user_data);
+}
+
+static void ase_debug_assisted_listening(const uint8_t *data, uint8_t len,
+				util_debug_func_t func, void *user_data)
+{
+	struct iovec frame = { (void *)data, len };
+	uint8_t value;
+
+	if (!util_iov_pull_u8(&frame, &value)) {
+		util_debug(func, user_data, "value: invalid size");
+		goto done;
+	}
+
+	if (value == 0x00)
+		util_debug(func, user_data, "Assisted Listening Stream: "
+				"Unspecified audio enhancement (0x00)");
+	else
+		util_debug(func, user_data,
+				"Assisted Listening Stream: RFU (0x%2.2x)",
+				value);
+
+done:
+	if (frame.iov_len)
+		util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+				user_data);
+}
+
+static void ase_debug_broadcast_name(const uint8_t *data, uint8_t len,
+				util_debug_func_t func, void *user_data)
+{
+	debug_string("Broadcast Name", data, len, func, user_data);
+}
+
+static void ase_debug_extended(const uint8_t *data, uint8_t len,
+				util_debug_func_t func, void *user_data)
+{
+	struct iovec frame = { (void *)data, len };
+	uint16_t value;
+
+	if (!util_iov_pull_le16(&frame, &value)) {
+		util_debug(func, user_data, "value: invalid size");
+		goto done;
+	}
+
+	util_debug(func, user_data, "Extended Metadata Type: 0x%4.4x", value);
+
+done:
+	if (frame.iov_len)
+		util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+				user_data);
+}
+
+static void ase_debug_vendor(const uint8_t *data, uint8_t len,
+				util_debug_func_t func, void *user_data)
+{
+	struct iovec frame = { (void *)data, len };
+	uint16_t value;
+
+	if (!util_iov_pull_le16(&frame, &value)) {
+		util_debug(func, user_data, "value: invalid size");
+		goto done;
+	}
+
+	util_debug(func, user_data, "Company ID: 0x%4.4x", value);
+
+done:
+	if (frame.iov_len)
+		util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+				user_data);
+}
+
 static const struct util_ltv_debugger ase_metadata_table[] = {
-	UTIL_LTV_DEBUG(0x01, ase_debug_preferred_context),
-	UTIL_LTV_DEBUG(0x02, ase_debug_context),
-	UTIL_LTV_DEBUG(0x03, ase_debug_program_info),
-	UTIL_LTV_DEBUG(0x04, ase_debug_language)
+	UTIL_LTV_DEBUG(BT_BAP_META_PREFERRED_CONTEXT,
+					ase_debug_preferred_context),
+	UTIL_LTV_DEBUG(BT_BAP_META_CONTEXT, ase_debug_context),
+	UTIL_LTV_DEBUG(BT_BAP_META_PROGRAM_INFO, ase_debug_program_info),
+	UTIL_LTV_DEBUG(BT_BAP_META_LANGUAGE, ase_debug_language),
+	UTIL_LTV_DEBUG(BT_BAP_META_CCID_LIST, ase_debug_ccid_list),
+	UTIL_LTV_DEBUG(BT_BAP_META_PARENTAL_RATING, ase_debug_parental_rating),
+	UTIL_LTV_DEBUG(BT_BAP_META_PROGRAM_INFO_URI,
+					ase_debug_program_info_uri),
+	UTIL_LTV_DEBUG(BT_BAP_META_AUDIO_ACTIVE_STATE,
+					ase_debug_audio_active_state),
+	UTIL_LTV_DEBUG(BT_BAP_META_BCAST_IMMEDIATE, ase_debug_bcast_immediate),
+	UTIL_LTV_DEBUG(BT_BAP_META_ASSISTED_LISTENING,
+					ase_debug_assisted_listening),
+	UTIL_LTV_DEBUG(BT_BAP_META_BROADCAST_NAME, ase_debug_broadcast_name),
+	UTIL_LTV_DEBUG(BT_BAP_META_EXTENDED, ase_debug_extended),
+	UTIL_LTV_DEBUG(BT_BAP_META_VENDOR, ase_debug_vendor)
 };
 
 bool bt_bap_debug_metadata(void *data, size_t len, util_debug_func_t func,
diff --git a/src/shared/bap-defs.h b/src/shared/bap-defs.h
index e5c2accb99f7..d232c21410c1 100644
--- a/src/shared/bap-defs.h
+++ b/src/shared/bap-defs.h
@@ -39,6 +39,58 @@
 #define BT_BAP_CONFIG_PHY_2M		BIT(1)
 #define BT_BAP_CONFIG_PHY_CODEC		BIT(2)
 
+/* Assigned Numbers 6.12.4 Codec_Specific_Capabilities LTV structures */
+/* Supported_Sampling_Frequencies */
+#define BT_BAP_CAP_FREQ			0x01
+/* Supported_Frame_Durations */
+#define BT_BAP_CAP_DURATION		0x02
+/* Supported_Audio_Channel_Counts */
+#define BT_BAP_CAP_CHANNELS		0x03
+/* Supported_Octets_Per_Codec_Frame */
+#define BT_BAP_CAP_FRAME_LENGTH		0x04
+/* Supported_Max_Codec_Frames_Per_SDU */
+#define BT_BAP_CAP_SDU			0x05
+
+/* Assigned Numbers 6.12.5 Codec_Specific_Configuration LTV structures */
+/* Sampling_Frequency */
+#define BT_BAP_CC_FREQ			0x01
+/* Frame_Duration */
+#define BT_BAP_CC_DURATION		0x02
+/* Audio_Channel_Allocation */
+#define BT_BAP_CC_LOCATION		0x03
+/* Octets_Per_Codec_Frame */
+#define BT_BAP_CC_FRAME_LENGTH		0x04
+/* Codec_Frame_Blocks_Per_SDU */
+#define BT_BAP_CC_SDU			0x05
+
+/* Assigned Numbers 6.12.6 Metadata LTV structures */
+/* Preferred_Audio_Contexts */
+#define BT_BAP_META_PREFERRED_CONTEXT	0x01
+/* Streaming_Audio_Contexts */
+#define BT_BAP_META_CONTEXT		0x02
+/* Program_Info */
+#define BT_BAP_META_PROGRAM_INFO	0x03
+/* Language */
+#define BT_BAP_META_LANGUAGE		0x04
+/* CCID_List */
+#define BT_BAP_META_CCID_LIST		0x05
+/* Parental_Rating */
+#define BT_BAP_META_PARENTAL_RATING	0x06
+/* Program_Info_URI */
+#define BT_BAP_META_PROGRAM_INFO_URI	0x07
+/* Audio_Active_State */
+#define BT_BAP_META_AUDIO_ACTIVE_STATE	0x08
+/* Broadcast_Audio_Immediate_Rendering_Flag */
+#define BT_BAP_META_BCAST_IMMEDIATE	0x09
+/* Assisted_Listening_Stream */
+#define BT_BAP_META_ASSISTED_LISTENING	0x0a
+/* Broadcast_Name */
+#define BT_BAP_META_BROADCAST_NAME	0x0b
+/* Extended_Metadata */
+#define BT_BAP_META_EXTENDED		0xfe
+/* Vendor_Specific */
+#define BT_BAP_META_VENDOR		0xff
+
 struct bt_bap_codec {
 	uint8_t  id;
 	uint16_t cid;
diff --git a/src/shared/bap.c b/src/shared/bap.c
index a6f5494e2985..d1836afc9ad2 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -49,19 +49,10 @@
 
 #define BAP_PROCESS_TIMEOUT 10
 
-#define BAP_FREQ_LTV_TYPE 1
-#define BAP_DURATION_LTV_TYPE 2
-#define BAP_CHANNEL_ALLOCATION_LTV_TYPE 3
-#define BAP_FRAME_LEN_LTV_TYPE 4
 #define CODEC_SPECIFIC_CONFIGURATION_MASK (\
-		(1<<BAP_FREQ_LTV_TYPE)|\
-		(1<<BAP_DURATION_LTV_TYPE)|\
-		(1<<BAP_FRAME_LEN_LTV_TYPE))
-
-#define BAP_METADATA_PREF_CONTEXT_LTV_TYPE	0x01
-#define BAP_METADATA_CONTEXT_LTV_TYPE		0x02
-#define BAP_METADATA_PROGRAM_INFO_LTV_TYPE	0x03
-#define BAP_METADATA_LANGUAGE_LTV_TYPE		0x04
+		(1<<BT_BAP_CC_FREQ)|\
+		(1<<BT_BAP_CC_DURATION)|\
+		(1<<BT_BAP_CC_FRAME_LENGTH))
 
 struct bt_bap_pac_changed {
 	unsigned int id;
@@ -2569,7 +2560,7 @@ static void bap_sink_get_allocation(size_t i, uint8_t l, uint8_t t,
 
 static unsigned int bap_bcast_get_location(struct bt_bap_stream *stream)
 {
-	uint8_t type = BAP_CHANNEL_ALLOCATION_LTV_TYPE;
+	uint8_t type = BT_BAP_CC_LOCATION;
 	uint32_t allocation = 0;
 	struct iovec *caps;
 
@@ -3432,9 +3423,9 @@ static void bap_metadata_process(size_t i, uint8_t l, uint8_t t, uint8_t *v,
 	uint16_t context;
 
 	switch (t) {
-	case BAP_METADATA_PREF_CONTEXT_LTV_TYPE:
+	case BT_BAP_META_PREFERRED_CONTEXT:
 		break;
-	case BAP_METADATA_CONTEXT_LTV_TYPE:
+	case BT_BAP_META_CONTEXT:
 		if (l != sizeof(context)) {
 			ascs_ase_rsp_add(data->rsp, data->ep->id,
 					BT_ASCS_RSP_METADATA_INVALID, t);
@@ -3450,8 +3441,8 @@ static void bap_metadata_process(size_t i, uint8_t l, uint8_t t, uint8_t *v,
 		}
 
 		break;
-	case BAP_METADATA_PROGRAM_INFO_LTV_TYPE:
-	case BAP_METADATA_LANGUAGE_LTV_TYPE:
+	case BT_BAP_META_PROGRAM_INFO:
+	case BT_BAP_META_LANGUAGE:
 		break;
 	default:
 		ascs_ase_rsp_add(data->rsp, data->ep->id,
@@ -7649,17 +7640,17 @@ static void check_pac_caps_ltv(size_t i, uint8_t l, uint8_t t, uint8_t *v,
 	uint16_t frame_len;
 
 	switch (t) {
-	case BAP_FREQ_LTV_TYPE:
+	case BT_BAP_CAP_FREQ:
 		mask = get_le16(v);
 
 		if (mask & (1 << (bis_v[0] - 1)))
 			compare_data->data32 |= 1<<t;
 		break;
-	case BAP_DURATION_LTV_TYPE:
+	case BT_BAP_CAP_DURATION:
 		if ((v[0]) & (1 << bis_v[0]))
 			compare_data->data32 |= 1<<t;
 		break;
-	case BAP_FRAME_LEN_LTV_TYPE:
+	case BT_BAP_CAP_FRAME_LENGTH:
 		min = get_le16(v);
 		max = get_le16(v + 2);
 		frame_len = get_le16(bis_v);
@@ -7798,7 +7789,7 @@ static struct bt_ltv_match bap_check_bis(uint32_t sink_loc, struct queue *pacs,
 	compare_data.found = true;
 
 	if (sink_loc) {
-		uint8_t type = BAP_CHANNEL_ALLOCATION_LTV_TYPE;
+		uint8_t type = BT_BAP_CC_LOCATION;
 
 		compare_data.data32 = sink_loc;
 		util_ltv_foreach(bis_data->iov_base, bis_data->iov_len, &type,
-- 
2.56.0


  reply	other threads:[~2026-10-28 13:55 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-28 13:55 [PATCH BlueZ v1 1/3] shared/bap: Fix line over 80 columns in set_base_subgroup Luiz Augusto von Dentz
2026-10-28 13:55 ` Luiz Augusto von Dentz [this message]
2026-10-28 13:55 ` [PATCH BlueZ v1 3/3] shared/bap: Accept all defined metadata types Luiz Augusto von Dentz
2026-10-28 16:19 ` [BlueZ,v1,1/3] shared/bap: Fix line over 80 columns in set_base_subgroup bluez.test.bot
2026-10-28 19:50 ` [PATCH BlueZ v1 1/3] " patchwork-bot+bluetooth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261028135517.2395290-2-luiz.dentz@gmail.com \
    --to=luiz.dentz@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox