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 <zephyr/kernel.h>
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/sys/check.h>
13 #include <zephyr/sys/util.h>
14
15 #include <zephyr/init.h>
16
17 #include <zephyr/bluetooth/bluetooth.h>
18 #include <zephyr/bluetooth/conn.h>
19 #include <zephyr/bluetooth/gatt.h>
20 #include <zephyr/bluetooth/l2cap.h>
21 #include <zephyr/bluetooth/buf.h>
22
23 #include <zephyr/logging/log.h>
24
25 LOG_MODULE_REGISTER(bt_bap_scan_delegator, CONFIG_BT_BAP_SCAN_DELEGATOR_LOG_LEVEL);
26
27 #include "common/bt_str.h"
28
29 #include "audio_internal.h"
30 #include "bap_internal.h"
31 #include "../host/conn_internal.h"
32 #include "../host/hci_core.h"
33
34 #define PAST_TIMEOUT K_SECONDS(10)
35
36 #define SCAN_DELEGATOR_BUF_SEM_TIMEOUT K_MSEC(CONFIG_BT_BAP_SCAN_DELEGATOR_BUF_TIMEOUT)
37 static K_SEM_DEFINE(read_buf_sem, 1, 1);
38 NET_BUF_SIMPLE_DEFINE_STATIC(read_buf, BT_ATT_MAX_ATTRIBUTE_LEN);
39
40 enum bass_recv_state_internal_flag {
41 BASS_RECV_STATE_INTERNAL_FLAG_NOTIFY_PEND,
42
43 BASS_RECV_STATE_INTERNAL_FLAG_NUM,
44 };
45
46 struct broadcast_assistant {
47 struct bt_conn *conn;
48 uint8_t scanning;
49 };
50
51 /* TODO: Merge bass_recv_state_internal_t and bt_bap_scan_delegator_recv_state */
52 struct bass_recv_state_internal {
53 const struct bt_gatt_attr *attr;
54
55 bool active;
56 uint8_t index;
57 struct bt_bap_scan_delegator_recv_state state;
58 uint8_t broadcast_code[BT_AUDIO_BROADCAST_CODE_SIZE];
59 struct bt_le_per_adv_sync *pa_sync;
60 /** Requested BIS sync bitfield for each subgroup */
61 uint32_t requested_bis_sync[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS];
62
63 ATOMIC_DEFINE(flags, BASS_RECV_STATE_INTERNAL_FLAG_NUM);
64 };
65
66 struct bt_bap_scan_delegator_inst {
67 uint8_t next_src_id;
68 struct broadcast_assistant assistant_configs[CONFIG_BT_MAX_CONN];
69 struct bass_recv_state_internal recv_states
70 [CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT];
71 };
72
73 static bool conn_cb_registered;
74 static struct bt_bap_scan_delegator_inst scan_delegator;
75 static struct bt_bap_scan_delegator_cb *scan_delegator_cbs;
76
77 /**
78 * @brief Returns whether a value's bits is a subset of another value's bits
79 *
80 * @param a The subset to check
81 * @param b The bits to check against
82 *
83 * @return True if @p a is a bitwise subset of @p b
84 */
bits_subset_of(uint32_t a,uint32_t b)85 static bool bits_subset_of(uint32_t a, uint32_t b)
86 {
87 return (((a) & (~(b))) == 0);
88 }
89
valid_bis_syncs(uint32_t bis_sync)90 static bool valid_bis_syncs(uint32_t bis_sync)
91 {
92 if (bis_sync == BT_BAP_BIS_SYNC_NO_PREF) {
93 return true;
94 }
95
96 if (bis_sync > BIT_MASK(31)) { /* Max BIS index */
97 return false;
98 }
99
100 return true;
101 }
102
bis_syncs_unique_or_no_pref(uint32_t requested_bis_syncs,uint32_t aggregated_bis_syncs)103 static bool bis_syncs_unique_or_no_pref(uint32_t requested_bis_syncs,
104 uint32_t aggregated_bis_syncs)
105 {
106 if (requested_bis_syncs == 0U || aggregated_bis_syncs == 0U) {
107 return true;
108 }
109
110 if (requested_bis_syncs == BT_BAP_BIS_SYNC_NO_PREF &&
111 aggregated_bis_syncs == BT_BAP_BIS_SYNC_NO_PREF) {
112 return true;
113 }
114
115 return (requested_bis_syncs & aggregated_bis_syncs) != 0U;
116 }
117
bt_debug_dump_recv_state(const struct bass_recv_state_internal * recv_state)118 static void bt_debug_dump_recv_state(const struct bass_recv_state_internal *recv_state)
119 {
120 const struct bt_bap_scan_delegator_recv_state *state = &recv_state->state;
121 const bool is_bad_code = state->encrypt_state ==
122 BT_BAP_BIG_ENC_STATE_BAD_CODE;
123
124 LOG_DBG("Receive State[%d]: src ID %u, addr %s, adv_sid %u, "
125 "broadcast_id 0x%06X, pa_sync_state %u, "
126 "encrypt state %u%s%s, num_subgroups %u",
127 recv_state->index, state->src_id, bt_addr_le_str(&state->addr), state->adv_sid,
128 state->broadcast_id, state->pa_sync_state, state->encrypt_state,
129 is_bad_code ? ", bad code" : "",
130 is_bad_code ? bt_hex(state->bad_code, sizeof(state->bad_code)) : "",
131 state->num_subgroups);
132
133 for (int i = 0; i < state->num_subgroups; i++) {
134 const struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
135
136 LOG_DBG("\tSubgroup[%d]: BIS sync %u (requested %u), metadata_len %zu, metadata: "
137 "%s",
138 i, subgroup->bis_sync, recv_state->requested_bis_sync[i],
139 subgroup->metadata_len, bt_hex(subgroup->metadata, subgroup->metadata_len));
140 }
141 }
142
bass_notify_receive_state(struct bt_conn * conn,const struct bass_recv_state_internal * internal_state)143 static void bass_notify_receive_state(struct bt_conn *conn,
144 const struct bass_recv_state_internal *internal_state)
145 {
146 const uint8_t att_ntf_header_size = 3; /* opcode (1) + handle (2) */
147 uint16_t max_ntf_size;
148 uint16_t ntf_size;
149 int err;
150
151 if (conn != NULL) {
152 max_ntf_size = bt_gatt_get_mtu(conn) - att_ntf_header_size;
153 } else {
154 max_ntf_size = MIN(BT_L2CAP_RX_MTU, BT_L2CAP_TX_MTU) - att_ntf_header_size;
155 }
156
157 ntf_size = MIN(max_ntf_size, read_buf.len);
158 if (ntf_size < read_buf.len) {
159 LOG_DBG("Sending truncated notification (%u/%u)", ntf_size, read_buf.len);
160 }
161
162 LOG_DBG("Sending bytes %d", ntf_size);
163 err = bt_gatt_notify_uuid(NULL, BT_UUID_BASS_RECV_STATE,
164 internal_state->attr, read_buf.data,
165 ntf_size);
166
167 if (err != 0 && err != -ENOTCONN) {
168 LOG_DBG("Could not notify receive state: %d", err);
169 }
170 }
171
net_buf_put_recv_state(const struct bass_recv_state_internal * recv_state)172 static void net_buf_put_recv_state(const struct bass_recv_state_internal *recv_state)
173 {
174 const struct bt_bap_scan_delegator_recv_state *state = &recv_state->state;
175
176 net_buf_simple_reset(&read_buf);
177
178 __ASSERT(recv_state, "NULL receive state");
179
180 if (!recv_state->active) {
181 /* Notify empty */
182
183 return;
184 }
185
186 (void)net_buf_simple_add_u8(&read_buf, state->src_id);
187 (void)net_buf_simple_add_u8(&read_buf, state->addr.type);
188 (void)net_buf_simple_add_mem(&read_buf, &state->addr.a,
189 sizeof(state->addr.a));
190 (void)net_buf_simple_add_u8(&read_buf, state->adv_sid);
191 (void)net_buf_simple_add_le24(&read_buf, state->broadcast_id);
192 (void)net_buf_simple_add_u8(&read_buf, state->pa_sync_state);
193 (void)net_buf_simple_add_u8(&read_buf, state->encrypt_state);
194 if (state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
195 (void)net_buf_simple_add_mem(&read_buf, &state->bad_code,
196 sizeof(state->bad_code));
197 }
198 (void)net_buf_simple_add_u8(&read_buf, state->num_subgroups);
199 for (int i = 0; i < state->num_subgroups; i++) {
200 const struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
201
202 (void)net_buf_simple_add_le32(&read_buf, subgroup->bis_sync >> 1);
203 (void)net_buf_simple_add_u8(&read_buf, subgroup->metadata_len);
204 (void)net_buf_simple_add_mem(&read_buf, subgroup->metadata,
205 subgroup->metadata_len);
206 }
207 }
208
receive_state_updated(struct bt_conn * conn,const struct bass_recv_state_internal * internal_state)209 static void receive_state_updated(struct bt_conn *conn,
210 const struct bass_recv_state_internal *internal_state)
211 {
212 int err;
213
214 /* If something is holding the NOTIFY_PEND flag we should not notify now */
215 if (atomic_test_bit(internal_state->flags,
216 BASS_RECV_STATE_INTERNAL_FLAG_NOTIFY_PEND)) {
217 return;
218 }
219
220 err = k_sem_take(&read_buf_sem, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
221 if (err != 0) {
222 LOG_DBG("Failed to take read_buf_sem: %d", err);
223
224 return;
225 }
226
227 bt_debug_dump_recv_state(internal_state);
228 net_buf_put_recv_state(internal_state);
229 bass_notify_receive_state(conn, internal_state);
230 if (scan_delegator_cbs != NULL &&
231 scan_delegator_cbs->recv_state_updated != NULL) {
232 scan_delegator_cbs->recv_state_updated(conn,
233 &internal_state->state);
234 }
235
236 k_sem_give(&read_buf_sem);
237 }
238
bis_sync_request_updated(struct bt_conn * conn,const struct bass_recv_state_internal * internal_state)239 static void bis_sync_request_updated(struct bt_conn *conn,
240 const struct bass_recv_state_internal *internal_state)
241 {
242 if (scan_delegator_cbs != NULL &&
243 scan_delegator_cbs->bis_sync_req != NULL) {
244 scan_delegator_cbs->bis_sync_req(conn, &internal_state->state,
245 internal_state->requested_bis_sync);
246 }
247 }
248
scan_delegator_disconnected(struct bt_conn * conn,uint8_t reason)249 static void scan_delegator_disconnected(struct bt_conn *conn, uint8_t reason)
250 {
251 int i;
252 struct broadcast_assistant *assistant = NULL;
253
254 for (i = 0; i < ARRAY_SIZE(scan_delegator.assistant_configs); i++) {
255 if (scan_delegator.assistant_configs[i].conn == conn) {
256 assistant = &scan_delegator.assistant_configs[i];
257 break;
258 }
259 }
260
261 if (assistant != NULL) {
262 LOG_DBG("Instance %u with addr %s disconnected",
263 i, bt_addr_le_str(bt_conn_get_dst(conn)));
264 (void)memset(assistant, 0, sizeof(*assistant));
265 }
266 }
267
scan_delegator_security_changed(struct bt_conn * conn,bt_security_t level,enum bt_security_err err)268 static void scan_delegator_security_changed(struct bt_conn *conn,
269 bt_security_t level,
270 enum bt_security_err err)
271 {
272 if (err != 0 || conn->encrypt == 0) {
273 return;
274 }
275
276 if (bt_addr_le_is_bonded(conn->id, &conn->le.dst) == 0) {
277 return;
278 }
279
280 /* Notify all receive states after a bonded device reconnects */
281 for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
282 struct bass_recv_state_internal *internal_state = &scan_delegator.recv_states[i];
283 int gatt_err;
284
285 if (!internal_state->active) {
286 continue;
287 }
288
289 err = k_sem_take(&read_buf_sem, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
290 if (err != 0) {
291 LOG_DBG("Failed to take read_buf_sem: %d", err);
292
293 return;
294 }
295
296 net_buf_put_recv_state(internal_state);
297
298 gatt_err = bt_gatt_notify_uuid(conn, BT_UUID_BASS_RECV_STATE,
299 internal_state->attr, read_buf.data,
300 read_buf.len);
301
302 k_sem_give(&read_buf_sem);
303
304 if (gatt_err != 0) {
305 LOG_WRN("Could not notify receive state[%d] to reconnecting assistant: %d",
306 i, gatt_err);
307 }
308 }
309 }
310
311 static struct bt_conn_cb conn_cb = {
312 .disconnected = scan_delegator_disconnected,
313 .security_changed = scan_delegator_security_changed,
314 };
315
get_bap_broadcast_assistant(struct bt_conn * conn)316 static struct broadcast_assistant *get_bap_broadcast_assistant(struct bt_conn *conn)
317 {
318 struct broadcast_assistant *new = NULL;
319
320 for (int i = 0; i < ARRAY_SIZE(scan_delegator.assistant_configs); i++) {
321 if (scan_delegator.assistant_configs[i].conn == conn) {
322 return &scan_delegator.assistant_configs[i];
323 } else if (new == NULL &&
324 scan_delegator.assistant_configs[i].conn == NULL) {
325 new = &scan_delegator.assistant_configs[i];
326 new->conn = conn;
327 }
328 }
329
330 if (!conn_cb_registered) {
331 bt_conn_cb_register(&conn_cb);
332 conn_cb_registered = true;
333 }
334
335 return new;
336 }
337
next_src_id(void)338 static uint8_t next_src_id(void)
339 {
340 uint8_t next_src_id;
341 bool unique = false;
342
343 while (!unique) {
344 next_src_id = scan_delegator.next_src_id++;
345 unique = true;
346 for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
347 if (scan_delegator.recv_states[i].active &&
348 scan_delegator.recv_states[i].state.src_id == next_src_id) {
349 unique = false;
350 break;
351 }
352 }
353 }
354
355 return next_src_id;
356 }
357
bass_lookup_src_id(uint8_t src_id)358 static struct bass_recv_state_internal *bass_lookup_src_id(uint8_t src_id)
359 {
360 for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
361 if (scan_delegator.recv_states[i].active &&
362 scan_delegator.recv_states[i].state.src_id == src_id) {
363 return &scan_delegator.recv_states[i];
364 }
365 }
366
367 return NULL;
368 }
369
bass_lookup_pa_sync(struct bt_le_per_adv_sync * sync)370 static struct bass_recv_state_internal *bass_lookup_pa_sync(struct bt_le_per_adv_sync *sync)
371 {
372 for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
373 if (scan_delegator.recv_states[i].pa_sync == sync) {
374 return &scan_delegator.recv_states[i];
375 }
376 }
377
378 return NULL;
379 }
380
bass_lookup_addr(const bt_addr_le_t * addr)381 static struct bass_recv_state_internal *bass_lookup_addr(const bt_addr_le_t *addr)
382 {
383 for (int i = 0; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
384 if (bt_addr_le_eq(&scan_delegator.recv_states[i].state.addr,
385 addr)) {
386 return &scan_delegator.recv_states[i];
387 }
388 }
389
390 return NULL;
391 }
392
get_free_recv_state(void)393 static struct bass_recv_state_internal *get_free_recv_state(void)
394 {
395 for (size_t i = 0U; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
396 struct bass_recv_state_internal *free_internal_state =
397 &scan_delegator.recv_states[i];
398
399 if (!free_internal_state->active) {
400 return free_internal_state;
401 }
402 }
403
404 return NULL;
405 }
406
pa_synced(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)407 static void pa_synced(struct bt_le_per_adv_sync *sync,
408 struct bt_le_per_adv_sync_synced_info *info)
409 {
410 struct bass_recv_state_internal *internal_state;
411
412 LOG_DBG("Synced%s", info->conn ? " via PAST" : "");
413
414 internal_state = bass_lookup_addr(info->addr);
415 if (internal_state == NULL) {
416 LOG_DBG("BASS receive state not found");
417 return;
418 }
419
420 internal_state->pa_sync = sync;
421
422 if (internal_state->state.pa_sync_state != BT_BAP_PA_STATE_SYNCED) {
423 internal_state->state.pa_sync_state = BT_BAP_PA_STATE_SYNCED;
424 receive_state_updated(info->conn, internal_state);
425 }
426 }
427
pa_terminated(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)428 static void pa_terminated(struct bt_le_per_adv_sync *sync,
429 const struct bt_le_per_adv_sync_term_info *info)
430 {
431 struct bass_recv_state_internal *internal_state = bass_lookup_pa_sync(sync);
432
433 LOG_DBG("Terminated");
434 if (internal_state == NULL) {
435 LOG_DBG("BASS receive state not found");
436 return;
437 }
438
439 internal_state->pa_sync = NULL;
440
441 if (internal_state->state.pa_sync_state != BT_BAP_PA_STATE_NOT_SYNCED) {
442 internal_state->state.pa_sync_state = BT_BAP_PA_STATE_NOT_SYNCED;
443 receive_state_updated(NULL, internal_state);
444 }
445 }
446
447 static struct bt_le_per_adv_sync_cb pa_sync_cb = {
448 .synced = pa_synced,
449 .term = pa_terminated,
450 };
451
supports_past(struct bt_conn * conn,uint8_t pa_sync_val)452 static bool supports_past(struct bt_conn *conn, uint8_t pa_sync_val)
453 {
454 return pa_sync_val == BT_BAP_BASS_PA_REQ_SYNC_PAST &&
455 BT_FEAT_LE_PAST_SEND(conn->le.features) &&
456 BT_FEAT_LE_PAST_RECV(bt_dev.le.features);
457 }
458
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)459 static int pa_sync_request(struct bt_conn *conn,
460 const struct bt_bap_scan_delegator_recv_state *state,
461 uint8_t pa_sync_val, uint16_t pa_interval)
462 {
463 int err = -EACCES;
464
465 if (scan_delegator_cbs != NULL &&
466 scan_delegator_cbs->pa_sync_req != NULL) {
467 const bool past_supported = supports_past(conn, pa_sync_val);
468
469 err = scan_delegator_cbs->pa_sync_req(conn, state,
470 past_supported,
471 pa_interval);
472 }
473
474 return err;
475 }
476
pa_sync_term_request(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * state)477 static int pa_sync_term_request(struct bt_conn *conn,
478 const struct bt_bap_scan_delegator_recv_state *state)
479 {
480 int err = -EACCES;
481
482 if (scan_delegator_cbs != NULL &&
483 scan_delegator_cbs->pa_sync_req != NULL) {
484 err = scan_delegator_cbs->pa_sync_term_req(conn, state);
485 }
486
487 return err;
488 }
489
scan_delegator_add_source(struct bt_conn * conn,struct net_buf_simple * buf)490 static int scan_delegator_add_source(struct bt_conn *conn,
491 struct net_buf_simple *buf)
492 {
493 struct bass_recv_state_internal *internal_state = NULL;
494 struct bt_bap_scan_delegator_recv_state *state;
495 bt_addr_t *addr;
496 uint8_t pa_sync;
497 uint16_t pa_interval;
498 uint32_t aggregated_bis_syncs = 0;
499 bool bis_sync_requested;
500
501 /* subtract 1 as the opcode has already been pulled */
502 if (buf->len < sizeof(struct bt_bap_bass_cp_add_src) - 1) {
503 LOG_DBG("Invalid length %u", buf->size);
504 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
505 }
506
507 internal_state = get_free_recv_state();
508 if (internal_state == NULL) {
509 LOG_DBG("Could not add src");
510 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
511 }
512
513 state = &internal_state->state;
514
515 state->src_id = next_src_id();
516 state->addr.type = net_buf_simple_pull_u8(buf);
517 if (state->addr.type > BT_ADDR_LE_RANDOM) {
518 LOG_DBG("Invalid address type %u", state->addr.type);
519 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
520 }
521
522 addr = net_buf_simple_pull_mem(buf, sizeof(*addr));
523 bt_addr_copy(&state->addr.a, addr);
524
525 state->adv_sid = net_buf_simple_pull_u8(buf);
526 if (state->adv_sid > BT_GAP_SID_MAX) {
527 LOG_DBG("Invalid adv SID %u", state->adv_sid);
528 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
529 }
530
531 state->broadcast_id = net_buf_simple_pull_le24(buf);
532
533 pa_sync = net_buf_simple_pull_u8(buf);
534 if (pa_sync > BT_BAP_BASS_PA_REQ_SYNC) {
535 LOG_DBG("Invalid PA sync value %u", pa_sync);
536 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
537 }
538
539 pa_interval = net_buf_simple_pull_le16(buf);
540
541 state->num_subgroups = net_buf_simple_pull_u8(buf);
542 if (state->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
543 LOG_WRN("Too many subgroups %u/%u", state->num_subgroups,
544 CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
545 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
546 }
547
548 bis_sync_requested = false;
549 for (int i = 0; i < state->num_subgroups; i++) {
550 struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
551 uint8_t *metadata;
552
553 if (buf->len < (sizeof(subgroup->bis_sync) + sizeof(subgroup->metadata_len))) {
554 LOG_DBG("Invalid length %u", buf->size);
555 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
556 }
557
558 internal_state->requested_bis_sync[i] = net_buf_simple_pull_le32(buf);
559 if (internal_state->requested_bis_sync[i] != BT_BAP_BIS_SYNC_NO_PREF) {
560 /* Received BIS Index bitfield uses BIT(0) for BIS Index 1 */
561 internal_state->requested_bis_sync[i] <<= 1;
562 }
563
564 if (internal_state->requested_bis_sync[i] &&
565 pa_sync == BT_BAP_BASS_PA_REQ_NO_SYNC) {
566 LOG_DBG("Cannot sync to BIS without PA");
567 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
568 }
569
570 if (internal_state->requested_bis_sync[i] != 0U) {
571 bis_sync_requested = true;
572 }
573
574 /* Verify that the request BIS sync indexes are unique or no preference */
575 if (!bis_syncs_unique_or_no_pref(internal_state->requested_bis_sync[i],
576 aggregated_bis_syncs)) {
577 LOG_DBG("Duplicate BIS index [%d]%x (aggregated %x)",
578 i, internal_state->requested_bis_sync[i],
579 aggregated_bis_syncs);
580
581 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
582 }
583
584 if (!valid_bis_syncs(internal_state->requested_bis_sync[i])) {
585 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
586 }
587 aggregated_bis_syncs |= internal_state->requested_bis_sync[i];
588
589 subgroup->metadata_len = net_buf_simple_pull_u8(buf);
590
591 if (buf->len < subgroup->metadata_len) {
592 LOG_DBG("Invalid length %u", buf->size);
593
594 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
595 }
596
597
598 if (subgroup->metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
599 LOG_WRN("Metadata too long %u/%u", subgroup->metadata_len,
600 CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE);
601
602 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
603 }
604
605 metadata = net_buf_simple_pull_mem(buf, subgroup->metadata_len);
606 (void)memcpy(subgroup->metadata, metadata,
607 subgroup->metadata_len);
608 }
609
610 if (buf->len != 0) {
611 LOG_DBG("Invalid length %u", buf->size);
612 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
613 }
614
615 if (pa_sync != BT_BAP_BASS_PA_REQ_NO_SYNC) {
616 int err;
617
618 /* Set NOTIFY_PEND flag to ensure that we only send 1
619 * notification in case that the upper layer calls another
620 * function that changes the state in the pa_sync_request
621 * callback
622 */
623 atomic_set_bit(internal_state->flags,
624 BASS_RECV_STATE_INTERNAL_FLAG_NOTIFY_PEND);
625 err = pa_sync_request(conn, state, pa_sync, pa_interval);
626
627 if (err != 0) {
628 (void)memset(state, 0, sizeof(*state));
629
630 LOG_DBG("PA sync %u from %p was rejected with reason %d", pa_sync, conn,
631 err);
632
633 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
634 }
635 }
636
637 internal_state->active = true;
638
639 LOG_DBG("Index %u: New source added: ID 0x%02x",
640 internal_state->index, state->src_id);
641
642 atomic_clear_bit(internal_state->flags,
643 BASS_RECV_STATE_INTERNAL_FLAG_NOTIFY_PEND);
644
645 receive_state_updated(conn, internal_state);
646
647 if (bis_sync_requested) {
648 bis_sync_request_updated(conn, internal_state);
649 }
650
651 return 0;
652 }
653
scan_delegator_mod_src(struct bt_conn * conn,struct net_buf_simple * buf)654 static int scan_delegator_mod_src(struct bt_conn *conn,
655 struct net_buf_simple *buf)
656 {
657 struct bt_bap_scan_delegator_recv_state backup_state;
658 struct bass_recv_state_internal *internal_state;
659 struct bt_bap_scan_delegator_recv_state *state;
660 uint8_t src_id;
661 bool state_changed = false;
662 uint16_t pa_interval;
663 uint8_t num_subgroups;
664 struct bt_bap_bass_subgroup
665 subgroups[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS] = { 0 };
666 uint8_t pa_sync;
667 uint32_t aggregated_bis_syncs = 0;
668 bool bis_sync_change_requested;
669
670 /* subtract 1 as the opcode has already been pulled */
671 if (buf->len < sizeof(struct bt_bap_bass_cp_mod_src) - 1) {
672 LOG_DBG("Invalid length %u", buf->len);
673
674 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
675 }
676
677 src_id = net_buf_simple_pull_u8(buf);
678 internal_state = bass_lookup_src_id(src_id);
679
680 LOG_DBG("src_id %u", src_id);
681
682 if (internal_state == NULL) {
683 LOG_DBG("Could not find state by src id %u", src_id);
684
685 return BT_GATT_ERR(BT_BAP_BASS_ERR_INVALID_SRC_ID);
686 }
687
688 pa_sync = net_buf_simple_pull_u8(buf);
689 if (pa_sync > BT_BAP_BASS_PA_REQ_SYNC) {
690 LOG_DBG("Invalid PA sync value %u", pa_sync);
691
692 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
693 }
694
695 pa_interval = net_buf_simple_pull_le16(buf);
696
697 num_subgroups = net_buf_simple_pull_u8(buf);
698 if (num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
699 LOG_WRN("Too many subgroups %u/%u", num_subgroups,
700 CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
701
702 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
703 }
704
705 bis_sync_change_requested = false;
706 for (int i = 0; i < num_subgroups; i++) {
707 struct bt_bap_bass_subgroup *subgroup = &subgroups[i];
708 uint32_t old_bis_sync_req;
709 uint8_t *metadata;
710
711 if (buf->len < (sizeof(subgroup->bis_sync) + sizeof(subgroup->metadata_len))) {
712 LOG_DBG("Invalid length %u", buf->len);
713 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
714 }
715
716 old_bis_sync_req = internal_state->requested_bis_sync[i];
717
718 internal_state->requested_bis_sync[i] = net_buf_simple_pull_le32(buf);
719 if (internal_state->requested_bis_sync[i] != BT_BAP_BIS_SYNC_NO_PREF) {
720 /* Received BIS Index bitfield uses BIT(0) for BIS Index 1 */
721 internal_state->requested_bis_sync[i] <<= 1;
722 }
723
724 if (internal_state->requested_bis_sync[i] &&
725 pa_sync == BT_BAP_BASS_PA_REQ_NO_SYNC) {
726 LOG_DBG("Cannot sync to BIS without PA");
727 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
728 }
729
730 if (old_bis_sync_req != internal_state->requested_bis_sync[i]) {
731 bis_sync_change_requested = true;
732 }
733
734 /* Verify that the request BIS sync indexes are unique or no preference */
735 if (!bis_syncs_unique_or_no_pref(internal_state->requested_bis_sync[i],
736 aggregated_bis_syncs)) {
737 LOG_DBG("Duplicate BIS index [%d]%x (aggregated %x)",
738 i, internal_state->requested_bis_sync[i],
739 aggregated_bis_syncs);
740
741 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
742 }
743
744 if (!valid_bis_syncs(internal_state->requested_bis_sync[i])) {
745 return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
746 }
747 aggregated_bis_syncs |= internal_state->requested_bis_sync[i];
748
749 subgroup->metadata_len = net_buf_simple_pull_u8(buf);
750
751 if (buf->len < subgroup->metadata_len) {
752 LOG_DBG("Invalid length %u", buf->len);
753 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
754 }
755
756 if (subgroup->metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
757 LOG_WRN("Metadata too long %u/%u", subgroup->metadata_len,
758 CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE);
759 return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES);
760 }
761
762 metadata = net_buf_simple_pull_mem(buf, subgroup->metadata_len);
763
764 (void)memcpy(subgroup->metadata, metadata,
765 subgroup->metadata_len);
766 }
767
768 if (buf->len != 0) {
769 LOG_DBG("Invalid length %u", buf->size);
770
771 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
772 }
773
774 /* All input has been validated; update receive state and check for changes */
775 state = &internal_state->state;
776
777 /* Store backup in case upper layers rejects */
778 (void)memcpy(&backup_state, state, sizeof(backup_state));
779
780 if (state->num_subgroups != num_subgroups) {
781 state->num_subgroups = num_subgroups;
782 state_changed = true;
783 }
784
785 for (int i = 0; i < num_subgroups; i++) {
786 /* If the metadata len is 0, we shall not overwrite the existing metadata */
787 if (subgroups[i].metadata_len == 0) {
788 continue;
789 }
790
791 if (subgroups[i].metadata_len != state->subgroups[i].metadata_len) {
792 state->subgroups[i].metadata_len = subgroups[i].metadata_len;
793 state_changed = true;
794 }
795
796 if (memcmp(subgroups[i].metadata, state->subgroups[i].metadata,
797 sizeof(subgroups[i].metadata)) != 0) {
798 (void)memcpy(state->subgroups[i].metadata,
799 subgroups[i].metadata,
800 state->subgroups[i].metadata_len);
801 state->subgroups[i].metadata_len = subgroups[i].metadata_len;
802 state_changed = true;
803 }
804 }
805
806 /* Only send the sync request to upper layers if it is requested, and
807 * we are not already synced to the device
808 */
809 if (pa_sync != BT_BAP_BASS_PA_REQ_NO_SYNC &&
810 state->pa_sync_state != BT_BAP_PA_STATE_SYNCED) {
811 const int err = pa_sync_request(conn, state, pa_sync,
812 pa_interval);
813
814 if (err != 0) {
815 /* Restore backup */
816 (void)memcpy(state, &backup_state,
817 sizeof(backup_state));
818
819 LOG_DBG("PA sync %u from %p was rejected with reason %d", pa_sync, conn,
820 err);
821
822 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
823 }
824 } else if (pa_sync == BT_BAP_BASS_PA_REQ_NO_SYNC &&
825 (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ ||
826 state->pa_sync_state == BT_BAP_PA_STATE_SYNCED)) {
827 /* Terminate PA sync */
828 const int err = pa_sync_term_request(conn, &internal_state->state);
829
830 if (err != 0) {
831 LOG_DBG("PA sync term from %p was rejected with reason %d", conn, err);
832
833 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
834 }
835
836 state_changed = true;
837 }
838
839 /* Notify if changed */
840 if (state_changed) {
841 LOG_DBG("Index %u: Source modified: ID 0x%02x",
842 internal_state->index, state->src_id);
843
844 receive_state_updated(conn, internal_state);
845 }
846
847 if (bis_sync_change_requested) {
848 bis_sync_request_updated(conn, internal_state);
849 }
850
851 return 0;
852 }
853
scan_delegator_broadcast_code(struct bt_conn * conn,struct net_buf_simple * buf)854 static int scan_delegator_broadcast_code(struct bt_conn *conn,
855 struct net_buf_simple *buf)
856 {
857 struct bass_recv_state_internal *internal_state;
858 uint8_t src_id;
859 const uint8_t *broadcast_code;
860
861 /* subtract 1 as the opcode has already been pulled */
862 if (buf->len != sizeof(struct bt_bap_bass_cp_broadcase_code) - 1) {
863 LOG_DBG("Invalid length %u", buf->size);
864 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
865 }
866
867 src_id = net_buf_simple_pull_u8(buf);
868 internal_state = bass_lookup_src_id(src_id);
869
870 if (internal_state == NULL) {
871 LOG_DBG("Could not find state by src id %u", src_id);
872 return BT_GATT_ERR(BT_BAP_BASS_ERR_INVALID_SRC_ID);
873 }
874
875 broadcast_code = net_buf_simple_pull_mem(buf, sizeof(internal_state->broadcast_code));
876
877 (void)memcpy(internal_state->broadcast_code, broadcast_code,
878 sizeof(internal_state->broadcast_code));
879
880 LOG_DBG("Index %u: broadcast code added: %s", internal_state->index,
881 bt_hex(internal_state->broadcast_code, sizeof(internal_state->broadcast_code)));
882
883 if (scan_delegator_cbs != NULL &&
884 scan_delegator_cbs->broadcast_code != NULL) {
885 scan_delegator_cbs->broadcast_code(conn, &internal_state->state,
886 broadcast_code);
887 }
888
889 return 0;
890 }
891
scan_delegator_rem_src(struct bt_conn * conn,struct net_buf_simple * buf)892 static int scan_delegator_rem_src(struct bt_conn *conn,
893 struct net_buf_simple *buf)
894 {
895 struct bass_recv_state_internal *internal_state;
896 struct bt_bap_scan_delegator_recv_state *state;
897 bool bis_sync_was_requested;
898 uint8_t src_id;
899
900 /* subtract 1 as the opcode has already been pulled */
901 if (buf->len != sizeof(struct bt_bap_bass_cp_rem_src) - 1) {
902 LOG_DBG("Invalid length %u", buf->size);
903 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
904 }
905
906 src_id = net_buf_simple_pull_u8(buf);
907 internal_state = bass_lookup_src_id(src_id);
908
909 if (internal_state == NULL) {
910 LOG_DBG("Could not find state by src id %u", src_id);
911 return BT_GATT_ERR(BT_BAP_BASS_ERR_INVALID_SRC_ID);
912 }
913
914 state = &internal_state->state;
915
916 /* If conn == NULL then it's a local operation and we do not need to ask the application */
917 if (conn != NULL && (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ ||
918 state->pa_sync_state == BT_BAP_PA_STATE_SYNCED)) {
919 int err;
920
921 /* Terminate PA sync */
922 err = pa_sync_term_request(conn, &internal_state->state);
923 if (err != 0) {
924 LOG_DBG("PA sync term from %p was rejected with reason %d", conn, err);
925
926 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
927 }
928 }
929
930 bis_sync_was_requested = false;
931 for (uint8_t i = 0U; i < state->num_subgroups; i++) {
932 if (internal_state->requested_bis_sync[i] != 0U) {
933 bis_sync_was_requested = true;
934 break;
935 }
936 }
937
938 LOG_DBG("Index %u: Removed source with ID 0x%02x",
939 internal_state->index, src_id);
940
941 internal_state->active = false;
942 internal_state->pa_sync = NULL;
943 (void)memset(&internal_state->state, 0, sizeof(internal_state->state));
944 (void)memset(internal_state->broadcast_code, 0,
945 sizeof(internal_state->broadcast_code));
946 (void)memset(internal_state->requested_bis_sync, 0,
947 sizeof(internal_state->requested_bis_sync));
948
949 if (bis_sync_was_requested) {
950 bis_sync_request_updated(conn, internal_state);
951 }
952 receive_state_updated(conn, internal_state);
953
954 return 0;
955 }
956
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)957 static ssize_t write_control_point(struct bt_conn *conn,
958 const struct bt_gatt_attr *attr,
959 const void *data, uint16_t len,
960 uint16_t offset, uint8_t flags)
961 {
962 struct broadcast_assistant *bap_broadcast_assistant;
963 struct net_buf_simple buf;
964 uint8_t opcode;
965 int err;
966
967 if (offset != 0) {
968 return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
969 } else if (len == 0) {
970 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
971 }
972
973 net_buf_simple_init_with_data(&buf, (void *)data, len);
974
975 opcode = net_buf_simple_pull_u8(&buf);
976
977 if (!BT_BAP_BASS_VALID_OPCODE(opcode)) {
978 return BT_GATT_ERR(BT_BAP_BASS_ERR_OPCODE_NOT_SUPPORTED);
979 }
980
981 bap_broadcast_assistant = get_bap_broadcast_assistant(conn);
982
983 if (bap_broadcast_assistant == NULL) {
984 return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
985 }
986
987 LOG_HEXDUMP_DBG(data, len, "Data");
988
989 switch (opcode) {
990 case BT_BAP_BASS_OP_SCAN_STOP:
991 LOG_DBG("Assistant stopping scanning");
992
993 if (buf.len != 0) {
994 LOG_DBG("Invalid length %u", buf.size);
995 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
996 }
997
998 bap_broadcast_assistant->scanning = false;
999 break;
1000 case BT_BAP_BASS_OP_SCAN_START:
1001 LOG_DBG("Assistant starting scanning");
1002
1003 if (buf.len != 0) {
1004 LOG_DBG("Invalid length %u", buf.size);
1005 return BT_GATT_ERR(BT_ATT_ERR_WRITE_REQ_REJECTED);
1006 }
1007 bap_broadcast_assistant->scanning = true;
1008 break;
1009 case BT_BAP_BASS_OP_ADD_SRC:
1010 LOG_DBG("Assistant adding source");
1011
1012 err = scan_delegator_add_source(conn, &buf);
1013 if (err != 0) {
1014 LOG_DBG("Could not add source %d", err);
1015 return err;
1016 }
1017
1018 break;
1019 case BT_BAP_BASS_OP_MOD_SRC:
1020 LOG_DBG("Assistant modifying source");
1021
1022 err = scan_delegator_mod_src(conn, &buf);
1023 if (err != 0) {
1024 LOG_DBG("Could not modify source %d", err);
1025 return err;
1026 }
1027
1028 break;
1029 case BT_BAP_BASS_OP_BROADCAST_CODE:
1030 LOG_DBG("Assistant setting broadcast code");
1031
1032 err = scan_delegator_broadcast_code(conn, &buf);
1033 if (err != 0) {
1034 LOG_DBG("Could not set broadcast code");
1035 return err;
1036 }
1037
1038 break;
1039 case BT_BAP_BASS_OP_REM_SRC:
1040 LOG_DBG("Assistant removing source");
1041
1042 err = scan_delegator_rem_src(conn, &buf);
1043 if (err != 0) {
1044 LOG_DBG("Could not remove source %d", err);
1045 return err;
1046 }
1047
1048 break;
1049 default:
1050 break;
1051 }
1052
1053 return len;
1054 }
1055
recv_state_cfg_changed(const struct bt_gatt_attr * attr,uint16_t value)1056 static void recv_state_cfg_changed(const struct bt_gatt_attr *attr,
1057 uint16_t value)
1058 {
1059 LOG_DBG("value 0x%04x", value);
1060 }
1061
read_recv_state(struct bt_conn * conn,const struct bt_gatt_attr * attr,void * buf,uint16_t len,uint16_t offset)1062 static ssize_t read_recv_state(struct bt_conn *conn,
1063 const struct bt_gatt_attr *attr, void *buf,
1064 uint16_t len, uint16_t offset)
1065 {
1066 uint8_t idx = POINTER_TO_UINT(BT_AUDIO_CHRC_USER_DATA(attr));
1067 struct bass_recv_state_internal *recv_state = &scan_delegator.recv_states[idx];
1068 struct bt_bap_scan_delegator_recv_state *state = &recv_state->state;
1069
1070 if (recv_state->active) {
1071 ssize_t ret_val;
1072 int err;
1073
1074 LOG_DBG("Index %u: Source ID 0x%02x", idx, state->src_id);
1075
1076 err = k_sem_take(&read_buf_sem, SCAN_DELEGATOR_BUF_SEM_TIMEOUT);
1077 if (err != 0) {
1078 LOG_DBG("Failed to take read_buf_sem: %d", err);
1079
1080 return err;
1081 }
1082
1083 bt_debug_dump_recv_state(recv_state);
1084 net_buf_put_recv_state(recv_state);
1085
1086 ret_val = bt_gatt_attr_read(conn, attr, buf, len, offset,
1087 read_buf.data, read_buf.len);
1088
1089 k_sem_give(&read_buf_sem);
1090
1091 return ret_val;
1092 } else {
1093 LOG_DBG("Index %u: Not active", idx);
1094
1095 return bt_gatt_attr_read(conn, attr, buf, len, offset, NULL, 0);
1096 }
1097 }
1098
1099 #define RECEIVE_STATE_CHARACTERISTIC(idx) \
1100 BT_AUDIO_CHRC(BT_UUID_BASS_RECV_STATE, \
1101 BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,\
1102 BT_GATT_PERM_READ_ENCRYPT, \
1103 read_recv_state, NULL, UINT_TO_POINTER(idx)), \
1104 BT_AUDIO_CCC(recv_state_cfg_changed)
1105
1106 BT_GATT_SERVICE_DEFINE(bass_svc,
1107 BT_GATT_PRIMARY_SERVICE(BT_UUID_BASS),
1108 BT_AUDIO_CHRC(BT_UUID_BASS_CONTROL_POINT,
1109 BT_GATT_CHRC_WRITE_WITHOUT_RESP | BT_GATT_CHRC_WRITE,
1110 BT_GATT_PERM_WRITE_ENCRYPT,
1111 NULL, write_control_point, NULL),
1112 RECEIVE_STATE_CHARACTERISTIC(0),
1113 #if CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1
1114 RECEIVE_STATE_CHARACTERISTIC(1),
1115 #if CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2
1116 RECEIVE_STATE_CHARACTERISTIC(2)
1117 #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2 */
1118 #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1 */
1119 );
1120
bt_bap_scan_delegator_init(void)1121 static int bt_bap_scan_delegator_init(void)
1122 {
1123 /* Store the pointer to the first characteristic in each receive state */
1124 scan_delegator.recv_states[0].attr = &bass_svc.attrs[3];
1125 scan_delegator.recv_states[0].index = 0;
1126 #if CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1
1127 scan_delegator.recv_states[1].attr = &bass_svc.attrs[6];
1128 scan_delegator.recv_states[1].index = 1;
1129 #if CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2
1130 scan_delegator.recv_states[2].attr = &bass_svc.attrs[9];
1131 scan_delegator.recv_states[2].index = 2;
1132 #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 2 */
1133 #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR_RECV_STATE_COUNT > 1 */
1134
1135 bt_le_per_adv_sync_cb_register(&pa_sync_cb);
1136
1137 return 0;
1138 }
1139
1140 SYS_INIT(bt_bap_scan_delegator_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
1141
1142 /****************************** PUBLIC API ******************************/
bt_bap_scan_delegator_register_cb(struct bt_bap_scan_delegator_cb * cb)1143 void bt_bap_scan_delegator_register_cb(struct bt_bap_scan_delegator_cb *cb)
1144 {
1145 scan_delegator_cbs = cb;
1146 }
1147
bt_bap_scan_delegator_set_pa_state(uint8_t src_id,enum bt_bap_pa_state pa_state)1148 int bt_bap_scan_delegator_set_pa_state(uint8_t src_id,
1149 enum bt_bap_pa_state pa_state)
1150 {
1151 struct bass_recv_state_internal *internal_state = bass_lookup_src_id(src_id);
1152 struct bt_bap_scan_delegator_recv_state *recv_state;
1153
1154 if (internal_state == NULL) {
1155 LOG_DBG("Could not find recv_state by src_id %u", src_id);
1156 return -EINVAL;
1157 }
1158
1159 recv_state = &internal_state->state;
1160
1161 if (recv_state->pa_sync_state != pa_state) {
1162 recv_state->pa_sync_state = pa_state;
1163 receive_state_updated(NULL, internal_state);
1164 }
1165
1166 return 0;
1167 }
1168
bt_bap_scan_delegator_set_bis_sync_state(uint8_t src_id,uint32_t bis_synced[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])1169 int bt_bap_scan_delegator_set_bis_sync_state(
1170 uint8_t src_id,
1171 uint32_t bis_synced[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])
1172 {
1173 struct bass_recv_state_internal *internal_state = bass_lookup_src_id(src_id);
1174 bool notify = false;
1175
1176 if (internal_state == NULL) {
1177 LOG_DBG("Could not find recv_state by src_id %u", src_id);
1178 return -EINVAL;
1179 }
1180
1181 if (internal_state->state.pa_sync_state != BT_BAP_PA_STATE_SYNCED) {
1182 LOG_DBG("PA for src_id %u isn't synced, cannot be BIG synced",
1183 src_id);
1184 return -EINVAL;
1185 }
1186
1187 /* Verify state for all subgroups before assigning any data */
1188 for (uint8_t i = 0U; i < internal_state->state.num_subgroups; i++) {
1189 if (i >= CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
1190 break;
1191 }
1192
1193 if (bis_synced[i] == BT_BAP_BIS_SYNC_NO_PREF ||
1194 !bits_subset_of(bis_synced[i],
1195 internal_state->requested_bis_sync[i])) {
1196 LOG_DBG("Subgroup[%u] invalid bis_sync value %x for %x",
1197 i, bis_synced[i], internal_state->requested_bis_sync[i]);
1198
1199 return -EINVAL;
1200 }
1201 }
1202
1203 for (uint8_t i = 0U; i < internal_state->state.num_subgroups; i++) {
1204 struct bt_bap_bass_subgroup *subgroup =
1205 &internal_state->state.subgroups[i];
1206
1207 if (i >= CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
1208 break;
1209 }
1210
1211 if (bis_synced[i] != subgroup->bis_sync) {
1212 notify = true;
1213 subgroup->bis_sync = bis_synced[i];
1214 }
1215 }
1216
1217 LOG_DBG("Index %u: Source ID 0x%02x synced",
1218 internal_state->index, src_id);
1219
1220 if (internal_state->state.encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
1221 (void)memcpy(internal_state->state.bad_code,
1222 internal_state->broadcast_code,
1223 sizeof(internal_state->state.bad_code));
1224 }
1225
1226 if (notify) {
1227 receive_state_updated(NULL, internal_state);
1228 }
1229
1230 return 0;
1231 }
1232
valid_bt_bap_scan_delegator_add_src_param(const struct bt_bap_scan_delegator_add_src_param * param)1233 static bool valid_bt_bap_scan_delegator_add_src_param(
1234 const struct bt_bap_scan_delegator_add_src_param *param)
1235 {
1236 uint32_t aggregated_bis_syncs = 0U;
1237
1238 if (param->broadcast_id > BT_AUDIO_BROADCAST_ID_MAX) {
1239 LOG_DBG("Invalid broadcast_id: %u", param->broadcast_id);
1240
1241 return false;
1242 }
1243
1244 if (param->pa_sync == NULL) {
1245 LOG_DBG("NULL pa_sync");
1246
1247 return false;
1248 }
1249
1250 if (param->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
1251 LOG_WRN("Too many subgroups %u/%u",
1252 param->num_subgroups,
1253 CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
1254
1255 return false;
1256 }
1257
1258 for (uint8_t i = 0U; i < param->num_subgroups; i++) {
1259 const struct bt_bap_bass_subgroup *subgroup = ¶m->subgroups[i];
1260
1261 if (!bis_syncs_unique_or_no_pref(subgroup->bis_sync,
1262 aggregated_bis_syncs)) {
1263 LOG_DBG("Invalid BIS sync: %u", subgroup->bis_sync);
1264
1265 return false;
1266 }
1267
1268 if (subgroup->metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
1269 LOG_DBG("subgroup[%u]: Invalid metadata_len: %u",
1270 i, subgroup->metadata_len);
1271
1272 return false;
1273 }
1274 }
1275
1276 return true;
1277 }
1278
bt_bap_scan_delegator_add_src(const struct bt_bap_scan_delegator_add_src_param * param)1279 int bt_bap_scan_delegator_add_src(const struct bt_bap_scan_delegator_add_src_param *param)
1280 {
1281 struct bass_recv_state_internal *internal_state = NULL;
1282 struct bt_bap_scan_delegator_recv_state *state;
1283 struct bt_le_per_adv_sync_info sync_info;
1284 int err;
1285
1286 CHECKIF(!valid_bt_bap_scan_delegator_add_src_param(param)) {
1287 return -EINVAL;
1288 }
1289
1290 internal_state = bass_lookup_pa_sync(param->pa_sync);
1291 if (internal_state != NULL) {
1292 LOG_DBG("PA Sync already in a receive state with src_id %u",
1293 internal_state->state.src_id);
1294
1295 return -EALREADY;
1296 }
1297
1298 internal_state = get_free_recv_state();
1299 if (internal_state == NULL) {
1300 LOG_DBG("Could not add src");
1301
1302 return -ENOMEM;
1303 }
1304
1305 err = bt_le_per_adv_sync_get_info(param->pa_sync, &sync_info);
1306 if (err != 0) {
1307 LOG_DBG("Failed to get sync info: %d", err);
1308
1309 return err;
1310 }
1311
1312 state = &internal_state->state;
1313
1314 state->src_id = next_src_id();
1315 bt_addr_le_copy(&state->addr, &sync_info.addr);
1316 state->adv_sid = sync_info.sid;
1317 state->broadcast_id = param->broadcast_id;
1318 state->pa_sync_state = BT_BAP_PA_STATE_SYNCED;
1319 state->num_subgroups = param->num_subgroups;
1320 if (state->num_subgroups > 0U) {
1321 (void)memcpy(state->subgroups, param->subgroups,
1322 sizeof(state->subgroups));
1323 } else {
1324 (void)memset(state->subgroups, 0, sizeof(state->subgroups));
1325 }
1326
1327 internal_state->active = true;
1328 internal_state->pa_sync = param->pa_sync;
1329
1330 /* Set all requested_bis_sync to BT_BAP_BIS_SYNC_NO_PREF, as no
1331 * Broadcast Assistant has set any requests yet
1332 */
1333 for (size_t i = 0U; i < ARRAY_SIZE(internal_state->requested_bis_sync); i++) {
1334 internal_state->requested_bis_sync[i] = BT_BAP_BIS_SYNC_NO_PREF;
1335 }
1336
1337 LOG_DBG("Index %u: New source added: ID 0x%02x",
1338 internal_state->index, state->src_id);
1339
1340 receive_state_updated(NULL, internal_state);
1341
1342 return state->src_id;
1343 }
1344
valid_bt_bap_scan_delegator_mod_src_param(const struct bt_bap_scan_delegator_mod_src_param * param)1345 static bool valid_bt_bap_scan_delegator_mod_src_param(
1346 const struct bt_bap_scan_delegator_mod_src_param *param)
1347 {
1348 uint32_t aggregated_bis_syncs = 0U;
1349
1350 if (param->broadcast_id > BT_AUDIO_BROADCAST_ID_MAX) {
1351 LOG_DBG("Invalid broadcast_id: %u", param->broadcast_id);
1352
1353 return false;
1354 }
1355
1356 if (param->num_subgroups > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
1357 LOG_WRN("Too many subgroups %u/%u",
1358 param->num_subgroups,
1359 CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
1360
1361 return false;
1362 }
1363
1364 for (uint8_t i = 0U; i < param->num_subgroups; i++) {
1365 const struct bt_bap_bass_subgroup *subgroup = ¶m->subgroups[i];
1366
1367 if (subgroup->bis_sync == BT_BAP_BIS_SYNC_NO_PREF ||
1368 !bis_syncs_unique_or_no_pref(subgroup->bis_sync,
1369 aggregated_bis_syncs)) {
1370 LOG_DBG("Invalid BIS sync: %u", subgroup->bis_sync);
1371
1372 return false;
1373 }
1374
1375 if (subgroup->metadata_len > CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE) {
1376 LOG_DBG("subgroup[%u]: Invalid metadata_len: %u",
1377 i, subgroup->metadata_len);
1378
1379 return false;
1380 }
1381 }
1382
1383 return true;
1384 }
1385
bt_bap_scan_delegator_mod_src(const struct bt_bap_scan_delegator_mod_src_param * param)1386 int bt_bap_scan_delegator_mod_src(const struct bt_bap_scan_delegator_mod_src_param *param)
1387 {
1388 struct bass_recv_state_internal *internal_state = NULL;
1389 struct bt_bap_scan_delegator_recv_state *state;
1390 bool state_changed = false;
1391
1392 CHECKIF(!valid_bt_bap_scan_delegator_mod_src_param(param)) {
1393 return -EINVAL;
1394 }
1395
1396 internal_state = bass_lookup_src_id(param->src_id);
1397 if (internal_state == NULL) {
1398 LOG_DBG("Could not find receive state with src_id %u", param->src_id);
1399
1400 return -ENOENT;
1401 }
1402
1403 state = &internal_state->state;
1404
1405 if (state->broadcast_id != param->broadcast_id) {
1406 state->broadcast_id = param->broadcast_id;
1407 state_changed = true;
1408 }
1409
1410 if (state->num_subgroups != param->num_subgroups) {
1411 state->num_subgroups = param->num_subgroups;
1412 state_changed = true;
1413 }
1414
1415 if (state->encrypt_state != param->encrypt_state) {
1416 state->encrypt_state = param->encrypt_state;
1417 state_changed = true;
1418 }
1419
1420 /* Verify that the BIS sync values is acceptable for the receive state */
1421 for (uint8_t i = 0U; i < state->num_subgroups; i++) {
1422 const uint32_t bis_sync = param->subgroups[i].bis_sync;
1423 const uint32_t bis_sync_requested = internal_state->requested_bis_sync[i];
1424
1425 if (!bits_subset_of(bis_sync, bis_sync_requested)) {
1426 LOG_DBG("Subgroup[%d] invalid bis_sync value %x for %x",
1427 i, bis_sync, bis_sync_requested);
1428
1429 return -EINVAL;
1430 }
1431 }
1432
1433 for (uint8_t i = 0U; i < state->num_subgroups; i++) {
1434 const struct bt_bap_bass_subgroup *param_subgroup = ¶m->subgroups[i];
1435 struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
1436
1437 if (subgroup->bis_sync != param_subgroup->bis_sync) {
1438 subgroup->bis_sync = param_subgroup->bis_sync;
1439 state_changed = true;
1440 }
1441
1442 /* If the metadata len is 0, we shall not overwrite the existing metadata */
1443 if (param_subgroup->metadata_len == 0U) {
1444 continue;
1445 }
1446
1447 if (subgroup->metadata_len != param_subgroup->metadata_len) {
1448 subgroup->metadata_len = param_subgroup->metadata_len;
1449 state_changed = true;
1450 }
1451
1452 if (subgroup->metadata_len != param_subgroup->metadata_len ||
1453 memcmp(subgroup->metadata, param_subgroup->metadata,
1454 param_subgroup->metadata_len) != 0) {
1455 (void)memcpy(subgroup->metadata,
1456 param_subgroup->metadata,
1457 param_subgroup->metadata_len);
1458 subgroup->metadata_len = param_subgroup->metadata_len;
1459 state_changed = true;
1460 }
1461 }
1462
1463 if (state_changed) {
1464 LOG_DBG("Index %u: Source modified: ID 0x%02x",
1465 internal_state->index, state->src_id);
1466
1467 receive_state_updated(NULL, internal_state);
1468 }
1469
1470 return 0;
1471 }
1472
bt_bap_scan_delegator_rem_src(uint8_t src_id)1473 int bt_bap_scan_delegator_rem_src(uint8_t src_id)
1474 {
1475 struct net_buf_simple buf;
1476
1477 net_buf_simple_init_with_data(&buf, (void *)&src_id, sizeof(src_id));
1478
1479 if (scan_delegator_rem_src(NULL, &buf) == 0) {
1480 return 0;
1481 } else {
1482 return -EINVAL;
1483 }
1484 }
1485
bt_bap_scan_delegator_foreach_state(bt_bap_scan_delegator_state_func_t func,void * user_data)1486 void bt_bap_scan_delegator_foreach_state(bt_bap_scan_delegator_state_func_t func, void *user_data)
1487 {
1488 for (size_t i = 0U; i < ARRAY_SIZE(scan_delegator.recv_states); i++) {
1489 if (scan_delegator.recv_states[i].active) {
1490 bool stop;
1491
1492 stop = func(&scan_delegator.recv_states[i].state, user_data);
1493 if (stop) {
1494 return;
1495 }
1496 }
1497 }
1498 }
1499
1500 struct scan_delegator_state_find_state_param {
1501 const struct bt_bap_scan_delegator_recv_state *recv_state;
1502 bt_bap_scan_delegator_state_func_t func;
1503 void *user_data;
1504 };
1505
1506 static bool
scan_delegator_state_find_state_cb(const struct bt_bap_scan_delegator_recv_state * recv_state,void * user_data)1507 scan_delegator_state_find_state_cb(const struct bt_bap_scan_delegator_recv_state *recv_state,
1508 void *user_data)
1509 {
1510 struct scan_delegator_state_find_state_param *param = user_data;
1511 bool found;
1512
1513 found = param->func(recv_state, param->user_data);
1514 if (found) {
1515 param->recv_state = recv_state;
1516
1517 return true;
1518 }
1519
1520 return false;
1521 }
1522
1523 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)1524 bt_bap_scan_delegator_find_state(bt_bap_scan_delegator_state_func_t func, void *user_data)
1525 {
1526 struct scan_delegator_state_find_state_param param = {
1527 .recv_state = NULL,
1528 .func = func,
1529 .user_data = user_data,
1530 };
1531
1532 bt_bap_scan_delegator_foreach_state(scan_delegator_state_find_state_cb, ¶m);
1533
1534 return param.recv_state;
1535 }
1536
bt_bap_scan_delegator_lookup_src_id(uint8_t src_id)1537 const struct bt_bap_scan_delegator_recv_state *bt_bap_scan_delegator_lookup_src_id(uint8_t src_id)
1538 {
1539 const struct bass_recv_state_internal *internal_state = bass_lookup_src_id(src_id);
1540
1541 if (internal_state != NULL) {
1542 return &internal_state->state;
1543 }
1544
1545 return NULL;
1546 }
1547