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, &ltv_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