* [PATCH BlueZ v2 2/4] monitor: Make use of util_debug_tlv to decode TLV entries
2023-10-20 18:08 [PATCH BlueZ v2 1/4] shared/util: Add util_debug_{tlv, bit} helpers Luiz Augusto von Dentz
@ 2023-10-20 18:08 ` Luiz Augusto von Dentz
2023-10-20 18:08 ` [PATCH BlueZ v2 3/4] shared/bap: Add debug helpers Luiz Augusto von Dentz
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2023-10-20 18:08 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This uses util_debug_tlv to decode TLV entries.
---
monitor/att.c | 101 +++++++++++++++++++++++++++++------------------
monitor/packet.c | 81 ++++++-------------------------------
monitor/packet.h | 14 -------
3 files changed, 75 insertions(+), 121 deletions(-)
diff --git a/monitor/att.c b/monitor/att.c
index 0e12ee352078..39ea5d6dac5a 100644
--- a/monitor/att.c
+++ b/monitor/att.c
@@ -675,8 +675,15 @@ static bool print_ase_codec(const struct l2cap_frame *frame)
return true;
}
+static void print_ltv(const char *str, void *user_data)
+{
+ const char *label = user_data;
+
+ print_field("%s: %s", label, str);
+}
+
static bool print_ase_lv(const struct l2cap_frame *frame, const char *label,
- struct packet_ltv_decoder *decoder, size_t decoder_len)
+ struct util_ltv_debugger *decoder, size_t decoder_len)
{
struct bt_hci_lv_data *lv;
@@ -691,13 +698,14 @@ static bool print_ase_lv(const struct l2cap_frame *frame, const char *label,
return false;
}
- packet_print_ltv(label, lv->data, lv->len, decoder, decoder_len);
+ util_debug_ltv(lv->data, lv->len, decoder, decoder_len, print_ltv,
+ (void *) label);
return true;
}
static bool print_ase_cc(const struct l2cap_frame *frame, const char *label,
- struct packet_ltv_decoder *decoder, size_t decoder_len)
+ struct util_ltv_debugger *decoder, size_t decoder_len)
{
return print_ase_lv(frame, label, decoder, decoder_len);
}
@@ -744,7 +752,8 @@ done:
print_hex_field(" Data", frame->data, frame->size);
}
-static void ase_decode_preferred_context(const uint8_t *data, uint8_t len)
+static void ase_debug_preferred_context(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
@@ -753,7 +762,8 @@ static void ase_decode_preferred_context(const uint8_t *data, uint8_t len)
print_context(&frame, " Preferred Context");
}
-static void ase_decode_context(const uint8_t *data, uint8_t len)
+static void ase_debug_context(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
@@ -762,7 +772,8 @@ static void ase_decode_context(const uint8_t *data, uint8_t len)
print_context(&frame, " Context");
}
-static void ase_decode_program_info(const uint8_t *data, uint8_t len)
+static void ase_debug_program_info(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
const char *str;
@@ -782,7 +793,8 @@ done:
print_hex_field(" Data", frame.data, frame.size);
}
-static void ase_decode_language(const uint8_t *data, uint8_t len)
+static void ase_debug_language(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
uint32_t value;
@@ -801,16 +813,17 @@ done:
print_hex_field(" Data", frame.data, frame.size);
}
-struct packet_ltv_decoder ase_metadata_table[] = {
- LTV_DEC(0x01, ase_decode_preferred_context),
- LTV_DEC(0x02, ase_decode_context),
- LTV_DEC(0x03, ase_decode_program_info),
- LTV_DEC(0x04, ase_decode_language)
+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)
};
static bool print_ase_metadata(const struct l2cap_frame *frame)
{
- return print_ase_lv(frame, " Metadata", NULL, 0);
+ return print_ase_lv(frame, " Metadata", ase_metadata_table,
+ ARRAY_SIZE(ase_metadata_table));
}
static const struct bitfield_data pac_freq_table[] = {
@@ -833,7 +846,8 @@ static const struct bitfield_data pac_freq_table[] = {
{ }
};
-static void pac_decode_freq(const uint8_t *data, uint8_t len)
+static void pac_decode_freq(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
uint16_t value;
@@ -870,7 +884,8 @@ static const struct bitfield_data pac_duration_table[] = {
{ }
};
-static void pac_decode_duration(const uint8_t *data, uint8_t len)
+static void pac_decode_duration(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
uint8_t value;
@@ -907,7 +922,8 @@ static const struct bitfield_data pac_channel_table[] = {
{ }
};
-static void pac_decode_channels(const uint8_t *data, uint8_t len)
+static void pac_decode_channels(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
uint8_t value;
@@ -932,7 +948,8 @@ done:
print_hex_field(" Data", frame.data, frame.size);
}
-static void pac_decode_frame_length(const uint8_t *data, uint8_t len)
+static void pac_decode_frame_length(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
uint16_t min, max;
@@ -957,7 +974,8 @@ done:
print_hex_field(" Data", frame.data, frame.size);
}
-static void pac_decode_sdu(const uint8_t *data, uint8_t len)
+static void pac_decode_sdu(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
uint8_t value;
@@ -976,12 +994,12 @@ done:
print_hex_field(" Data", frame.data, frame.size);
}
-struct packet_ltv_decoder pac_cap_table[] = {
- LTV_DEC(0x01, pac_decode_freq),
- LTV_DEC(0x02, pac_decode_duration),
- LTV_DEC(0x03, pac_decode_channels),
- LTV_DEC(0x04, pac_decode_frame_length),
- LTV_DEC(0x05, pac_decode_sdu)
+struct util_ltv_debugger pac_cap_table[] = {
+ UTIL_LTV_DEBUG(0x01, pac_decode_freq),
+ UTIL_LTV_DEBUG(0x02, pac_decode_duration),
+ UTIL_LTV_DEBUG(0x03, pac_decode_channels),
+ UTIL_LTV_DEBUG(0x04, pac_decode_frame_length),
+ UTIL_LTV_DEBUG(0x05, pac_decode_sdu)
};
static void print_pac(const struct l2cap_frame *frame)
@@ -1117,7 +1135,8 @@ static bool print_ase_pd(const struct l2cap_frame *frame, const char *label)
return true;
}
-static void ase_decode_freq(const uint8_t *data, uint8_t len)
+static void ase_debug_freq(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
uint8_t value;
@@ -1179,7 +1198,8 @@ done:
print_hex_field(" Data", frame.data, frame.size);
}
-static void ase_decode_duration(const uint8_t *data, uint8_t len)
+static void ase_debug_duration(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
uint8_t value;
@@ -1266,7 +1286,8 @@ done:
print_hex_field(" Data", frame->data, frame->size);
}
-static void ase_decode_location(const uint8_t *data, uint8_t len)
+static void ase_debug_location(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
@@ -1275,7 +1296,8 @@ static void ase_decode_location(const uint8_t *data, uint8_t len)
print_location(&frame);
}
-static void ase_decode_frame_length(const uint8_t *data, uint8_t len)
+static void ase_debug_frame_length(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
uint16_t value;
@@ -1294,7 +1316,8 @@ done:
print_hex_field(" Data", frame.data, frame.size);
}
-static void ase_decode_blocks(const uint8_t *data, uint8_t len)
+static void ase_debug_blocks(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
{
struct l2cap_frame frame;
uint8_t value;
@@ -1313,12 +1336,12 @@ done:
print_hex_field(" Data", frame.data, frame.size);
}
-struct packet_ltv_decoder ase_cc_table[] = {
- LTV_DEC(0x01, ase_decode_freq),
- LTV_DEC(0x02, ase_decode_duration),
- LTV_DEC(0x03, ase_decode_location),
- LTV_DEC(0x04, ase_decode_frame_length),
- LTV_DEC(0x05, ase_decode_blocks)
+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)
};
static void print_ase_config(const struct l2cap_frame *frame)
@@ -2745,8 +2768,9 @@ static const struct big_enc_decoder {
};
static bool print_subgroup_lv(const struct l2cap_frame *frame,
- const char *label, struct packet_ltv_decoder *decoder,
- size_t decoder_len)
+ const char *label,
+ struct util_ltv_debugger *debugger,
+ size_t debugger_len)
{
struct bt_hci_lv_data *lv;
@@ -2761,7 +2785,8 @@ static bool print_subgroup_lv(const struct l2cap_frame *frame,
return false;
}
- packet_print_ltv(label, lv->data, lv->len, decoder, decoder_len);
+ util_debug_ltv(lv->data, lv->len, debugger, debugger_len,
+ print_ltv, (void *)label);
return true;
}
diff --git a/monitor/packet.c b/monitor/packet.c
index 30ffe79c6c09..87805be0122a 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -3419,72 +3419,11 @@ static void *iov_pull(struct iovec *iov, size_t len)
return data;
}
-static struct packet_ltv_decoder*
-get_ltv_decoder(struct packet_ltv_decoder *decoder, size_t num, uint8_t type)
+static void print_ltv(const char *str, void *user_data)
{
- size_t i;
+ const char *label = user_data;
- if (!decoder || !num)
- return NULL;
-
- for (i = 0; i < num; i++) {
- struct packet_ltv_decoder *dec = &decoder[i];
-
- if (dec->type == type)
- return dec;
- }
-
- return NULL;
-}
-
-static void print_ltv(const char *label, const uint8_t *data, uint8_t len,
- struct packet_ltv_decoder *decoder, size_t num)
-{
- struct iovec iov;
- int i;
-
- iov.iov_base = (void *) data;
- iov.iov_len = len;
-
- for (i = 0; iov.iov_len; i++) {
- uint8_t l, t, *v;
- struct packet_ltv_decoder *dec;
-
- l = get_u8(iov_pull(&iov, sizeof(l)));
- if (!l) {
- print_field("%s #%d: len 0x%02x", label, i, l);
- break;
- }
-
- v = iov_pull(&iov, sizeof(*v));
- if (!v)
- break;
-
- t = get_u8(v);
-
- print_field("%s #%d: len 0x%02x type 0x%02x", label, i, l, t);
-
- l -= 1;
-
- v = iov_pull(&iov, l);
- if (!v)
- break;
-
- dec = get_ltv_decoder(decoder, num, t);
- if (dec)
- dec->func(v, l);
- else
- print_hex_field(label, v, l);
- }
-
- if (iov.iov_len)
- print_hex_field(label, iov.iov_base, iov.iov_len);
-}
-
-void packet_print_ltv(const char *label, const uint8_t *data, uint8_t len,
- struct packet_ltv_decoder *decoder, size_t decoder_len)
-{
- print_ltv(label, data, len, decoder, decoder_len);
+ print_field("%s: %s", label, str);
}
static void print_base_annoucement(const uint8_t *data, uint8_t data_len)
@@ -3510,6 +3449,7 @@ static void print_base_annoucement(const uint8_t *data, uint8_t data_len)
struct bt_hci_lv_data *codec_cfg;
struct bt_hci_lv_data *metadata;
uint8_t j;
+ const char *label;
print_field(" Subgroup #%u:", i);
@@ -3537,9 +3477,10 @@ static void print_base_annoucement(const uint8_t *data, uint8_t data_len)
if (!iov_pull(&iov, codec_cfg->len))
goto done;
- print_ltv(" Codec Specific Configuration",
- codec_cfg->data, codec_cfg->len,
- NULL, 0);
+ label = " Codec Specific Configuration";
+
+ util_debug_ltv(codec_cfg->data, codec_cfg->len, NULL, 0,
+ print_ltv, (void *)label);
metadata = iov_pull(&iov, sizeof(*metadata));
if (!metadata)
@@ -3548,8 +3489,10 @@ static void print_base_annoucement(const uint8_t *data, uint8_t data_len)
if (!iov_pull(&iov, metadata->len))
goto done;
- print_ltv(" Metadata", metadata->data, metadata->len,
- NULL, 0);
+ label = " Metadata";
+
+ util_debug_ltv(metadata->data, metadata->len, NULL, 0,
+ print_ltv, (void *)label);
/* Level 3 - BIS(s)*/
for (j = 0; j < subgroup->num_bis; j++) {
diff --git a/monitor/packet.h b/monitor/packet.h
index 384f460d2f58..856f74f4db16 100644
--- a/monitor/packet.h
+++ b/monitor/packet.h
@@ -84,20 +84,6 @@ void packet_print_io_capability(uint8_t capability);
void packet_print_io_authentication(uint8_t authentication);
void packet_print_codec_id(const char *label, uint8_t codec);
-#define LTV_DEC(_type, _func) \
-{ \
- .type = _type, \
- .func = _func, \
-}
-
-struct packet_ltv_decoder {
- uint8_t type;
- void (*func)(const uint8_t *data, uint8_t len);
-};
-
-void packet_print_ltv(const char *label, const uint8_t *data, uint8_t len,
- struct packet_ltv_decoder *decoder, size_t num);
-
void packet_control(struct timeval *tv, struct ucred *cred,
uint16_t index, uint16_t opcode,
const void *data, uint16_t size);
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH BlueZ v2 3/4] shared/bap: Add debug helpers
2023-10-20 18:08 [PATCH BlueZ v2 1/4] shared/util: Add util_debug_{tlv, bit} helpers Luiz Augusto von Dentz
2023-10-20 18:08 ` [PATCH BlueZ v2 2/4] monitor: Make use of util_debug_tlv to decode TLV entries Luiz Augusto von Dentz
@ 2023-10-20 18:08 ` Luiz Augusto von Dentz
2023-10-20 18:08 ` [PATCH BlueZ v2 4/4] client: Make use of bap-debug functions Luiz Augusto von Dentz
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2023-10-20 18:08 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This adds bap-debug.{c.h} that implements function helpers that can be
used to print BAP/ASCS/PACS TLV entries.
---
Makefile.am | 1 +
profiles/audio/media.c | 7 +-
src/shared/bap-debug.c | 539 +++++++++++++++++++++++++++++++++++++++++
src/shared/bap-debug.h | 14 ++
src/shared/bap.c | 60 +----
src/shared/bap.h | 3 -
6 files changed, 564 insertions(+), 60 deletions(-)
create mode 100644 src/shared/bap-debug.c
create mode 100644 src/shared/bap-debug.h
diff --git a/Makefile.am b/Makefile.am
index 6187f298e81a..e9a952e72d69 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -231,6 +231,7 @@ shared_sources = src/shared/io.h src/shared/timeout.h \
src/shared/gap.h src/shared/gap.c \
src/shared/log.h src/shared/log.c \
src/shared/bap.h src/shared/bap.c src/shared/ascs.h \
+ src/shared/bap-debug.h src/shared/bap-debug.c \
src/shared/mcs.h src/shared/mcp.h src/shared/mcp.c \
src/shared/vcp.c src/shared/vcp.h \
src/shared/micp.c src/shared/micp.h \
diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index 1d98ac5a1a70..825f3cf97f5f 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
@@ -42,6 +42,7 @@
#include "src/shared/queue.h"
#include "src/shared/att.h"
#include "src/shared/bap.h"
+#include "src/shared/bap-debug.h"
#include "avdtp.h"
#include "media.h"
@@ -1217,13 +1218,13 @@ static bool endpoint_init_pac(struct media_endpoint *endpoint, uint8_t type,
return false;
}
- if (!bap_print_cc(endpoint->capabilities, endpoint->size, bap_debug,
- NULL)) {
+ if (!bt_bap_debug_caps(endpoint->capabilities, endpoint->size,
+ bap_debug, NULL)) {
error("Unable to parse endpoint capabilities");
return false;
}
- if (!bap_print_cc(endpoint->metadata, endpoint->metadata_size,
+ if (!bt_bap_debug_metadata(endpoint->metadata, endpoint->metadata_size,
bap_debug, NULL)) {
error("Unable to parse endpoint metadata");
return false;
diff --git a/src/shared/bap-debug.c b/src/shared/bap-debug.c
new file mode 100644
index 000000000000..20dc3a1419c0
--- /dev/null
+++ b/src/shared/bap-debug.c
@@ -0,0 +1,539 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2023 Intel Corporation.
+ */
+
+#define _GNU_SOURCE
+#include <inttypes.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "src/shared/util.h"
+#include "src/shared/bap-debug.h"
+
+static const struct util_bit_debugger pac_freq_table[] = {
+ UTIL_BIT_DEBUG(0, "\t8 Khz (0x0001)"),
+ UTIL_BIT_DEBUG(1, "\t11.25 Khz (0x0002)"),
+ UTIL_BIT_DEBUG(2, "\t16 Khz (0x0004)"),
+ UTIL_BIT_DEBUG(3, "\t22.05 Khz (0x0008)"),
+ UTIL_BIT_DEBUG(4, "\t24 Khz (0x0010)"),
+ UTIL_BIT_DEBUG(5, "\t32 Khz (0x0020)"),
+ UTIL_BIT_DEBUG(6, "\t44.1 Khz (0x0040)"),
+ UTIL_BIT_DEBUG(7, "\t48 Khz (0x0080)"),
+ UTIL_BIT_DEBUG(8, "\t88.2 Khz (0x0100)"),
+ UTIL_BIT_DEBUG(9, "\t96 Khz (0x0200)"),
+ UTIL_BIT_DEBUG(10, "\t176.4 Khz (0x0400)"),
+ UTIL_BIT_DEBUG(11, "\t192 Khz (0x0800)"),
+ UTIL_BIT_DEBUG(12, "\t384 Khz (0x1000)"),
+ UTIL_BIT_DEBUG(13, "\tRFU (0x2000)"),
+ UTIL_BIT_DEBUG(14, "\tRFU (0x4000)"),
+ UTIL_BIT_DEBUG(15, "\tRFU (0x8000)"),
+ { }
+};
+
+static void pac_debug_freq(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
+{
+ struct iovec frame = { (void *)data, len };
+ uint16_t value;
+ uint16_t mask;
+
+ if (!util_iov_pull_le16(&frame, &value)) {
+ util_debug(func, user_data, "value: invalid size");
+ goto done;
+ }
+
+ util_debug(func, user_data, "Sampling Frequencies: 0x%4.4x", value);
+
+ mask = util_debug_bit(value, pac_freq_table, func, user_data);
+ if (mask)
+ util_debug(func, user_data, "Unknown fields (0x%4.4x)",
+ mask);
+
+done:
+ if (frame.iov_len)
+ util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+ user_data);
+}
+
+static const struct util_bit_debugger pac_duration_table[] = {
+ UTIL_BIT_DEBUG(0, "\t7.5 ms (0x01)"),
+ UTIL_BIT_DEBUG(1, "\t10 ms (0x02)"),
+ UTIL_BIT_DEBUG(2, "\tRFU (0x04)"),
+ UTIL_BIT_DEBUG(3, "\tRFU (0x08)"),
+ UTIL_BIT_DEBUG(4, "\t7.5 ms preferred (0x10)"),
+ UTIL_BIT_DEBUG(5, "\t10 ms preferred (0x20)"),
+ UTIL_BIT_DEBUG(6, "\tRFU (0x40)"),
+ UTIL_BIT_DEBUG(7, "\tRFU (0x80)"),
+ { }
+};
+
+static void pac_debug_duration(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
+{
+ struct iovec frame = { (void *)data, len };
+ uint8_t value;
+ uint8_t mask;
+
+ if (!util_iov_pull_u8(&frame, &value)) {
+ util_debug(func, user_data, "value: invalid size");
+ goto done;
+ }
+
+ util_debug(func, user_data, "Frame Duration: 0x%2.2x", value);
+
+ mask = util_debug_bit(value, pac_duration_table, func, user_data);
+ if (mask)
+ util_debug(func, user_data, "Unknown fields (0x%2.2x)",
+ mask);
+
+done:
+ if (frame.iov_len)
+ util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+ user_data);
+}
+
+static const struct util_bit_debugger pac_channel_table[] = {
+ UTIL_BIT_DEBUG(0, "\t1 channel (0x01)"),
+ UTIL_BIT_DEBUG(1, "\t2 channel (0x02)"),
+ UTIL_BIT_DEBUG(2, "\t3 channel (0x04)"),
+ UTIL_BIT_DEBUG(3, "\t4 channel (0x08)"),
+ UTIL_BIT_DEBUG(4, "\t5 channel (0x10)"),
+ UTIL_BIT_DEBUG(5, "\t6 channel (0x20)"),
+ UTIL_BIT_DEBUG(6, "\t7 channel (0x40)"),
+ UTIL_BIT_DEBUG(7, "\t8 channel (0x80)"),
+ { }
+};
+
+static void pac_debug_channels(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
+{
+ struct iovec frame = { (void *)data, len };
+ uint8_t value;
+ uint8_t mask;
+
+ if (!util_iov_pull_u8(&frame, &value)) {
+ util_debug(func, user_data, "value: invalid size");
+ goto done;
+ }
+
+ util_debug(func, user_data, "Audio Channel Count: 0x%2.2x", value);
+
+ mask = util_debug_bit(value, pac_channel_table, func, user_data);
+ if (mask)
+ util_debug(func, user_data, "Unknown fields (0x%2.2x)",
+ mask);
+
+done:
+ if (frame.iov_len)
+ util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+ user_data);
+}
+
+static void pac_debug_frame_length(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
+{
+ struct iovec frame = { (void *)data, len };
+ uint16_t min, max;
+
+ if (!util_iov_pull_le16(&frame, &min)) {
+ util_debug(func, user_data, "min: invalid size");
+ goto done;
+ }
+
+ if (!util_iov_pull_le16(&frame, &max)) {
+ util_debug(func, user_data, "max: invalid size");
+ goto done;
+ }
+
+ util_debug(func, user_data,
+ "Frame Length: %u (0x%4.4x) - %u (0x%4.4x)",
+ min, min, max, max);
+
+done:
+ if (frame.iov_len)
+ util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+ user_data);
+}
+
+static void pac_debug_sdu(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;
+ }
+
+ util_debug(func, user_data, "Max SDU: %u (0x%2.2x)", value, value);
+
+done:
+ if (frame.iov_len)
+ util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+ user_data);
+}
+
+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)
+};
+
+bool bt_bap_debug_caps(void *data, size_t len, util_debug_func_t func,
+ void *user_data)
+{
+ return util_debug_ltv(data, len, pac_cap_table,
+ ARRAY_SIZE(pac_cap_table),
+ func, user_data);
+}
+
+static void ase_debug_freq(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 0x01:
+ util_debug(func, user_data, "Sampling Frequency: 8 Khz (0x01)");
+ break;
+ case 0x02:
+ util_debug(func, user_data,
+ "Sampling Frequency: 11.25 Khz (0x02)");
+ break;
+ case 0x03:
+ util_debug(func, user_data,
+ "Sampling Frequency: 16 Khz (0x03)");
+ break;
+ case 0x04:
+ util_debug(func, user_data,
+ "Sampling Frequency: 22.05 Khz (0x04)");
+ break;
+ case 0x05:
+ util_debug(func, user_data,
+ "Sampling Frequency: 24 Khz (0x05)");
+ break;
+ case 0x06:
+ util_debug(func, user_data,
+ "Sampling Frequency: 32 Khz (0x06)");
+ break;
+ case 0x07:
+ util_debug(func, user_data,
+ "Sampling Frequency: 44.1 Khz (0x07)");
+ break;
+ case 0x08:
+ util_debug(func, user_data,
+ "Sampling Frequency: 48 Khz (0x08)");
+ break;
+ case 0x09:
+ util_debug(func, user_data,
+ "Sampling Frequency: 88.2 Khz (0x09)");
+ break;
+ case 0x0a:
+ util_debug(func, user_data,
+ "Sampling Frequency: 96 Khz (0x0a)");
+ break;
+ case 0x0b:
+ util_debug(func, user_data,
+ "Sampling Frequency: 176.4 Khz (0x0b)");
+ break;
+ case 0x0c:
+ util_debug(func, user_data,
+ "Sampling Frequency: 192 Khz (0x0c)");
+ break;
+ case 0x0d:
+ util_debug(func, user_data,
+ "Sampling Frequency: 384 Khz (0x0d)");
+ break;
+ default:
+ util_debug(func, user_data,
+ "Sampling Frequency: 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_duration(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, "\tvalue: invalid size\n");
+ goto done;
+ }
+
+ switch (value) {
+ case 0x00:
+ util_debug(func, user_data, "Frame Duration: 7.5 ms (0x00)");
+ break;
+ case 0x01:
+ util_debug(func, user_data, "Frame Duration: 10 ms (0x01)");
+ break;
+ default:
+ util_debug(func, user_data, "Frame Duration: RFU (0x%2.2x)",
+ value);
+ break;
+ }
+
+done:
+ if (frame.iov_len)
+ util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+ user_data);
+}
+
+static const struct util_bit_debugger channel_location_table[] = {
+ UTIL_BIT_DEBUG(0, "\tFront Left (0x00000001)"),
+ UTIL_BIT_DEBUG(1, "\tFront Right (0x00000002)"),
+ UTIL_BIT_DEBUG(2, "\tFront Center (0x00000004)"),
+ UTIL_BIT_DEBUG(3, "\tLow Frequency Effects 1 (0x00000008)"),
+ UTIL_BIT_DEBUG(4, "\tBack Left (0x00000010)"),
+ UTIL_BIT_DEBUG(5, "\tBack Right (0x00000020)"),
+ UTIL_BIT_DEBUG(6, "\tFront Left of Center (0x00000040)"),
+ UTIL_BIT_DEBUG(7, "\tFront Right of Center (0x00000080)"),
+ UTIL_BIT_DEBUG(8, "\tBack Center (0x00000100)"),
+ UTIL_BIT_DEBUG(9, "\tLow Frequency Effects 2 (0x00000200)"),
+ UTIL_BIT_DEBUG(10, "\tSide Left (0x00000400)"),
+ UTIL_BIT_DEBUG(11, "\tSide Right (0x00000800)"),
+ UTIL_BIT_DEBUG(12, "\tTop Front Left (0x00001000)"),
+ UTIL_BIT_DEBUG(13, "\tTop Front Right (0x00002000)"),
+ UTIL_BIT_DEBUG(14, "\tTop Front Center (0x00004000)"),
+ UTIL_BIT_DEBUG(15, "\tTop Center (0x00008000)"),
+ UTIL_BIT_DEBUG(16, "\tTop Back Left (0x00010000)"),
+ UTIL_BIT_DEBUG(17, "\tTop Back Right (0x00020000)"),
+ UTIL_BIT_DEBUG(18, "\tTop Side Left (0x00040000)"),
+ UTIL_BIT_DEBUG(19, "\tTop Side Right (0x00080000)"),
+ UTIL_BIT_DEBUG(20, "\tTop Back Center (0x00100000)"),
+ UTIL_BIT_DEBUG(21, "\tBottom Front Center (0x00200000)"),
+ UTIL_BIT_DEBUG(22, "\tBottom Front Left (0x00400000)"),
+ UTIL_BIT_DEBUG(23, "\tBottom Front Right (0x00800000)"),
+ UTIL_BIT_DEBUG(24, "\tFront Left Wide (0x01000000)"),
+ UTIL_BIT_DEBUG(25, "\tFront Right Wide (0x02000000)"),
+ UTIL_BIT_DEBUG(26, "\tLeft Surround (0x04000000)"),
+ UTIL_BIT_DEBUG(27, "\tRight Surround (0x08000000)"),
+ UTIL_BIT_DEBUG(28, "\tRFU (0x10000000)"),
+ UTIL_BIT_DEBUG(29, "\tRFU (0x20000000)"),
+ UTIL_BIT_DEBUG(30, "\tRFU (0x40000000)"),
+ UTIL_BIT_DEBUG(31, "\tRFU (0x80000000)"),
+ { }
+};
+
+static void debug_location(const struct iovec *frame, util_debug_func_t func,
+ void *user_data)
+{
+ uint32_t value;
+ uint32_t mask;
+
+ if (!util_iov_pull_le32((void *)frame, &value)) {
+ util_debug(func, user_data, "value: invalid size");
+ goto done;
+ }
+
+ util_debug(func, user_data, "Location: 0x%8.8x", value);
+
+ mask = util_debug_bit(value, channel_location_table, func, user_data);
+ if (mask)
+ util_debug(func, user_data, "Unknown fields (0x%8.8x)", mask);
+
+done:
+ if (frame->iov_len)
+ util_hexdump(' ', frame->iov_base, frame->iov_len, func,
+ user_data);
+}
+
+static void ase_debug_location(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
+{
+ struct iovec frame = { (void *)data, len };
+
+ debug_location(&frame, func, user_data);
+}
+
+static void ase_debug_frame_length(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, "\tvalue: invalid size\n");
+ goto done;
+ }
+
+ util_debug(func, user_data, "Frame Length: %u (0x%4.4x)",
+ value, value);
+
+done:
+ if (frame.iov_len)
+ util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+ user_data);
+}
+
+static void ase_debug_blocks(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;
+ }
+
+ util_debug(func, user_data, "Frame Blocks per SDU: %u (0x%2.2x)",
+ value, value);
+
+done:
+ if (frame.iov_len)
+ util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+ user_data);
+}
+
+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)
+};
+
+bool bt_bap_debug_config(void *data, size_t len, util_debug_func_t func,
+ void *user_data)
+{
+ return util_debug_ltv(data, len, ase_cc_table,
+ ARRAY_SIZE(ase_cc_table),
+ func, user_data);
+}
+
+static const struct util_bit_debugger pac_context_table[] = {
+ UTIL_BIT_DEBUG(0, "\tUnspecified (0x0001)"),
+ UTIL_BIT_DEBUG(1, "\tConversational (0x0002)"),
+ UTIL_BIT_DEBUG(2, "\tMedia (0x0004)"),
+ UTIL_BIT_DEBUG(3, "\tGame (0x0008)"),
+ UTIL_BIT_DEBUG(4, "\tInstructional (0x0010)"),
+ UTIL_BIT_DEBUG(5, "\tVoice Assistants (0x0020)"),
+ UTIL_BIT_DEBUG(6, "\tLive (0x0040)"),
+ UTIL_BIT_DEBUG(7, "\tSound Effects (0x0080)"),
+ UTIL_BIT_DEBUG(8, "\tNotifications (0x0100)"),
+ UTIL_BIT_DEBUG(9, "\tRingtone (0x0200)"),
+ UTIL_BIT_DEBUG(10, "\tAlerts (0x0400)"),
+ UTIL_BIT_DEBUG(11, "\tEmergency alarm (0x0800)"),
+ UTIL_BIT_DEBUG(12, "\tRFU (0x1000)"),
+ UTIL_BIT_DEBUG(13, "\tRFU (0x2000)"),
+ UTIL_BIT_DEBUG(14, "\tRFU (0x4000)"),
+ UTIL_BIT_DEBUG(15, "\tRFU (0x8000)"),
+ { }
+};
+
+static void debug_context(const struct iovec *frame, const char *label,
+ util_debug_func_t func, void *user_data)
+{
+ uint16_t value;
+ uint16_t mask;
+
+ if (!util_iov_pull_le16((void *)frame, &value)) {
+ util_debug(func, user_data, "value: invalid size");
+ goto done;
+ }
+
+ util_debug(func, user_data, "%s: 0x%4.4x", label, value);
+
+ mask = util_debug_bit(value, pac_context_table, func, user_data);
+ if (mask)
+ util_debug(func, user_data, "Unknown fields (0x%4.4x)", mask);
+
+done:
+ if (frame->iov_len)
+ util_hexdump(' ', frame->iov_base, frame->iov_len, func,
+ user_data);
+}
+
+static void ase_debug_preferred_context(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
+{
+ struct iovec frame = { (void *)data, len };
+
+ debug_context(&frame, "Preferred Context", func, user_data);
+}
+
+static void ase_debug_context(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
+{
+ struct iovec frame = { (void *)data, len };
+
+ debug_context(&frame, "Context", func, user_data);
+}
+
+static void ase_debug_program_info(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
+{
+ struct iovec frame = { (void *)data, len };
+ const char *str;
+
+ str = util_iov_pull_mem(&frame, len);
+ if (!str) {
+ util_debug(func, user_data, "value: invalid size");
+ goto done;
+ }
+
+ util_debug(func, user_data, "Program Info: %*s", len, str);
+
+done:
+ if (frame.iov_len)
+ util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+ user_data);
+}
+
+static void ase_debug_language(const uint8_t *data, uint8_t len,
+ util_debug_func_t func, void *user_data)
+{
+ struct iovec frame = { (void *)data, len };
+ uint32_t value;
+
+ if (!util_iov_pull_le24(&frame, &value)) {
+ util_debug(func, user_data, "value: invalid size");
+ goto done;
+ }
+
+ util_debug(func, user_data, "Language: 0x%6.6x\n", value);
+
+done:
+ if (frame.iov_len)
+ util_hexdump(' ', frame.iov_base, frame.iov_len, func,
+ user_data);
+}
+
+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)
+};
+
+bool bt_bap_debug_metadata(void *data, size_t len, util_debug_func_t func,
+ void *user_data)
+{
+ return util_debug_ltv(data, len, ase_metadata_table,
+ ARRAY_SIZE(ase_metadata_table),
+ func, user_data);
+}
diff --git a/src/shared/bap-debug.h b/src/shared/bap-debug.h
new file mode 100644
index 000000000000..93f3b18e17c4
--- /dev/null
+++ b/src/shared/bap-debug.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2023 Intel Corporation.
+ */
+
+bool bt_bap_debug_caps(void *data, size_t len, util_debug_func_t func,
+ void *user_data);
+bool bt_bap_debug_config(void *data, size_t len, util_debug_func_t func,
+ void *user_data);
+bool bt_bap_debug_metadata(void *data, size_t len, util_debug_func_t func,
+ void *user_data);
diff --git a/src/shared/bap.c b/src/shared/bap.c
index 925501c48d98..85460a813108 100644
--- a/src/shared/bap.c
+++ b/src/shared/bap.c
@@ -29,6 +29,7 @@
#include "src/shared/gatt-client.h"
#include "src/shared/bap.h"
#include "src/shared/ascs.h"
+#include "src/shared/bap-debug.h"
/* Maximum number of ASE(s) */
#define NUM_SINKS 2
@@ -1568,7 +1569,7 @@ static uint8_t ep_config(struct bt_bap_endpoint *ep, struct bt_bap *bap,
cc.iov_base = util_iov_pull_mem(iov, req->cc_len);
cc.iov_len = req->cc_len;
- if (!bap_print_cc(cc.iov_base, cc.iov_len, bap->debug_func,
+ if (!bt_bap_debug_caps(cc.iov_base, cc.iov_len, bap->debug_func,
bap->debug_data)) {
ascs_ase_rsp_add(rsp, req->ase,
BT_ASCS_RSP_CONF_INVALID,
@@ -1735,49 +1736,6 @@ static uint8_t stream_enable(struct bt_bap_stream *stream, struct iovec *meta,
return 0;
}
-static bool bap_print_ltv(const char *label, void *data, size_t len,
- util_debug_func_t func, void *user_data)
-{
- struct iovec iov = {
- .iov_base = data,
- .iov_len = len,
- };
- int i;
-
- util_debug(func, user_data, "Length %zu", iov.iov_len);
-
- for (i = 0; iov.iov_len > 1; i++) {
- struct bt_ltv *ltv = util_iov_pull_mem(&iov, sizeof(*ltv));
- uint8_t *data;
-
- if (!ltv) {
- util_debug(func, user_data, "Unable to parse %s",
- label);
- return false;
- }
-
- util_debug(func, user_data, "%s #%u: len %u type %u",
- label, i, ltv->len, ltv->type);
-
- data = util_iov_pull_mem(&iov, ltv->len - 1);
- if (!data) {
- util_debug(func, user_data, "Unable to parse %s",
- label);
- return false;
- }
-
- util_hexdump(' ', ltv->value, ltv->len - 1, func, user_data);
- }
-
- return true;
-}
-
-static bool bap_print_metadata(void *data, size_t len, util_debug_func_t func,
- void *user_data)
-{
- return bap_print_ltv("Metadata", data, len, func, user_data);
-}
-
static uint8_t ep_enable(struct bt_bap_endpoint *ep, struct bt_bap *bap,
struct bt_ascs_enable *req, struct iovec *iov,
struct iovec *rsp)
@@ -1801,8 +1759,8 @@ static uint8_t ep_enable(struct bt_bap_endpoint *ep, struct bt_bap *bap,
meta.iov_base = util_iov_pull_mem(iov, req->meta.len);
meta.iov_len = req->meta.len;
- if (!bap_print_metadata(meta.iov_base, meta.iov_len, bap->debug_func,
- bap->debug_data)) {
+ if (!bt_bap_debug_metadata(meta.iov_base, meta.iov_len,
+ bap->debug_func, bap->debug_data)) {
ascs_ase_rsp_add(rsp, ep->id,
BT_ASCS_RSP_METADATA_INVALID,
BT_ASCS_REASON_NONE);
@@ -3175,12 +3133,6 @@ static void bap_notify_ready(struct bt_bap *bap)
bt_bap_unref(bap);
}
-bool bap_print_cc(void *data, size_t len, util_debug_func_t func,
- void *user_data)
-{
- return bap_print_ltv("CC", data, len, func, user_data);
-}
-
static void bap_parse_pacs(struct bt_bap *bap, uint8_t type,
struct queue *queue,
const uint8_t *value,
@@ -3221,7 +3173,7 @@ static void bap_parse_pacs(struct bt_bap *bap, uint8_t type,
pac = NULL;
- if (!bap_print_cc(iov.iov_base, p->cc_len, bap->debug_func,
+ if (!bt_bap_debug_caps(iov.iov_base, p->cc_len, bap->debug_func,
bap->debug_data))
return;
@@ -4632,7 +4584,7 @@ unsigned int bt_bap_stream_config(struct bt_bap_stream *stream,
iov[0].iov_len = sizeof(config);
if (data) {
- if (!bap_print_cc(data->iov_base, data->iov_len,
+ if (!bt_bap_debug_config(data->iov_base, data->iov_len,
stream->bap->debug_func,
stream->bap->debug_data))
return 0;
diff --git a/src/shared/bap.h b/src/shared/bap.h
index ebe4dbf7d858..23edbf4c6953 100644
--- a/src/shared/bap.h
+++ b/src/shared/bap.h
@@ -201,9 +201,6 @@ void bt_bap_detach(struct bt_bap *bap);
bool bt_bap_set_debug(struct bt_bap *bap, bt_bap_debug_func_t cb,
void *user_data, bt_bap_destroy_func_t destroy);
-bool bap_print_cc(void *data, size_t len, util_debug_func_t func,
- void *user_data);
-
unsigned int bt_bap_pac_register(struct bt_bap *bap, bt_bap_pac_func_t added,
bt_bap_pac_func_t removed, void *user_data,
bt_bap_destroy_func_t destroy);
--
2.41.0
^ permalink raw reply related [flat|nested] 6+ messages in thread