mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-15 00:04:29 +08:00
shared/bap: Add debug helpers
This adds bap-debug.{c.h} that implements function helpers that can be used to print BAP/ASCS/PACS TLV entries.
This commit is contained in:
parent
e1ec086614
commit
6d4491649e
@ -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 \
|
||||
|
@ -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;
|
||||
|
539
src/shared/bap-debug.c
Normal file
539
src/shared/bap-debug.c
Normal file
@ -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);
|
||||
}
|
14
src/shared/bap-debug.h
Normal file
14
src/shared/bap-debug.h
Normal file
@ -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);
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user