1 /*  Bluetooth BAP Broadcast Assistant */
2 
3 /*
4  * Copyright (c) 2019 Bose Corporation
5  * Copyright (c) 2022-2023 Nordic Semiconductor ASA
6  * Copyright (c) 2024 Demant A/S
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 #include <errno.h>
12 #include <stdbool.h>
13 #include <stddef.h>
14 #include <stdint.h>
15 #include <string.h>
16 
17 #include <zephyr/autoconf.h>
18 #include <zephyr/bluetooth/addr.h>
19 #include <zephyr/bluetooth/audio/audio.h>
20 #include <zephyr/bluetooth/audio/bap.h>
21 #include <zephyr/bluetooth/bluetooth.h>
22 #include <zephyr/bluetooth/conn.h>
23 #include <zephyr/bluetooth/gap.h>
24 #include <zephyr/bluetooth/gatt.h>
25 #include <zephyr/bluetooth/att.h>
26 #include <zephyr/bluetooth/hci_types.h>
27 #include <zephyr/bluetooth/iso.h>
28 #include <zephyr/bluetooth/l2cap.h>
29 #include <zephyr/bluetooth/buf.h>
30 #include <zephyr/bluetooth/uuid.h>
31 #include <zephyr/device.h>
32 #include <zephyr/init.h>
33 #include <zephyr/kernel.h>
34 #include <zephyr/net_buf.h>
35 #include <zephyr/sys/__assert.h>
36 #include <zephyr/sys/atomic.h>
37 #include <zephyr/sys/byteorder.h>
38 #include <zephyr/sys/check.h>
39 #include <zephyr/sys/slist.h>
40 #include <zephyr/sys/util.h>
41 #include <zephyr/sys/util_macro.h>
42 #include <zephyr/types.h>
43 
44 #include <zephyr/logging/log.h>
45 #include <sys/errno.h>
46 
47 LOG_MODULE_REGISTER(bt_bap_broadcast_assistant, CONFIG_BT_BAP_BROADCAST_ASSISTANT_LOG_LEVEL);
48 
49 #include "common/bt_str.h"
50 
51 #include "audio_internal.h"
52 #include "bap_internal.h"
53 
54 #define MINIMUM_RECV_STATE_LEN          15
55 
56 struct bap_broadcast_assistant_recv_state_info {
57 	uint8_t src_id;
58 	/** Cached PAST available */
59 	bool past_avail;
60 	uint8_t adv_sid;
61 	uint32_t broadcast_id;
62 	bt_addr_le_t addr;
63 };
64 
65 enum bap_broadcast_assistant_flag {
66 	BAP_BA_FLAG_BUSY,
67 	BAP_BA_FLAG_DISCOVER_IN_PROGRESS,
68 	BAP_BA_FLAG_SCANNING,
69 
70 	BAP_BA_FLAG_NUM_FLAGS, /* keep as last */
71 };
72 
73 struct bap_broadcast_assistant_instance {
74 	struct bt_conn *conn;
75 	bool scanning;
76 	uint8_t pa_sync;
77 	uint8_t recv_state_cnt;
78 
79 	uint16_t start_handle;
80 	uint16_t end_handle;
81 	uint16_t cp_handle;
82 	uint16_t recv_state_handles[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];
83 
84 	struct bt_gatt_subscribe_params recv_state_sub_params
85 		[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];
86 	struct bt_gatt_discover_params
87 		recv_state_disc_params[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];
88 
89 	/* We ever only allow a single outstanding operation per instance, so we can resuse the
90 	 * memory for the GATT params
91 	 */
92 	union {
93 		struct bt_gatt_read_params read_params;
94 		struct bt_gatt_write_params write_params;
95 		struct bt_gatt_discover_params disc_params;
96 	};
97 
98 	struct k_work_delayable bap_read_work;
99 	uint16_t long_read_handle;
100 
101 	struct bap_broadcast_assistant_recv_state_info
102 		recv_states[CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT];
103 
104 	ATOMIC_DEFINE(flags, BAP_BA_FLAG_NUM_FLAGS);
105 };
106 
107 static sys_slist_t broadcast_assistant_cbs = SYS_SLIST_STATIC_INIT(&broadcast_assistant_cbs);
108 
109 static struct bap_broadcast_assistant_instance broadcast_assistants[CONFIG_BT_MAX_CONN];
110 static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0);
111 
112 #define ATT_BUF_SIZE BT_ATT_MAX_ATTRIBUTE_LEN
113 NET_BUF_SIMPLE_DEFINE_STATIC(att_buf, ATT_BUF_SIZE);
114 
115 static int read_recv_state(struct bap_broadcast_assistant_instance *inst, uint8_t idx);
116 
lookup_index_by_handle(struct bap_broadcast_assistant_instance * inst,uint16_t handle)117 static int16_t lookup_index_by_handle(struct bap_broadcast_assistant_instance *inst,
118 				      uint16_t handle)
119 {
120 	for (size_t i = 0U; i < ARRAY_SIZE(inst->recv_state_handles); i++) {
121 		if (inst->recv_state_handles[i] == handle) {
122 			return i;
123 		}
124 	}
125 
126 	LOG_ERR("Unknown handle 0x%04x", handle);
127 
128 	return -1;
129 }
130 
inst_by_conn(struct bt_conn * conn)131 static struct bap_broadcast_assistant_instance *inst_by_conn(struct bt_conn *conn)
132 {
133 	struct bap_broadcast_assistant_instance *inst;
134 
135 	if (conn == NULL) {
136 		LOG_DBG("NULL conn");
137 		return NULL;
138 	}
139 
140 	inst = &broadcast_assistants[bt_conn_index(conn)];
141 
142 	if (inst->conn == conn) {
143 		return inst;
144 	}
145 
146 	return NULL;
147 }
148 
bap_broadcast_assistant_discover_complete(struct bt_conn * conn,int err,uint8_t recv_state_count)149 static void bap_broadcast_assistant_discover_complete(struct bt_conn *conn, int err,
150 						      uint8_t recv_state_count)
151 {
152 	struct bap_broadcast_assistant_instance *inst = inst_by_conn(conn);
153 	struct bt_bap_broadcast_assistant_cb *listener, *next;
154 
155 	net_buf_simple_reset(&att_buf);
156 	if (inst != NULL) {
157 		atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
158 		atomic_clear_bit(inst->flags, BAP_BA_FLAG_DISCOVER_IN_PROGRESS);
159 	}
160 
161 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&broadcast_assistant_cbs,
162 					  listener, next, _node) {
163 		if (listener->discover) {
164 			listener->discover(conn, err, recv_state_count);
165 		}
166 	}
167 }
168 
bap_broadcast_assistant_recv_state_changed(struct bt_conn * conn,int err,const struct bt_bap_scan_delegator_recv_state * state)169 static void bap_broadcast_assistant_recv_state_changed(
170 	struct bt_conn *conn, int err, const struct bt_bap_scan_delegator_recv_state *state)
171 {
172 	struct bt_bap_broadcast_assistant_cb *listener, *next;
173 
174 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&broadcast_assistant_cbs,
175 					  listener, next, _node) {
176 		if (listener->recv_state) {
177 			listener->recv_state(conn, err, state);
178 		}
179 	}
180 }
181 
bap_broadcast_assistant_recv_state_removed(struct bt_conn * conn,uint8_t src_id)182 static void bap_broadcast_assistant_recv_state_removed(struct bt_conn *conn, uint8_t src_id)
183 {
184 	struct bt_bap_broadcast_assistant_cb *listener, *next;
185 
186 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&broadcast_assistant_cbs,
187 					  listener, next, _node) {
188 		if (listener->recv_state_removed) {
189 			listener->recv_state_removed(conn, src_id);
190 		}
191 	}
192 }
193 
bap_broadcast_assistant_scan_results(const struct bt_le_scan_recv_info * info,uint32_t broadcast_id)194 static void bap_broadcast_assistant_scan_results(const struct bt_le_scan_recv_info *info,
195 						 uint32_t broadcast_id)
196 {
197 	struct bt_bap_broadcast_assistant_cb *listener, *next;
198 
199 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&broadcast_assistant_cbs, listener, next, _node) {
200 		if (listener->scan) {
201 			listener->scan(info, broadcast_id);
202 		}
203 	}
204 }
205 
past_available(const struct bt_conn * conn,const bt_addr_le_t * adv_addr,uint8_t sid)206 static bool past_available(const struct bt_conn *conn,
207 			   const bt_addr_le_t *adv_addr,
208 			   uint8_t sid)
209 {
210 	if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)) {
211 		struct bt_le_local_features local_features;
212 		struct bt_conn_remote_info remote_info;
213 		int err;
214 
215 		err = bt_le_get_local_features(&local_features);
216 		if (err != 0) {
217 			LOG_DBG("Failed to get local features: %d", err);
218 			return false;
219 		}
220 
221 		err = bt_conn_get_remote_info(conn, &remote_info);
222 		if (err != 0) {
223 			LOG_DBG("Failed to get remote info: %d", err);
224 			return false;
225 		}
226 
227 		LOG_DBG("%p remote %s PAST, local %s PAST", (void *)conn,
228 			BT_FEAT_LE_PAST_RECV(remote_info.le.features) ? "supports"
229 								      : "does not support",
230 			BT_FEAT_LE_PAST_SEND(local_features.features) ? "supports"
231 								      : "does not support");
232 
233 		return BT_FEAT_LE_PAST_RECV(remote_info.le.features) &&
234 		       BT_FEAT_LE_PAST_SEND(local_features.features) &&
235 		       bt_le_per_adv_sync_lookup_addr(adv_addr, sid) != NULL;
236 	} else {
237 		return false;
238 	}
239 }
240 
parse_recv_state(const void * data,uint16_t length,struct bt_bap_scan_delegator_recv_state * recv_state)241 static int parse_recv_state(const void *data, uint16_t length,
242 			    struct bt_bap_scan_delegator_recv_state *recv_state)
243 {
244 	struct net_buf_simple buf;
245 	bt_addr_t *addr;
246 
247 	__ASSERT(recv_state, "NULL receive state");
248 
249 	if (data == NULL || length == 0) {
250 		LOG_DBG("NULL data");
251 		return -EINVAL;
252 	}
253 
254 	if (length < MINIMUM_RECV_STATE_LEN) {
255 		LOG_DBG("Invalid receive state length %u, expected at least %u",
256 			length, MINIMUM_RECV_STATE_LEN);
257 		return -EINVAL;
258 	}
259 
260 	net_buf_simple_init_with_data(&buf, (void *)data, length);
261 
262 	(void)memset(recv_state, 0, sizeof(*recv_state));
263 
264 	recv_state->src_id = net_buf_simple_pull_u8(&buf);
265 	recv_state->addr.type = net_buf_simple_pull_u8(&buf);
266 	addr = net_buf_simple_pull_mem(&buf, sizeof(*addr));
267 	bt_addr_copy(&recv_state->addr.a, addr);
268 	recv_state->adv_sid = net_buf_simple_pull_u8(&buf);
269 	recv_state->broadcast_id = net_buf_simple_pull_le24(&buf);
270 	recv_state->pa_sync_state = net_buf_simple_pull_u8(&buf);
271 	recv_state->encrypt_state = net_buf_simple_pull_u8(&buf);
272 	if (recv_state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
273 		uint8_t *broadcast_code;
274 		const size_t minimum_size = sizeof(recv_state->bad_code) +
275 					    sizeof(recv_state->num_subgroups);
276 
277 		if (buf.len < minimum_size) {
278 			LOG_DBG("Invalid receive state length %u, expected at least %zu",
279 			       buf.len, minimum_size);
280 			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
281 		}
282 
283 		broadcast_code = net_buf_simple_pull_mem(&buf, BT_ISO_BROADCAST_CODE_SIZE);
284 		(void)memcpy(recv_state->bad_code, broadcast_code,
285 			     sizeof(recv_state->bad_code));
286 	}
287 
288 	recv_state->num_subgroups = net_buf_simple_pull_u8(&buf);
289 	if (recv_state->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
290 		LOG_DBG("Cannot parse %u subgroups (max %d)", recv_state->num_subgroups,
291 			CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
292 
293 		return -ENOMEM;
294 	}
295 
296 	for (int i = 0; i < recv_state->num_subgroups; i++) {
297 		struct bt_bap_bass_subgroup *subgroup = &recv_state->subgroups[i];
298 		uint8_t *metadata;
299 
300 		if (buf.len < sizeof(subgroup->bis_sync)) {
301 			LOG_DBG("Invalid receive state length %u, expected at least %zu",
302 			       buf.len, buf.len + sizeof(subgroup->bis_sync));
303 			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
304 		}
305 
306 		subgroup->bis_sync = net_buf_simple_pull_le32(&buf);
307 
308 		if (buf.len < sizeof(subgroup->metadata_len)) {
309 			LOG_DBG("Invalid receive state length %u, expected at least %zu",
310 			       buf.len, buf.len + sizeof(subgroup->metadata_len));
311 			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
312 		}
313 		subgroup->metadata_len = net_buf_simple_pull_u8(&buf);
314 
315 		if (buf.len < subgroup->metadata_len) {
316 			LOG_DBG("Invalid receive state length %u, expected at least %u",
317 			       buf.len, buf.len + subgroup->metadata_len);
318 			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
319 		}
320 
321 		if (subgroup->metadata_len > sizeof(subgroup->metadata)) {
322 			LOG_DBG("Metadata too long: %u/%zu",
323 			       subgroup->metadata_len,
324 			       sizeof(subgroup->metadata));
325 			return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
326 		}
327 
328 		metadata = net_buf_simple_pull_mem(&buf,
329 						   subgroup->metadata_len);
330 		(void)memcpy(subgroup->metadata, metadata,
331 			     subgroup->metadata_len);
332 	}
333 
334 	if (buf.len != 0) {
335 		LOG_DBG("Invalid receive state length %u, but only %u was parsed",
336 		       length, length - buf.len);
337 		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
338 	}
339 
340 	return 0;
341 }
342 
bap_long_read_reset(struct bap_broadcast_assistant_instance * inst)343 static void bap_long_read_reset(struct bap_broadcast_assistant_instance *inst)
344 {
345 	inst->long_read_handle = 0;
346 	net_buf_simple_reset(&att_buf);
347 	atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
348 }
349 
parse_and_send_recv_state(struct bt_conn * conn,uint16_t handle,const void * data,uint16_t length,struct bt_bap_scan_delegator_recv_state * recv_state)350 static uint8_t parse_and_send_recv_state(struct bt_conn *conn, uint16_t handle,
351 					 const void *data, uint16_t length,
352 					 struct bt_bap_scan_delegator_recv_state *recv_state)
353 {
354 	int err;
355 	int16_t index;
356 	struct bap_broadcast_assistant_instance *inst = inst_by_conn(conn);
357 
358 	if (inst == NULL) {
359 		return BT_GATT_ITER_STOP;
360 	}
361 
362 	err = parse_recv_state(data, length, recv_state);
363 	if (err != 0) {
364 		LOG_WRN("Invalid receive state received");
365 
366 		return BT_GATT_ITER_STOP;
367 	}
368 
369 	index = lookup_index_by_handle(inst, handle);
370 	if (index < 0) {
371 		LOG_DBG("Invalid index");
372 
373 		return BT_GATT_ITER_STOP;
374 	}
375 
376 	inst->recv_states[index].src_id = recv_state->src_id;
377 	inst->recv_states[index].past_avail = past_available(conn, &recv_state->addr,
378 							     recv_state->adv_sid);
379 
380 	bap_broadcast_assistant_recv_state_changed(conn, 0, recv_state);
381 
382 	return BT_GATT_ITER_CONTINUE;
383 }
384 
broadcast_assistant_bap_ntf_read_func(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * read,const void * data,uint16_t length)385 static uint8_t broadcast_assistant_bap_ntf_read_func(struct bt_conn *conn, uint8_t err,
386 						     struct bt_gatt_read_params *read,
387 						     const void *data, uint16_t length)
388 {
389 	struct bt_bap_scan_delegator_recv_state recv_state;
390 	uint16_t handle = read->single.handle;
391 	uint16_t data_length;
392 	struct bap_broadcast_assistant_instance *inst = inst_by_conn(conn);
393 
394 	if (inst == NULL) {
395 		return BT_GATT_ITER_STOP;
396 	}
397 
398 	LOG_DBG("conn %p err 0x%02x len %u", (void *)conn, err, length);
399 
400 	if (err) {
401 		LOG_DBG("Failed to read: %u", err);
402 		memset(read, 0, sizeof(*read));
403 		bap_long_read_reset(inst);
404 
405 		return BT_GATT_ITER_STOP;
406 	}
407 
408 	LOG_DBG("handle 0x%04x", handle);
409 
410 	if (data != NULL) {
411 		if (net_buf_simple_tailroom(&att_buf) < length) {
412 			LOG_DBG("Buffer full, invalid server response of size %u",
413 				length + att_buf.len);
414 			memset(read, 0, sizeof(*read));
415 			bap_long_read_reset(inst);
416 
417 			return BT_GATT_ITER_STOP;
418 		}
419 
420 		/* store data*/
421 		net_buf_simple_add_mem(&att_buf, data, length);
422 
423 		return BT_GATT_ITER_CONTINUE;
424 	}
425 
426 	/* we reset the buffer so that it is ready for new data */
427 	memset(read, 0, sizeof(*read));
428 	data_length = att_buf.len;
429 	bap_long_read_reset(inst);
430 
431 	/* do the parse and callback to send  notify to application*/
432 	parse_and_send_recv_state(conn, handle, att_buf.data, data_length, &recv_state);
433 
434 	return BT_GATT_ITER_STOP;
435 }
436 
long_bap_read(struct bt_conn * conn,uint16_t handle)437 static void long_bap_read(struct bt_conn *conn, uint16_t handle)
438 {
439 	int err;
440 	struct bap_broadcast_assistant_instance *inst = inst_by_conn(conn);
441 
442 	if (inst == NULL) {
443 		return;
444 	}
445 
446 	if (atomic_test_and_set_bit(inst->flags, BAP_BA_FLAG_BUSY)) {
447 		LOG_DBG("conn %p", (void *)conn);
448 
449 		/* If the client is busy reading reschedule the long read */
450 		struct bt_conn_info conn_info;
451 
452 		err = bt_conn_get_info(conn, &conn_info);
453 		if (err != 0) {
454 			LOG_DBG("Failed to get conn info, use default interval");
455 
456 			conn_info.le.interval = BT_GAP_INIT_CONN_INT_MIN;
457 		}
458 
459 		/* Wait a connection interval to retry */
460 		err = k_work_reschedule(&inst->bap_read_work,
461 					K_USEC(BT_CONN_INTERVAL_TO_US(conn_info.le.interval)));
462 		if (err < 0) {
463 			LOG_DBG("Failed to reschedule read work: %d", err);
464 			bap_long_read_reset(inst);
465 		}
466 
467 		return;
468 	}
469 
470 	inst->read_params.func = broadcast_assistant_bap_ntf_read_func;
471 	inst->read_params.handle_count = 1U;
472 	inst->read_params.single.handle = handle;
473 	inst->read_params.single.offset = att_buf.len;
474 
475 	err = bt_gatt_read(conn, &inst->read_params);
476 	if (err != 0) {
477 		/* TODO: If read failed due to buffers, retry */
478 		LOG_DBG("Failed to read: %d", err);
479 		bap_long_read_reset(inst);
480 	}
481 }
482 
delayed_bap_read_handler(struct k_work * work)483 static void delayed_bap_read_handler(struct k_work *work)
484 {
485 	struct bap_broadcast_assistant_instance *inst =
486 		CONTAINER_OF((struct k_work_delayable *)work,
487 			     struct bap_broadcast_assistant_instance, bap_read_work);
488 	long_bap_read(inst->conn, inst->long_read_handle);
489 }
490 
491 /** @brief Handles notifications and indications from the server */
notify_handler(struct bt_conn * conn,struct bt_gatt_subscribe_params * params,const void * data,uint16_t length)492 static uint8_t notify_handler(struct bt_conn *conn,
493 			      struct bt_gatt_subscribe_params *params,
494 			      const void *data, uint16_t length)
495 {
496 	uint16_t handle = params->value_handle;
497 	struct bt_bap_scan_delegator_recv_state recv_state;
498 	int16_t index;
499 	struct bap_broadcast_assistant_instance *inst;
500 
501 	if (conn == NULL) {
502 		/* Indicates that the CCC has been removed - no-op */
503 		return BT_GATT_ITER_CONTINUE;
504 	}
505 
506 	inst = inst_by_conn(conn);
507 
508 	if (inst == NULL) {
509 		return BT_GATT_ITER_STOP;
510 	}
511 
512 	if (atomic_test_bit(inst->flags, BAP_BA_FLAG_DISCOVER_IN_PROGRESS)) {
513 		/* If we are discovering then we ignore notifications as the handles may change */
514 		return BT_GATT_ITER_CONTINUE;
515 	}
516 
517 	if (data == NULL) {
518 		LOG_DBG("[UNSUBSCRIBED] %u", handle);
519 		params->value_handle = 0U;
520 
521 		return BT_GATT_ITER_STOP;
522 	}
523 
524 	LOG_HEXDUMP_DBG(data, length, "Receive state notification:");
525 
526 	index = lookup_index_by_handle(inst, handle);
527 	if (index < 0) {
528 		LOG_DBG("Invalid index");
529 
530 		return BT_GATT_ITER_STOP;
531 	}
532 
533 	if (length != 0) {
534 		const uint16_t max_ntf_size = bt_audio_get_max_ntf_size(conn);
535 
536 		/* Cancel any pending long reads containing now obsolete information */
537 		(void)k_work_cancel_delayable(&inst->bap_read_work);
538 
539 		if (length == max_ntf_size) {
540 			/* TODO: if we are busy we should not overwrite the long_read_handle,
541 			 * we'll have to keep track of the handle and parameters separately
542 			 * for each characteristic, similar to the bt_bap_unicast_client_ep
543 			 * struct for the unicast client
544 			 */
545 			inst->long_read_handle = handle;
546 
547 			if (!atomic_test_bit(inst->flags, BAP_BA_FLAG_BUSY)) {
548 				net_buf_simple_add_mem(&att_buf, data, length);
549 			}
550 
551 			long_bap_read(conn, handle);
552 		} else {
553 			return parse_and_send_recv_state(conn, handle, data, length, &recv_state);
554 		}
555 	} else {
556 		inst->recv_states[index].past_avail = false;
557 		bap_broadcast_assistant_recv_state_removed(conn, inst->recv_states[index].src_id);
558 	}
559 
560 	return BT_GATT_ITER_CONTINUE;
561 }
562 
read_recv_state_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_read_params * params,const void * data,uint16_t length)563 static uint8_t read_recv_state_cb(struct bt_conn *conn, uint8_t err,
564 				  struct bt_gatt_read_params *params,
565 				  const void *data, uint16_t length)
566 {
567 	struct bap_broadcast_assistant_instance *inst = inst_by_conn(conn);
568 
569 	if (inst == NULL) {
570 		return BT_GATT_ITER_STOP;
571 	}
572 
573 	uint16_t handle = params->single.handle;
574 	uint8_t last_handle_index = inst->recv_state_cnt - 1;
575 	uint16_t last_handle = inst->recv_state_handles[last_handle_index];
576 	struct bt_bap_scan_delegator_recv_state recv_state;
577 	int cb_err = err;
578 	bool active_recv_state = data != NULL && length != 0;
579 
580 	/* TODO: Split discovery and receive state characteristic read */
581 
582 	(void)memset(params, 0, sizeof(*params));
583 
584 	LOG_DBG("%s receive state", active_recv_state ? "Active " : "Inactive");
585 
586 	if (cb_err == 0 && active_recv_state) {
587 		int16_t index;
588 
589 		index = lookup_index_by_handle(inst, handle);
590 		if (index < 0) {
591 			cb_err = BT_GATT_ERR(BT_ATT_ERR_INVALID_HANDLE);
592 		} else {
593 			cb_err = parse_recv_state(data, length, &recv_state);
594 
595 			if (cb_err != 0) {
596 				LOG_DBG("Invalid receive state");
597 			} else {
598 				struct bap_broadcast_assistant_recv_state_info *stored_state =
599 					&inst->recv_states[index];
600 
601 				stored_state->src_id = recv_state.src_id;
602 				stored_state->adv_sid = recv_state.adv_sid;
603 				stored_state->broadcast_id = recv_state.broadcast_id;
604 				bt_addr_le_copy(&stored_state->addr, &recv_state.addr);
605 				inst->recv_states[index].past_avail =
606 					past_available(conn, &recv_state.addr,
607 						       recv_state.adv_sid);
608 			}
609 		}
610 	}
611 
612 	if (cb_err != 0) {
613 		LOG_DBG("err %d", cb_err);
614 
615 		if (atomic_test_bit(inst->flags, BAP_BA_FLAG_DISCOVER_IN_PROGRESS)) {
616 			bap_broadcast_assistant_discover_complete(conn, cb_err, 0);
617 		} else {
618 			atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
619 			bap_broadcast_assistant_recv_state_changed(conn, cb_err, NULL);
620 		}
621 	} else if (handle == last_handle) {
622 		if (atomic_test_bit(inst->flags, BAP_BA_FLAG_DISCOVER_IN_PROGRESS)) {
623 			const uint8_t recv_state_cnt = inst->recv_state_cnt;
624 
625 			bap_broadcast_assistant_discover_complete(conn, cb_err, recv_state_cnt);
626 		} else {
627 			atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
628 			bap_broadcast_assistant_recv_state_changed(conn, cb_err,
629 								   active_recv_state ?
630 								   &recv_state : NULL);
631 		}
632 	} else {
633 		for (uint8_t i = 0U; i < inst->recv_state_cnt; i++) {
634 			if (handle != inst->recv_state_handles[i]) {
635 				continue;
636 			}
637 
638 			if (i + 1 < ARRAY_SIZE(inst->recv_state_handles)) {
639 				cb_err = read_recv_state(inst, i + 1);
640 				if (cb_err != 0) {
641 					LOG_DBG("Failed to read receive state: %d", cb_err);
642 
643 					if (atomic_test_bit(inst->flags,
644 							    BAP_BA_FLAG_DISCOVER_IN_PROGRESS)) {
645 						bap_broadcast_assistant_discover_complete(
646 							conn, cb_err, 0);
647 					} else {
648 						atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
649 						bap_broadcast_assistant_recv_state_changed(
650 							conn, cb_err, NULL);
651 					}
652 				}
653 			}
654 			break;
655 		}
656 	}
657 
658 	return BT_GATT_ITER_STOP;
659 }
660 
discover_init(struct bap_broadcast_assistant_instance * inst)661 static void discover_init(struct bap_broadcast_assistant_instance *inst)
662 {
663 	k_work_init_delayable(&inst->bap_read_work, delayed_bap_read_handler);
664 	net_buf_simple_reset(&att_buf);
665 	atomic_set_bit(inst->flags, BAP_BA_FLAG_DISCOVER_IN_PROGRESS);
666 }
667 
668 /**
669  * @brief This will discover all characteristics on the server, retrieving the
670  * handles of the writeable characteristics and subscribing to all notify and
671  * indicate characteristics.
672  */
char_discover_func(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)673 static uint8_t char_discover_func(struct bt_conn *conn,
674 				  const struct bt_gatt_attr *attr,
675 				  struct bt_gatt_discover_params *params)
676 {
677 	struct bt_gatt_subscribe_params *sub_params = NULL;
678 	int err;
679 	struct bap_broadcast_assistant_instance *inst = inst_by_conn(conn);
680 
681 	if (inst == NULL) {
682 		return BT_GATT_ITER_STOP;
683 	}
684 
685 	if (attr == NULL) {
686 		LOG_DBG("Found %u BASS receive states", inst->recv_state_cnt);
687 		(void)memset(params, 0, sizeof(*params));
688 
689 		err = read_recv_state(inst, 0);
690 		if (err != 0) {
691 			bap_broadcast_assistant_discover_complete(conn, err, 0);
692 		}
693 
694 		return BT_GATT_ITER_STOP;
695 	}
696 
697 	LOG_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);
698 
699 	if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) {
700 		struct bt_gatt_chrc *chrc =
701 			(struct bt_gatt_chrc *)attr->user_data;
702 
703 		if (bt_uuid_cmp(chrc->uuid, BT_UUID_BASS_CONTROL_POINT) == 0) {
704 			LOG_DBG("Control Point");
705 			inst->cp_handle = attr->handle + 1;
706 		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_BASS_RECV_STATE) == 0) {
707 			if (inst->recv_state_cnt <
708 				CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT) {
709 				const uint8_t idx = inst->recv_state_cnt;
710 
711 				LOG_DBG("Receive State %u", inst->recv_state_cnt);
712 				inst->recv_state_handles[idx] =
713 					attr->handle + 1;
714 				sub_params = &inst->recv_state_sub_params[idx];
715 				sub_params->disc_params = &inst->recv_state_disc_params[idx];
716 				inst->recv_state_cnt++;
717 			}
718 		} else {
719 			LOG_DBG("Invalid UUID %s", bt_uuid_str(chrc->uuid));
720 			bap_broadcast_assistant_discover_complete(conn, -EBADMSG, 0);
721 
722 			return BT_GATT_ITER_STOP;
723 		}
724 
725 		if (sub_params != NULL) {
726 			sub_params->end_handle = inst->end_handle;
727 			sub_params->ccc_handle = BT_GATT_AUTO_DISCOVER_CCC_HANDLE;
728 			sub_params->value = BT_GATT_CCC_NOTIFY;
729 			sub_params->value_handle = attr->handle + 1;
730 			sub_params->notify = notify_handler;
731 			atomic_set_bit(sub_params->flags, BT_GATT_SUBSCRIBE_FLAG_VOLATILE);
732 
733 			err = bt_gatt_subscribe(conn, sub_params);
734 			if (err != 0) {
735 				LOG_DBG("Could not subscribe to handle 0x%04x: %d",
736 					sub_params->value_handle, err);
737 
738 				bap_broadcast_assistant_discover_complete(conn, err, 0);
739 
740 				return BT_GATT_ITER_STOP;
741 			}
742 		}
743 	}
744 
745 	return BT_GATT_ITER_CONTINUE;
746 }
747 
service_discover_func(struct bt_conn * conn,const struct bt_gatt_attr * attr,struct bt_gatt_discover_params * params)748 static uint8_t service_discover_func(struct bt_conn *conn,
749 				     const struct bt_gatt_attr *attr,
750 				     struct bt_gatt_discover_params *params)
751 {
752 	int err;
753 	struct bt_gatt_service_val *prim_service;
754 	struct bap_broadcast_assistant_instance *inst = inst_by_conn(conn);
755 
756 	if (inst == NULL) {
757 		return BT_GATT_ITER_STOP;
758 	}
759 
760 	if (attr == NULL) {
761 		LOG_DBG("Could not discover BASS");
762 		(void)memset(params, 0, sizeof(*params));
763 
764 		err = BT_GATT_ERR(BT_ATT_ERR_NOT_SUPPORTED);
765 
766 		bap_broadcast_assistant_discover_complete(conn, err, 0);
767 
768 		return BT_GATT_ITER_STOP;
769 	}
770 
771 	LOG_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);
772 
773 	if (params->type == BT_GATT_DISCOVER_PRIMARY) {
774 		prim_service = (struct bt_gatt_service_val *)attr->user_data;
775 		inst->start_handle = attr->handle + 1;
776 		inst->end_handle = prim_service->end_handle;
777 
778 		inst->disc_params.uuid = NULL;
779 		inst->disc_params.start_handle = inst->start_handle;
780 		inst->disc_params.end_handle = inst->end_handle;
781 		inst->disc_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
782 		inst->disc_params.func = char_discover_func;
783 
784 		err = bt_gatt_discover(conn, &inst->disc_params);
785 		if (err != 0) {
786 			LOG_DBG("Discover failed (err %d)", err);
787 			bap_broadcast_assistant_discover_complete(conn, err, 0);
788 		}
789 	}
790 
791 	return BT_GATT_ITER_STOP;
792 }
793 
bap_broadcast_assistant_write_cp_cb(struct bt_conn * conn,uint8_t err,struct bt_gatt_write_params * params)794 static void bap_broadcast_assistant_write_cp_cb(struct bt_conn *conn, uint8_t err,
795 						struct bt_gatt_write_params *params)
796 {
797 	struct bt_bap_broadcast_assistant_cb *listener, *next;
798 	uint8_t opcode = net_buf_simple_pull_u8(&att_buf);
799 	struct bap_broadcast_assistant_instance *inst = inst_by_conn(conn);
800 
801 	if (inst == NULL) {
802 		return;
803 	}
804 
805 	/* we reset the buffer, so that we are ready for new notifications and writes */
806 	net_buf_simple_reset(&att_buf);
807 
808 	atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
809 
810 	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&broadcast_assistant_cbs, listener, next, _node) {
811 		switch (opcode) {
812 		case BT_BAP_BASS_OP_SCAN_STOP:
813 			if (listener->scan_stop != NULL) {
814 				listener->scan_stop(conn, err);
815 			}
816 			break;
817 		case BT_BAP_BASS_OP_SCAN_START:
818 			if (listener->scan_start != NULL) {
819 				listener->scan_start(conn, err);
820 			}
821 			break;
822 		case BT_BAP_BASS_OP_ADD_SRC:
823 			if (listener->add_src != NULL) {
824 				listener->add_src(conn, err);
825 			}
826 			break;
827 		case BT_BAP_BASS_OP_MOD_SRC:
828 			if (listener->mod_src != NULL) {
829 				listener->mod_src(conn, err);
830 			}
831 			break;
832 		case BT_BAP_BASS_OP_BROADCAST_CODE:
833 			if (listener->broadcast_code != NULL) {
834 				listener->broadcast_code(conn, err);
835 			}
836 			break;
837 		case BT_BAP_BASS_OP_REM_SRC:
838 			if (listener->rem_src != NULL) {
839 				listener->rem_src(conn, err);
840 			}
841 			break;
842 		default:
843 			LOG_DBG("Unknown opcode 0x%02x", opcode);
844 			break;
845 		}
846 	}
847 }
848 
bt_bap_broadcast_assistant_common_cp(struct bt_conn * conn,const struct net_buf_simple * buf)849 static int bt_bap_broadcast_assistant_common_cp(struct bt_conn *conn,
850 				    const struct net_buf_simple *buf)
851 {
852 	int err;
853 	struct bap_broadcast_assistant_instance *inst;
854 
855 	if (conn == NULL) {
856 		LOG_DBG("conn is NULL");
857 
858 		return -EINVAL;
859 	}
860 
861 	inst = inst_by_conn(conn);
862 
863 	if (inst == NULL) {
864 		return -EINVAL;
865 	}
866 
867 	if (inst->cp_handle == 0) {
868 		LOG_DBG("Handle not set");
869 		return -EINVAL;
870 	}
871 
872 	inst->write_params.offset = 0;
873 	inst->write_params.data = buf->data;
874 	inst->write_params.length = buf->len;
875 	inst->write_params.handle = inst->cp_handle;
876 	inst->write_params.func = bap_broadcast_assistant_write_cp_cb;
877 
878 	err = bt_gatt_write(conn, &inst->write_params);
879 	if (err != 0) {
880 		atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
881 
882 		/* Report expected possible errors */
883 		if (err == -ENOTCONN || err == -ENOMEM) {
884 			return err;
885 		}
886 
887 		return -ENOEXEC;
888 	}
889 
890 	return 0;
891 }
892 
893 
broadcast_source_found(struct bt_data * data,void * user_data)894 static bool broadcast_source_found(struct bt_data *data, void *user_data)
895 {
896 	const struct bt_le_scan_recv_info *info = user_data;
897 	struct bt_uuid_16 adv_uuid;
898 	uint32_t broadcast_id;
899 
900 	if (data->type != BT_DATA_SVC_DATA16) {
901 		return true;
902 	}
903 
904 	if (data->data_len < BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE) {
905 		return true;
906 	}
907 
908 	if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
909 		return true;
910 	}
911 
912 	if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO) != 0) {
913 		return true;
914 	}
915 
916 	broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);
917 
918 	LOG_DBG("Found BIS advertiser with address %s SID 0x%02X and broadcast_id 0x%06X",
919 		bt_addr_le_str(info->addr), info->sid, broadcast_id);
920 
921 	bap_broadcast_assistant_scan_results(info, broadcast_id);
922 
923 	return false;
924 }
925 
scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad)926 void scan_recv(const struct bt_le_scan_recv_info *info,
927 	       struct net_buf_simple *ad)
928 {
929 	/* We are only interested in non-connectable periodic advertisers */
930 	if ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) != 0 ||
931 	    info->interval == 0) {
932 		return;
933 	}
934 
935 	bt_data_parse(ad, broadcast_source_found, (void *)info);
936 }
937 
938 static struct bt_le_scan_cb scan_cb = {
939 	.recv = scan_recv
940 };
941 
942 /* BAP 6.5.4 states that the Broadcast Assistant shall not initiate the Add Source operation
943  * if the operation would result in duplicate values for the combined Source_Address_Type,
944  * Source_Adv_SID, and Broadcast_ID fields of any Broadcast Receive State characteristic exposed
945  * by the Scan Delegator.
946  */
broadcast_src_is_duplicate(struct bap_broadcast_assistant_instance * inst,uint32_t broadcast_id,uint8_t adv_sid,uint8_t addr_type)947 static bool broadcast_src_is_duplicate(struct bap_broadcast_assistant_instance *inst,
948 				       uint32_t broadcast_id, uint8_t adv_sid, uint8_t addr_type)
949 {
950 	for (size_t i = 0; i < ARRAY_SIZE(inst->recv_states); i++) {
951 		const struct bap_broadcast_assistant_recv_state_info *state =
952 							&inst->recv_states[i];
953 
954 		if (state != NULL && state->broadcast_id == broadcast_id &&
955 			state->adv_sid == adv_sid && state->addr.type == addr_type) {
956 			LOG_DBG("recv_state already exists at src_id=0x%02X", state->src_id);
957 
958 			return true;
959 		}
960 	}
961 
962 	return false;
963 }
964 
965 /****************************** PUBLIC API ******************************/
966 
broadcast_assistant_reset(struct bap_broadcast_assistant_instance * inst)967 static int broadcast_assistant_reset(struct bap_broadcast_assistant_instance *inst)
968 {
969 	inst->scanning = false;
970 	inst->pa_sync = 0U;
971 	inst->recv_state_cnt = 0U;
972 	inst->start_handle = 0U;
973 	inst->end_handle = 0U;
974 	inst->cp_handle = 0U;
975 	inst->long_read_handle = 0;
976 	(void)k_work_cancel_delayable(&inst->bap_read_work);
977 
978 	for (int i = 0U; i < CONFIG_BT_BAP_BROADCAST_ASSISTANT_RECV_STATE_COUNT; i++) {
979 		memset(&inst->recv_states[i], 0, sizeof(inst->recv_states[i]));
980 		inst->recv_states[i].broadcast_id = BT_BAP_INVALID_BROADCAST_ID;
981 		inst->recv_states[i].adv_sid = BT_HCI_LE_EXT_ADV_SID_INVALID;
982 		inst->recv_states[i].past_avail = false;
983 		inst->recv_state_handles[i] = 0U;
984 	}
985 
986 	if (inst->conn != NULL) {
987 		struct bt_conn *conn = inst->conn;
988 		struct bt_conn_info info;
989 		int err;
990 
991 		err = bt_conn_get_info(conn, &info);
992 		if (err != 0) {
993 			return err;
994 		}
995 
996 		if (info.state == BT_CONN_STATE_CONNECTED) {
997 			for (size_t i = 0U; i < ARRAY_SIZE(inst->recv_state_sub_params); i++) {
998 				/* It's okay if this fail with -EINVAL as that means that they are
999 				 * not currently subscribed
1000 				 */
1001 				err = bt_gatt_unsubscribe(conn, &inst->recv_state_sub_params[i]);
1002 				if (err != 0 && err != -EINVAL) {
1003 					LOG_DBG("Failed to unsubscribe to state: %d", err);
1004 
1005 					return err;
1006 				}
1007 			}
1008 		}
1009 
1010 		bt_conn_unref(conn);
1011 		inst->conn = NULL;
1012 	}
1013 
1014 	/* The subscribe parameters must remain instact so they can get cleaned up by GATT */
1015 	memset(&inst->disc_params, 0, sizeof(inst->disc_params));
1016 	memset(&inst->recv_state_disc_params, 0, sizeof(inst->recv_state_disc_params));
1017 	memset(&inst->read_params, 0, sizeof(inst->read_params));
1018 	memset(&inst->write_params, 0, sizeof(inst->write_params));
1019 
1020 	return 0;
1021 }
1022 
disconnected_cb(struct bt_conn * conn,uint8_t reason)1023 static void disconnected_cb(struct bt_conn *conn, uint8_t reason)
1024 {
1025 	struct bap_broadcast_assistant_instance *inst = inst_by_conn(conn);
1026 
1027 	if (inst) {
1028 		(void)broadcast_assistant_reset(inst);
1029 	}
1030 }
1031 
1032 BT_CONN_CB_DEFINE(conn_callbacks) = {
1033 	.disconnected = disconnected_cb,
1034 };
1035 
bt_bap_broadcast_assistant_discover(struct bt_conn * conn)1036 int bt_bap_broadcast_assistant_discover(struct bt_conn *conn)
1037 {
1038 	int err;
1039 	struct bap_broadcast_assistant_instance *inst;
1040 
1041 	if (conn == NULL) {
1042 		LOG_DBG("conn is NULL");
1043 
1044 		return -EINVAL;
1045 	}
1046 
1047 	inst = &broadcast_assistants[bt_conn_index(conn)];
1048 
1049 	/* Do not allow new discoveries while we are reading or writing */
1050 	if (atomic_test_and_set_bit(inst->flags, BAP_BA_FLAG_BUSY)) {
1051 		LOG_DBG("Instance is busy");
1052 		return -EBUSY;
1053 	}
1054 
1055 	err = broadcast_assistant_reset(inst);
1056 	if (err != 0) {
1057 		atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
1058 
1059 		LOG_DBG("Failed to reset broadcast assistant: %d", err);
1060 
1061 		return -ENOEXEC;
1062 	}
1063 
1064 	inst->conn = bt_conn_ref(conn);
1065 
1066 	/* Discover BASS on peer, setup handles and notify */
1067 	discover_init(inst);
1068 
1069 	(void)memcpy(&uuid, BT_UUID_BASS, sizeof(uuid));
1070 	inst->disc_params.func = service_discover_func;
1071 	inst->disc_params.uuid = &uuid.uuid;
1072 	inst->disc_params.type = BT_GATT_DISCOVER_PRIMARY;
1073 	inst->disc_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
1074 	inst->disc_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
1075 	err = bt_gatt_discover(conn, &inst->disc_params);
1076 	if (err != 0) {
1077 		atomic_clear_bit(inst->flags, BAP_BA_FLAG_DISCOVER_IN_PROGRESS);
1078 		atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
1079 
1080 		/* Report expected possible errors */
1081 		if (err == -ENOTCONN || err == -ENOMEM) {
1082 			return err;
1083 		}
1084 
1085 		LOG_DBG("Unexpected err %d from bt_gatt_discover", err);
1086 
1087 		return -ENOEXEC;
1088 	}
1089 
1090 	return 0;
1091 }
1092 
1093 /* TODO: naming is different from e.g. bt_vcp_vol_ctrl_cb_register */
bt_bap_broadcast_assistant_register_cb(struct bt_bap_broadcast_assistant_cb * cb)1094 int bt_bap_broadcast_assistant_register_cb(struct bt_bap_broadcast_assistant_cb *cb)
1095 {
1096 	struct bt_bap_broadcast_assistant_cb *tmp;
1097 
1098 	CHECKIF(cb == NULL) {
1099 		return -EINVAL;
1100 	}
1101 
1102 	SYS_SLIST_FOR_EACH_CONTAINER(&broadcast_assistant_cbs, tmp, _node) {
1103 		if (tmp == cb) {
1104 			LOG_DBG("Already registered");
1105 			return -EALREADY;
1106 		}
1107 	}
1108 
1109 	sys_slist_append(&broadcast_assistant_cbs, &cb->_node);
1110 
1111 	return 0;
1112 }
1113 
bt_bap_broadcast_assistant_unregister_cb(struct bt_bap_broadcast_assistant_cb * cb)1114 int bt_bap_broadcast_assistant_unregister_cb(struct bt_bap_broadcast_assistant_cb *cb)
1115 {
1116 	CHECKIF(cb == NULL) {
1117 		return -EINVAL;
1118 	}
1119 
1120 	if (!sys_slist_find_and_remove(&broadcast_assistant_cbs, &cb->_node)) {
1121 		return -EALREADY;
1122 	}
1123 
1124 	return 0;
1125 }
1126 
bt_bap_broadcast_assistant_scan_start(struct bt_conn * conn,bool start_scan)1127 int bt_bap_broadcast_assistant_scan_start(struct bt_conn *conn, bool start_scan)
1128 {
1129 	struct bt_bap_bass_cp_scan_start *cp;
1130 	int err;
1131 	struct bap_broadcast_assistant_instance *inst;
1132 
1133 	if (conn == NULL) {
1134 		LOG_DBG("conn is NULL");
1135 
1136 		return -EINVAL;
1137 	}
1138 
1139 	inst = inst_by_conn(conn);
1140 	if (inst == NULL) {
1141 		return -EINVAL;
1142 	}
1143 
1144 	if (inst->cp_handle == 0) {
1145 		LOG_DBG("handle not set");
1146 
1147 		return -EINVAL;
1148 	} else if (atomic_test_and_set_bit(inst->flags, BAP_BA_FLAG_BUSY)) {
1149 		/* Do not allow writes while we are discovering as the handles may change */
1150 
1151 		LOG_DBG("instance busy");
1152 
1153 		return -EBUSY;
1154 	}
1155 
1156 	/* TODO: Remove the start_scan parameter and support from the assistant */
1157 	if (start_scan) {
1158 		static bool cb_registered;
1159 
1160 		if (atomic_test_and_set_bit(inst->flags, BAP_BA_FLAG_SCANNING)) {
1161 			LOG_DBG("Already scanning");
1162 
1163 			atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
1164 
1165 			return -EALREADY;
1166 		}
1167 
1168 		if (!cb_registered) {
1169 			bt_le_scan_cb_register(&scan_cb);
1170 			cb_registered = true;
1171 		}
1172 
1173 		err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
1174 		if (err != 0) {
1175 			LOG_DBG("Could not start scan (%d)", err);
1176 
1177 			atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
1178 			atomic_clear_bit(inst->flags, BAP_BA_FLAG_SCANNING);
1179 
1180 			/* Report expected possible errors */
1181 			if (err == -EAGAIN) {
1182 				return err;
1183 			}
1184 
1185 			LOG_DBG("Unexpected err %d from bt_le_scan_start", err);
1186 
1187 			return -ENOEXEC;
1188 		}
1189 	}
1190 
1191 	/* Reset buffer before using */
1192 	net_buf_simple_reset(&att_buf);
1193 	cp = net_buf_simple_add(&att_buf, sizeof(*cp));
1194 
1195 	cp->opcode = BT_BAP_BASS_OP_SCAN_START;
1196 
1197 	err = bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
1198 	if (err != 0 && start_scan) {
1199 		/* bt_bap_broadcast_assistant_common_cp clears the busy flag on error */
1200 		err = bt_le_scan_stop();
1201 		if (err != 0) {
1202 			LOG_DBG("Could not stop scan (%d)", err);
1203 
1204 			return -ENOEXEC;
1205 		}
1206 
1207 		atomic_clear_bit(inst->flags, BAP_BA_FLAG_SCANNING);
1208 	}
1209 
1210 	return err;
1211 }
1212 
bt_bap_broadcast_assistant_scan_stop(struct bt_conn * conn)1213 int bt_bap_broadcast_assistant_scan_stop(struct bt_conn *conn)
1214 {
1215 	struct bt_bap_bass_cp_scan_stop *cp;
1216 	int err;
1217 	struct bap_broadcast_assistant_instance *inst;
1218 
1219 	if (conn == NULL) {
1220 		LOG_DBG("conn is NULL");
1221 
1222 		return -EINVAL;
1223 	}
1224 
1225 	inst = inst_by_conn(conn);
1226 	if (inst == NULL) {
1227 		return -EINVAL;
1228 	}
1229 
1230 	if (inst->cp_handle == 0) {
1231 		LOG_DBG("handle not set");
1232 
1233 		return -EINVAL;
1234 	} else if (atomic_test_and_set_bit(inst->flags, BAP_BA_FLAG_BUSY)) {
1235 		LOG_DBG("instance busy");
1236 
1237 		return -EBUSY;
1238 	}
1239 
1240 	if (atomic_test_bit(inst->flags, BAP_BA_FLAG_SCANNING)) {
1241 		err = bt_le_scan_stop();
1242 		if (err != 0) {
1243 			LOG_DBG("Could not stop scan (%d)", err);
1244 
1245 			atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
1246 
1247 			return err;
1248 		}
1249 
1250 		atomic_clear_bit(inst->flags, BAP_BA_FLAG_SCANNING);
1251 	}
1252 
1253 	/* Reset buffer before using */
1254 	net_buf_simple_reset(&att_buf);
1255 	cp = net_buf_simple_add(&att_buf, sizeof(*cp));
1256 
1257 	cp->opcode = BT_BAP_BASS_OP_SCAN_STOP;
1258 
1259 	return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
1260 }
1261 
bis_syncs_unique_or_no_pref(uint32_t requested_bis_syncs,uint32_t aggregated_bis_syncs)1262 static bool bis_syncs_unique_or_no_pref(uint32_t requested_bis_syncs, uint32_t aggregated_bis_syncs)
1263 {
1264 	if (requested_bis_syncs == 0U || aggregated_bis_syncs == 0U) {
1265 		return true;
1266 	}
1267 
1268 	if (requested_bis_syncs == BT_BAP_BIS_SYNC_NO_PREF &&
1269 	    aggregated_bis_syncs == BT_BAP_BIS_SYNC_NO_PREF) {
1270 		return true;
1271 	}
1272 
1273 	return (requested_bis_syncs & aggregated_bis_syncs) != 0U;
1274 }
1275 
valid_bis_sync_request(uint32_t requested_bis_syncs,uint32_t aggregated_bis_syncs)1276 static bool valid_bis_sync_request(uint32_t requested_bis_syncs, uint32_t aggregated_bis_syncs)
1277 {
1278 	/* Verify that the request BIS sync indexes are unique or no preference */
1279 	if (!bis_syncs_unique_or_no_pref(requested_bis_syncs, aggregated_bis_syncs)) {
1280 		LOG_DBG("Duplicate BIS index 0x%08x (aggregated %x)", requested_bis_syncs,
1281 			aggregated_bis_syncs);
1282 		return false;
1283 	}
1284 
1285 	if (requested_bis_syncs != BT_BAP_BIS_SYNC_NO_PREF &&
1286 	    aggregated_bis_syncs == BT_BAP_BIS_SYNC_NO_PREF) {
1287 		LOG_DBG("Invalid BIS index 0x%08X mixing BT_BAP_BIS_SYNC_NO_PREF and specific BIS",
1288 			requested_bis_syncs);
1289 		return false;
1290 	}
1291 
1292 	if (!valid_bis_syncs(requested_bis_syncs)) {
1293 		LOG_DBG("Invalid BIS sync: 0x%08X", requested_bis_syncs);
1294 		return false;
1295 	}
1296 
1297 	return true;
1298 }
1299 
valid_subgroup_params(uint8_t pa_sync,const struct bt_bap_bass_subgroup subgroups[],uint8_t num_subgroups)1300 static bool valid_subgroup_params(uint8_t pa_sync, const struct bt_bap_bass_subgroup subgroups[],
1301 				  uint8_t num_subgroups)
1302 {
1303 	uint32_t aggregated_bis_syncs = 0U;
1304 
1305 	for (uint8_t i = 0U; i < num_subgroups; i++) {
1306 		/* BIS sync values of 0 and BT_BAP_BIS_SYNC_NO_PREF are allowed at any time, but any
1307 		 * other values are only allowed if PA sync state is also set
1308 		 */
1309 		CHECKIF(pa_sync == 0 && (subgroups[i].bis_sync != 0U &&
1310 					 subgroups[i].bis_sync != BT_BAP_BIS_SYNC_NO_PREF)) {
1311 			LOG_DBG("[%u]: Only syncing to BIS is not allowed", i);
1312 
1313 			return false;
1314 		}
1315 
1316 		/* Verify that the request BIS sync indexes are unique or no preference */
1317 		if (!valid_bis_sync_request(subgroups[i].bis_sync, aggregated_bis_syncs)) {
1318 			LOG_DBG("Invalid BIS Sync request[%d]", i);
1319 
1320 			return false;
1321 		}
1322 
1323 		/* Keep track of BIS sync values to ensure that we do not have duplicates */
1324 		aggregated_bis_syncs |= subgroups[i].bis_sync;
1325 
1326 #if defined(CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE)
1327 		if (subgroups[i].metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
1328 			LOG_DBG("[%u]: Invalid metadata_len: %u", i, subgroups[i].metadata_len);
1329 
1330 			return false;
1331 		}
1332 	}
1333 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE */
1334 
1335 	return true;
1336 }
1337 
valid_add_src_param(const struct bt_bap_broadcast_assistant_add_src_param * param)1338 static bool valid_add_src_param(const struct bt_bap_broadcast_assistant_add_src_param *param)
1339 {
1340 	CHECKIF(param == NULL) {
1341 		LOG_DBG("param is NULL");
1342 		return false;
1343 	}
1344 
1345 	CHECKIF(param->addr.type > BT_ADDR_LE_RANDOM) {
1346 		LOG_DBG("Invalid address type %u", param->addr.type);
1347 		return false;
1348 	}
1349 
1350 	CHECKIF(param->adv_sid > BT_GAP_SID_MAX) {
1351 		LOG_DBG("Invalid adv_sid %u", param->adv_sid);
1352 		return false;
1353 	}
1354 
1355 	CHECKIF(!(param->pa_interval != BT_BAP_PA_INTERVAL_UNKNOWN) &&
1356 		!IN_RANGE(param->pa_interval, BT_GAP_PER_ADV_MIN_INTERVAL,
1357 			  BT_GAP_PER_ADV_MAX_INTERVAL)) {
1358 		LOG_DBG("Invalid pa_interval 0x%04X", param->pa_interval);
1359 		return false;
1360 	}
1361 
1362 	CHECKIF(param->broadcast_id > BT_AUDIO_BROADCAST_ID_MAX) {
1363 		LOG_DBG("Invalid broadcast_id 0x%08X", param->broadcast_id);
1364 		return false;
1365 	}
1366 
1367 	CHECKIF(param->num_subgroups != 0 && param->subgroups == NULL) {
1368 		LOG_DBG("Subgroups are NULL when num_subgroups = %u", param->num_subgroups);
1369 		return false;
1370 	}
1371 
1372 	CHECKIF(param->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
1373 		LOG_DBG("Too many subgroups %u/%u", param->num_subgroups,
1374 			CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
1375 
1376 		return false;
1377 	}
1378 
1379 	CHECKIF(param->subgroups != NULL) {
1380 		if (!valid_subgroup_params(param->pa_sync, param->subgroups,
1381 					   param->num_subgroups)) {
1382 			return false;
1383 		}
1384 	}
1385 
1386 	return true;
1387 }
1388 
bt_bap_broadcast_assistant_add_src(struct bt_conn * conn,const struct bt_bap_broadcast_assistant_add_src_param * param)1389 int bt_bap_broadcast_assistant_add_src(struct bt_conn *conn,
1390 				       const struct bt_bap_broadcast_assistant_add_src_param *param)
1391 {
1392 	struct bt_bap_bass_cp_add_src *cp;
1393 	struct bap_broadcast_assistant_instance *inst;
1394 
1395 	if (conn == NULL) {
1396 		LOG_DBG("conn is NULL");
1397 
1398 		return -EINVAL;
1399 	}
1400 
1401 	inst = inst_by_conn(conn);
1402 
1403 	if (inst == NULL) {
1404 		return -EINVAL;
1405 	}
1406 
1407 	/* Check if this operation would result in a duplicate before proceeding */
1408 	if (broadcast_src_is_duplicate(inst, param->broadcast_id, param->adv_sid,
1409 				       param->addr.type)) {
1410 		LOG_DBG("Broadcast source already exists");
1411 
1412 		return -EINVAL;
1413 	}
1414 
1415 	if (!valid_add_src_param(param)) {
1416 		return -EINVAL;
1417 	}
1418 
1419 	if (inst->cp_handle == 0) {
1420 		LOG_DBG("handle not set");
1421 
1422 		return -EINVAL;
1423 	} else if (atomic_test_and_set_bit(inst->flags, BAP_BA_FLAG_BUSY)) {
1424 		LOG_DBG("instance busy");
1425 
1426 		return -EBUSY;
1427 	}
1428 	/* Reset buffer before using */
1429 	net_buf_simple_reset(&att_buf);
1430 	cp = net_buf_simple_add(&att_buf, sizeof(*cp));
1431 
1432 	cp->opcode = BT_BAP_BASS_OP_ADD_SRC;
1433 	cp->adv_sid = param->adv_sid;
1434 	bt_addr_le_copy(&cp->addr, &param->addr);
1435 
1436 	sys_put_le24(param->broadcast_id, cp->broadcast_id);
1437 
1438 	if (param->pa_sync) {
1439 		if (past_available(conn, &param->addr, param->adv_sid)) {
1440 			cp->pa_sync = BT_BAP_BASS_PA_REQ_SYNC_PAST;
1441 		} else {
1442 			cp->pa_sync = BT_BAP_BASS_PA_REQ_SYNC;
1443 		}
1444 	} else {
1445 		cp->pa_sync = BT_BAP_BASS_PA_REQ_NO_SYNC;
1446 	}
1447 	cp->pa_interval = sys_cpu_to_le16(param->pa_interval);
1448 
1449 	cp->num_subgroups = param->num_subgroups;
1450 	for (int i = 0; i < param->num_subgroups; i++) {
1451 		struct bt_bap_bass_cp_subgroup *subgroup;
1452 		const size_t subgroup_size = sizeof(subgroup->bis_sync) +
1453 					     sizeof(subgroup->metadata_len) +
1454 					     param->subgroups[i].metadata_len;
1455 
1456 		if (att_buf.len + subgroup_size > att_buf.size) {
1457 			LOG_DBG("MTU is too small to send %zu octets", att_buf.len + subgroup_size);
1458 
1459 			/* TODO: Validate parameters before setting the busy flag to reduce cleanup
1460 			 */
1461 			atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
1462 
1463 			return -EINVAL;
1464 		}
1465 
1466 		subgroup = net_buf_simple_add(&att_buf, subgroup_size);
1467 
1468 		subgroup->bis_sync = param->subgroups[i].bis_sync;
1469 
1470 #if defined(CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE)
1471 		if (param->subgroups[i].metadata_len != 0) {
1472 			(void)memcpy(subgroup->metadata, param->subgroups[i].metadata,
1473 				     param->subgroups[i].metadata_len);
1474 			subgroup->metadata_len = param->subgroups[i].metadata_len;
1475 		} else {
1476 			subgroup->metadata_len = 0U;
1477 		}
1478 #else
1479 		subgroup->metadata_len = 0U;
1480 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE */
1481 	}
1482 
1483 	return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
1484 }
1485 
valid_add_mod_param(const struct bt_bap_broadcast_assistant_mod_src_param * param)1486 static bool valid_add_mod_param(const struct bt_bap_broadcast_assistant_mod_src_param *param)
1487 {
1488 	CHECKIF(param == NULL) {
1489 		LOG_DBG("param is NULL");
1490 		return false;
1491 	}
1492 
1493 	CHECKIF(!(param->pa_interval != BT_BAP_PA_INTERVAL_UNKNOWN) &&
1494 		!IN_RANGE(param->pa_interval, BT_GAP_PER_ADV_MIN_INTERVAL,
1495 			  BT_GAP_PER_ADV_MAX_INTERVAL)) {
1496 		LOG_DBG("Invalid pa_interval 0x%04X", param->pa_interval);
1497 		return false;
1498 	}
1499 
1500 	CHECKIF(param->num_subgroups != 0 && param->subgroups == NULL) {
1501 		LOG_DBG("Subgroups are NULL when num_subgroups = %u", param->num_subgroups);
1502 		return false;
1503 	}
1504 
1505 	CHECKIF(param->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
1506 		LOG_DBG("Too many subgroups %u/%u", param->num_subgroups,
1507 			CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
1508 
1509 		return false;
1510 	}
1511 
1512 	CHECKIF(param->subgroups != NULL) {
1513 		if (!valid_subgroup_params(param->pa_sync, param->subgroups,
1514 					   param->num_subgroups)) {
1515 			return false;
1516 		}
1517 	}
1518 
1519 	return true;
1520 }
1521 
bt_bap_broadcast_assistant_mod_src(struct bt_conn * conn,const struct bt_bap_broadcast_assistant_mod_src_param * param)1522 int bt_bap_broadcast_assistant_mod_src(struct bt_conn *conn,
1523 				       const struct bt_bap_broadcast_assistant_mod_src_param *param)
1524 {
1525 	struct bt_bap_bass_cp_mod_src *cp;
1526 	bool known_recv_state;
1527 	bool past_avail;
1528 	struct bap_broadcast_assistant_instance *inst;
1529 
1530 	if (conn == NULL) {
1531 		LOG_DBG("conn is NULL");
1532 
1533 		return -EINVAL;
1534 	}
1535 
1536 	if (!valid_add_mod_param(param)) {
1537 		return -EINVAL;
1538 	}
1539 
1540 	inst = inst_by_conn(conn);
1541 	if (inst == NULL) {
1542 		return -EINVAL;
1543 	}
1544 
1545 	if (inst->cp_handle == 0) {
1546 		LOG_DBG("handle not set");
1547 
1548 		return -EINVAL;
1549 	} else if (atomic_test_and_set_bit(inst->flags, BAP_BA_FLAG_BUSY)) {
1550 		LOG_DBG("instance busy");
1551 
1552 		return -EBUSY;
1553 	}
1554 
1555 	/* Reset buffer before using */
1556 	net_buf_simple_reset(&att_buf);
1557 	cp = net_buf_simple_add(&att_buf, sizeof(*cp));
1558 
1559 	cp->opcode = BT_BAP_BASS_OP_MOD_SRC;
1560 	cp->src_id = param->src_id;
1561 
1562 	/* Since we do not have the address and SID in this function, we
1563 	 * rely on cached PAST support information
1564 	 */
1565 	known_recv_state = false;
1566 	past_avail = false;
1567 	for (size_t i = 0; i < ARRAY_SIZE(inst->recv_states); i++) {
1568 		if (inst->recv_states[i].src_id == param->src_id) {
1569 			known_recv_state = true;
1570 			past_avail = inst->recv_states[i].past_avail;
1571 			break;
1572 		}
1573 	}
1574 
1575 	if (!known_recv_state) {
1576 		LOG_WRN("Attempting to modify unknown receive state: %u",
1577 			param->src_id);
1578 	}
1579 
1580 	if (param->pa_sync) {
1581 		if (known_recv_state && past_avail) {
1582 			cp->pa_sync = BT_BAP_BASS_PA_REQ_SYNC_PAST;
1583 		} else {
1584 			cp->pa_sync = BT_BAP_BASS_PA_REQ_SYNC;
1585 		}
1586 	} else {
1587 		cp->pa_sync = BT_BAP_BASS_PA_REQ_NO_SYNC;
1588 	}
1589 
1590 	cp->pa_interval = sys_cpu_to_le16(param->pa_interval);
1591 
1592 	cp->num_subgroups = param->num_subgroups;
1593 	for (int i = 0; i < param->num_subgroups; i++) {
1594 		struct bt_bap_bass_cp_subgroup *subgroup;
1595 		const size_t subgroup_size = sizeof(subgroup->bis_sync) +
1596 					     sizeof(subgroup->metadata_len) +
1597 					     param->subgroups[i].metadata_len;
1598 
1599 		if (att_buf.len + subgroup_size > att_buf.size) {
1600 			LOG_DBG("MTU is too small to send %zu octets", att_buf.len + subgroup_size);
1601 
1602 			/* TODO: Validate parameters before setting the busy flag to reduce cleanup
1603 			 */
1604 			atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
1605 
1606 			return -EINVAL;
1607 		}
1608 		subgroup = net_buf_simple_add(&att_buf, subgroup_size);
1609 
1610 		subgroup->bis_sync = param->subgroups[i].bis_sync;
1611 
1612 #if defined(CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE)
1613 		if (param->subgroups[i].metadata_len != 0) {
1614 			(void)memcpy(subgroup->metadata,
1615 				     param->subgroups[i].metadata,
1616 				     param->subgroups[i].metadata_len);
1617 			subgroup->metadata_len = param->subgroups[i].metadata_len;
1618 		} else {
1619 			subgroup->metadata_len = 0U;
1620 		}
1621 #else
1622 		subgroup->metadata_len = 0U;
1623 #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE */
1624 	}
1625 
1626 	return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
1627 }
1628 
bt_bap_broadcast_assistant_set_broadcast_code(struct bt_conn * conn,uint8_t src_id,const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])1629 int bt_bap_broadcast_assistant_set_broadcast_code(
1630 	struct bt_conn *conn, uint8_t src_id,
1631 	const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])
1632 {
1633 	struct bt_bap_bass_cp_broadcase_code *cp;
1634 	struct bap_broadcast_assistant_instance *inst;
1635 
1636 	if (conn == NULL) {
1637 		LOG_DBG("conn is NULL");
1638 
1639 		return -EINVAL;
1640 	}
1641 
1642 	inst = inst_by_conn(conn);
1643 	if (inst == NULL) {
1644 		return -EINVAL;
1645 	}
1646 
1647 	if (inst->cp_handle == 0) {
1648 		LOG_DBG("handle not set");
1649 
1650 		return -EINVAL;
1651 	} else if (atomic_test_and_set_bit(inst->flags, BAP_BA_FLAG_BUSY)) {
1652 		LOG_DBG("instance busy");
1653 
1654 		return -EBUSY;
1655 	}
1656 
1657 	/* Reset buffer before using */
1658 	net_buf_simple_reset(&att_buf);
1659 	cp = net_buf_simple_add(&att_buf, sizeof(*cp));
1660 
1661 	cp->opcode = BT_BAP_BASS_OP_BROADCAST_CODE;
1662 	cp->src_id = src_id;
1663 
1664 	(void)memcpy(cp->broadcast_code, broadcast_code, BT_ISO_BROADCAST_CODE_SIZE);
1665 
1666 	LOG_HEXDUMP_DBG(cp->broadcast_code, BT_ISO_BROADCAST_CODE_SIZE, "broadcast code:");
1667 
1668 	return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
1669 }
1670 
bt_bap_broadcast_assistant_rem_src(struct bt_conn * conn,uint8_t src_id)1671 int bt_bap_broadcast_assistant_rem_src(struct bt_conn *conn, uint8_t src_id)
1672 {
1673 	struct bt_bap_bass_cp_rem_src *cp;
1674 	struct bap_broadcast_assistant_instance *inst;
1675 
1676 	if (conn == NULL) {
1677 		LOG_DBG("conn is NULL");
1678 
1679 		return -EINVAL;
1680 	}
1681 
1682 	inst = inst_by_conn(conn);
1683 	if (inst == NULL) {
1684 		return -EINVAL;
1685 	}
1686 
1687 	if (inst->cp_handle == 0) {
1688 		LOG_DBG("handle not set");
1689 
1690 		return -EINVAL;
1691 	} else if (atomic_test_and_set_bit(inst->flags, BAP_BA_FLAG_BUSY)) {
1692 		LOG_DBG("instance busy");
1693 
1694 		return -EBUSY;
1695 	}
1696 
1697 	/* Reset buffer before using */
1698 	net_buf_simple_reset(&att_buf);
1699 	cp = net_buf_simple_add(&att_buf, sizeof(*cp));
1700 
1701 	cp->opcode = BT_BAP_BASS_OP_REM_SRC;
1702 	cp->src_id = src_id;
1703 
1704 	return bt_bap_broadcast_assistant_common_cp(conn, &att_buf);
1705 }
1706 
read_recv_state(struct bap_broadcast_assistant_instance * inst,uint8_t idx)1707 static int read_recv_state(struct bap_broadcast_assistant_instance *inst, uint8_t idx)
1708 {
1709 	int err;
1710 
1711 	inst->read_params.func = read_recv_state_cb;
1712 	inst->read_params.handle_count = 1;
1713 	inst->read_params.single.handle = inst->recv_state_handles[idx];
1714 
1715 	err = bt_gatt_read(inst->conn, &inst->read_params);
1716 	if (err != 0) {
1717 		(void)memset(&inst->read_params, 0, sizeof(inst->read_params));
1718 	}
1719 
1720 	return err;
1721 }
1722 
bt_bap_broadcast_assistant_read_recv_state(struct bt_conn * conn,uint8_t idx)1723 int bt_bap_broadcast_assistant_read_recv_state(struct bt_conn *conn,
1724 					       uint8_t idx)
1725 {
1726 	int err;
1727 	struct bap_broadcast_assistant_instance *inst;
1728 
1729 	if (conn == NULL) {
1730 		LOG_DBG("conn is NULL");
1731 
1732 		return -EINVAL;
1733 	}
1734 
1735 	inst = inst_by_conn(conn);
1736 	if (inst == NULL) {
1737 		return -EINVAL;
1738 	}
1739 
1740 	CHECKIF(idx >= ARRAY_SIZE(inst->recv_state_handles)) {
1741 		LOG_DBG("Invalid idx: %u", idx);
1742 
1743 		return -EINVAL;
1744 	}
1745 
1746 	if (inst->recv_state_handles[idx] == 0) {
1747 		LOG_DBG("handle not set");
1748 
1749 		return -EINVAL;
1750 	} else if (atomic_test_and_set_bit(inst->flags, BAP_BA_FLAG_BUSY)) {
1751 		LOG_DBG("instance busy");
1752 
1753 		return -EBUSY;
1754 	}
1755 
1756 	err = read_recv_state(inst, idx);
1757 	if (err != 0) {
1758 		(void)memset(&inst->read_params, 0,
1759 			     sizeof(inst->read_params));
1760 		atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
1761 	}
1762 
1763 	return err;
1764 }
1765