1 /*
2 * Copyright (c) 2021-2023 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdbool.h>
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <string.h>
11
12 #include <zephyr/autoconf.h>
13 #include <zephyr/bluetooth/audio/audio.h>
14 #include <zephyr/bluetooth/audio/bap.h>
15 #include <zephyr/bluetooth/bluetooth.h>
16 #include <zephyr/bluetooth/hci_types.h>
17 #include <zephyr/bluetooth/iso.h>
18 #include <zephyr/sys/byteorder.h>
19 #include <zephyr/sys/printk.h>
20
21 #include "bap_common.h"
22
23 #define VS_CODEC_CID 0x05F1 /* Linux foundation*/
24 #define VS_CODEC_VID 0x1234 /* any value*/
25
26 /* Vendor specific codec configuration with some random values */
27 struct bt_audio_codec_cfg vs_codec_cfg = {
28 .path_id = BT_ISO_DATA_PATH_HCI,
29 .ctlr_transcode = false,
30 .id = BT_HCI_CODING_FORMAT_VS,
31 .cid = VS_CODEC_CID,
32 .vid = VS_CODEC_VID,
33 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
34 .data_len = 5,
35 .data = {1, 2, 3, 4, 5}, /* any value */
36 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
37 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0
38 .meta_len = 5,
39 .meta = {10, 20, 30, 40, 50}, /* any value */
40 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */
41 };
42
43 /* Vendor specific codec configuration with some random values */
44 struct bt_audio_codec_cap vs_codec_cap = {
45 .path_id = BT_ISO_DATA_PATH_HCI,
46 .ctlr_transcode = false,
47 .id = BT_HCI_CODING_FORMAT_VS,
48 .cid = VS_CODEC_CID,
49 .vid = VS_CODEC_VID,
50 #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0
51 .data_len = 5,
52 .data = {1, 2, 3, 4, 5}, /* any value */
53 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
54 #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0
55 .meta_len = 5,
56 .meta = {10, 20, 30, 40, 50}, /* any value */
57 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */
58 };
59
print_hex(const uint8_t * ptr,size_t len)60 void print_hex(const uint8_t *ptr, size_t len)
61 {
62 while (len-- != 0) {
63 printk("%02x", *ptr++);
64 }
65 }
66
67 struct print_ltv_info {
68 const char *str;
69 size_t cnt;
70 };
71
print_ltv_elem(struct bt_data * data,void * user_data)72 static bool print_ltv_elem(struct bt_data *data, void *user_data)
73 {
74 struct print_ltv_info *ltv_info = user_data;
75
76 printk("%s #%zu: type 0x%02x value_len %u", ltv_info->str, ltv_info->cnt, data->type,
77 data->data_len);
78 print_hex(data->data, data->data_len);
79 printk("\n");
80
81 ltv_info->cnt++;
82
83 return true;
84 }
85
print_ltv_array(const char * str,const uint8_t * ltv_data,size_t ltv_data_len)86 static void print_ltv_array(const char *str, const uint8_t *ltv_data, size_t ltv_data_len)
87 {
88 struct print_ltv_info ltv_info = {
89 .str = str,
90 .cnt = 0U,
91 };
92
93 bt_audio_data_parse(ltv_data, ltv_data_len, print_ltv_elem, <v_info);
94 }
95
print_codec_cap(const struct bt_audio_codec_cap * codec_cap)96 void print_codec_cap(const struct bt_audio_codec_cap *codec_cap)
97 {
98 printk("codec_cap ID 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cap->id,
99 codec_cap->cid, codec_cap->vid, codec_cap->data_len);
100
101 if (codec_cap->id == BT_HCI_CODING_FORMAT_LC3) {
102 print_ltv_array("data", codec_cap->data, codec_cap->data_len);
103 } else { /* If not LC3, we cannot assume it's LTV */
104 printk("data: ");
105 print_hex(codec_cap->data, codec_cap->data_len);
106 printk("\n");
107 }
108
109 print_ltv_array("meta", codec_cap->meta, codec_cap->meta_len);
110 }
111
print_codec_cfg(const struct bt_audio_codec_cfg * codec_cfg)112 void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg)
113 {
114 printk("codec_cfg ID 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cfg->id,
115 codec_cfg->cid, codec_cfg->vid, codec_cfg->data_len);
116
117 if (codec_cfg->id == BT_HCI_CODING_FORMAT_LC3) {
118 print_ltv_array("data", codec_cfg->data, codec_cfg->data_len);
119 } else { /* If not LC3, we cannot assume it's LTV */
120 printk("data: ");
121 print_hex(codec_cfg->data, codec_cfg->data_len);
122 printk("\n");
123 }
124
125 print_ltv_array("meta", codec_cfg->meta, codec_cfg->meta_len);
126 }
127
print_qos(const struct bt_bap_qos_cfg * qos)128 void print_qos(const struct bt_bap_qos_cfg *qos)
129 {
130 printk("QoS: interval %u framing 0x%02x phy 0x%02x sdu %u "
131 "rtn %u latency %u pd %u\n",
132 qos->interval, qos->framing, qos->phy, qos->sdu, qos->rtn, qos->latency, qos->pd);
133 }
134
copy_unicast_stream_preset(struct unicast_stream * stream,const struct named_lc3_preset * named_preset)135 void copy_unicast_stream_preset(struct unicast_stream *stream,
136 const struct named_lc3_preset *named_preset)
137 {
138 memcpy(&stream->qos, &named_preset->preset.qos, sizeof(stream->qos));
139 memcpy(&stream->codec_cfg, &named_preset->preset.codec_cfg, sizeof(stream->codec_cfg));
140 }
141