1 /* Common functions for LE Audio services */
2 
3 /*
4  * Copyright (c) 2022 Codecoup
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/bluetooth/att.h>
10 #include <zephyr/bluetooth/conn.h>
11 #include <zephyr/bluetooth/hci.h>
12 #include <zephyr/bluetooth/audio/audio.h>
13 #include <zephyr/bluetooth/audio/bap.h>
14 #include <zephyr/logging/log.h>
15 #include <zephyr/sys/check.h>
16 
17 #include "audio_internal.h"
18 
19 LOG_MODULE_REGISTER(bt_audio, CONFIG_BT_AUDIO_LOG_LEVEL);
20 
21 #if defined(CONFIG_BT_CONN)
22 
bt_audio_security_check(const struct bt_conn * conn)23 static uint8_t bt_audio_security_check(const struct bt_conn *conn)
24 {
25 	struct bt_conn_info info;
26 	int err;
27 
28 	err = bt_conn_get_info(conn, &info);
29 	if (err < 0) {
30 		return BT_ATT_ERR_UNLIKELY;
31 	}
32 
33 	/* Require an encryption key with at least 128 bits of entropy, derived from SC or OOB
34 	 * method.
35 	 */
36 	if ((info.security.flags & (BT_SECURITY_FLAG_OOB | BT_SECURITY_FLAG_SC)) == 0) {
37 		/* If the client has insufficient security to read/write the requested attribute
38 		 * then an ATT_ERROR_RSP PDU shall be sent with the Error Code parameter set to
39 		 * Insufficient Authentication (0x05).
40 		 */
41 		return BT_ATT_ERR_AUTHENTICATION;
42 	}
43 
44 	if (info.security.enc_key_size < BT_ENC_KEY_SIZE_MAX) {
45 		return BT_ATT_ERR_ENCRYPTION_KEY_SIZE;
46 	}
47 
48 	return BT_ATT_ERR_SUCCESS;
49 }
50 
bt_audio_read_chrc(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)51 ssize_t bt_audio_read_chrc(struct bt_conn *conn, const struct bt_gatt_attr *attr,
52 			   void *buf, uint16_t len, uint16_t offset)
53 {
54 	const struct bt_audio_attr_user_data *user_data = attr->user_data;
55 
56 	if (user_data->read == NULL) {
57 		return BT_GATT_ERR(BT_ATT_ERR_READ_NOT_PERMITTED);
58 	}
59 
60 	if (conn != NULL) {
61 		uint8_t err;
62 
63 		err = bt_audio_security_check(conn);
64 		if (err != 0) {
65 			return BT_GATT_ERR(err);
66 		}
67 	}
68 
69 	return user_data->read(conn, attr, buf, len, offset);
70 }
71 
bt_audio_write_chrc(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * buf,uint16_t len,uint16_t offset,uint8_t flags)72 ssize_t bt_audio_write_chrc(struct bt_conn *conn, const struct bt_gatt_attr *attr,
73 			    const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
74 {
75 	const struct bt_audio_attr_user_data *user_data = attr->user_data;
76 
77 	if (user_data->write == NULL) {
78 		return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
79 	}
80 
81 	if (conn != NULL) {
82 		uint8_t err;
83 
84 		err = bt_audio_security_check(conn);
85 		if (err != 0) {
86 			return BT_GATT_ERR(err);
87 		}
88 	}
89 
90 	return user_data->write(conn, attr, buf, len, offset, flags);
91 }
92 
bt_audio_ccc_cfg_write(struct bt_conn * conn,const struct bt_gatt_attr * attr,uint16_t value)93 ssize_t bt_audio_ccc_cfg_write(struct bt_conn *conn, const struct bt_gatt_attr *attr,
94 			       uint16_t value)
95 {
96 	if (conn != NULL) {
97 		uint8_t err;
98 
99 		err = bt_audio_security_check(conn);
100 		if (err != 0) {
101 			return BT_GATT_ERR(err);
102 		}
103 	}
104 
105 	return sizeof(value);
106 }
107 #endif /* CONFIG_BT_CONN */
108 
109 /* Broadcast sink depends on Scan Delegator, so we can just guard it with the Scan Delegator */
110 #if defined(CONFIG_BT_BAP_SCAN_DELEGATOR)
111 
decode_codec_ltv(struct net_buf_simple * buf,struct bt_codec_data * codec_data)112 static int decode_codec_ltv(struct net_buf_simple *buf,
113 			    struct bt_codec_data *codec_data)
114 {
115 	void *value;
116 
117 	if (buf->len < sizeof(codec_data->data.data_len)) {
118 		LOG_DBG("Not enough data for LTV length field: %u", buf->len);
119 
120 		return -ENOMEM;
121 	}
122 
123 	codec_data->data.data_len = net_buf_simple_pull_u8(buf);
124 
125 	if (buf->len < sizeof(codec_data->data.type)) {
126 		LOG_DBG("Not enough data for LTV type field: %u", buf->len);
127 
128 		return -EMSGSIZE;
129 	}
130 
131 	/* LTV structures include the data.type in the length field,
132 	 * but we do not do that for the bt_data struct in Zephyr
133 	 */
134 	codec_data->data.data_len -= sizeof(codec_data->data.type);
135 
136 	codec_data->data.type = net_buf_simple_pull_u8(buf);
137 
138 	codec_data->data.data = codec_data->value;
139 
140 	if (buf->len < codec_data->data.data_len) {
141 		LOG_DBG("Not enough data for LTV value field: %u/%zu", buf->len,
142 			codec_data->data.data_len);
143 
144 		return -EMSGSIZE;
145 	}
146 
147 	value = net_buf_simple_pull_mem(buf, codec_data->data.data_len);
148 	(void)memcpy(codec_data->value, value, codec_data->data.data_len);
149 
150 	return 0;
151 }
152 
decode_bis_data(struct net_buf_simple * buf,struct bt_bap_base_bis_data * bis)153 static int decode_bis_data(struct net_buf_simple *buf, struct bt_bap_base_bis_data *bis)
154 {
155 	uint8_t len;
156 
157 	if (buf->len < BT_BAP_BASE_BIS_DATA_MIN_SIZE) {
158 		LOG_DBG("Not enough bytes (%u) to decode BIS data", buf->len);
159 
160 		return -ENOMEM;
161 	}
162 
163 	bis->index = net_buf_simple_pull_u8(buf);
164 	if (!IN_RANGE(bis->index, BT_ISO_BIS_INDEX_MIN, BT_ISO_BIS_INDEX_MAX)) {
165 		LOG_DBG("Invalid BIS index %u", bis->index);
166 
167 		return -EINVAL;
168 	}
169 
170 	/* codec config data length */
171 	len = net_buf_simple_pull_u8(buf);
172 	if (len > buf->len) {
173 		LOG_DBG("Invalid BIS specific codec config data length: %u (buf is %u)", len,
174 			buf->len);
175 
176 		return -EMSGSIZE;
177 	}
178 
179 	if (len > 0) {
180 		struct net_buf_simple ltv_buf;
181 		void *ltv_data;
182 
183 		/* Use an extra net_buf_simple to be able to decode until it
184 		 * is empty (len = 0)
185 		 */
186 		ltv_data = net_buf_simple_pull_mem(buf, len);
187 		net_buf_simple_init_with_data(&ltv_buf, ltv_data, len);
188 
189 
190 		while (ltv_buf.len != 0) {
191 			struct bt_codec_data *bis_codec_data;
192 			int err;
193 
194 			if (bis->data_count >= ARRAY_SIZE(bis->data)) {
195 				LOG_WRN("BIS data overflow; discarding");
196 				break;
197 			}
198 
199 			bis_codec_data = &bis->data[bis->data_count];
200 
201 			err = decode_codec_ltv(&ltv_buf, bis_codec_data);
202 			if (err != 0) {
203 				LOG_DBG("Failed to decode BIS config data for entry[%u]: %d",
204 					bis->data_count, err);
205 
206 				return err;
207 			}
208 
209 			bis->data_count++;
210 		}
211 	}
212 
213 	return 0;
214 }
215 
decode_subgroup(struct net_buf_simple * buf,struct bt_bap_base_subgroup * subgroup)216 static int decode_subgroup(struct net_buf_simple *buf, struct bt_bap_base_subgroup *subgroup)
217 {
218 	struct net_buf_simple ltv_buf;
219 	struct bt_codec	*codec;
220 	void *ltv_data;
221 	uint8_t len;
222 
223 	codec = &subgroup->codec;
224 
225 	subgroup->bis_count = net_buf_simple_pull_u8(buf);
226 	if (subgroup->bis_count > ARRAY_SIZE(subgroup->bis_data)) {
227 		LOG_DBG("BASE has more BIS %u than we support %u", subgroup->bis_count,
228 			(uint8_t)ARRAY_SIZE(subgroup->bis_data));
229 
230 		return -ENOMEM;
231 	}
232 
233 	codec->id = net_buf_simple_pull_u8(buf);
234 	codec->cid = net_buf_simple_pull_le16(buf);
235 	codec->vid = net_buf_simple_pull_le16(buf);
236 
237 	/* codec configuration data length */
238 	len = net_buf_simple_pull_u8(buf);
239 	if (len > buf->len) {
240 		LOG_DBG("Invalid codec config data length: %u (buf is %u)", len, buf->len);
241 
242 		return -EINVAL;
243 	}
244 
245 #if CONFIG_BT_CODEC_MAX_DATA_COUNT > 0
246 	/* Use an extra net_buf_simple to be able to decode until it
247 	 * is empty (len = 0)
248 	 */
249 	ltv_data = net_buf_simple_pull_mem(buf, len);
250 	net_buf_simple_init_with_data(&ltv_buf, ltv_data, len);
251 
252 	/* The loop below is very similar to codec_config_store with notable
253 	 * exceptions that it can do early termination, and also does not log
254 	 * every LTV entry, which would simply be too much for handling
255 	 * broadcasted BASEs
256 	 */
257 	while (ltv_buf.len != 0) {
258 		struct bt_codec_data *codec_data;
259 		int err;
260 
261 		if (codec->data_count >= ARRAY_SIZE(codec->data)) {
262 			LOG_WRN("BIS codec data overflow; discarding");
263 			break;
264 		}
265 
266 		codec_data = &codec->data[codec->data_count];
267 
268 		err = decode_codec_ltv(&ltv_buf, codec_data);
269 		if (err != 0) {
270 			LOG_DBG("Failed to decode codec config data for entry %u: %d",
271 				codec->data_count, err);
272 
273 			return err;
274 		}
275 
276 		codec->data_count++;
277 	}
278 
279 	if (buf->len < sizeof(len)) {
280 		LOG_DBG("Cannot store BASE in buffer");
281 
282 		return -ENOMEM;
283 	}
284 #else /* CONFIG_BT_CODEC_MAX_DATA_COUNT == 0 */
285 	if (len > 0) {
286 		LOG_DBG("Cannot store codec config data");
287 
288 		return -ENOMEM;
289 	}
290 #endif /* CONFIG_BT_CODEC_MAX_DATA_COUNT */
291 
292 	/* codec metadata length */
293 	len = net_buf_simple_pull_u8(buf);
294 	if (len > buf->len) {
295 		LOG_DBG("Invalid codec config data length: %u (buf is %u)", len, buf->len);
296 
297 		return -EMSGSIZE;
298 	}
299 
300 #if CONFIG_BT_CODEC_MAX_METADATA_COUNT > 0
301 	/* Use an extra net_buf_simple to be able to decode until it
302 	 * is empty (len = 0)
303 	 */
304 	ltv_data = net_buf_simple_pull_mem(buf, len);
305 	net_buf_simple_init_with_data(&ltv_buf, ltv_data, len);
306 
307 	/* The loop below is very similar to codec_config_store with notable
308 	 * exceptions that it can do early termination, and also does not log
309 	 * every LTV entry, which would simply be too much for handling
310 	 * broadcasted BASEs
311 	 */
312 	while (ltv_buf.len != 0) {
313 		struct bt_codec_data *metadata;
314 		int err;
315 
316 		if (codec->meta_count >= ARRAY_SIZE(codec->meta)) {
317 			LOG_WRN("BIS codec metadata overflow; discarding");
318 			break;
319 		}
320 
321 		metadata = &codec->meta[codec->meta_count];
322 
323 		err = decode_codec_ltv(&ltv_buf, metadata);
324 		if (err != 0) {
325 			LOG_DBG("Failed to decode codec metadata for entry %u: %d",
326 				codec->meta_count, err);
327 
328 			return err;
329 		}
330 
331 		codec->meta_count++;
332 	}
333 #else /* CONFIG_BT_CODEC_MAX_METADATA_COUNT == 0 */
334 	if (len > 0) {
335 		LOG_DBG("Cannot store metadata");
336 
337 		return -ENOMEM;
338 	}
339 #endif /* CONFIG_BT_CODEC_MAX_METADATA_COUNT */
340 
341 	for (size_t i = 0U; i < subgroup->bis_count; i++) {
342 		const int err = decode_bis_data(buf, &subgroup->bis_data[i]);
343 
344 		if (err != 0) {
345 			LOG_DBG("Failed to decode BIS data for bis[%zu]: %d", i, err);
346 
347 			return err;
348 		}
349 	}
350 
351 	return 0;
352 }
353 
bt_bap_decode_base(struct bt_data * data,struct bt_bap_base * base)354 int bt_bap_decode_base(struct bt_data *data, struct bt_bap_base *base)
355 {
356 	struct bt_uuid_16 broadcast_uuid;
357 	struct net_buf_simple net_buf;
358 	void *uuid;
359 
360 	CHECKIF(data == NULL) {
361 		LOG_DBG("data is NULL");
362 
363 		return -EINVAL;
364 	}
365 
366 	CHECKIF(base == NULL) {
367 		LOG_DBG("base is NULL");
368 
369 		return -EINVAL;
370 	}
371 
372 	if (data->type != BT_DATA_SVC_DATA16) {
373 		LOG_DBG("Invalid type: %u", data->type);
374 
375 		return -ENOMSG;
376 	}
377 
378 	if (data->data_len < BT_BAP_BASE_MIN_SIZE) {
379 		return -EMSGSIZE;
380 	}
381 
382 	net_buf_simple_init_with_data(&net_buf, (void *)data->data,
383 				      data->data_len);
384 
385 	uuid = net_buf_simple_pull_mem(&net_buf, BT_UUID_SIZE_16);
386 	if (!bt_uuid_create(&broadcast_uuid.uuid, uuid, BT_UUID_SIZE_16)) {
387 		LOG_ERR("bt_uuid_create failed");
388 
389 		return -EINVAL;
390 	}
391 
392 	if (bt_uuid_cmp(&broadcast_uuid.uuid, BT_UUID_BASIC_AUDIO) != 0) {
393 		LOG_DBG("Invalid UUID");
394 
395 		return -ENOMSG;
396 	}
397 
398 	base->pd = net_buf_simple_pull_le24(&net_buf);
399 	base->subgroup_count = net_buf_simple_pull_u8(&net_buf);
400 
401 	if (base->subgroup_count > ARRAY_SIZE(base->subgroups)) {
402 		LOG_DBG("Cannot decode BASE with %u subgroups (max supported is %zu)",
403 			base->subgroup_count, ARRAY_SIZE(base->subgroups));
404 
405 		return -ENOMEM;
406 	}
407 
408 	for (size_t i = 0U; i < base->subgroup_count; i++) {
409 		const int err = decode_subgroup(&net_buf, &base->subgroups[i]);
410 
411 		if (err != 0) {
412 			LOG_DBG("Failed to decode subgroup[%zu]: %d", i, err);
413 
414 			return err;
415 		}
416 	}
417 
418 	return 0;
419 }
420 #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR */
421 
bt_audio_codec_data_to_buf(const struct bt_codec_data * codec_data,size_t count,uint8_t * buf,size_t buf_size)422 ssize_t bt_audio_codec_data_to_buf(const struct bt_codec_data *codec_data, size_t count,
423 				   uint8_t *buf, size_t buf_size)
424 {
425 	size_t total_len = 0;
426 
427 	for (size_t i = 0; i < count; i++) {
428 		const struct bt_data *ltv = &codec_data[i].data;
429 		const uint8_t length = ltv->data_len;
430 		const uint8_t type = ltv->type;
431 		const uint8_t *value = ltv->data;
432 		const size_t ltv_len = sizeof(length) + sizeof(type) + length;
433 
434 		/* Verify that the buffer can hold the next LTV structure */
435 		if (buf_size < total_len + ltv_len) {
436 			return -ENOMEM;
437 		}
438 
439 		/* Copy data */
440 		buf[total_len++] = length + sizeof(type);
441 		buf[total_len++] = type;
442 		(void)memcpy(&buf[total_len], value, length);
443 
444 		total_len += length;
445 	}
446 
447 	return total_len;
448 }
449