diff mbox series

[BlueZ,2/2] monitor: Decode LTV fields of Basic Audio Announcements

Message ID 20220502210553.2271064-2-luiz.dentz@gmail.com
State New
Headers show
Series [BlueZ,1/2] btdev: Fix not removing connection and advertising set on reset | expand

Commit Message

Luiz Augusto von Dentz May 2, 2022, 9:05 p.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This decodes the LTV fields of Basic Audio Announcements:

< HCI Command: LE Set Periodic Advertising Data (0x08|0x003f) plen 41
        Handle: 0
        Operation: Complete ext advertising data (0x03)
        Data length: 0x26
        Service Data: Basic Audio Announcement (0x1851)
          Presetation Delay: 40000
          Number of Subgroups: 1
            Subgroup #0:
            Number of BIS(s): 1
            Codec: LC3 (0x06)
            Codec Specific Configuration #0: len 0x02 type 0x01
            Codec Specific Configuration: 03
            Codec Specific Configuration #1: len 0x02 type 0x02
            Codec Specific Configuration: 01
            Codec Specific Configuration #2: len 0x05 type 0x03
            Codec Specific Configuration: 01000000
            Codec Specific Configuration #3: len 0x03 type 0x04
            Codec Specific Configuration: 2800
            Metadata #0: len 0x03 type 0x02
            Metadata: 0200
              BIS #0:
              Index: 1
              Codec Specific Configuration:
---
 monitor/packet.c | 42 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/monitor/packet.c b/monitor/packet.c
index d409e4e63..99ed9c281 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -3318,6 +3318,44 @@  static void *iov_pull(struct iovec *iov, size_t len)
 	return data;
 }
 
+static void print_ltv(const char *label, const uint8_t *data, uint8_t len)
+{
+	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;
+
+		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;
+
+		print_hex_field(label , v, l);
+	}
+
+	if (iov.iov_len)
+		print_hex_field(label , iov.iov_base, iov.iov_len);
+}
+
 static void print_base_annoucement(const uint8_t *data, uint8_t data_len)
 {
 	struct iovec iov;
@@ -3368,7 +3406,7 @@  static void print_base_annoucement(const uint8_t *data, uint8_t data_len)
 		if (!iov_pull(&iov, codec_cfg->len))
 			goto done;
 
-		print_hex_field("    Codec Specific Configuration",
+		print_ltv("    Codec Specific Configuration",
 					codec_cfg->data, codec_cfg->len);
 
 		metadata = iov_pull(&iov, sizeof(*metadata));
@@ -3378,7 +3416,7 @@  static void print_base_annoucement(const uint8_t *data, uint8_t data_len)
 		if (!iov_pull(&iov, metadata->len))
 			goto done;
 
-		print_hex_field("    Metadata", metadata->data, metadata->len);
+		print_ltv("    Metadata", metadata->data, metadata->len);
 
 		/* Level 3 - BIS(s)*/
 		for (j = 0; j < subgroup->num_bis; j++) {