1 /* Bluetooth Scan Delegator */
2
3 /*
4 * Copyright (c) 2019 Bose Corporation
5 * Copyright (c) 2021-2023 Nordic Semiconductor ASA
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10 #include <errno.h>
11 #include <stdbool.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 #include <string.h>
15 #include <sys/types.h>
16
17 #include <zephyr/autoconf.h>
18 #include <zephyr/bluetooth/addr.h>
19 #include <zephyr/bluetooth/att.h>
20 #include <zephyr/bluetooth/audio/audio.h>
21 #include <zephyr/bluetooth/audio/bap.h>
22 #include <zephyr/bluetooth/bluetooth.h>
23 #include <zephyr/bluetooth/conn.h>
24 #include <zephyr/bluetooth/gap.h>
25 #include <zephyr/bluetooth/gatt.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/init.h>
32 #include <zephyr/kernel.h>
33 #include <zephyr/logging/log.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/util.h>
40 #include <zephyr/sys/util_macro.h>
41
42 LOG_MODULE_REGISTER(bt_bap_scan_delegator, CONFIG_BT_BAP_SCAN_DELEGATOR_LOG_LEVEL);
43
44 #include "common/bt_str.h"
45
46 #include "audio_internal.h"
47 #include "bap_internal.h"
48 #include "../host/conn_internal.h"
49 #include "../host/hci_core.h"
50
51 #define PAST_TIMEOUT K_SECONDS(10)
52
53 #define SCAN_DELEGATOR_BUF_SEM_TIMEOUT K_MSEC(CONFIG_BT_BAP_SCAN_DELEGATOR_BUF_TIMEOUT)
54 NET_BUF_SIMPLE_DEFINE_STATIC(read_buf, BT_ATT_MAX_ATTRIBUTE_LEN);
55
56 struct bass_recv_state_flags {
57 bool updated: 1;
58 };
59
60 /* TODO: Merge bass_recv_state_internal_t and bt_bap_scan_delegator_recv_state */
61 struct bass_recv_state_internal {
62 const struct bt_gatt_attr *attr;
63
64 bool active;
65 uint8_t index;
66 struct bt_bap_scan_delegator_recv_state state;
67 uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE];
68 struct bt_le_per_adv_sync *pa_sync;
69 /** Requested BIS sync bitfield for each subgroup */
70 uint32_t requested_bis_sync[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS];
71
72 /* Mutex (reentrant Locking) ensure multiple threads to safely access receive state data */
73 struct k_mutex mutex;
74 struct bass_recv_state_flags flags[CONFIG_BT_MAX_CONN];
75
76 struct k_work_delayable notify_work;
77 };
78
79 struct bt_bap_scan_delegator_inst {
80 uint8_t next_src_id;
81 struct bass_recv_state_internal recv_states
82 [CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT];
83 };
84
85 enum scan_delegator_flag {
86 SCAN_DELEGATOR_FLAG_REGISTERED_CONN_CB,
87 SCAN_DELEGATOR_FLAG_REGISTERED_SCAN_DELIGATOR,
88 SCAN_DELEGATOR_FLAG_REGISTERED_PA_SYNC_CB,
89
90 SCAN_DELEGATOR_FLAG_NUM,
91 };
92
93 static ATOMIC_DEFINE(scan_delegator_flags, SCAN_DELEGATOR_FLAG_NUM);
94
95 static struct bt_bap_scan_delegator_inst scan_delegator;
96 static struct bt_bap_scan_delegator_cb *scan_delegator_cbs;
97
set_receive_state_changed_cb(struct bt_conn * conn,void * data)98 static void set_receive_state_changed_cb(struct bt_conn *conn, void *data)
99 {
100 struct bass_recv_state_internal *internal_state = data;
101 struct bass_recv_state_flags *flags = &internal_state->flags[bt_conn_index(conn)];
102 struct bt_conn_info conn_info;
103 int err;
104
105 err = bt_conn_get_info(conn, &conn_info);
106 __ASSERT_NO_MSG(err == 0);
107
108 if (conn_info.state != BT_CONN_STATE_CONNECTED ||
109 !bt_gatt_is_subscribed(conn, internal_state->attr, BT_GATT_CCC_NOTIFY)) {
110 return;
111 }
112
113 flags->updated = true;
114
115 /* We may schedule the same work multiple times, but that is OK as scheduling the same work
116 * multiple times is a no-op
117 */
118 err = k_work_schedule(&internal_state->notify_work, K_NO_WAIT);
119 __ASSERT(err >= 0, "Failed to schedule work: %d", err);
120 }
121
set_receive_state_changed(struct bass_recv_state_internal * internal_state)122 static void set_receive_state_changed(struct bass_recv_state_internal *internal_state)
123 {
124 bt_conn_foreach(BT_CONN_TYPE_LE, set_receive_state_changed_cb, (void *)internal_state);
125 }
126
127 /**
128 * @brief Returns whether a value's bits is a subset of another value's bits
129 *
130 * @param a The subset to check
131 * @param b The bits to check against
132 *
133 * @return True if @p a is a bitwise subset of @p b
134 */
bits_subset_of(uint32_t a,uint32_t b)135 static bool bits_subset_of(uint32_t a, uint32_t b)
136 {
137 return (((a) & (~(b))) == 0);
138 }
139
bis_syncs_unique_or_no_pref(uint32_t requested_bis_syncs,uint32_t aggregated_bis_syncs)140 static bool bis_syncs_unique_or_no_pref(uint32_t requested_bis_syncs,
141 uint32_t aggregated_bis_syncs)
142 {
143 if (requested_bis_syncs == 0U || aggregated_bis_syncs == 0U) {
144 return true;
145 }
146
147 if (requested_bis_syncs == BT_BAP_BIS_SYNC_NO_PREF &&
148 aggregated_bis_syncs == BT_BAP_BIS_SYNC_NO_PREF) {
149 return true;
150 }
151
152 return (requested_bis_syncs & aggregated_bis_syncs) != 0U;
153 }
154
valid_bis_sync_request(uint32_t requested_bis_syncs,uint32_t aggregated_bis_syncs)155 static bool valid_bis_sync_request(uint32_t requested_bis_syncs, uint32_t aggregated_bis_syncs)
156 {
157 /* Verify that the request BIS sync indexes are unique or no preference */
158 if (!bis_syncs_unique_or_no_pref(requested_bis_syncs, aggregated_bis_syncs)) {
159 LOG_DBG("Duplicate BIS index 0x%08x (aggregated %x)", requested_bis_syncs,
160 aggregated_bis_syncs);
161 return false;
162 }
163
164 if (requested_bis_syncs != BT_BAP_BIS_SYNC_NO_PREF &&
165 aggregated_bis_syncs == BT_BAP_BIS_SYNC_NO_PREF) {
166 LOG_DBG("Invalid BIS index 0x%08X mixing BT_BAP_BIS_SYNC_NO_PREF and specific BIS",
167 requested_bis_syncs);
168 return false;
169 }
170
171 if (!valid_bis_syncs(requested_bis_syncs)) {
172 LOG_DBG("Invalid BIS sync: 0x%08X", requested_bis_syncs);
173 return false;
174 }
175
176 return true;
177 }
178
bt_debug_dump_recv_state(const struct bass_recv_state_internal * recv_state)179 static void bt_debug_dump_recv_state(const struct bass_recv_state_internal *recv_state)
180 {
181 if (recv_state->active) {
182 const struct bt_bap_scan_delegator_recv_state *state = &recv_state->state;
183 const bool is_bad_code = state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE;
184
185 LOG_DBG("Receive State[%d]: src ID %u, addr %s, adv_sid %u, broadcast_id 0x%06X, "
186 "pa_sync_state %u, encrypt state %u%s%s, num_subgroups %u",
187 recv_state->index, state->src_id, bt_addr_le_str(&state->addr),
188 state->adv_sid, state->broadcast_id, state->pa_sync_state,
189 state->encrypt_state, is_bad_code ? ", bad code" : "",
190 is_bad_code ? bt_hex(state->bad_code, sizeof(state->bad_code)) : "",
191 state->num_subgroups);
192
193 for (uint8_t i = 0U; i < state->num_subgroups; i++) {
194 const struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
195
196 LOG_DBG("\tSubgroup[%u]: BIS sync %u (requested %u), metadata_len %zu, "
197 "metadata: %s",
198 i, subgroup->bis_sync, recv_state->requested_bis_sync[i],
199 subgroup->metadata_len,
200 bt_hex(subgroup->metadata, subgroup->metadata_len));
201 }
202 } else {
203 LOG_DBG("Inactive receive state");
204 }
205 }
206
receive_state_notify_cb(struct bt_conn * conn,void * data)207 static void receive_state_notify_cb(struct bt_conn *conn, void *data)
208 {
209 struct bass_recv_state_internal *internal_state = data;
210 struct bass_recv_state_flags *flags = &internal_state->flags[bt_conn_index(conn)];
211 struct bt_conn_info conn_info;
212 int err;
213
214 err = bt_conn_get_info(conn, &conn_info);
215 __ASSERT_NO_MSG(err == 0);
216
217 if (conn_info.state != BT_CONN_STATE_CONNECTED ||
218 !bt_gatt_is_subscribed(conn, internal_state->attr, BT_GATT_CCC_NOTIFY)) {
219 return;
220 }
221
222 if (flags->updated) {
223 uint16_t max_ntf_size;
224 uint16_t ntf_size;
225
226 max_ntf_size = bt_audio_get_max_ntf_size(conn);
227
228 ntf_size = MIN(max_ntf_size, read_buf.len);
229 if (ntf_size < read_buf.len) {
230 LOG_DBG("Sending truncated notification (%u/%u)", ntf_size, read_buf.len);
231 }
232
233 LOG_DBG("Sending bytes %u for %p", ntf_size, (void *)conn);
234 err = bt_gatt_notify_uuid(conn, BT_UUID_BASS_RECV_STATE, internal_state->attr,
235 read_buf.data, ntf_size);
236 if (err == 0) {
237 flags->updated = false;
238 return;
239 }
240
241 LOG_DBG("Could not notify receive state: %d", err);
242 err = k_work_reschedule(&internal_state->notify_work,
243 K_USEC(BT_CONN_INTERVAL_TO_US(conn_info.le.interval)));
244 __ASSERT(err >= 0, "Failed to reschedule work: %d", err);
245 }
246 }
247
net_buf_put_recv_state(const struct bass_recv_state_internal * recv_state)248 static void net_buf_put_recv_state(const struct bass_recv_state_internal *recv_state)
249 {
250 const struct bt_bap_scan_delegator_recv_state *state = &recv_state->state;
251
252 net_buf_simple_reset(&read_buf);
253
254 __ASSERT(recv_state, "NULL receive state");
255
256 if (!recv_state->active) {
257 /* Notify empty */
258
259 return;
260 }
261
262 (void)net_buf_simple_add_u8(&read_buf, state->src_id);
263 (void)net_buf_simple_add_u8(&read_buf, state->addr.type);
264 (void)net_buf_simple_add_mem(&read_buf, &state->addr.a,
265 sizeof(state->addr.a));
266 (void)net_buf_simple_add_u8(&read_buf, state->adv_sid);
267 (void)net_buf_simple_add_le24(&read_buf, state->broadcast_id);
268 (void)net_buf_simple_add_u8(&read_buf, state->pa_sync_state);
269 (void)net_buf_simple_add_u8(&read_buf, state->encrypt_state);
270 if (state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
271 (void)net_buf_simple_add_mem(&read_buf, &state->bad_code,
272 sizeof(state->bad_code));
273 }
274 (void)net_buf_simple_add_u8(&read_buf, state->num_subgroups);
275 for (int i = 0; i < state->num_subgroups; i++) {
276 const struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
277
278 (void)net_buf_simple_add_le32(&read_buf, subgroup->bis_sync);
279 (void)net_buf_simple_add_u8(&read_buf, subgroup->metadata_len);
280 (void)net_buf_simple_add_mem(&read_buf, subgroup->metadata,
281 subgroup->metadata_len);
282 }
283 }
284
receive_state_updated(struct bt_conn * conn,struct bass_recv_state_internal * internal_state)285 static void receive_state_updated(struct bt_conn *conn,
286 struct bass_recv_state_internal *internal_state)
287 {
288 if (IS_ENABLED(CONFIG_BT_BAP_SCAN_DELEGATOR_LOG_LEVEL_DBG)) {
289 int err;
290
291 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
292 if (err == 0) {
293 bt_debug_dump_recv_state(internal_state);
294 err = k_mutex_unlock(&internal_state->mutex);
295 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
296
297 } else {
298 LOG_DBG("Failed to lock mutex: %d", err);
299 }
300 }
301
302 if (scan_delegator_cbs != NULL && scan_delegator_cbs->recv_state_updated != NULL) {
303 scan_delegator_cbs->recv_state_updated(conn, &internal_state->state);
304 }
305 }
306
notify_work_handler(struct k_work * work)307 static void notify_work_handler(struct k_work *work)
308 {
309 struct bass_recv_state_internal *internal_state = CONTAINER_OF(
310 k_work_delayable_from_work(work), struct bass_recv_state_internal, notify_work);
311 int err;
312
313 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
314 if (err != 0) {
315 LOG_DBG("Failed to take mutex: %d", err);
316 err = k_work_reschedule(&internal_state->notify_work, K_NO_WAIT);
317 __ASSERT(err >= 0, "Failed to reschedule work: %d", err);
318 return;
319 }
320
321 net_buf_put_recv_state(internal_state);
322 bt_conn_foreach(BT_CONN_TYPE_LE, receive_state_notify_cb, internal_state);
323
324 err = k_mutex_unlock(&internal_state->mutex);
325 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
326 }
327
bis_sync_request_updated(struct bt_conn * conn,const struct bass_recv_state_internal * internal_state)328 static void bis_sync_request_updated(struct bt_conn *conn,
329 const struct bass_recv_state_internal *internal_state)
330 {
331 if (scan_delegator_cbs != NULL &&
332 scan_delegator_cbs->bis_sync_req != NULL) {
333 scan_delegator_cbs->bis_sync_req(conn, &internal_state->state,
334 internal_state->requested_bis_sync);
335 } else {
336 LOG_WRN("bis_sync_req callback is missing");
337 }
338 }
339
scan_delegator_security_changed(struct bt_conn * conn,bt_security_t level,enum bt_security_err err)340 static void scan_delegator_security_changed(struct bt_conn *conn,
341 bt_security_t level,
342 enum bt_security_err err)
343 {
344
345 if (err != 0 || level < BT_SECURITY_L2 || !bt_le_bond_exists(conn->id, &conn->le.dst)) {
346 return;
347 }
348
349 /* Notify all receive states after a bonded device reconnects */
350 for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
351 const struct bass_recv_state_internal *internal_state =
352 &scan_delegator.recv_states[i];
353
354 if (!internal_state->active) {
355 continue;
356 }
357
358 set_receive_state_changed_cb(conn, (void *)internal_state);
359 }
360 }
361
362 BT_CONN_CB_DEFINE(conn_callbacks) = {
363 .security_changed = scan_delegator_security_changed,
364 };
365
next_src_id(void)366 static uint8_t next_src_id(void)
367 {
368 uint8_t next_src_id;
369 bool unique = false;
370
371 while (!unique) {
372 next_src_id = scan_delegator.next_src_id++;
373 unique = true;
374 for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
375 if (scan_delegator.recv_states[i].active &&
376 scan_delegator.recv_states[i].state.src_id == next_src_id) {
377 unique = false;
378 break;
379 }
380 }
381 }
382
383 return next_src_id;
384 }
385
bass_lookup_src_id(uint8_t src_id)386 static struct bass_recv_state_internal *bass_lookup_src_id(uint8_t src_id)
387 {
388 for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
389 if (scan_delegator.recv_states[i].active &&
390 scan_delegator.recv_states[i].state.src_id == src_id) {
391 return &scan_delegator.recv_states[i];
392 }
393 }
394
395 return NULL;
396 }
397
bass_lookup_pa_sync(struct bt_le_per_adv_sync * sync)398 static struct bass_recv_state_internal *bass_lookup_pa_sync(struct bt_le_per_adv_sync *sync)
399 {
400 for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
401 if (scan_delegator.recv_states[i].pa_sync == sync) {
402 return &scan_delegator.recv_states[i];
403 }
404 }
405
406 return NULL;
407 }
408
bass_lookup_addr(const bt_addr_le_t * addr)409 static struct bass_recv_state_internal *bass_lookup_addr(const bt_addr_le_t *addr)
410 {
411 for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
412 if (bt_addr_le_eq(&scan_delegator.recv_states[i].state.addr,
413 addr)) {
414 return &scan_delegator.recv_states[i];
415 }
416 }
417
418 return NULL;
419 }
420
get_free_recv_state(void)421 static struct bass_recv_state_internal *get_free_recv_state(void)
422 {
423 for (size_t i = 0U; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
424 struct bass_recv_state_internal *free_internal_state =
425 &scan_delegator.recv_states[i];
426
427 if (!free_internal_state->active) {
428 return free_internal_state;
429 }
430 }
431
432 return NULL;
433 }
434
pa_synced(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)435 static void pa_synced(struct bt_le_per_adv_sync *sync,
436 struct bt_le_per_adv_sync_synced_info *info)
437 {
438 struct bass_recv_state_internal *internal_state;
439 bool state_changed = false;
440 int err;
441
442 LOG_DBG("Synced%s", info->conn ? " via PAST" : "");
443
444 internal_state = bass_lookup_addr(info->addr);
445 if (internal_state == NULL) {
446 LOG_DBG("BASS receive state not found");
447 return;
448 }
449
450 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
451 if (err != 0) {
452 LOG_DBG("Failed to lock mutex: %d", err);
453 return;
454 }
455
456 internal_state->pa_sync = sync;
457
458 if (internal_state->state.pa_sync_state != BT_BAP_PA_STATE_SYNCED) {
459 internal_state->state.pa_sync_state = BT_BAP_PA_STATE_SYNCED;
460 set_receive_state_changed(internal_state);
461 state_changed = true;
462 }
463
464 err = k_mutex_unlock(&internal_state->mutex);
465 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
466
467 if (state_changed) {
468 /* app callback */
469 receive_state_updated(info->conn, internal_state);
470 }
471 }
472
pa_terminated(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)473 static void pa_terminated(struct bt_le_per_adv_sync *sync,
474 const struct bt_le_per_adv_sync_term_info *info)
475 {
476 struct bass_recv_state_internal *internal_state = bass_lookup_pa_sync(sync);
477 bool state_changed = false;
478 int err;
479
480 LOG_DBG("Terminated");
481 if (internal_state == NULL) {
482 LOG_DBG("BASS receive state not found");
483 return;
484 }
485
486 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
487 if (err != 0) {
488 LOG_DBG("Failed to lock mutex: %d", err);
489 return;
490 }
491
492 internal_state->pa_sync = NULL;
493
494 if (internal_state->state.pa_sync_state != BT_BAP_PA_STATE_NOT_SYNCED) {
495 internal_state->state.pa_sync_state = BT_BAP_PA_STATE_NOT_SYNCED;
496 set_receive_state_changed(internal_state);
497 state_changed = true;
498 }
499
500 err = k_mutex_unlock(&internal_state->mutex);
501 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
502
503 if (state_changed) {
504 /* app callback */
505 receive_state_updated(NULL, internal_state);
506 }
507 }
508
509 static struct bt_le_per_adv_sync_cb pa_sync_cb = {
510 .synced = pa_synced,
511 .term = pa_terminated,
512 };
513
supports_past(struct bt_conn * conn,uint8_t pa_sync_val)514 static bool supports_past(struct bt_conn *conn, uint8_t pa_sync_val)
515 {
516 if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER)) {
517 struct bt_le_local_features local_features;
518 struct bt_conn_remote_info remote_info;
519 int err;
520
521 err = bt_le_get_local_features(&local_features);
522 if (err != 0) {
523 LOG_DBG("Failed to get local features: %d", err);
524 return false;
525 }
526
527 err = bt_conn_get_remote_info(conn, &remote_info);
528 if (err != 0) {
529 LOG_DBG("Failed to get remote info: %d", err);
530 return false;
531 }
532
533 LOG_DBG("%p remote %s PAST, local %s PAST (req %u)", (void *)conn,
534 BT_FEAT_LE_PAST_SEND(remote_info.le.features) ? "supports"
535 : "does not support",
536 BT_FEAT_LE_PAST_RECV(local_features.features) ? "supports"
537 : "does not support",
538 pa_sync_val);
539
540 return pa_sync_val == BT_BAP_BASS_PA_REQ_SYNC_PAST &&
541 BT_FEAT_LE_PAST_SEND(remote_info.le.features) &&
542 BT_FEAT_LE_PAST_RECV(local_features.features);
543 } else {
544 return false;
545 }
546 }
547
pa_sync_request(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * state,uint8_t pa_sync_val,uint16_t pa_interval)548 static int pa_sync_request(struct bt_conn *conn,
549 const struct bt_bap_scan_delegator_recv_state *state,
550 uint8_t pa_sync_val, uint16_t pa_interval)
551 {
552 int err = -EACCES;
553
554 if (scan_delegator_cbs != NULL &&
555 scan_delegator_cbs->pa_sync_req != NULL) {
556 const bool past_supported = supports_past(conn, pa_sync_val);
557
558 err = scan_delegator_cbs->pa_sync_req(conn, state,
559 past_supported,
560 pa_interval);
561 } else {
562 LOG_WRN("pa_sync_req callback is missing, rejecting PA sync request");
563 }
564
565 return err;
566 }
567
pa_sync_term_request(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * state)568 static int pa_sync_term_request(struct bt_conn *conn,
569 const struct bt_bap_scan_delegator_recv_state *state)
570 {
571 int err = -EACCES;
572
573 if (scan_delegator_cbs != NULL &&
574 scan_delegator_cbs->pa_sync_req != NULL) {
575 err = scan_delegator_cbs->pa_sync_term_req(conn, state);
576 } else {
577 LOG_WRN("pa_sync_term_req callback is missing, rejecting PA sync term request");
578 }
579
580 return err;
581 }
582
583 /* BAP 6.5.4 states that the Broadcast Assistant shall not initiate the Add Source operation
584 * if the operation would result in duplicate values for the combined Source_Address_Type,
585 * Source_Adv_SID, and Broadcast_ID fields of any Broadcast Receive State characteristic exposed
586 * by the Scan Delegator.
587 */
bass_source_is_duplicate(uint32_t broadcast_id,uint8_t adv_sid,uint8_t addr_type)588 static bool bass_source_is_duplicate(uint32_t broadcast_id, uint8_t adv_sid, uint8_t addr_type)
589 {
590 struct bass_recv_state_internal *state;
591
592 for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
593 state = &scan_delegator.recv_states[i];
594
595 if (state != NULL && state->state.broadcast_id == broadcast_id &&
596 state->state.adv_sid == adv_sid && state->state.addr.type == addr_type) {
597 LOG_DBG("recv_state already exists at src_id=0x%02X", state->state.src_id);
598
599 return true;
600 }
601 }
602
603 return false;
604 }
605
scan_delegator_add_src(struct bt_conn * conn,struct net_buf_simple * buf)606 static int scan_delegator_add_src(struct bt_conn *conn,
607 struct net_buf_simple *buf)
608 {
609 struct bass_recv_state_internal *internal_state = NULL;
610 struct bt_bap_scan_delegator_recv_state *state;
611 bt_addr_t *addr;
612 uint8_t pa_sync;
613 uint16_t pa_interval;
614 uint32_t aggregated_bis_syncs = 0;
615 uint32_t broadcast_id;
616 bool bis_sync_requested;
617 uint16_t total_len;
618 struct bt_bap_bass_cp_add_src *add_src;
619 int ret = BT_GATT_ERR(BT_ATT_ERR_SUCCESS);
620 int err;
621
622 /* subtract 1 as the opcode has already been pulled */
623 if (buf->len < sizeof(struct bt_bap_bass_cp_add_src) - 1) {
624 LOG_DBG("Invalid length %u", buf->size);
625 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
626 }
627
628 add_src = (void *)(buf->data - 1);
629 total_len = sizeof(struct bt_bap_bass_cp_add_src) - 1;
630 for (int i = 0; i < add_src->num_subgroups; i++) {
631 struct bt_bap_bass_cp_subgroup *subgroup;
632 uint16_t index = total_len;
633
634 total_len += sizeof(struct bt_bap_bass_cp_subgroup);
635 if (total_len > buf->len) {
636 LOG_DBG("Invalid length %u", buf->len);
637
638 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
639 }
640
641 subgroup = (void *)&buf->data[index];
642 total_len += subgroup->metadata_len;
643 if (total_len > buf->len) {
644 LOG_DBG("Invalid length %u", buf->len);
645
646 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
647 }
648 }
649
650 if (total_len != buf->len) {
651 LOG_DBG("Invalid length %u", buf->len);
652
653 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
654 }
655
656 internal_state = get_free_recv_state();
657 if (internal_state == NULL) {
658 LOG_DBG("Could not get free receive state");
659
660 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
661 }
662
663 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
664 if (err != 0) {
665 LOG_DBG("Failed to lock mutex: %d", err);
666
667 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
668 }
669
670 state = &internal_state->state;
671
672 state->src_id = next_src_id();
673 state->addr.type = net_buf_simple_pull_u8(buf);
674 if (state->addr.type > BT_ADDR_LE_RANDOM) {
675 LOG_DBG("Invalid address type %u", state->addr.type);
676 ret = BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
677 goto unlock_return;
678 }
679
680 addr = net_buf_simple_pull_mem(buf, sizeof(*addr));
681 bt_addr_copy(&state->addr.a, addr);
682
683 state->adv_sid = net_buf_simple_pull_u8(buf);
684 if (state->adv_sid > BT_GAP_SID_MAX) {
685 LOG_DBG("Invalid adv SID %u", state->adv_sid);
686 ret = BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
687 goto unlock_return;
688 }
689
690 broadcast_id = net_buf_simple_pull_le24(buf);
691
692 if (bass_source_is_duplicate(broadcast_id, state->adv_sid, state->addr.type)) {
693 LOG_DBG("Adding broadcast_id=0x%06X, adv_sid=0x%02X, and addr.type=0x%02X would "
694 "result in duplication", state->broadcast_id, state->adv_sid,
695 state->addr.type);
696 ret = BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
697 goto unlock_return;
698 }
699
700 state->broadcast_id = broadcast_id;
701
702 pa_sync = net_buf_simple_pull_u8(buf);
703 if (pa_sync > BT_BAP_BASS_PA_REQ_SYNC) {
704 LOG_DBG("Invalid PA sync value %u", pa_sync);
705 ret = BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
706 goto unlock_return;
707 }
708
709 pa_interval = net_buf_simple_pull_le16(buf);
710
711 state->num_subgroups = net_buf_simple_pull_u8(buf);
712 if (state->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
713 LOG_WRN("Too many subgroups %u/%u", state->num_subgroups,
714 CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
715 ret = BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
716 goto unlock_return;
717 }
718
719 bis_sync_requested = false;
720 for (int i = 0; i < state->num_subgroups; i++) {
721 struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
722 uint8_t *metadata;
723
724 internal_state->requested_bis_sync[i] = net_buf_simple_pull_le32(buf);
725
726 if (internal_state->requested_bis_sync[i] &&
727 pa_sync == BT_BAP_BASS_PA_REQ_NO_SYNC) {
728 LOG_DBG("Cannot sync to BIS without PA");
729 ret = BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
730 goto unlock_return;
731 }
732
733 if (internal_state->requested_bis_sync[i] != 0U) {
734 bis_sync_requested = true;
735 }
736
737 if (!valid_bis_sync_request(internal_state->requested_bis_sync[i],
738 aggregated_bis_syncs)) {
739 LOG_DBG("Invalid BIS Sync request[%d]", i);
740 ret = BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
741 goto unlock_return;
742 }
743
744 aggregated_bis_syncs |= internal_state->requested_bis_sync[i];
745
746 subgroup->metadata_len = net_buf_simple_pull_u8(buf);
747
748 if (subgroup->metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
749 LOG_WRN("Metadata too long %u/%u", subgroup->metadata_len,
750 CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE);
751 ret = BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
752 goto unlock_return;
753 }
754
755 metadata = net_buf_simple_pull_mem(buf, subgroup->metadata_len);
756 (void)memcpy(subgroup->metadata, metadata,
757 subgroup->metadata_len);
758 }
759
760 if (scan_delegator_cbs != NULL && scan_delegator_cbs->add_source != NULL) {
761 err = scan_delegator_cbs->add_source(conn, state);
762 if (err != 0) {
763 LOG_DBG("add_source callback rejected: 0x%02x", err);
764 ret = BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
765 goto unlock_return;
766 }
767 }
768
769 /* The active flag shall be set before any application callbacks, so that any calls for the
770 * receive state can be processed
771 */
772 internal_state->active = true;
773
774 if (pa_sync != BT_BAP_BASS_PA_REQ_NO_SYNC) {
775 /* Unlock mutex to avoid potential deadlock on app callback */
776 err = k_mutex_unlock(&internal_state->mutex);
777 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
778
779 err = pa_sync_request(conn, state, pa_sync, pa_interval);
780 if (err != 0) {
781 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
782 if (err != 0) {
783 LOG_DBG("Failed to lock mutex: %d", err);
784
785 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
786 }
787
788 (void)memset(state, 0, sizeof(*state));
789 internal_state->active = false;
790
791 LOG_DBG("PA sync %u from %p was rejected with reason %d", pa_sync,
792 (void *)conn, err);
793
794 err = k_mutex_unlock(&internal_state->mutex);
795 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
796
797 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
798 }
799
800 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
801 if (err != 0) {
802 LOG_DBG("Failed to lock mutex: %d", err);
803
804 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
805 }
806 }
807
808 LOG_DBG("Index %u: New source added: ID 0x%02x",
809 internal_state->index, state->src_id);
810
811 set_receive_state_changed(internal_state);
812
813 unlock_return:
814 err = k_mutex_unlock(&internal_state->mutex);
815 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
816
817 if (ret == BT_GATT_ERR(BT_ATT_ERR_SUCCESS)) {
818 /* app callback */
819 receive_state_updated(conn, internal_state);
820
821 if (bis_sync_requested) {
822 bis_sync_request_updated(conn, internal_state);
823 }
824 }
825
826 return ret;
827 }
828
scan_delegator_mod_src(struct bt_conn * conn,struct net_buf_simple * buf)829 static int scan_delegator_mod_src(struct bt_conn *conn,
830 struct net_buf_simple *buf)
831 {
832 uint32_t requested_bis_sync[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS] = {};
833 struct bt_bap_scan_delegator_recv_state backup_state;
834 struct bass_recv_state_internal *internal_state;
835 struct bt_bap_scan_delegator_recv_state *state;
836 uint8_t src_id;
837 bool state_changed = false;
838 uint16_t pa_interval;
839 uint8_t num_subgroups;
840 struct bt_bap_bass_subgroup
841 subgroups[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS] = { 0 };
842 uint8_t pa_sync;
843 uint32_t aggregated_bis_syncs = 0;
844 bool bis_sync_change_requested;
845 uint16_t total_len;
846 struct bt_bap_bass_cp_mod_src *mod_src;
847 int ret = BT_GATT_ERR(BT_ATT_ERR_SUCCESS);
848 int err;
849
850 /* subtract 1 as the opcode has already been pulled */
851 if (buf->len < sizeof(struct bt_bap_bass_cp_mod_src) - 1) {
852 LOG_DBG("Invalid length %u", buf->len);
853
854 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
855 }
856
857 mod_src = (void *)(buf->data - 1);
858 total_len = sizeof(struct bt_bap_bass_cp_mod_src) - 1;
859 for (int i = 0; i < mod_src->num_subgroups; i++) {
860 struct bt_bap_bass_cp_subgroup *subgroup;
861 uint16_t index = total_len;
862
863 total_len += sizeof(struct bt_bap_bass_cp_subgroup);
864 if (total_len > buf->len) {
865 LOG_DBG("Invalid length %u", buf->len);
866
867 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
868 }
869
870 subgroup = (void *)&buf->data[index];
871 total_len += subgroup->metadata_len;
872 if (total_len > buf->len) {
873 LOG_DBG("Invalid length %u", buf->len);
874
875 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
876 }
877 }
878
879 if (total_len != buf->len) {
880 LOG_DBG("Invalid length %u", buf->len);
881
882 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
883 }
884
885 src_id = net_buf_simple_pull_u8(buf);
886 internal_state = bass_lookup_src_id(src_id);
887
888 LOG_DBG("src_id %u", src_id);
889
890 if (internal_state == NULL) {
891 LOG_DBG("Could not find state by src id %u", src_id);
892
893 return BT_GATT_ERR(BT_BAP_BASS_ERR_INVALID_SRC_ID);
894 }
895
896 pa_sync = net_buf_simple_pull_u8(buf);
897 if (pa_sync > BT_BAP_BASS_PA_REQ_SYNC) {
898 LOG_DBG("Invalid PA sync value %u", pa_sync);
899
900 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
901 }
902
903 pa_interval = net_buf_simple_pull_le16(buf);
904
905 num_subgroups = net_buf_simple_pull_u8(buf);
906 if (num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
907 LOG_WRN("Too many subgroups %u/%u", num_subgroups,
908 CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
909 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
910 }
911
912 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
913 if (err != 0) {
914 LOG_DBG("Failed to lock mutex: %d", err);
915
916 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
917 }
918
919 bis_sync_change_requested = false;
920 for (int i = 0; i < num_subgroups; i++) {
921 struct bt_bap_bass_subgroup *subgroup = &subgroups[i];
922 uint8_t *metadata;
923
924 requested_bis_sync[i] = net_buf_simple_pull_le32(buf);
925
926 if (requested_bis_sync[i] != 0U && pa_sync == BT_BAP_BASS_PA_REQ_NO_SYNC) {
927 LOG_DBG("Cannot sync to BIS without PA");
928 ret = BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
929 goto unlock_return;
930 }
931
932 /* If the BIS sync request is different than what was previously was requested, or
933 * different than what we are current synced to, we set bis_sync_change_requested to
934 * let the application know that the state may need a change
935 */
936 if (internal_state->requested_bis_sync[i] != requested_bis_sync[i] ||
937 internal_state->state.subgroups[i].bis_sync != requested_bis_sync[i]) {
938 bis_sync_change_requested = true;
939 }
940
941 if (!valid_bis_sync_request(internal_state->requested_bis_sync[i],
942 aggregated_bis_syncs)) {
943 LOG_DBG("Invalid BIS Sync request[%d]", i);
944 ret = BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
945 goto unlock_return;
946 }
947 aggregated_bis_syncs |= requested_bis_sync[i];
948
949 subgroup->metadata_len = net_buf_simple_pull_u8(buf);
950
951 if (subgroup->metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
952 LOG_WRN("Metadata too long %u/%u", subgroup->metadata_len,
953 CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE);
954 ret = BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
955 goto unlock_return;
956 }
957
958 metadata = net_buf_simple_pull_mem(buf, subgroup->metadata_len);
959
960 (void)memcpy(subgroup->metadata, metadata,
961 subgroup->metadata_len);
962 }
963
964 /* All input has been validated; update receive state and check for changes */
965 state = &internal_state->state;
966
967 /* Store backup in case upper layers rejects */
968 (void)memcpy(&backup_state, state, sizeof(backup_state));
969
970 if (state->num_subgroups != num_subgroups) {
971 state->num_subgroups = num_subgroups;
972 state_changed = true;
973 }
974
975 for (int i = 0; i < num_subgroups; i++) {
976 const bool metadata_len_changed =
977 subgroups[i].metadata_len != state->subgroups[i].metadata_len;
978
979 if (metadata_len_changed) {
980 state->subgroups[i].metadata_len = subgroups[i].metadata_len;
981 state_changed = true;
982 }
983
984 if (metadata_len_changed ||
985 memcmp(subgroups[i].metadata, state->subgroups[i].metadata,
986 sizeof(subgroups[i].metadata)) != 0) {
987
988 if (state->subgroups[i].metadata_len == 0U) {
989 memset(state->subgroups[i].metadata, 0,
990 state->subgroups[i].metadata_len);
991 } else {
992 (void)memcpy(state->subgroups[i].metadata, subgroups[i].metadata,
993 state->subgroups[i].metadata_len);
994 }
995
996 state_changed = true;
997 }
998 }
999
1000 if (scan_delegator_cbs != NULL && scan_delegator_cbs->modify_source != NULL) {
1001 err = scan_delegator_cbs->modify_source(conn, state);
1002 if (err != 0) {
1003 LOG_DBG("Modify Source rejected with reason 0x%02x", err);
1004 (void)memcpy(state, &backup_state, sizeof(backup_state));
1005
1006 err = k_mutex_unlock(&internal_state->mutex);
1007 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1008
1009 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1010 }
1011 }
1012
1013 /* Only send the sync request to upper layers if it is requested, and
1014 * we are not already synced to the device
1015 */
1016 if (pa_sync != BT_BAP_BASS_PA_REQ_NO_SYNC &&
1017 state->pa_sync_state != BT_BAP_PA_STATE_SYNCED) {
1018 const uint8_t pa_sync_state = state->pa_sync_state;
1019
1020 /* Unlock mutex to avoid potential deadlock on app callback */
1021 err = k_mutex_unlock(&internal_state->mutex);
1022 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1023
1024 err = pa_sync_request(conn, state, pa_sync, pa_interval);
1025 if (err != 0) {
1026 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
1027 if (err != 0) {
1028 LOG_DBG("Failed to lock mutex: %d", err);
1029
1030 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
1031 }
1032
1033 /* Restore backup */
1034 (void)memcpy(state, &backup_state, sizeof(backup_state));
1035
1036 LOG_DBG("PA sync %u from %p was rejected with reason %d", pa_sync,
1037 (void *)conn, err);
1038
1039 err = k_mutex_unlock(&internal_state->mutex);
1040 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1041
1042 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1043 } else if (pa_sync_state != state->pa_sync_state) {
1044 /* Temporary work around if the state is changed when pa_sync_request is
1045 * called. See https://github.com/zephyrproject-rtos/zephyr/issues/79308 for
1046 * more information about this issue.
1047 */
1048 state_changed = true;
1049 }
1050
1051 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
1052 if (err != 0) {
1053 LOG_DBG("Failed to lock mutex: %d", err);
1054
1055 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
1056 }
1057 } else if (pa_sync == BT_BAP_BASS_PA_REQ_NO_SYNC &&
1058 (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ ||
1059 state->pa_sync_state == BT_BAP_PA_STATE_SYNCED)) {
1060 /* Terminate PA sync */
1061 err = pa_sync_term_request(conn, &internal_state->state);
1062
1063 if (err != 0) {
1064 LOG_DBG("PA sync term from %p was rejected with reason %d", (void *)conn,
1065 err);
1066 err = k_mutex_unlock(&internal_state->mutex);
1067 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1068 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1069 }
1070 state_changed = true;
1071 }
1072
1073 /* Store requested_bis_sync after everything has been validated */
1074 (void)memcpy(internal_state->requested_bis_sync, requested_bis_sync,
1075 sizeof(requested_bis_sync));
1076
1077 /* Notify if changed */
1078 if (state_changed) {
1079 LOG_DBG("Index %u: Source modified: ID 0x%02x", internal_state->index,
1080 state->src_id);
1081 set_receive_state_changed(internal_state);
1082 }
1083
1084 unlock_return:
1085 err = k_mutex_unlock(&internal_state->mutex);
1086 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1087
1088 if (state_changed) {
1089 /* app callback */
1090 receive_state_updated(conn, internal_state);
1091 }
1092
1093 if (bis_sync_change_requested) {
1094 bis_sync_request_updated(conn, internal_state);
1095 }
1096
1097 return ret;
1098 }
1099
scan_delegator_broadcast_code(struct bt_conn * conn,struct net_buf_simple * buf)1100 static int scan_delegator_broadcast_code(struct bt_conn *conn,
1101 struct net_buf_simple *buf)
1102 {
1103 struct bass_recv_state_internal *internal_state;
1104 uint8_t src_id;
1105 const uint8_t *broadcast_code;
1106
1107 /* subtract 1 as the opcode has already been pulled */
1108 if (buf->len != sizeof(struct bt_bap_bass_cp_broadcase_code) - 1) {
1109 LOG_DBG("Invalid length %u", buf->size);
1110 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1111 }
1112
1113 src_id = net_buf_simple_pull_u8(buf);
1114 internal_state = bass_lookup_src_id(src_id);
1115
1116 if (internal_state == NULL) {
1117 LOG_DBG("Could not find state by src id %u", src_id);
1118 return BT_GATT_ERR(BT_BAP_BASS_ERR_INVALID_SRC_ID);
1119 }
1120
1121 broadcast_code = net_buf_simple_pull_mem(buf, sizeof(internal_state->broadcast_code));
1122
1123 (void)memcpy(internal_state->broadcast_code, broadcast_code,
1124 sizeof(internal_state->broadcast_code));
1125
1126 LOG_DBG("Index %u: broadcast code added: %s", internal_state->index,
1127 bt_hex(internal_state->broadcast_code, sizeof(internal_state->broadcast_code)));
1128
1129 if (scan_delegator_cbs != NULL &&
1130 scan_delegator_cbs->broadcast_code != NULL) {
1131 scan_delegator_cbs->broadcast_code(conn, &internal_state->state,
1132 broadcast_code);
1133 }
1134
1135 return 0;
1136 }
1137
scan_delegator_rem_src(struct bt_conn * conn,struct net_buf_simple * buf)1138 static int scan_delegator_rem_src(struct bt_conn *conn,
1139 struct net_buf_simple *buf)
1140 {
1141 struct bass_recv_state_internal *internal_state;
1142 struct bt_bap_scan_delegator_recv_state *state;
1143 bool bis_sync_was_requested = false;
1144 uint8_t src_id;
1145 int err;
1146
1147 /* subtract 1 as the opcode has already been pulled */
1148 if (buf->len != sizeof(struct bt_bap_bass_cp_rem_src) - 1) {
1149 LOG_DBG("Invalid length %u", buf->size);
1150 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1151 }
1152
1153 src_id = net_buf_simple_pull_u8(buf);
1154 internal_state = bass_lookup_src_id(src_id);
1155
1156 if (internal_state == NULL) {
1157 LOG_DBG("Could not find state by src id %u", src_id);
1158 return BT_GATT_ERR(BT_BAP_BASS_ERR_INVALID_SRC_ID);
1159 }
1160
1161 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
1162 if (err != 0) {
1163 LOG_DBG("Failed to lock mutex: %d", err);
1164
1165 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
1166 }
1167
1168 state = &internal_state->state;
1169
1170 /* If conn == NULL then it's a local operation and we do not need to ask the application */
1171 if (conn != NULL) {
1172
1173 if (scan_delegator_cbs != NULL && scan_delegator_cbs->remove_source != NULL) {
1174 err = scan_delegator_cbs->remove_source(conn, src_id);
1175 if (err != 0) {
1176 LOG_DBG("Remove Source rejected with reason 0x%02x", err);
1177 err = k_mutex_unlock(&internal_state->mutex);
1178 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1179 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1180 }
1181 }
1182
1183 if (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ ||
1184 state->pa_sync_state == BT_BAP_PA_STATE_SYNCED) {
1185 /* Terminate PA sync */
1186 err = pa_sync_term_request(conn, &internal_state->state);
1187 if (err != 0) {
1188 LOG_DBG("PA sync term from %p was rejected with reason %d",
1189 (void *)conn, err);
1190 err = k_mutex_unlock(&internal_state->mutex);
1191 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1192 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1193 }
1194 }
1195 }
1196
1197 for (uint8_t i = 0U; i < state->num_subgroups; i++) {
1198 if (internal_state->requested_bis_sync[i] != 0U &&
1199 internal_state->state.subgroups[i].bis_sync != 0U) {
1200 bis_sync_was_requested = true;
1201 break;
1202 }
1203 }
1204
1205 LOG_DBG("Index %u: Removed source with ID 0x%02x",
1206 internal_state->index, src_id);
1207
1208 internal_state->active = false;
1209 internal_state->pa_sync = NULL;
1210 (void)memset(&internal_state->state, 0, sizeof(internal_state->state));
1211 (void)memset(internal_state->broadcast_code, 0,
1212 sizeof(internal_state->broadcast_code));
1213 (void)memset(internal_state->requested_bis_sync, 0,
1214 sizeof(internal_state->requested_bis_sync));
1215
1216 set_receive_state_changed(internal_state);
1217
1218 err = k_mutex_unlock(&internal_state->mutex);
1219 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1220
1221 if (bis_sync_was_requested) {
1222 bis_sync_request_updated(conn, internal_state);
1223 }
1224
1225 /* app callback */
1226 receive_state_updated(conn, internal_state);
1227
1228 return BT_GATT_ERR(BT_ATT_ERR_SUCCESS);
1229 }
1230
write_control_point(struct bt_conn * conn,const struct bt_gatt_attr * attr,const void * data,uint16_t len,uint16_t offset,uint8_t flags)1231 static ssize_t write_control_point(struct bt_conn *conn,
1232 const struct bt_gatt_attr *attr,
1233 const void *data, uint16_t len,
1234 uint16_t offset, uint8_t flags)
1235 {
1236 struct net_buf_simple buf;
1237 uint8_t opcode;
1238 int err;
1239
1240 if (offset != 0) {
1241 return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
1242 } else if (len == 0) {
1243 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1244 }
1245
1246 net_buf_simple_init_with_data(&buf, (void *)data, len);
1247
1248 opcode = net_buf_simple_pull_u8(&buf);
1249
1250 if (!BT_BAP_BASS_VALID_OPCODE(opcode)) {
1251 return BT_GATT_ERR(BT_BAP_BASS_ERR_OPCODE_NOT_SUPPORTED);
1252 }
1253
1254 LOG_HEXDUMP_DBG(data, len, "Data");
1255
1256 switch (opcode) {
1257 case BT_BAP_BASS_OP_SCAN_STOP:
1258 LOG_DBG("Assistant stopping scanning");
1259
1260 if (buf.len != 0) {
1261 LOG_DBG("Invalid length %u", buf.size);
1262 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1263 }
1264
1265 if (scan_delegator_cbs != NULL && scan_delegator_cbs->scanning_state != NULL) {
1266 scan_delegator_cbs->scanning_state(conn, false);
1267 }
1268
1269 break;
1270 case BT_BAP_BASS_OP_SCAN_START:
1271 LOG_DBG("Assistant starting scanning");
1272
1273 if (buf.len != 0) {
1274 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1275 }
1276
1277 if (scan_delegator_cbs != NULL && scan_delegator_cbs->scanning_state != NULL) {
1278 scan_delegator_cbs->scanning_state(conn, true);
1279 }
1280
1281 break;
1282 case BT_BAP_BASS_OP_ADD_SRC:
1283 LOG_DBG("Assistant adding source");
1284
1285 err = scan_delegator_add_src(conn, &buf);
1286 if (err != 0) {
1287 LOG_DBG("Could not add source %d", err);
1288 return err;
1289 }
1290
1291 break;
1292 case BT_BAP_BASS_OP_MOD_SRC:
1293 LOG_DBG("Assistant modifying source");
1294
1295 err = scan_delegator_mod_src(conn, &buf);
1296 if (err != 0) {
1297 LOG_DBG("Could not modify source %d", err);
1298 return err;
1299 }
1300
1301 break;
1302 case BT_BAP_BASS_OP_BROADCAST_CODE:
1303 LOG_DBG("Assistant setting broadcast code");
1304
1305 err = scan_delegator_broadcast_code(conn, &buf);
1306 if (err != 0) {
1307 LOG_DBG("Could not set broadcast code");
1308 return err;
1309 }
1310
1311 break;
1312 case BT_BAP_BASS_OP_REM_SRC:
1313 LOG_DBG("Assistant removing source");
1314
1315 err = scan_delegator_rem_src(conn, &buf);
1316 if (err != 0) {
1317 LOG_DBG("Could not remove source %d", err);
1318 return err;
1319 }
1320
1321 break;
1322 default:
1323 break;
1324 }
1325
1326 return len;
1327 }
1328
recv_state_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)1329 static void recv_state_cfg_changed(const struct bt_gatt_attr *attr,
1330 uint16_t value)
1331 {
1332 LOG_DBG("value 0x%04x", value);
1333 }
1334
read_recv_state(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)1335 static ssize_t read_recv_state(struct bt_conn *conn,
1336 const struct bt_gatt_attr *attr, void *buf,
1337 uint16_t len, uint16_t offset)
1338 {
1339 uint8_t idx = POINTER_TO_UINT(BT_AUDIO_CHRC_USER_DATA(attr));
1340 struct bass_recv_state_internal *recv_state = &scan_delegator.recv_states[idx];
1341 struct bt_bap_scan_delegator_recv_state *state = &recv_state->state;
1342
1343 if (recv_state->active) {
1344 ssize_t ret_val;
1345 int err;
1346
1347 LOG_DBG("Index %u: Source ID 0x%02x", idx, state->src_id);
1348
1349 err = k_mutex_lock(&recv_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
1350 if (err != 0) {
1351 LOG_DBG("Failed to lock mutex: %d", err);
1352
1353 return err;
1354 }
1355
1356 if (IS_ENABLED(CONFIG_BT_BAP_SCAN_DELEGATOR_LOG_LEVEL_DBG)) {
1357 bt_debug_dump_recv_state(recv_state);
1358 }
1359 net_buf_put_recv_state(recv_state);
1360
1361 ret_val = bt_gatt_attr_read(conn, attr, buf, len, offset,
1362 read_buf.data, read_buf.len);
1363
1364 err = k_mutex_unlock(&recv_state->mutex);
1365 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1366
1367 return ret_val;
1368 }
1369 LOG_DBG("Index %u: Not active", idx);
1370 return bt_gatt_attr_read(conn, attr, buf, len, offset, NULL, 0);
1371
1372 }
1373
1374 #define RECEIVE_STATE_CHARACTERISTIC(idx) \
1375 BT_AUDIO_CHRC(BT_UUID_BASS_RECV_STATE, \
1376 BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,\
1377 BT_GATT_PERM_READ_ENCRYPT, \
1378 read_recv_state, NULL, UINT_TO_POINTER(idx)), \
1379 BT_AUDIO_CCC(recv_state_cfg_changed)
1380
1381 static struct bt_gatt_attr attr_bass_svc[] = {
1382 BT_GATT_PRIMARY_SERVICE(BT_UUID_BASS),
1383 BT_AUDIO_CHRC(BT_UUID_BASS_CONTROL_POINT,
1384 BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_WRITE,
1385 BT_GATT_PERM_WRITE_ENCRYPT,
1386 NULL, write_control_point, NULL),
1387 RECEIVE_STATE_CHARACTERISTIC(0),
1388 #if CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1
1389 RECEIVE_STATE_CHARACTERISTIC(1),
1390 #if CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2
1391 RECEIVE_STATE_CHARACTERISTIC(2)
1392 #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2 */
1393 #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1 */
1394 };
1395
1396 static struct bt_gatt_service bass_svc = BT_GATT_SERVICE(attr_bass_svc);
1397
bass_register(void)1398 static int bass_register(void)
1399 {
1400 int err;
1401
1402 err = bt_gatt_service_register(&bass_svc);
1403 if (err) {
1404 LOG_DBG("Failed to register BASS service (err %d)", err);
1405 return err;
1406 }
1407
1408 LOG_DBG("BASS service registered");
1409
1410 return 0;
1411 }
1412
bass_unregister(void)1413 static int bass_unregister(void)
1414 {
1415 int err;
1416
1417 err = bt_gatt_service_unregister(&bass_svc);
1418 if (err) {
1419 LOG_DBG("Failed to unregister BASS service (err %d)", err);
1420 return err;
1421 }
1422
1423 LOG_DBG("BASS service unregistered");
1424
1425 return 0;
1426 }
1427
1428 /****************************** PUBLIC API ******************************/
bt_bap_scan_delegator_register(struct bt_bap_scan_delegator_cb * cb)1429 int bt_bap_scan_delegator_register(struct bt_bap_scan_delegator_cb *cb)
1430 {
1431 int err;
1432
1433 if (atomic_test_and_set_bit(scan_delegator_flags,
1434 SCAN_DELEGATOR_FLAG_REGISTERED_SCAN_DELIGATOR)) {
1435 LOG_DBG("Scan delegator already registered");
1436 return -EALREADY;
1437 }
1438
1439 err = bass_register();
1440 if (err) {
1441 atomic_clear_bit(scan_delegator_flags,
1442 SCAN_DELEGATOR_FLAG_REGISTERED_SCAN_DELIGATOR);
1443 return err;
1444 }
1445
1446 /* Store the pointer to the first characteristic in each receive state */
1447 scan_delegator.recv_states[0].attr = &bass_svc.attrs[3];
1448 scan_delegator.recv_states[0].index = 0;
1449 #if CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1
1450 scan_delegator.recv_states[1].attr = &bass_svc.attrs[6];
1451 scan_delegator.recv_states[1].index = 1;
1452 #if CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2
1453 scan_delegator.recv_states[2].attr = &bass_svc.attrs[9];
1454 scan_delegator.recv_states[2].index = 2;
1455 #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2 */
1456 #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1 */
1457
1458 if (!atomic_test_and_set_bit(scan_delegator_flags,
1459 SCAN_DELEGATOR_FLAG_REGISTERED_PA_SYNC_CB)) {
1460 err = bt_le_per_adv_sync_cb_register(&pa_sync_cb);
1461 if (err) {
1462 atomic_clear_bit(scan_delegator_flags,
1463 SCAN_DELEGATOR_FLAG_REGISTERED_PA_SYNC_CB);
1464 atomic_clear_bit(scan_delegator_flags,
1465 SCAN_DELEGATOR_FLAG_REGISTERED_SCAN_DELIGATOR);
1466 return err;
1467 }
1468 }
1469
1470 for (size_t i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
1471 struct bass_recv_state_internal *internal_state = &scan_delegator.recv_states[i];
1472
1473 err = k_mutex_init(&internal_state->mutex);
1474 __ASSERT(err == 0, "Failed to initialize mutex");
1475
1476 k_work_init_delayable(&internal_state->notify_work, notify_work_handler);
1477 }
1478
1479 scan_delegator_cbs = cb;
1480
1481 return 0;
1482 }
1483
bt_bap_scan_delegator_unregister(void)1484 int bt_bap_scan_delegator_unregister(void)
1485 {
1486 int err;
1487
1488 if (!atomic_test_and_clear_bit(scan_delegator_flags,
1489 SCAN_DELEGATOR_FLAG_REGISTERED_SCAN_DELIGATOR)) {
1490 LOG_DBG("Scan delegator not yet registered");
1491 return -EALREADY;
1492 }
1493
1494 err = bass_unregister();
1495 if (err) {
1496 atomic_set_bit(scan_delegator_flags,
1497 SCAN_DELEGATOR_FLAG_REGISTERED_SCAN_DELIGATOR);
1498 return err;
1499 }
1500
1501 scan_delegator_cbs = NULL;
1502
1503 return 0;
1504 }
1505
bt_bap_scan_delegator_set_pa_state(uint8_t src_id,enum bt_bap_pa_state pa_state)1506 int bt_bap_scan_delegator_set_pa_state(uint8_t src_id,
1507 enum bt_bap_pa_state pa_state)
1508 {
1509 struct bass_recv_state_internal *internal_state = bass_lookup_src_id(src_id);
1510 struct bt_bap_scan_delegator_recv_state *recv_state;
1511 bool state_changed = false;
1512 int err;
1513
1514 if (internal_state == NULL) {
1515 LOG_DBG("Could not find recv_state by src_id %u", src_id);
1516 return -EINVAL;
1517 }
1518
1519 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
1520 if (err != 0) {
1521 LOG_DBG("Failed to lock mutex: %d", err);
1522
1523 return -EBUSY;
1524 }
1525
1526 recv_state = &internal_state->state;
1527
1528 if (recv_state->pa_sync_state != pa_state) {
1529 recv_state->pa_sync_state = pa_state;
1530 set_receive_state_changed(internal_state);
1531 state_changed = true;
1532 }
1533
1534 err = k_mutex_unlock(&internal_state->mutex);
1535 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1536
1537 if (state_changed) {
1538 /* app callback */
1539 receive_state_updated(NULL, internal_state);
1540 }
1541
1542 return 0;
1543 }
1544
bt_bap_scan_delegator_set_bis_sync_state(uint8_t src_id,uint32_t bis_synced[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])1545 int bt_bap_scan_delegator_set_bis_sync_state(
1546 uint8_t src_id,
1547 uint32_t bis_synced[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])
1548 {
1549 struct bass_recv_state_internal *internal_state = bass_lookup_src_id(src_id);
1550 bool notify = false;
1551 int ret = 0;
1552 int err;
1553
1554 if (internal_state == NULL) {
1555 LOG_DBG("Could not find recv_state by src_id %u", src_id);
1556 return -EINVAL;
1557 }
1558
1559 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
1560 if (err != 0) {
1561 LOG_DBG("Failed to lock mutex: %d", err);
1562
1563 return -EBUSY;
1564 }
1565
1566 if (internal_state->state.pa_sync_state != BT_BAP_PA_STATE_SYNCED) {
1567 LOG_DBG("PA for src_id %u isn't synced, cannot be BIG synced",
1568 src_id);
1569 ret = -EINVAL;
1570 goto unlock_return;
1571 }
1572
1573 /* Verify state for all subgroups before assigning any data */
1574 for (uint8_t i = 0U; i < internal_state->state.num_subgroups; i++) {
1575 if (i >= CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
1576 break;
1577 }
1578
1579 if (bis_synced[i] == BT_BAP_BIS_SYNC_NO_PREF ||
1580 !bits_subset_of(bis_synced[i],
1581 internal_state->requested_bis_sync[i])) {
1582 LOG_DBG("Subgroup[%u] invalid bis_sync value %x for %x",
1583 i, bis_synced[i], internal_state->requested_bis_sync[i]);
1584 ret = -EINVAL;
1585 goto unlock_return;
1586 }
1587 }
1588
1589 for (uint8_t i = 0U; i < internal_state->state.num_subgroups; i++) {
1590 struct bt_bap_bass_subgroup *subgroup =
1591 &internal_state->state.subgroups[i];
1592
1593 if (i >= CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
1594 break;
1595 }
1596
1597 if (bis_synced[i] != subgroup->bis_sync) {
1598 notify = true;
1599 subgroup->bis_sync = bis_synced[i];
1600 }
1601 }
1602
1603 LOG_DBG("Index %u: Source ID 0x%02x synced",
1604 internal_state->index, src_id);
1605
1606 if (internal_state->state.encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
1607 (void)memset(internal_state->state.bad_code, 0xFF,
1608 sizeof(internal_state->state.bad_code));
1609 }
1610
1611 if (notify) {
1612 set_receive_state_changed(internal_state);
1613 }
1614
1615 unlock_return:
1616 err = k_mutex_unlock(&internal_state->mutex);
1617 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1618
1619 if (notify) {
1620 /* app callback */
1621 receive_state_updated(NULL, internal_state);
1622 }
1623
1624 return ret;
1625 }
1626
valid_bt_bap_scan_delegator_add_src_param(const struct bt_bap_scan_delegator_add_src_param * param)1627 static bool valid_bt_bap_scan_delegator_add_src_param(
1628 const struct bt_bap_scan_delegator_add_src_param *param)
1629 {
1630 uint32_t aggregated_bis_syncs = 0U;
1631
1632 if (param->broadcast_id > BT_AUDIO_BROADCAST_ID_MAX) {
1633 LOG_DBG("Invalid broadcast_id: %u", param->broadcast_id);
1634
1635 return false;
1636 }
1637
1638 CHECKIF(param->addr.type > BT_ADDR_LE_RANDOM) {
1639 LOG_DBG("param->addr.type %u is invalid", param->addr.type);
1640 return false;
1641 }
1642
1643 CHECKIF(param->sid > BT_GAP_SID_MAX) {
1644 LOG_DBG("param->sid %d is invalid", param->sid);
1645 return false;
1646 }
1647
1648 if (param->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
1649 LOG_WRN("Too many subgroups %u/%u",
1650 param->num_subgroups,
1651 CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
1652
1653 return false;
1654 }
1655
1656 for (uint8_t i = 0U; i < param->num_subgroups; i++) {
1657 const struct bt_bap_bass_subgroup *subgroup = ¶m->subgroups[i];
1658
1659 if (!bis_syncs_unique_or_no_pref(subgroup->bis_sync,
1660 aggregated_bis_syncs)) {
1661 LOG_DBG("Invalid BIS sync: %u", subgroup->bis_sync);
1662
1663 return false;
1664 }
1665
1666 if (subgroup->metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
1667 LOG_DBG("subgroup[%u]: Invalid metadata_len: %u",
1668 i, subgroup->metadata_len);
1669
1670 return false;
1671 }
1672 }
1673
1674 return true;
1675 }
1676
bt_bap_scan_delegator_add_src(const struct bt_bap_scan_delegator_add_src_param * param)1677 int bt_bap_scan_delegator_add_src(const struct bt_bap_scan_delegator_add_src_param *param)
1678 {
1679 struct bass_recv_state_internal *internal_state = NULL;
1680 struct bt_bap_scan_delegator_recv_state *state;
1681 struct bt_le_per_adv_sync *pa_sync;
1682 int err;
1683
1684 CHECKIF(!valid_bt_bap_scan_delegator_add_src_param(param)) {
1685 return -EINVAL;
1686 }
1687
1688 pa_sync = bt_le_per_adv_sync_lookup_addr(¶m->addr, param->sid);
1689
1690 if (pa_sync != NULL) {
1691 internal_state = bass_lookup_pa_sync(pa_sync);
1692 if (internal_state != NULL) {
1693 LOG_DBG("PA Sync already in a receive state with src_id %u",
1694 internal_state->state.src_id);
1695
1696 return -EALREADY;
1697 }
1698 }
1699
1700 internal_state = get_free_recv_state();
1701 if (internal_state == NULL) {
1702 LOG_DBG("Could not get free receive state");
1703
1704 return -ENOMEM;
1705 }
1706
1707 state = &internal_state->state;
1708
1709 state->src_id = next_src_id();
1710 bt_addr_le_copy(&state->addr, ¶m->addr);
1711 state->adv_sid = param->sid;
1712 state->broadcast_id = param->broadcast_id;
1713 state->pa_sync_state =
1714 pa_sync == NULL ? BT_BAP_PA_STATE_NOT_SYNCED : BT_BAP_PA_STATE_SYNCED;
1715 state->num_subgroups = param->num_subgroups;
1716 if (state->num_subgroups > 0U) {
1717 (void)memcpy(state->subgroups, param->subgroups,
1718 sizeof(state->subgroups));
1719 } else {
1720 (void)memset(state->subgroups, 0, sizeof(state->subgroups));
1721 }
1722
1723 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
1724 if (err != 0) {
1725 LOG_DBG("Failed to lock mutex: %d", err);
1726
1727 return -EBUSY;
1728 }
1729
1730 internal_state->active = true;
1731 internal_state->pa_sync = pa_sync;
1732
1733 /* Set all requested_bis_sync to BT_BAP_BIS_SYNC_NO_PREF, as no
1734 * Broadcast Assistant has set any requests yet
1735 */
1736 for (size_t i = 0U; i < ARRAY_SIZE(internal_state->requested_bis_sync); i++) {
1737 internal_state->requested_bis_sync[i] = BT_BAP_BIS_SYNC_NO_PREF;
1738 }
1739
1740 LOG_DBG("Index %u: New source added: ID 0x%02x",
1741 internal_state->index, state->src_id);
1742
1743 set_receive_state_changed(internal_state);
1744
1745 err = k_mutex_unlock(&internal_state->mutex);
1746 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1747
1748 /* app callback */
1749 receive_state_updated(NULL, internal_state);
1750
1751 return state->src_id;
1752 }
1753
valid_bt_bap_scan_delegator_mod_src_param(const struct bt_bap_scan_delegator_mod_src_param * param)1754 static bool valid_bt_bap_scan_delegator_mod_src_param(
1755 const struct bt_bap_scan_delegator_mod_src_param *param)
1756 {
1757 uint32_t aggregated_bis_syncs = 0U;
1758
1759 if (param->broadcast_id > BT_AUDIO_BROADCAST_ID_MAX) {
1760 LOG_DBG("Invalid broadcast_id: %u", param->broadcast_id);
1761
1762 return false;
1763 }
1764
1765 if (param->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
1766 LOG_WRN("Too many subgroups %u/%u",
1767 param->num_subgroups,
1768 CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
1769
1770 return false;
1771 }
1772
1773 for (uint8_t i = 0U; i < param->num_subgroups; i++) {
1774 const struct bt_bap_bass_subgroup *subgroup = ¶m->subgroups[i];
1775
1776 if (subgroup->bis_sync != BT_BAP_BIS_SYNC_FAILED &&
1777 !bis_syncs_unique_or_no_pref(subgroup->bis_sync, aggregated_bis_syncs)) {
1778 LOG_DBG("Invalid BIS sync: %u", subgroup->bis_sync);
1779
1780 return false;
1781 }
1782
1783 if (subgroup->metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
1784 LOG_DBG("subgroup[%u]: Invalid metadata_len: %u",
1785 i, subgroup->metadata_len);
1786
1787 return false;
1788 }
1789 }
1790
1791 return true;
1792 }
1793
bt_bap_scan_delegator_mod_src(const struct bt_bap_scan_delegator_mod_src_param * param)1794 int bt_bap_scan_delegator_mod_src(const struct bt_bap_scan_delegator_mod_src_param *param)
1795 {
1796 struct bass_recv_state_internal *internal_state = NULL;
1797 struct bt_bap_scan_delegator_recv_state *state;
1798 bool state_changed = false;
1799 int ret = 0;
1800 int err;
1801
1802 CHECKIF(!valid_bt_bap_scan_delegator_mod_src_param(param)) {
1803 return -EINVAL;
1804 }
1805
1806 internal_state = bass_lookup_src_id(param->src_id);
1807 if (internal_state == NULL) {
1808 LOG_DBG("Could not find receive state with src_id %u", param->src_id);
1809
1810 return -ENOENT;
1811 }
1812
1813 err = k_mutex_lock(&internal_state->mutex, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
1814 if (err != 0) {
1815 LOG_DBG("Failed to lock mutex: %d", err);
1816
1817 return -EBUSY;
1818 }
1819
1820 state = &internal_state->state;
1821
1822 if (state->broadcast_id != param->broadcast_id) {
1823 state->broadcast_id = param->broadcast_id;
1824 state_changed = true;
1825 }
1826
1827 if (state->num_subgroups != param->num_subgroups) {
1828 state->num_subgroups = param->num_subgroups;
1829 state_changed = true;
1830 }
1831
1832 if (state->encrypt_state != param->encrypt_state) {
1833 state->encrypt_state = param->encrypt_state;
1834
1835 if (state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
1836 (void)memset(state->bad_code, 0xFF, sizeof(internal_state->state.bad_code));
1837 }
1838
1839 state_changed = true;
1840 }
1841
1842 /* Verify that the BIS sync values is acceptable for the receive state */
1843 for (uint8_t i = 0U; i < state->num_subgroups; i++) {
1844 const uint32_t bis_sync = param->subgroups[i].bis_sync;
1845 const uint32_t bis_sync_requested = internal_state->requested_bis_sync[i];
1846
1847 if (bis_sync != BT_BAP_BIS_SYNC_FAILED &&
1848 !bits_subset_of(bis_sync, bis_sync_requested)) {
1849 LOG_DBG("Subgroup[%d] invalid bis_sync value %x for %x",
1850 i, bis_sync, bis_sync_requested);
1851 ret = -EINVAL;
1852 goto unlock_return;
1853 }
1854 }
1855
1856 for (uint8_t i = 0U; i < state->num_subgroups; i++) {
1857 const struct bt_bap_bass_subgroup *param_subgroup = ¶m->subgroups[i];
1858 struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
1859
1860 if (subgroup->bis_sync != param_subgroup->bis_sync) {
1861 subgroup->bis_sync = param_subgroup->bis_sync;
1862 state_changed = true;
1863 }
1864
1865 /* If the metadata len is 0, we shall not overwrite the existing metadata */
1866 if (param_subgroup->metadata_len == 0U) {
1867 continue;
1868 }
1869
1870 if (subgroup->metadata_len != param_subgroup->metadata_len) {
1871 subgroup->metadata_len = param_subgroup->metadata_len;
1872 state_changed = true;
1873 }
1874
1875 if (subgroup->metadata_len != param_subgroup->metadata_len ||
1876 memcmp(subgroup->metadata, param_subgroup->metadata,
1877 param_subgroup->metadata_len) != 0) {
1878 (void)memcpy(subgroup->metadata,
1879 param_subgroup->metadata,
1880 param_subgroup->metadata_len);
1881 subgroup->metadata_len = param_subgroup->metadata_len;
1882 state_changed = true;
1883 }
1884 }
1885
1886 if (state_changed) {
1887 LOG_DBG("Index %u: Source modified: ID 0x%02x",
1888 internal_state->index, state->src_id);
1889 set_receive_state_changed(internal_state);
1890 }
1891
1892 unlock_return:
1893 err = k_mutex_unlock(&internal_state->mutex);
1894 __ASSERT(err == 0, "Failed to unlock mutex: %d", err);
1895
1896
1897 if (state_changed) {
1898 /* app callback */
1899 receive_state_updated(NULL, internal_state);
1900 }
1901
1902 return ret;
1903 }
1904
bt_bap_scan_delegator_rem_src(uint8_t src_id)1905 int bt_bap_scan_delegator_rem_src(uint8_t src_id)
1906 {
1907 struct net_buf_simple buf;
1908
1909 net_buf_simple_init_with_data(&buf, (void *)&src_id, sizeof(src_id));
1910
1911 if (scan_delegator_rem_src(NULL, &buf) == 0) {
1912 return 0;
1913 } else {
1914 return -EINVAL;
1915 }
1916 }
1917
bt_bap_scan_delegator_foreach_state(bt_bap_scan_delegator_state_func_t func,void * user_data)1918 void bt_bap_scan_delegator_foreach_state(bt_bap_scan_delegator_state_func_t func, void *user_data)
1919 {
1920 for (size_t i = 0U; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
1921 if (scan_delegator.recv_states[i].active) {
1922 bool stop;
1923
1924 stop = func(&scan_delegator.recv_states[i].state, user_data);
1925 if (stop) {
1926 return;
1927 }
1928 }
1929 }
1930 }
1931
1932 struct scan_delegator_state_find_state_param {
1933 const struct bt_bap_scan_delegator_recv_state *recv_state;
1934 bt_bap_scan_delegator_state_func_t func;
1935 void *user_data;
1936 };
1937
1938 static bool
scan_delegator_state_find_state_cb(const struct bt_bap_scan_delegator_recv_state * recv_state,void * user_data)1939 scan_delegator_state_find_state_cb(const struct bt_bap_scan_delegator_recv_state *recv_state,
1940 void *user_data)
1941 {
1942 struct scan_delegator_state_find_state_param *param = user_data;
1943 bool found;
1944
1945 found = param->func(recv_state, param->user_data);
1946 if (found) {
1947 param->recv_state = recv_state;
1948
1949 return true;
1950 }
1951
1952 return false;
1953 }
1954
1955 const struct bt_bap_scan_delegator_recv_state *
bt_bap_scan_delegator_find_state(bt_bap_scan_delegator_state_func_t func,void * user_data)1956 bt_bap_scan_delegator_find_state(bt_bap_scan_delegator_state_func_t func, void *user_data)
1957 {
1958 struct scan_delegator_state_find_state_param param = {
1959 .recv_state = NULL,
1960 .func = func,
1961 .user_data = user_data,
1962 };
1963
1964 bt_bap_scan_delegator_foreach_state(scan_delegator_state_find_state_cb, ¶m);
1965
1966 return param.recv_state;
1967 }
1968
bt_bap_scan_delegator_lookup_src_id(uint8_t src_id)1969 const struct bt_bap_scan_delegator_recv_state *bt_bap_scan_delegator_lookup_src_id(uint8_t src_id)
1970 {
1971 const struct bass_recv_state_internal *internal_state = bass_lookup_src_id(src_id);
1972
1973 if (internal_state != NULL) {
1974 return &internal_state->state;
1975 }
1976
1977 return NULL;
1978 }
1979