monitor: Decode LTV fields of Basic Audio Announcements
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Mon, 2 May 2022 20:02:46 +0000 (13:02 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Mon, 15 May 2023 09:25:54 +0000 (14:55 +0530)
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:

Signed-off-by: Manika Shrivastava <manika.sh@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
monitor/packet.c

index 3b23642..7ef0038 100755 (executable)
@@ -3317,6 +3317,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;
@@ -3367,7 +3405,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));
@@ -3377,7 +3415,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++) {