1 /* main.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2020 Demant
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/kernel.h>
10 #include <stddef.h>
11 #include <zephyr/ztest.h>
12 
13 #include <zephyr/bluetooth/hci.h>
14 #include <zephyr/sys/byteorder.h>
15 
16 #define NUM_STD_CODECS 3
17 static const struct bt_hci_std_codec_info_v2 std_codecs[NUM_STD_CODECS] = {
18 	{ BT_HCI_CODING_FORMAT_ALAW_LOG,
19 	  (BT_HCI_CODEC_TRANSPORT_MASK_BREDR_ACL |
20 	   BT_HCI_CODEC_TRANSPORT_MASK_BREDR_SCO) },
21 	{ BT_HCI_CODING_FORMAT_TRANSPARENT,
22 	  BT_HCI_CODEC_TRANSPORT_MASK_LE_CIS },
23 	{ BT_HCI_CODING_FORMAT_LINEAR_PCM,
24 	  BT_HCI_CODEC_TRANSPORT_MASK_LE_BIS },
25 };
26 
27 #define NUM_VS_CODECS 2
28 static const struct bt_hci_vs_codec_info_v2 vs_codecs[NUM_VS_CODECS] = {
29 	{ BT_COMP_ID_LF, 23,
30 	  BT_HCI_CODEC_TRANSPORT_MASK_LE_CIS },
31 	{ BT_COMP_ID_LF, 42,
32 	  (BT_HCI_CODEC_TRANSPORT_MASK_LE_CIS |
33 	   BT_HCI_CODEC_TRANSPORT_MASK_LE_BIS) },
34 };
35 
36 
hci_vendor_read_std_codecs(const struct bt_hci_std_codec_info_v2 ** codecs)37 uint8_t hci_vendor_read_std_codecs(
38 	const struct bt_hci_std_codec_info_v2 **codecs)
39 {
40 	*codecs = std_codecs;
41 	return NUM_STD_CODECS;
42 }
43 
hci_vendor_read_vs_codecs(const struct bt_hci_vs_codec_info_v2 ** codecs)44 uint8_t hci_vendor_read_vs_codecs(
45 	const struct bt_hci_vs_codec_info_v2 **codecs)
46 {
47 	*codecs = vs_codecs;
48 	return NUM_VS_CODECS;
49 }
50 
51 ZTEST_SUITE(test_hci_codecs_info, NULL, NULL, NULL, NULL, NULL);
52 
ZTEST(test_hci_codecs_info,test_read_codecs)53 ZTEST(test_hci_codecs_info, test_read_codecs)
54 {
55 	int err;
56 
57 	/* Initialize bluetooth subsystem */
58 	bt_enable(NULL);
59 
60 	/*
61 	 * An LE controller shall no longer support
62 	 * HCI_Read_Local_Supported_Codecs [v1]
63 	 * according to BT Core 5.3.
64 	 */
65 
66 
67 	/* Read Local Supported Codecs */
68 	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_CODECS, NULL, NULL);
69 	zassert_not_equal(err, 0, "Reading local supported codecs failed");
70 
71 }
72 
ZTEST(test_hci_codecs_info,test_read_codecs_v2)73 ZTEST(test_hci_codecs_info, test_read_codecs_v2)
74 {
75 	const struct bt_hci_rp_read_codecs_v2 *codecs;
76 	struct net_buf *rsp;
77 	uint8_t num_std_codecs;
78 	uint8_t num_vs_codecs;
79 	const uint8_t *ptr;
80 	uint8_t i;
81 	int err;
82 
83 	/* Initialize bluetooth subsystem */
84 	bt_enable(NULL);
85 
86 	/* Read Local Supported Codecs */
87 	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_CODECS_V2, NULL, &rsp);
88 	zassert_equal(err, 0, "Reading local supported codecs v2 failed");
89 
90 	/* Check returned data */
91 	codecs = (const struct bt_hci_rp_read_codecs_v2 *)rsp->data;
92 	zassert_equal(codecs->status, 0,
93 		      "Reading local supported codecs v2 status failed");
94 
95 	ptr = (uint8_t *)&codecs->status + sizeof(codecs->status);
96 	num_std_codecs = *ptr++;
97 	zassert_equal(num_std_codecs, NUM_STD_CODECS,
98 		      "Reading std codecs count failed");
99 
100 	for (i = 0; i < num_std_codecs; i++) {
101 		const struct bt_hci_std_codec_info_v2 *codec;
102 
103 		codec = (const struct bt_hci_std_codec_info_v2 *)ptr;
104 		ptr += sizeof(*codec);
105 		zassert_equal(codec->codec_id, std_codecs[i].codec_id,
106 			      "Reading std codecs codec_id %d failed", i);
107 		zassert_equal(codec->transports, std_codecs[i].transports,
108 			      "Reading std codecs transports %d failed", i);
109 	}
110 
111 	num_vs_codecs = *ptr++;
112 	zassert_equal(num_vs_codecs, NUM_VS_CODECS,
113 		      "Reading vendor codecs count failed");
114 	for (i = 0; i < num_vs_codecs; i++) {
115 		const struct bt_hci_vs_codec_info_v2 *codec;
116 
117 		codec = (const struct bt_hci_vs_codec_info_v2 *)ptr;
118 		ptr += sizeof(*codec);
119 		zassert_equal(codec->company_id,
120 			      sys_cpu_to_le16(vs_codecs[i].company_id),
121 			      "Reading vendor codecs company_id %d failed", i);
122 		zassert_equal(codec->codec_id,
123 			      sys_cpu_to_le16(vs_codecs[i].codec_id),
124 			      "Reading vendor codecs codec_id %d failed", i);
125 		zassert_equal(codec->transports, vs_codecs[i].transports,
126 			      "Reading vendor codecs transports %d failed", i);
127 	}
128 
129 	net_buf_unref(rsp);
130 }
131 
132 #define NUM_CAPABILITIES 2
133 #define CODEC_CAPAB_0 'Z', 'e', 'p', 'h', 'y', 'r'
134 #define CODEC_CAPAB_1 'C', 'o', 'd', 'e', 'c'
135 static const uint8_t codec_capabilities[] = {
136 	sizeof((uint8_t []){CODEC_CAPAB_0}), CODEC_CAPAB_0,
137 	sizeof((uint8_t []){CODEC_CAPAB_1}), CODEC_CAPAB_1,
138 };
139 
140 #define READ_CAPABS_CODING_FMT 0xff
141 #define READ_CAPABS_COMPANY_ID 0x1234
142 #define READ_CAPABS_VS_CODEC_ID 0x5678
143 #define READ_CAPABS_TRANSPORT BT_HCI_LOGICAL_TRANSPORT_TYPE_LE_CIS
144 #define READ_CAPABS_DIRECTION BT_HCI_DATAPATH_DIR_CTLR_TO_HOST
145 
hci_vendor_read_codec_capabilities(uint8_t coding_format,uint16_t company_id,uint16_t vs_codec_id,uint8_t transport,uint8_t direction,uint8_t * num_capabilities,size_t * capabilities_bytes,const uint8_t ** capabilities)146 uint8_t hci_vendor_read_codec_capabilities(uint8_t coding_format,
147 					   uint16_t company_id,
148 					   uint16_t vs_codec_id,
149 					   uint8_t transport,
150 					   uint8_t direction,
151 					   uint8_t *num_capabilities,
152 					   size_t *capabilities_bytes,
153 					   const uint8_t **capabilities)
154 {
155 	/* Check input parameters */
156 	zassert_equal(coding_format, READ_CAPABS_CODING_FMT,
157 		      "Reading codec capabilities passed wrong coding_format");
158 	zassert_equal(company_id, READ_CAPABS_COMPANY_ID,
159 		      "Reading codec capabilities passed wrong company_id");
160 	zassert_equal(vs_codec_id, READ_CAPABS_VS_CODEC_ID,
161 		      "Reading codec capabilities passed wrong vs_codec_id");
162 	zassert_equal(transport, READ_CAPABS_TRANSPORT,
163 		      "Reading codec capabilities passed wrong transport");
164 	zassert_equal(direction, READ_CAPABS_DIRECTION,
165 		      "Reading codec capabilities passed wrong direction");
166 
167 	/* Fill in response data */
168 	*num_capabilities = NUM_CAPABILITIES;
169 	*capabilities_bytes = sizeof(codec_capabilities);
170 	*capabilities = codec_capabilities;
171 
172 	return 0;
173 }
174 
ZTEST(test_hci_codecs_info,test_read_codec_capabilities)175 ZTEST(test_hci_codecs_info, test_read_codec_capabilities)
176 {
177 	struct bt_hci_cp_read_codec_capabilities *cp;
178 	struct bt_hci_rp_read_codec_capabilities *rp;
179 	struct net_buf *buf;
180 	struct net_buf *rsp;
181 	const uint8_t *ptr;
182 	int err;
183 
184 	/* Initialize bluetooth subsystem */
185 	bt_enable(NULL);
186 
187 	/* Read Local Supported Codec Capabilities */
188 	buf = bt_hci_cmd_create(BT_HCI_OP_READ_CODEC_CAPABILITIES, sizeof(*cp));
189 	cp = net_buf_add(buf, sizeof(*cp));
190 
191 	cp->codec_id.coding_format = READ_CAPABS_CODING_FMT;
192 	cp->codec_id.company_id = sys_cpu_to_le16(READ_CAPABS_COMPANY_ID);
193 	cp->codec_id.vs_codec_id = sys_cpu_to_le16(READ_CAPABS_VS_CODEC_ID);
194 	cp->transport = READ_CAPABS_TRANSPORT;
195 	cp->direction = READ_CAPABS_DIRECTION;
196 
197 	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_CODEC_CAPABILITIES,
198 				   buf, &rsp);
199 	zassert_equal(err, 0,
200 		      "Reading local supported codec capabilities failed");
201 
202 	/* Check returned data */
203 	rp = (struct bt_hci_rp_read_codec_capabilities *)rsp->data;
204 	zassert_equal(rp->status, 0,
205 		      "Reading codec capabilities status failed");
206 	zassert_equal(rp->num_capabilities, NUM_CAPABILITIES,
207 		      "Reading codec capabilities count failed");
208 	ptr = &rp->capabilities[0];
209 	zassert_mem_equal(ptr, codec_capabilities, sizeof(codec_capabilities),
210 			  0, "Reading codec capabilities content failed");
211 }
212 
213 #define READ_DELAY_CODING_FMT 0xff
214 #define READ_DELAY_COMPANY_ID 0x9abc
215 #define READ_DELAY_VS_CODEC_ID 0xdef0
216 #define READ_DELAY_TRANSPORT BT_HCI_LOGICAL_TRANSPORT_TYPE_LE_BIS
217 #define READ_DELAY_DIRECTION BT_HCI_DATAPATH_DIR_HOST_TO_CTLR
218 const uint8_t read_delay_codec_config[] = { 17, 23, 42, 18, 86 };
219 
220 #define MIN_CTLR_DELAY 0x12
221 #define MAX_CTLR_DELAY 0x3456
222 
hci_vendor_read_ctlr_delay(uint8_t coding_format,uint16_t company_id,uint16_t vs_codec_id,uint8_t transport,uint8_t direction,uint8_t codec_config_len,const uint8_t * codec_config,uint32_t * min_delay,uint32_t * max_delay)223 uint8_t hci_vendor_read_ctlr_delay(uint8_t coding_format,
224 				   uint16_t company_id,
225 				   uint16_t vs_codec_id,
226 				   uint8_t transport,
227 				   uint8_t direction,
228 				   uint8_t codec_config_len,
229 				   const uint8_t *codec_config,
230 				   uint32_t *min_delay,
231 				   uint32_t *max_delay)
232 {
233 	/* Check input parameters */
234 	zassert_equal(coding_format, READ_DELAY_CODING_FMT,
235 		      "Reading controller delay passed wrong coding_format");
236 	zassert_equal(company_id, READ_DELAY_COMPANY_ID,
237 		      "Reading controller delay passed wrong company_id");
238 	zassert_equal(vs_codec_id, READ_DELAY_VS_CODEC_ID,
239 		      "Reading controller delay passed wrong vs_codec_id");
240 	zassert_equal(transport, READ_DELAY_TRANSPORT,
241 		      "Reading controller delay passed wrong transport");
242 	zassert_equal(direction, READ_DELAY_DIRECTION,
243 		      "Reading controller delay passed wrong direction");
244 	zassert_equal(codec_config_len, sizeof(read_delay_codec_config),
245 		      "Reading controller delay passed wrong config length");
246 	zassert_equal(memcmp(codec_config, read_delay_codec_config,
247 			     codec_config_len), 0,
248 		      "Reading controller delay passed wrong config data");
249 
250 	/* Fill in response data */
251 	*min_delay = MIN_CTLR_DELAY;
252 	*max_delay = MAX_CTLR_DELAY;
253 
254 	return 0;
255 }
256 
ZTEST(test_hci_codecs_info,test_read_ctlr_delay)257 ZTEST(test_hci_codecs_info, test_read_ctlr_delay)
258 {
259 	struct bt_hci_cp_read_ctlr_delay *cp;
260 	struct bt_hci_rp_read_ctlr_delay *rp;
261 	struct net_buf *buf;
262 	struct net_buf *rsp;
263 	int err;
264 
265 	/* Initialize bluetooth subsystem */
266 	bt_enable(NULL);
267 
268 	/* Read Local Supported Controller Delay */
269 	buf = bt_hci_cmd_create(BT_HCI_OP_READ_CTLR_DELAY, sizeof(*cp));
270 	cp = net_buf_add(buf, sizeof(*cp) + sizeof(read_delay_codec_config));
271 
272 	cp->codec_id.coding_format = READ_DELAY_CODING_FMT;
273 	cp->codec_id.company_id = sys_cpu_to_le16(READ_DELAY_COMPANY_ID);
274 	cp->codec_id.vs_codec_id = sys_cpu_to_le16(READ_DELAY_VS_CODEC_ID);
275 	cp->transport = READ_DELAY_TRANSPORT;
276 	cp->direction = READ_DELAY_DIRECTION;
277 	cp->codec_config_len = sizeof(read_delay_codec_config);
278 	memcpy(cp->codec_config, read_delay_codec_config,
279 	       sizeof(read_delay_codec_config));
280 
281 	err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_CTLR_DELAY, buf, &rsp);
282 	zassert_equal(err, 0,
283 		      "Reading local supported controller delay failed");
284 
285 	/* Check returned data */
286 	rp = (struct bt_hci_rp_read_ctlr_delay *)rsp->data;
287 	zassert_equal(rp->status, 0,
288 		      "Reading controller delay status failed");
289 	zassert_equal(sys_get_le24(rp->min_ctlr_delay), MIN_CTLR_DELAY,
290 		      "Reading controller min delay failed");
291 	zassert_equal(sys_get_le24(rp->max_ctlr_delay), MAX_CTLR_DELAY,
292 		      "Reading controller max delay failed");
293 }
294