* [PATCH BlueZ v1 2/3] shared/bap: Move LTV type defines to bap-defs.h
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
2026-10-28 13:55 ` [PATCH BlueZ v1 3/3] shared/bap: Accept all defined metadata types Luiz Augusto von Dentz
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2026-10-28 13:55 UTC (permalink / raw)
To: linux-bluetooth
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
^ permalink raw reply related [flat|nested] 5+ messages in thread