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 
bt_audio_data_parse(const uint8_t ltv[],size_t size,bool (* func)(struct bt_data * data,void * user_data),void * user_data)21 int bt_audio_data_parse(const uint8_t ltv[], size_t size,
22 			bool (*func)(struct bt_data *data, void *user_data), void *user_data)
23 {
24 	CHECKIF(ltv == NULL) {
25 		LOG_DBG("ltv is NULL");
26 
27 		return -EINVAL;
28 	}
29 
30 	CHECKIF(func == NULL) {
31 		LOG_DBG("func is NULL");
32 
33 		return -EINVAL;
34 	}
35 
36 	for (size_t i = 0; i < size;) {
37 		const uint8_t len = ltv[i];
38 		struct bt_data data;
39 
40 		if (i + len > size || len < sizeof(data.type)) {
41 			LOG_DBG("Invalid len %u at i = %zu", len, i);
42 
43 			return -EINVAL;
44 		}
45 
46 		i++; /* Increment as we have parsed the len field */
47 
48 		data.type = ltv[i++];
49 		data.data_len = len - sizeof(data.type);
50 
51 		if (data.data_len > 0) {
52 			data.data = &ltv[i];
53 		} else {
54 			data.data = NULL;
55 		}
56 
57 		if (!func(&data, user_data)) {
58 			return -ECANCELED;
59 		}
60 
61 		/* Since we are incrementing i by the value_len, we don't need to increment it
62 		 * further in the `for` statement
63 		 */
64 		i += data.data_len;
65 	}
66 
67 	return 0;
68 }
69 
70 #if defined(CONFIG_BT_CONN)
71 
bt_audio_security_check(const struct bt_conn * conn)72 static uint8_t bt_audio_security_check(const struct bt_conn *conn)
73 {
74 	struct bt_conn_info info;
75 	int err;
76 
77 	err = bt_conn_get_info(conn, &info);
78 	if (err < 0) {
79 		return BT_ATT_ERR_UNLIKELY;
80 	}
81 
82 	/* Require an encryption key with at least 128 bits of entropy, derived from SC or OOB
83 	 * method.
84 	 */
85 	if ((info.security.flags & (BT_SECURITY_FLAG_OOB | BT_SECURITY_FLAG_SC)) == 0) {
86 		/* If the client has insufficient security to read/write the requested attribute
87 		 * then an ATT_ERROR_RSP PDU shall be sent with the Error Code parameter set to
88 		 * Insufficient Authentication (0x05).
89 		 */
90 		return BT_ATT_ERR_AUTHENTICATION;
91 	}
92 
93 	if (info.security.enc_key_size < BT_ENC_KEY_SIZE_MAX) {
94 		return BT_ATT_ERR_ENCRYPTION_KEY_SIZE;
95 	}
96 
97 	return BT_ATT_ERR_SUCCESS;
98 }
99 
bt_audio_read_chrc(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)100 ssize_t bt_audio_read_chrc(struct bt_conn *conn, const struct bt_gatt_attr *attr,
101 			   void *buf, uint16_t len, uint16_t offset)
102 {
103 	const struct bt_audio_attr_user_data *user_data = attr->user_data;
104 
105 	if (user_data->read == NULL) {
106 		return BT_GATT_ERR(BT_ATT_ERR_READ_NOT_PERMITTED);
107 	}
108 
109 	if (conn != NULL) {
110 		uint8_t err;
111 
112 		err = bt_audio_security_check(conn);
113 		if (err != 0) {
114 			return BT_GATT_ERR(err);
115 		}
116 	}
117 
118 	return user_data->read(conn, attr, buf, len, offset);
119 }
120 
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)121 ssize_t bt_audio_write_chrc(struct bt_conn *conn, const struct bt_gatt_attr *attr,
122 			    const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
123 {
124 	const struct bt_audio_attr_user_data *user_data = attr->user_data;
125 
126 	if (user_data->write == NULL) {
127 		return BT_GATT_ERR(BT_ATT_ERR_WRITE_NOT_PERMITTED);
128 	}
129 
130 	if (conn != NULL) {
131 		uint8_t err;
132 
133 		err = bt_audio_security_check(conn);
134 		if (err != 0) {
135 			return BT_GATT_ERR(err);
136 		}
137 	}
138 
139 	return user_data->write(conn, attr, buf, len, offset, flags);
140 }
141 
bt_audio_ccc_cfg_write(struct bt_conn * conn,const struct bt_gatt_attr * attr,uint16_t value)142 ssize_t bt_audio_ccc_cfg_write(struct bt_conn *conn, const struct bt_gatt_attr *attr,
143 			       uint16_t value)
144 {
145 	if (conn != NULL) {
146 		uint8_t err;
147 
148 		err = bt_audio_security_check(conn);
149 		if (err != 0) {
150 			return BT_GATT_ERR(err);
151 		}
152 	}
153 
154 	return sizeof(value);
155 }
156 #endif /* CONFIG_BT_CONN */
157 
158 /* Broadcast sink depends on Scan Delegator, so we can just guard it with the Scan Delegator */
159 #if defined(CONFIG_BT_BAP_SCAN_DELEGATOR)
160 
decode_bis_data(struct net_buf_simple * buf,struct bt_bap_base_bis_data * bis)161 static int decode_bis_data(struct net_buf_simple *buf, struct bt_bap_base_bis_data *bis)
162 {
163 	uint8_t len;
164 
165 	if (buf->len < BT_BAP_BASE_BIS_DATA_MIN_SIZE) {
166 		LOG_DBG("Not enough bytes (%u) to decode BIS data", buf->len);
167 
168 		return -ENOMEM;
169 	}
170 
171 	bis->index = net_buf_simple_pull_u8(buf);
172 	if (!IN_RANGE(bis->index, BT_ISO_BIS_INDEX_MIN, BT_ISO_BIS_INDEX_MAX)) {
173 		LOG_DBG("Invalid BIS index %u", bis->index);
174 
175 		return -EINVAL;
176 	}
177 
178 	/* codec config data length */
179 	len = net_buf_simple_pull_u8(buf);
180 	if (len > buf->len) {
181 		LOG_DBG("Invalid BIS specific codec config data length: %u (buf is %u)", len,
182 			buf->len);
183 
184 		return -EMSGSIZE;
185 	}
186 
187 	if (len > 0) {
188 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0
189 		void *ltv_data;
190 
191 		if (len > sizeof(bis->data)) {
192 			LOG_DBG("Cannot store codec config data of length %u", len);
193 
194 			return -ENOMEM;
195 		}
196 
197 		ltv_data = net_buf_simple_pull_mem(buf, len);
198 
199 		bis->data_len = len;
200 		memcpy(bis->data, ltv_data, len);
201 #else  /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE == 0 */
202 		LOG_DBG("Cannot store codec config data");
203 
204 		return -ENOMEM;
205 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE */
206 	}
207 
208 	return 0;
209 }
210 
decode_subgroup(struct net_buf_simple * buf,struct bt_bap_base_subgroup * subgroup)211 static int decode_subgroup(struct net_buf_simple *buf, struct bt_bap_base_subgroup *subgroup)
212 {
213 	struct bt_audio_codec_cfg *codec_cfg;
214 	uint8_t len;
215 
216 	codec_cfg = &subgroup->codec_cfg;
217 
218 	subgroup->bis_count = net_buf_simple_pull_u8(buf);
219 	if (subgroup->bis_count > ARRAY_SIZE(subgroup->bis_data)) {
220 		LOG_DBG("BASE has more BIS %u than we support %u", subgroup->bis_count,
221 			(uint8_t)ARRAY_SIZE(subgroup->bis_data));
222 
223 		return -ENOMEM;
224 	}
225 
226 	codec_cfg->id = net_buf_simple_pull_u8(buf);
227 	codec_cfg->cid = net_buf_simple_pull_le16(buf);
228 	codec_cfg->vid = net_buf_simple_pull_le16(buf);
229 
230 	/* codec configuration data length */
231 	len = net_buf_simple_pull_u8(buf);
232 	if (len > buf->len) {
233 		LOG_DBG("Invalid codec config data length: %u (buf is %u)", len, buf->len);
234 
235 		return -EINVAL;
236 	}
237 
238 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0
239 	void *cfg_ltv_data;
240 
241 	if (len > sizeof(subgroup->codec_cfg.data)) {
242 		LOG_DBG("Cannot store codec config data of length %u", len);
243 
244 		return -ENOMEM;
245 	}
246 
247 	cfg_ltv_data = net_buf_simple_pull_mem(buf, len);
248 
249 	subgroup->codec_cfg.data_len = len;
250 	memcpy(subgroup->codec_cfg.data, cfg_ltv_data, len);
251 #else  /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE == 0 */
252 	if (len > 0) {
253 		LOG_DBG("Cannot store codec config data of length %u", len);
254 
255 		return -ENOMEM;
256 	}
257 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */
258 
259 	/* codec metadata length */
260 	len = net_buf_simple_pull_u8(buf);
261 	if (len > buf->len) {
262 		LOG_DBG("Invalid codec config data length: %u (buf is %u)", len, buf->len);
263 
264 		return -EMSGSIZE;
265 	}
266 
267 #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0
268 	void *meta_ltv_data;
269 
270 	if (len > sizeof(subgroup->codec_cfg.meta)) {
271 		LOG_DBG("Cannot store codec config meta of length %u", len);
272 
273 		return -ENOMEM;
274 	}
275 
276 	meta_ltv_data = net_buf_simple_pull_mem(buf, len);
277 
278 	subgroup->codec_cfg.meta_len = len;
279 	memcpy(subgroup->codec_cfg.meta, meta_ltv_data, len);
280 #else  /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE == 0 */
281 	if (len > 0) {
282 		LOG_DBG("Cannot store metadata");
283 
284 		return -ENOMEM;
285 	}
286 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE */
287 
288 	for (size_t i = 0U; i < subgroup->bis_count; i++) {
289 		const int err = decode_bis_data(buf, &subgroup->bis_data[i]);
290 
291 		if (err != 0) {
292 			LOG_DBG("Failed to decode BIS data for bis[%zu]: %d", i, err);
293 
294 			return err;
295 		}
296 	}
297 
298 	return 0;
299 }
300 
bt_bap_decode_base(struct bt_data * data,struct bt_bap_base * base)301 int bt_bap_decode_base(struct bt_data *data, struct bt_bap_base *base)
302 {
303 	struct bt_uuid_16 broadcast_uuid;
304 	struct net_buf_simple net_buf;
305 	void *uuid;
306 
307 	CHECKIF(data == NULL) {
308 		LOG_DBG("data is NULL");
309 
310 		return -EINVAL;
311 	}
312 
313 	CHECKIF(base == NULL) {
314 		LOG_DBG("base is NULL");
315 
316 		return -EINVAL;
317 	}
318 
319 	if (data->type != BT_DATA_SVC_DATA16) {
320 		LOG_DBG("Invalid type: %u", data->type);
321 
322 		return -ENOMSG;
323 	}
324 
325 	if (data->data_len < BT_BAP_BASE_MIN_SIZE) {
326 		return -EMSGSIZE;
327 	}
328 
329 	net_buf_simple_init_with_data(&net_buf, (void *)data->data,
330 				      data->data_len);
331 
332 	uuid = net_buf_simple_pull_mem(&net_buf, BT_UUID_SIZE_16);
333 	if (!bt_uuid_create(&broadcast_uuid.uuid, uuid, BT_UUID_SIZE_16)) {
334 		LOG_ERR("bt_uuid_create failed");
335 
336 		return -EINVAL;
337 	}
338 
339 	if (bt_uuid_cmp(&broadcast_uuid.uuid, BT_UUID_BASIC_AUDIO) != 0) {
340 		LOG_DBG("Invalid UUID");
341 
342 		return -ENOMSG;
343 	}
344 
345 	base->pd = net_buf_simple_pull_le24(&net_buf);
346 	base->subgroup_count = net_buf_simple_pull_u8(&net_buf);
347 
348 	if (base->subgroup_count > ARRAY_SIZE(base->subgroups)) {
349 		LOG_DBG("Cannot decode BASE with %u subgroups (max supported is %zu)",
350 			base->subgroup_count, ARRAY_SIZE(base->subgroups));
351 
352 		return -ENOMEM;
353 	}
354 
355 	for (size_t i = 0U; i < base->subgroup_count; i++) {
356 		const int err = decode_subgroup(&net_buf, &base->subgroups[i]);
357 
358 		if (err != 0) {
359 			LOG_DBG("Failed to decode subgroup[%zu]: %d", i, err);
360 
361 			return err;
362 		}
363 	}
364 
365 	return 0;
366 }
367 #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR */
368