1 /* btp_bap_broadcast.c - Bluetooth BAP Tester */
2
3 /*
4 * Copyright (c) 2023 Codecoup
5 * Copyright (c) 2024 Nordic Semiconductor ASA
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10 #include <stddef.h>
11 #include <errno.h>
12
13 #include <zephyr/bluetooth/bluetooth.h>
14 #include <zephyr/bluetooth/iso.h>
15 #include <zephyr/types.h>
16 #include <zephyr/kernel.h>
17 #include <zephyr/sys/ring_buffer.h>
18 #include <zephyr/bluetooth/audio/audio.h>
19 #include <zephyr/bluetooth/gap.h>
20
21 #include "bap_endpoint.h"
22 #include <zephyr/logging/log.h>
23 #include <zephyr/sys/byteorder.h>
24 #define LOG_MODULE_NAME bttester_bap_broadcast
25 LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);
26 #include "btp/btp.h"
27 #include "btp_bap_audio_stream.h"
28 #include "btp_bap_broadcast.h"
29
30 static K_SEM_DEFINE(sem_stream_stopped, 0U, CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT);
31
32 static struct btp_bap_broadcast_remote_source remote_broadcast_sources[1];
33 static struct btp_bap_broadcast_local_source local_source;
34 /* Only one PA sync supported for now. */
35 static struct btp_bap_broadcast_remote_source *broadcast_source_to_sync;
36 /* A mask for the maximum BIS we can sync to. +1 since the BIS indexes start from 1. */
37 static const uint32_t bis_index_mask = BIT_MASK(CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT + 1);
38 #define PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO 20 /* Set the timeout relative to interval */
39 #define PA_SYNC_SKIP 5
40 static struct bt_bap_bass_subgroup
41 delegator_subgroups[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS];
42
stream_bap_to_broadcast(struct bt_bap_stream * stream)43 static inline struct btp_bap_broadcast_stream *stream_bap_to_broadcast(struct bt_bap_stream *stream)
44 {
45 return CONTAINER_OF(CONTAINER_OF(CONTAINER_OF(stream, struct bt_cap_stream, bap_stream),
46 struct btp_bap_audio_stream, cap_stream), struct btp_bap_broadcast_stream,
47 audio_stream);
48 }
49
stream_broadcast_to_bap(struct btp_bap_broadcast_stream * stream)50 static inline struct bt_bap_stream *stream_broadcast_to_bap(struct btp_bap_broadcast_stream *stream)
51 {
52 return &stream->audio_stream.cap_stream.bap_stream;
53 }
54
btp_bap_broadcast_local_source_get(uint8_t source_id)55 struct btp_bap_broadcast_local_source *btp_bap_broadcast_local_source_get(uint8_t source_id)
56 {
57 /* Only one local broadcast source supported for now */
58 (void) source_id;
59
60 return &local_source;
61 }
62
remote_broadcaster_alloc(void)63 static struct btp_bap_broadcast_remote_source *remote_broadcaster_alloc(void)
64 {
65 for (size_t i = 0; i < ARRAY_SIZE(remote_broadcast_sources); i++) {
66 struct btp_bap_broadcast_remote_source *broadcaster = &remote_broadcast_sources[i];
67
68 if (broadcaster->broadcast_id == BT_BAP_INVALID_BROADCAST_ID) {
69 return broadcaster;
70 }
71 }
72
73 return NULL;
74 }
75
remote_broadcaster_find(const bt_addr_le_t * addr,uint32_t broadcast_id)76 static struct btp_bap_broadcast_remote_source *remote_broadcaster_find(const bt_addr_le_t *addr,
77 uint32_t broadcast_id)
78 {
79 for (size_t i = 0; i < ARRAY_SIZE(remote_broadcast_sources); i++) {
80 struct btp_bap_broadcast_remote_source *broadcaster = &remote_broadcast_sources[i];
81
82 if (broadcaster->broadcast_id == broadcast_id &&
83 bt_addr_le_cmp(addr, &broadcaster->address) == 0) {
84 return broadcaster;
85 }
86 }
87
88 return NULL;
89 }
90
remote_broadcaster_find_by_sink(struct bt_bap_broadcast_sink * sink)91 static struct btp_bap_broadcast_remote_source *remote_broadcaster_find_by_sink(
92 struct bt_bap_broadcast_sink *sink)
93 {
94 for (size_t i = 0; i < ARRAY_SIZE(remote_broadcast_sources); i++) {
95 struct btp_bap_broadcast_remote_source *broadcaster = &remote_broadcast_sources[i];
96
97 if (broadcaster->sink == sink) {
98 return broadcaster;
99 }
100 }
101
102 return NULL;
103 }
104
btp_send_bis_syced_ev(const bt_addr_le_t * address,uint32_t broadcast_id,uint8_t bis_id)105 static void btp_send_bis_syced_ev(const bt_addr_le_t *address, uint32_t broadcast_id,
106 uint8_t bis_id)
107 {
108 struct btp_bap_bis_syned_ev ev;
109
110 bt_addr_le_copy(&ev.address, address);
111 sys_put_le24(broadcast_id, ev.broadcast_id);
112 ev.bis_id = bis_id;
113
114 tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BIS_SYNCED, &ev, sizeof(ev));
115 }
116
stream_started(struct bt_bap_stream * stream)117 static void stream_started(struct bt_bap_stream *stream)
118 {
119 struct btp_bap_broadcast_remote_source *broadcaster;
120 struct btp_bap_broadcast_stream *b_stream = stream_bap_to_broadcast(stream);
121 int err;
122
123 /* Callback called on transition to Streaming state */
124
125 LOG_DBG("Started stream %p", stream);
126
127 /* Start TX */
128 err = btp_bap_audio_stream_tx_register(&b_stream->audio_stream);
129 if (err != 0) {
130 LOG_ERR("Failed to register stream: %d", err);
131 }
132
133 b_stream->bis_synced = true;
134 broadcaster = &remote_broadcast_sources[b_stream->source_id];
135
136 btp_send_bis_syced_ev(&broadcaster->address, broadcaster->broadcast_id, b_stream->bis_id);
137 }
138
stream_stopped(struct bt_bap_stream * stream,uint8_t reason)139 static void stream_stopped(struct bt_bap_stream *stream, uint8_t reason)
140 {
141 struct btp_bap_broadcast_stream *b_stream = stream_bap_to_broadcast(stream);
142 int err;
143
144 LOG_DBG("Stopped stream %p with reason 0x%02X", stream, reason);
145
146 /* Stop TX */
147 err = btp_bap_audio_stream_tx_unregister(&b_stream->audio_stream);
148 if (err != 0) {
149 LOG_ERR("Failed to unregister stream: %d", err);
150 }
151
152 b_stream->bis_synced = false;
153
154 k_sem_give(&sem_stream_stopped);
155 }
156
send_bis_stream_received_ev(const bt_addr_le_t * address,uint32_t broadcast_id,uint8_t bis_id,uint8_t data_len,uint8_t * data)157 static void send_bis_stream_received_ev(const bt_addr_le_t *address, uint32_t broadcast_id,
158 uint8_t bis_id, uint8_t data_len, uint8_t *data)
159 {
160 struct btp_bap_bis_stream_received_ev *ev;
161
162 tester_rsp_buffer_lock();
163 tester_rsp_buffer_allocate(sizeof(*ev) + data_len, (uint8_t **)&ev);
164
165 LOG_DBG("Stream received, len %d", data_len);
166
167 bt_addr_le_copy(&ev->address, address);
168 sys_put_le24(broadcast_id, ev->broadcast_id);
169 ev->bis_id = bis_id;
170 ev->data_len = data_len;
171 memcpy(ev->data, data, data_len);
172
173 tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BIS_STREAM_RECEIVED, ev,
174 sizeof(*ev) + data_len);
175
176 tester_rsp_buffer_free();
177 tester_rsp_buffer_unlock();
178 }
179
stream_recv(struct bt_bap_stream * stream,const struct bt_iso_recv_info * info,struct net_buf * buf)180 static void stream_recv(struct bt_bap_stream *stream,
181 const struct bt_iso_recv_info *info,
182 struct net_buf *buf)
183 {
184 struct btp_bap_broadcast_remote_source *broadcaster;
185 struct btp_bap_broadcast_stream *b_stream = stream_bap_to_broadcast(stream);
186
187 if (b_stream->already_sent == false) {
188 /* For now, send just a first packet, to limit the number
189 * of logs and not unnecessarily spam through btp.
190 */
191 LOG_DBG("Incoming audio on stream %p len %u flags 0x%02X seq_num %u and ts %u",
192 stream, buf->len, info->flags, info->seq_num, info->ts);
193
194 if ((info->flags & BT_ISO_FLAGS_VALID) == 0) {
195 b_stream->already_sent = true;
196 broadcaster = &remote_broadcast_sources[b_stream->source_id];
197 send_bis_stream_received_ev(&broadcaster->address,
198 broadcaster->broadcast_id, b_stream->bis_id,
199 buf->len, buf->data);
200 }
201 }
202 }
203
204 static struct bt_bap_stream_ops stream_ops = {
205 .started = stream_started,
206 .stopped = stream_stopped,
207 .recv = stream_recv,
208 .sent = btp_bap_audio_stream_sent_cb,
209 };
210
btp_bap_broadcast_stream_alloc(struct btp_bap_broadcast_local_source * source)211 struct btp_bap_broadcast_stream *btp_bap_broadcast_stream_alloc(
212 struct btp_bap_broadcast_local_source *source)
213 {
214 for (size_t i = 0; i < ARRAY_SIZE(source->streams); i++) {
215 struct btp_bap_broadcast_stream *stream = &source->streams[i];
216
217 if (stream->in_use == false) {
218 bt_bap_stream_cb_register(stream_broadcast_to_bap(stream), &stream_ops);
219 stream->in_use = true;
220
221 return stream;
222 }
223 }
224
225 return NULL;
226 }
227
remote_broadcaster_free(struct btp_bap_broadcast_remote_source * broadcaster)228 static void remote_broadcaster_free(struct btp_bap_broadcast_remote_source *broadcaster)
229 {
230 (void)memset(broadcaster, 0, sizeof(*broadcaster));
231
232 broadcaster->broadcast_id = BT_BAP_INVALID_BROADCAST_ID;
233
234 for (size_t i = 0U; i < ARRAY_SIZE(broadcaster->sink_streams); i++) {
235 broadcaster->sink_streams[i] = stream_broadcast_to_bap(&broadcaster->streams[i]);
236 broadcaster->sink_streams[i]->ops = &stream_ops;
237 }
238 }
239
setup_broadcast_source(uint8_t streams_per_subgroup,uint8_t subgroups,struct btp_bap_broadcast_local_source * source,struct bt_audio_codec_cfg * codec_cfg)240 static int setup_broadcast_source(uint8_t streams_per_subgroup, uint8_t subgroups,
241 struct btp_bap_broadcast_local_source *source,
242 struct bt_audio_codec_cfg *codec_cfg)
243 {
244 int err;
245 struct bt_bap_broadcast_source_stream_param
246 stream_params[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT];
247 struct bt_bap_broadcast_source_subgroup_param
248 subgroup_param[CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT];
249 struct bt_bap_broadcast_source_param create_param;
250
251 if (streams_per_subgroup * subgroups > CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT ||
252 subgroups > CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT) {
253 return -EINVAL;
254 }
255
256 /* BIS Codec Specific Configuration will be specified on subgroup level,
257 * with a pointer, so let's store the codec_cfg in the first stream instance.
258 */
259 memcpy(&source->streams[0].codec_cfg, codec_cfg, sizeof(*codec_cfg));
260
261 for (size_t i = 0U; i < subgroups; i++) {
262 subgroup_param[i].params_count = streams_per_subgroup;
263 subgroup_param[i].params = stream_params + i * streams_per_subgroup;
264 subgroup_param[i].codec_cfg = &source->streams[0].codec_cfg;
265 }
266
267 for (size_t j = 0U; j < streams_per_subgroup; j++) {
268 struct btp_bap_broadcast_stream *b_stream = &source->streams[j];
269 struct bt_bap_stream *stream = stream_broadcast_to_bap(b_stream);
270
271 stream_params[j].stream = stream;
272 bt_bap_stream_cb_register(stream, &stream_ops);
273
274 /* BIS Codec Specific Configuration specified on subgroup level */
275 stream_params[j].data = NULL;
276 stream_params[j].data_len = 0U;
277 }
278
279 create_param.params_count = subgroups;
280 create_param.params = subgroup_param;
281 create_param.qos = &source->qos;
282 create_param.encryption = false;
283 create_param.packing = BT_ISO_PACKING_SEQUENTIAL;
284
285 LOG_DBG("Creating broadcast source with %zu subgroups with %zu streams",
286 subgroups, subgroups * streams_per_subgroup);
287
288 if (source->bap_broadcast == NULL) {
289 err = bt_bap_broadcast_source_create(&create_param,
290 &source->bap_broadcast);
291 if (err != 0) {
292 LOG_DBG("Unable to create broadcast source: %d", err);
293
294 return err;
295 }
296 } else {
297 err = bt_bap_broadcast_source_reconfig(source->bap_broadcast,
298 &create_param);
299 if (err != 0) {
300 LOG_DBG("Unable to reconfig broadcast source: %d", err);
301
302 return err;
303 }
304 }
305
306 return 0;
307 }
308
btp_bap_broadcast_source_setup(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)309 uint8_t btp_bap_broadcast_source_setup(const void *cmd, uint16_t cmd_len,
310 void *rsp, uint16_t *rsp_len)
311 {
312 struct bt_le_per_adv_param per_adv_param =
313 *BT_LE_PER_ADV_PARAM(BT_GAP_MS_TO_PER_ADV_INTERVAL(150),
314 BT_GAP_MS_TO_PER_ADV_INTERVAL(150), BT_LE_PER_ADV_OPT_NONE);
315 /* Zephyr Controller works best while Extended Advertising interval is a multiple
316 * of the ISO Interval minus 10 ms (max. advertising random delay). This is
317 * required to place the AUX_ADV_IND PDUs in a non-overlapping interval with the
318 * Broadcast ISO radio events.
319 */
320 struct bt_le_adv_param ext_adv_param =
321 *BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV, BT_GAP_MS_TO_ADV_INTERVAL(140),
322 BT_GAP_MS_TO_ADV_INTERVAL(140), NULL);
323 int err;
324 struct bt_audio_codec_cfg codec_cfg;
325 const struct btp_bap_broadcast_source_setup_cmd *cp = cmd;
326 struct btp_bap_broadcast_source_setup_rp *rp = rsp;
327 uint32_t broadcast_id;
328
329 /* Only one local source/BIG supported for now */
330 struct btp_bap_broadcast_local_source *source = &local_source;
331
332 uint32_t gap_settings = BIT(BTP_GAP_SETTINGS_DISCOVERABLE) |
333 BIT(BTP_GAP_SETTINGS_EXTENDED_ADVERTISING);
334
335 NET_BUF_SIMPLE_DEFINE(ad_buf, BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE);
336 NET_BUF_SIMPLE_DEFINE(base_buf, 128);
337
338 /* Broadcast Audio Streaming Endpoint advertising data */
339 struct bt_data base_ad[2];
340 struct bt_data per_ad;
341
342 LOG_DBG("");
343
344 memset(&codec_cfg, 0, sizeof(codec_cfg));
345 codec_cfg.id = cp->coding_format;
346 codec_cfg.vid = cp->vid;
347 codec_cfg.cid = cp->cid;
348 codec_cfg.data_len = cp->cc_ltvs_len;
349 memcpy(codec_cfg.data, cp->cc_ltvs, cp->cc_ltvs_len);
350
351 source->qos.phy = BT_BAP_QOS_CFG_2M;
352 source->qos.framing = cp->framing;
353 source->qos.rtn = cp->retransmission_num;
354 source->qos.latency = sys_le16_to_cpu(cp->max_transport_latency);
355 source->qos.interval = sys_get_le24(cp->sdu_interval);
356 source->qos.pd = sys_get_le24(cp->presentation_delay);
357 source->qos.sdu = sys_le16_to_cpu(cp->max_sdu);
358
359 source->stream_count = cp->subgroups * cp->streams_per_subgroup;
360
361 err = setup_broadcast_source(cp->streams_per_subgroup, cp->subgroups, source, &codec_cfg);
362 if (err != 0) {
363 LOG_DBG("Unable to setup broadcast source: %d", err);
364
365 return BTP_STATUS_FAILED;
366 }
367
368 err = bt_rand(&broadcast_id, BT_AUDIO_BROADCAST_ID_SIZE);
369 if (err) {
370 LOG_DBG("Unable to generate broadcast ID: %d\n", err);
371
372 return BTP_STATUS_FAILED;
373 }
374
375 /* Setup extended advertising data */
376 net_buf_simple_add_le16(&ad_buf, BT_UUID_BROADCAST_AUDIO_VAL);
377 net_buf_simple_add_le24(&ad_buf, broadcast_id);
378 base_ad[0].type = BT_DATA_SVC_DATA16;
379 base_ad[0].data_len = ad_buf.len;
380 base_ad[0].data = ad_buf.data;
381 base_ad[1].type = BT_DATA_NAME_COMPLETE;
382 base_ad[1].data_len = sizeof(CONFIG_BT_DEVICE_NAME) - 1;
383 base_ad[1].data = CONFIG_BT_DEVICE_NAME;
384 err = tester_gap_create_adv_instance(&ext_adv_param, BTP_GAP_ADDR_TYPE_IDENTITY, base_ad, 2,
385 NULL, 0, &gap_settings);
386 if (err != 0) {
387 LOG_DBG("Failed to create extended advertising instance: %d", err);
388
389 return BTP_STATUS_FAILED;
390 }
391
392 err = tester_gap_padv_configure(&per_adv_param);
393 if (err != 0) {
394 LOG_DBG("Failed to configure periodic advertising: %d", err);
395
396 return BTP_STATUS_FAILED;
397 }
398
399 err = bt_bap_broadcast_source_get_base(source->bap_broadcast, &base_buf);
400 if (err != 0) {
401 LOG_DBG("Failed to get encoded BASE: %d\n", err);
402
403 return BTP_STATUS_FAILED;
404 }
405
406 per_ad.type = BT_DATA_SVC_DATA16;
407 per_ad.data_len = base_buf.len;
408 per_ad.data = base_buf.data;
409 err = tester_gap_padv_set_data(&per_ad, 1);
410 if (err != 0) {
411 return BTP_STATUS_FAILED;
412 }
413
414 rp->gap_settings = gap_settings;
415 sys_put_le24(broadcast_id, rp->broadcast_id);
416 *rsp_len = sizeof(*rp) + 1;
417
418 return BTP_STATUS_SUCCESS;
419 }
420
btp_bap_broadcast_source_release(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)421 uint8_t btp_bap_broadcast_source_release(const void *cmd, uint16_t cmd_len,
422 void *rsp, uint16_t *rsp_len)
423 {
424 int err;
425 struct btp_bap_broadcast_local_source *source = &local_source;
426
427 LOG_DBG("");
428
429 err = bt_bap_broadcast_source_delete(source->bap_broadcast);
430 if (err != 0) {
431 LOG_DBG("Unable to delete broadcast source: %d", err);
432
433 return BTP_STATUS_FAILED;
434 }
435
436 memset(source, 0, sizeof(*source));
437
438 return BTP_STATUS_SUCCESS;
439 }
440
btp_bap_broadcast_adv_start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)441 uint8_t btp_bap_broadcast_adv_start(const void *cmd, uint16_t cmd_len,
442 void *rsp, uint16_t *rsp_len)
443 {
444 int err;
445 struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get();
446
447 LOG_DBG("");
448
449 if (ext_adv == NULL) {
450 return BTP_STATUS_FAILED;
451 }
452
453 err = tester_gap_start_ext_adv();
454 if (err != 0) {
455 return BTP_STATUS_FAILED;
456 }
457
458 err = tester_gap_padv_start();
459 if (err != 0) {
460 LOG_DBG("Unable to start periodic advertising: %d", err);
461
462 return BTP_STATUS_FAILED;
463 }
464
465 return BTP_STATUS_SUCCESS;
466 }
467
btp_bap_broadcast_adv_stop(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)468 uint8_t btp_bap_broadcast_adv_stop(const void *cmd, uint16_t cmd_len,
469 void *rsp, uint16_t *rsp_len)
470 {
471 int err;
472
473 LOG_DBG("");
474
475 err = tester_gap_padv_stop();
476 if (err != 0) {
477 return BTP_STATUS_FAILED;
478 }
479
480 err = tester_gap_stop_ext_adv();
481
482 return BTP_STATUS_VAL(err);
483 }
484
btp_bap_broadcast_source_start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)485 uint8_t btp_bap_broadcast_source_start(const void *cmd, uint16_t cmd_len,
486 void *rsp, uint16_t *rsp_len)
487 {
488 int err;
489 struct btp_bap_broadcast_local_source *source = &local_source;
490 struct bt_le_ext_adv *ext_adv = tester_gap_ext_adv_get();
491
492 LOG_DBG("");
493
494 if (ext_adv == NULL) {
495 return BTP_STATUS_FAILED;
496 }
497
498 err = bt_bap_broadcast_source_start(source->bap_broadcast, ext_adv);
499 if (err != 0) {
500 LOG_DBG("Unable to start broadcast source: %d", err);
501
502 return BTP_STATUS_FAILED;
503 }
504
505 return BTP_STATUS_SUCCESS;
506 }
507
btp_bap_broadcast_source_stop(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)508 uint8_t btp_bap_broadcast_source_stop(const void *cmd, uint16_t cmd_len,
509 void *rsp, uint16_t *rsp_len)
510 {
511 int err;
512 struct btp_bap_broadcast_local_source *source = &local_source;
513
514 LOG_DBG("");
515
516 k_sem_reset(&sem_stream_stopped);
517
518 err = bt_bap_broadcast_source_stop(source->bap_broadcast);
519 if (err != 0) {
520 LOG_DBG("Unable to stop broadcast source: %d", err);
521
522 return BTP_STATUS_FAILED;
523 }
524
525 for (int i = 0; i < source->stream_count; i++) {
526 err = k_sem_take(&sem_stream_stopped, K_MSEC(1000));
527 if (err != 0) {
528 LOG_DBG("Timed out waiting for stream nr %d to stop", i);
529
530 return BTP_STATUS_FAILED;
531 }
532 }
533
534 return BTP_STATUS_SUCCESS;
535 }
536
broadcast_sink_reset(void)537 static int broadcast_sink_reset(void)
538 {
539 for (size_t i = 0; i < ARRAY_SIZE(remote_broadcast_sources); i++) {
540 remote_broadcaster_free(&remote_broadcast_sources[i]);
541 }
542
543 return 0;
544 }
545
btp_send_baa_found_ev(const bt_addr_le_t * address,uint32_t broadcast_id,uint8_t sid,uint16_t interval)546 static void btp_send_baa_found_ev(const bt_addr_le_t *address, uint32_t broadcast_id,
547 uint8_t sid, uint16_t interval)
548 {
549 struct btp_bap_baa_found_ev ev;
550
551 bt_addr_le_copy(&ev.address, address);
552 sys_put_le24(broadcast_id, ev.broadcast_id);
553 ev.advertiser_sid = sid;
554 ev.padv_interval = sys_cpu_to_le16(interval);
555
556 tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BAA_FOUND, &ev, sizeof(ev));
557 }
558
baa_check(struct bt_data * data,void * user_data)559 static bool baa_check(struct bt_data *data, void *user_data)
560 {
561 const struct bt_le_scan_recv_info *info = user_data;
562 char le_addr[BT_ADDR_LE_STR_LEN];
563 struct bt_uuid_16 adv_uuid;
564 uint32_t broadcast_id;
565
566 /* Parse the scanned Broadcast Audio Announcement */
567
568 if (data->type != BT_DATA_SVC_DATA16) {
569 return true;
570 }
571
572 if (data->data_len < BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE) {
573 return true;
574 }
575
576 if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
577 return true;
578 }
579
580 if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO)) {
581 return true;
582 }
583
584 broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);
585
586 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
587
588 LOG_DBG("Found BAA with ID 0x%06X, addr %s, sid 0x%02X, interval 0x%04X",
589 broadcast_id, le_addr, info->sid, info->interval);
590
591 btp_send_baa_found_ev(info->addr, broadcast_id, info->sid, info->interval);
592
593 /* Stop parsing */
594 return false;
595 }
596
broadcast_scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad)597 static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad)
598 {
599 /* If 0 there is no periodic advertising. */
600 if (info->interval != 0U) {
601 bt_data_parse(ad, baa_check, (void *)info);
602 }
603 }
604
605 static struct bt_le_scan_cb bap_scan_cb = {
606 .recv = broadcast_scan_recv,
607 };
608
btp_send_bis_found_ev(const bt_addr_le_t * address,uint32_t broadcast_id,uint32_t pd,uint8_t subgroup_index,uint8_t bis_index,const struct bt_audio_codec_cfg * codec_cfg)609 static void btp_send_bis_found_ev(const bt_addr_le_t *address, uint32_t broadcast_id, uint32_t pd,
610 uint8_t subgroup_index, uint8_t bis_index,
611 const struct bt_audio_codec_cfg *codec_cfg)
612 {
613 struct btp_bap_bis_found_ev *ev;
614
615 tester_rsp_buffer_lock();
616 tester_rsp_buffer_allocate(sizeof(*ev) + codec_cfg->data_len, (uint8_t **)&ev);
617
618 bt_addr_le_copy(&ev->address, address);
619 sys_put_le24(broadcast_id, ev->broadcast_id);
620 sys_put_le24(pd, ev->presentation_delay);
621 ev->subgroup_id = subgroup_index;
622 ev->bis_id = bis_index;
623 ev->coding_format = codec_cfg->id;
624 ev->vid = sys_cpu_to_le16(codec_cfg->vid);
625 ev->cid = sys_cpu_to_le16(codec_cfg->cid);
626
627 ev->cc_ltvs_len = codec_cfg->data_len;
628 memcpy(ev->cc_ltvs, codec_cfg->data, ev->cc_ltvs_len);
629
630 tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BIS_FOUND, ev,
631 sizeof(*ev) + ev->cc_ltvs_len);
632
633 tester_rsp_buffer_free();
634 tester_rsp_buffer_unlock();
635 }
636
637 struct base_parse_data {
638 struct btp_bap_broadcast_remote_source *broadcaster;
639 uint32_t pd;
640 struct bt_audio_codec_cfg codec_cfg;
641 uint8_t subgroup_cnt;
642 uint32_t bis_bitfield;
643 size_t stream_cnt;
644 };
645
base_subgroup_bis_cb(const struct bt_bap_base_subgroup_bis * bis,void * user_data)646 static bool base_subgroup_bis_cb(const struct bt_bap_base_subgroup_bis *bis, void *user_data)
647 {
648 struct base_parse_data *parse_data = user_data;
649 struct bt_audio_codec_cfg *codec_cfg = &parse_data->codec_cfg;
650 struct btp_bap_broadcast_remote_source *broadcaster = parse_data->broadcaster;
651
652 parse_data->bis_bitfield |= BT_ISO_BIS_INDEX_BIT(bis->index);
653
654 if (parse_data->stream_cnt < ARRAY_SIZE(broadcaster->streams)) {
655 struct btp_bap_broadcast_stream *stream =
656 &broadcaster->streams[parse_data->stream_cnt++];
657
658 stream->bis_id = bis->index;
659 memcpy(&stream->codec_cfg, codec_cfg, sizeof(*codec_cfg));
660 }
661
662 btp_send_bis_found_ev(&broadcaster->address, broadcaster->broadcast_id, parse_data->pd,
663 parse_data->subgroup_cnt, bis->index, codec_cfg);
664
665 return true;
666 }
667
base_subgroup_cb(const struct bt_bap_base_subgroup * subgroup,void * user_data)668 static bool base_subgroup_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data)
669 {
670 struct base_parse_data *parse_data = user_data;
671 int err;
672
673 err = bt_bap_base_subgroup_codec_to_codec_cfg(subgroup, &parse_data->codec_cfg);
674 if (err != 0) {
675 LOG_DBG("Failed to retrieve codec config: %d", err);
676 return false;
677 }
678
679 err = bt_bap_base_subgroup_foreach_bis(subgroup, base_subgroup_bis_cb, user_data);
680 if (err != 0) {
681 LOG_DBG("Failed to parse all BIS: %d", err);
682 return false;
683 }
684
685 return true;
686 }
687
base_recv_cb(struct bt_bap_broadcast_sink * sink,const struct bt_bap_base * base,size_t base_size)688 static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base,
689 size_t base_size)
690 {
691 struct btp_bap_broadcast_remote_source *broadcaster;
692 struct base_parse_data parse_data = {0};
693 int ret;
694
695 LOG_DBG("");
696
697 broadcaster = remote_broadcaster_find_by_sink(sink);
698 if (broadcaster == NULL) {
699 LOG_ERR("Failed to find broadcaster");
700
701 return;
702 }
703
704 LOG_DBG("Received BASE: broadcast sink %p subgroups %u",
705 sink, bt_bap_base_get_subgroup_count(base));
706
707 ret = bt_bap_base_get_pres_delay(base);
708 if (ret < 0) {
709 LOG_ERR("Failed to get presentation delay: %d", ret);
710 return;
711 }
712
713 parse_data.broadcaster = broadcaster;
714 parse_data.pd = (uint32_t)ret;
715
716 ret = bt_bap_base_foreach_subgroup(base, base_subgroup_cb, &parse_data);
717 if (ret != 0) {
718 LOG_ERR("Failed to parse subgroups: %d", ret);
719 return;
720 }
721
722 broadcaster->bis_index_bitfield = parse_data.bis_bitfield & bis_index_mask;
723 LOG_DBG("bis_index_bitfield 0x%08x", broadcaster->bis_index_bitfield);
724 }
725
syncable_cb(struct bt_bap_broadcast_sink * sink,const struct bt_iso_biginfo * biginfo)726 static void syncable_cb(struct bt_bap_broadcast_sink *sink, const struct bt_iso_biginfo *biginfo)
727 {
728 int err;
729 uint32_t index_bitfield;
730 struct btp_bap_broadcast_remote_source *broadcaster = remote_broadcaster_find_by_sink(sink);
731
732 if (broadcaster == NULL) {
733 LOG_ERR("remote_broadcaster_find_by_sink failed, %p", sink);
734
735 return;
736 }
737
738 LOG_DBG("Broadcaster PA found, encrypted %d, requested_bis_sync %d", biginfo->encryption,
739 broadcaster->requested_bis_sync);
740
741 if (biginfo->encryption) {
742 /* Wait for Set Broadcast Code and start sync at broadcast_code_cb */
743 return;
744 }
745
746 if (!broadcaster->assistant_request || !broadcaster->requested_bis_sync) {
747 /* No sync with any BIS was requested yet */
748 return;
749 }
750
751 index_bitfield = broadcaster->bis_index_bitfield & broadcaster->requested_bis_sync;
752 err = bt_bap_broadcast_sink_sync(broadcaster->sink, index_bitfield,
753 broadcaster->sink_streams,
754 broadcaster->sink_broadcast_code);
755 if (err != 0) {
756 LOG_DBG("Unable to sync to broadcast source: %d", err);
757 }
758
759 broadcaster->assistant_request = false;
760 }
761
762 static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = {
763 .base_recv = base_recv_cb,
764 .syncable = syncable_cb,
765 };
766
pa_timer_handler(struct k_work * work)767 static void pa_timer_handler(struct k_work *work)
768 {
769 if (broadcast_source_to_sync != NULL) {
770 enum bt_bap_pa_state pa_state;
771 const struct bt_bap_scan_delegator_recv_state *recv_state =
772 broadcast_source_to_sync->sink_recv_state;
773
774 if (recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
775 pa_state = BT_BAP_PA_STATE_NO_PAST;
776 } else {
777 pa_state = BT_BAP_PA_STATE_FAILED;
778 }
779
780 bt_bap_scan_delegator_set_pa_state(recv_state->src_id, pa_state);
781 }
782
783 LOG_DBG("PA timeout");
784 }
785
786 static K_WORK_DELAYABLE_DEFINE(pa_timer, pa_timer_handler);
787
bap_pa_sync_synced_cb(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)788 static void bap_pa_sync_synced_cb(struct bt_le_per_adv_sync *sync,
789 struct bt_le_per_adv_sync_synced_info *info)
790 {
791 int err;
792
793 LOG_DBG("Sync info: service_data 0x%04X", info->service_data);
794
795 k_work_cancel_delayable(&pa_timer);
796
797 /* We are synced to a PA. We know that this is the Broadcaster PA we wanted
798 * to sync to, because we support only one sync for now.
799 */
800 if (broadcast_source_to_sync == NULL) {
801 LOG_DBG("Failed to create broadcast sink, NULL ptr");
802
803 return;
804 }
805
806 /* In order to parse the BASE and BIG Info from the Broadcast PA, we have to create
807 * a Broadcast Sink instance. From now on callbacks of the broadcast_sink_cbs will be used.
808 */
809 err = bt_bap_broadcast_sink_create(sync, broadcast_source_to_sync->broadcast_id,
810 &broadcast_source_to_sync->sink);
811 if (err != 0) {
812 LOG_DBG("Failed to create broadcast sink: ID 0x%06X, err %d",
813 broadcast_source_to_sync->broadcast_id, err);
814 }
815
816 broadcast_source_to_sync = NULL;
817 }
818
819 static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = {
820 .synced = bap_pa_sync_synced_cb,
821 };
822
btp_send_pas_sync_req_ev(struct bt_conn * conn,uint8_t src_id,uint8_t advertiser_sid,uint32_t broadcast_id,bool past_avail,uint16_t pa_interval)823 static void btp_send_pas_sync_req_ev(struct bt_conn *conn, uint8_t src_id,
824 uint8_t advertiser_sid, uint32_t broadcast_id,
825 bool past_avail, uint16_t pa_interval)
826 {
827 struct btp_bap_pa_sync_req_ev ev;
828
829 bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
830 ev.src_id = src_id;
831 ev.advertiser_sid = advertiser_sid;
832 sys_put_le24(broadcast_id, ev.broadcast_id);
833 ev.past_avail = past_avail;
834 ev.pa_interval = sys_cpu_to_le16(pa_interval);
835
836 tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_PA_SYNC_REQ, &ev, sizeof(ev));
837 }
838
btp_send_scan_delegator_found_ev(struct bt_conn * conn)839 static void btp_send_scan_delegator_found_ev(struct bt_conn *conn)
840 {
841 struct btp_bap_scan_delegator_found_ev ev;
842
843 bt_addr_le_copy(&ev.address, bt_conn_get_dst(conn));
844
845 tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_SCAN_DELEGATOR_FOUND, &ev, sizeof(ev));
846 }
847
btp_send_broadcast_receive_state_ev(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * state)848 static void btp_send_broadcast_receive_state_ev(struct bt_conn *conn,
849 const struct bt_bap_scan_delegator_recv_state *state)
850 {
851 struct btp_bap_broadcast_receive_state_ev *ev;
852 size_t len;
853 uint8_t *ptr;
854
855 tester_rsp_buffer_lock();
856 tester_rsp_buffer_allocate(sizeof(*ev) + CONFIG_BT_BAP_BASS_MAX_SUBGROUPS *
857 sizeof(struct bt_bap_bass_subgroup), (uint8_t **)&ev);
858
859 if (conn) {
860 bt_addr_le_copy(&ev->address, bt_conn_get_dst(conn));
861 } else {
862 (void)memset(&ev->address, 0, sizeof(ev->address));
863 }
864
865 ev->src_id = state->src_id;
866 bt_addr_le_copy(&ev->broadcaster_address, &state->addr);
867 ev->advertiser_sid = state->adv_sid;
868 sys_put_le24(state->broadcast_id, ev->broadcast_id);
869 ev->pa_sync_state = state->pa_sync_state;
870 ev->big_encryption = state->encrypt_state;
871 ev->num_subgroups = state->num_subgroups;
872
873 ptr = ev->subgroups;
874 for (uint8_t i = 0; i < ev->num_subgroups; i++) {
875 const struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
876
877 sys_put_le32(subgroup->bis_sync >> 1, ptr);
878 ptr += sizeof(subgroup->bis_sync);
879 *ptr = subgroup->metadata_len;
880 ptr += sizeof(subgroup->metadata_len);
881 memcpy(ptr, subgroup->metadata, subgroup->metadata_len);
882 ptr += subgroup->metadata_len;
883 }
884
885 len = sizeof(*ev) + ptr - ev->subgroups;
886 tester_event(BTP_SERVICE_ID_BAP, BTP_BAP_EV_BROADCAST_RECEIVE_STATE, ev, len);
887
888 tester_rsp_buffer_free();
889 tester_rsp_buffer_unlock();
890 }
891
pa_sync_past(struct bt_conn * conn,uint16_t sync_timeout)892 static int pa_sync_past(struct bt_conn *conn, uint16_t sync_timeout)
893 {
894 struct bt_le_per_adv_sync_transfer_param param = { 0 };
895 int err;
896
897 param.skip = PA_SYNC_SKIP;
898 param.timeout = sync_timeout;
899
900 err = bt_le_per_adv_sync_transfer_subscribe(conn, ¶m);
901 if (err != 0) {
902 LOG_DBG("Could not do PAST subscribe: %d", err);
903 } else {
904 LOG_DBG("Syncing with PAST: %d", err);
905 (void)k_work_reschedule(&pa_timer, K_MSEC(param.timeout * 10));
906 }
907
908 return err;
909 }
910
pa_sync_req_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state,bool past_avail,uint16_t pa_interval)911 static int pa_sync_req_cb(struct bt_conn *conn,
912 const struct bt_bap_scan_delegator_recv_state *recv_state,
913 bool past_avail, uint16_t pa_interval)
914 {
915 struct btp_bap_broadcast_remote_source *broadcaster;
916
917 LOG_DBG("sync state %d ", recv_state->pa_sync_state);
918
919 broadcaster = remote_broadcaster_find(&recv_state->addr, recv_state->broadcast_id);
920 if (broadcaster == NULL) {
921 /* The Broadcast Assistant gave us the info about the Broadcaster, we have not
922 * scanned this Broadcaster before. The Broadcast Sink does not exist yet.
923 */
924
925 broadcaster = remote_broadcaster_alloc();
926 if (broadcaster == NULL) {
927 LOG_ERR("Failed to allocate broadcast source");
928 return -EINVAL;
929 }
930
931 broadcaster->broadcast_id = recv_state->broadcast_id;
932 bt_addr_le_copy(&broadcaster->address, &recv_state->addr);
933 }
934
935 broadcaster->sink_recv_state = recv_state;
936
937 btp_send_pas_sync_req_ev(conn, recv_state->src_id, recv_state->adv_sid,
938 recv_state->broadcast_id, past_avail, pa_interval);
939
940 return 0;
941 }
942
pa_sync_term_req_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state)943 static int pa_sync_term_req_cb(struct bt_conn *conn,
944 const struct bt_bap_scan_delegator_recv_state *recv_state)
945 {
946 struct btp_bap_broadcast_remote_source *broadcaster;
947
948 LOG_DBG("");
949
950 broadcaster = remote_broadcaster_find(&recv_state->addr, recv_state->broadcast_id);
951 if (broadcaster == NULL) {
952 LOG_ERR("Failed to find broadcaster");
953
954 return -EINVAL;
955 }
956
957 broadcaster->sink_recv_state = recv_state;
958
959 tester_gap_padv_stop_sync();
960
961 return 0;
962 }
963
broadcast_code_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state,const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])964 static void broadcast_code_cb(struct bt_conn *conn,
965 const struct bt_bap_scan_delegator_recv_state *recv_state,
966 const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])
967 {
968 int err;
969 uint32_t index_bitfield;
970 struct btp_bap_broadcast_remote_source *broadcaster;
971
972 LOG_DBG("Broadcast code received for %p", recv_state);
973
974 broadcaster = remote_broadcaster_find(&recv_state->addr, recv_state->broadcast_id);
975 if (broadcaster == NULL) {
976 LOG_ERR("Failed to find broadcaster");
977
978 return;
979 }
980
981 broadcaster->sink_recv_state = recv_state;
982 (void)memcpy(broadcaster->sink_broadcast_code, broadcast_code, BT_ISO_BROADCAST_CODE_SIZE);
983
984 if (!broadcaster->requested_bis_sync) {
985 return;
986 }
987
988 index_bitfield = broadcaster->bis_index_bitfield & broadcaster->requested_bis_sync;
989 err = bt_bap_broadcast_sink_sync(broadcaster->sink, index_bitfield,
990 broadcaster->sink_streams,
991 broadcaster->sink_broadcast_code);
992 if (err != 0) {
993 LOG_DBG("Unable to sync to broadcast source: %d", err);
994 }
995 }
996
bis_sync_req_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state,const uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])997 static int bis_sync_req_cb(struct bt_conn *conn,
998 const struct bt_bap_scan_delegator_recv_state *recv_state,
999 const uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])
1000 {
1001 struct btp_bap_broadcast_remote_source *broadcaster;
1002 bool bis_synced = false;
1003
1004 LOG_DBG("BIS sync request received for %p: 0x%08x", recv_state, bis_sync_req[0]);
1005
1006 broadcaster = remote_broadcaster_find(&recv_state->addr, recv_state->broadcast_id);
1007 if (broadcaster == NULL) {
1008 LOG_ERR("Failed to find broadcaster");
1009
1010 return -EINVAL;
1011 }
1012
1013 broadcaster->requested_bis_sync = bis_sync_req[0];
1014 broadcaster->assistant_request = true;
1015
1016 for (int i = 0; i < ARRAY_SIZE(broadcaster->streams); i++) {
1017 if (broadcaster->streams[i].bis_synced) {
1018 bis_synced = true;
1019 break;
1020 }
1021 }
1022
1023 /* We only care about a single subgroup in this sample */
1024 if (bis_synced) {
1025 /* If the BIS sync request is received while we are already
1026 * synced, it means that the requested BIS sync has changed.
1027 */
1028 int err;
1029
1030 /* The stream stopped callback will be called as part of this,
1031 * and we do not need to wait for any events from the
1032 * controller. Thus, when this returns, the `bis_synced`
1033 * is back to false.
1034 */
1035 err = bt_bap_broadcast_sink_stop(broadcaster->sink);
1036 if (err != 0) {
1037 LOG_DBG("Failed to stop Broadcast Sink: %d", err);
1038
1039 return err;
1040 }
1041 }
1042
1043 return 0;
1044 }
1045
recv_state_updated_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state)1046 static void recv_state_updated_cb(struct bt_conn *conn,
1047 const struct bt_bap_scan_delegator_recv_state *recv_state)
1048 {
1049 LOG_DBG("Receive state with ID %u updated", recv_state->src_id);
1050
1051 btp_send_broadcast_receive_state_ev(conn, recv_state);
1052 }
1053
1054 static struct bt_bap_scan_delegator_cb scan_delegator_cbs = {
1055 .recv_state_updated = recv_state_updated_cb,
1056 .pa_sync_req = pa_sync_req_cb,
1057 .pa_sync_term_req = pa_sync_term_req_cb,
1058 .broadcast_code = broadcast_code_cb,
1059 .bis_sync_req = bis_sync_req_cb,
1060 };
1061
btp_bap_broadcast_sink_setup(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1062 uint8_t btp_bap_broadcast_sink_setup(const void *cmd, uint16_t cmd_len,
1063 void *rsp, uint16_t *rsp_len)
1064 {
1065 int err;
1066
1067 LOG_DBG("");
1068
1069 err = broadcast_sink_reset();
1070 if (err != 0) {
1071 return BTP_STATUS_FAILED;
1072 }
1073
1074 /* For Scan Delegator role */
1075 err = bt_bap_scan_delegator_register(&scan_delegator_cbs);
1076 if (err != 0) {
1077 return BTP_STATUS_FAILED;
1078 }
1079
1080 /* For Broadcast Sink role */
1081 bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs);
1082 bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb);
1083
1084 /* For Broadcast Sink or Broadcast Assistant role */
1085 bt_le_scan_cb_register(&bap_scan_cb);
1086
1087 return BTP_STATUS_SUCCESS;
1088 }
1089
btp_bap_broadcast_sink_release(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1090 uint8_t btp_bap_broadcast_sink_release(const void *cmd, uint16_t cmd_len,
1091 void *rsp, uint16_t *rsp_len)
1092 {
1093 int err;
1094
1095 LOG_DBG("");
1096
1097 err = broadcast_sink_reset();
1098
1099 return BTP_STATUS_VAL(err);
1100 }
1101
btp_bap_broadcast_scan_start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1102 uint8_t btp_bap_broadcast_scan_start(const void *cmd, uint16_t cmd_len,
1103 void *rsp, uint16_t *rsp_len)
1104 {
1105 int err;
1106
1107 LOG_DBG("");
1108
1109 err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL);
1110 if (err != 0 && err != -EALREADY) {
1111 LOG_DBG("Unable to start scan for broadcast sources: %d", err);
1112
1113 return BTP_STATUS_FAILED;
1114 }
1115
1116 return BTP_STATUS_SUCCESS;
1117 }
1118
btp_bap_broadcast_scan_stop(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1119 uint8_t btp_bap_broadcast_scan_stop(const void *cmd, uint16_t cmd_len,
1120 void *rsp, uint16_t *rsp_len)
1121 {
1122 int err;
1123
1124 LOG_DBG("");
1125
1126 err = bt_le_scan_stop();
1127 if (err != 0) {
1128 LOG_DBG("Failed to stop scan, %d", err);
1129
1130 return BTP_STATUS_FAILED;
1131 }
1132
1133 return BTP_STATUS_SUCCESS;
1134 }
1135
btp_bap_broadcast_sink_sync(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1136 uint8_t btp_bap_broadcast_sink_sync(const void *cmd, uint16_t cmd_len,
1137 void *rsp, uint16_t *rsp_len)
1138 {
1139 int err;
1140 struct bt_conn *conn;
1141 struct btp_bap_broadcast_remote_source *broadcaster;
1142 const struct btp_bap_broadcast_sink_sync_cmd *cp = cmd;
1143 struct bt_le_per_adv_sync_param create_params = {0};
1144 uint32_t broadcast_id = sys_get_le24(cp->broadcast_id);
1145
1146 LOG_DBG("");
1147
1148 broadcaster = remote_broadcaster_find(&cp->address, broadcast_id);
1149 if (broadcaster == NULL) {
1150 broadcaster = remote_broadcaster_alloc();
1151 if (broadcaster == NULL) {
1152 LOG_ERR("Failed to allocate broadcast source");
1153 return BTP_STATUS_FAILED;
1154 }
1155
1156 broadcaster->broadcast_id = broadcast_id;
1157 bt_addr_le_copy(&broadcaster->address, &cp->address);
1158 }
1159
1160 broadcast_source_to_sync = broadcaster;
1161
1162 if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER) && cp->past_avail) {
1163 /* The Broadcast Assistant supports PAST transfer, and it has found
1164 * a Broadcaster for us. Let's sync to the Broadcaster PA with the PAST.
1165 */
1166
1167 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1168 if (!conn) {
1169 broadcast_source_to_sync = NULL;
1170
1171 return BTP_STATUS_FAILED;
1172 }
1173
1174 err = bt_bap_scan_delegator_set_pa_state(cp->src_id, BT_BAP_PA_STATE_INFO_REQ);
1175 if (err != 0) {
1176 LOG_DBG("Failed to set INFO_REQ state: %d", err);
1177 }
1178
1179 err = pa_sync_past(conn, cp->sync_timeout);
1180 } else {
1181 /* We scanned on our own or the Broadcast Assistant does not support PAST transfer.
1182 * Let's sync to the Broadcaster PA without PAST.
1183 */
1184 bt_addr_le_copy(&create_params.addr, &cp->address);
1185 create_params.options = 0;
1186 create_params.sid = cp->advertiser_sid;
1187 create_params.skip = cp->skip;
1188 create_params.timeout = cp->sync_timeout;
1189 err = tester_gap_padv_create_sync(&create_params);
1190 }
1191
1192 if (err != 0) {
1193 broadcast_source_to_sync = NULL;
1194
1195 return BTP_STATUS_FAILED;
1196 }
1197
1198 return BTP_STATUS_SUCCESS;
1199 }
1200
btp_bap_broadcast_sink_stop(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1201 uint8_t btp_bap_broadcast_sink_stop(const void *cmd, uint16_t cmd_len,
1202 void *rsp, uint16_t *rsp_len)
1203 {
1204 int err;
1205 struct btp_bap_broadcast_remote_source *broadcaster;
1206 const struct btp_bap_broadcast_sink_stop_cmd *cp = cmd;
1207 uint32_t broadcast_id = sys_get_le24(cp->broadcast_id);
1208
1209 LOG_DBG("");
1210
1211 broadcaster = remote_broadcaster_find(&cp->address, broadcast_id);
1212 if (broadcaster == NULL) {
1213 LOG_ERR("Failed to find broadcaster");
1214
1215 return BTP_STATUS_FAILED;
1216 }
1217
1218 broadcaster->requested_bis_sync = 0;
1219
1220 err = bt_bap_broadcast_sink_stop(broadcaster->sink);
1221 if (err != 0) {
1222 LOG_DBG("Unable to sync to broadcast source: %d", err);
1223
1224 return BTP_STATUS_FAILED;
1225 }
1226
1227 err = tester_gap_padv_stop_sync();
1228 if (err != 0) {
1229 LOG_DBG("Failed to stop PA sync, %d", err);
1230
1231 return BTP_STATUS_FAILED;
1232 }
1233
1234 return BTP_STATUS_SUCCESS;
1235 }
1236
btp_bap_broadcast_sink_bis_sync(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1237 uint8_t btp_bap_broadcast_sink_bis_sync(const void *cmd, uint16_t cmd_len,
1238 void *rsp, uint16_t *rsp_len)
1239 {
1240 int err;
1241 struct btp_bap_broadcast_remote_source *broadcaster;
1242 const struct btp_bap_broadcast_sink_bis_sync_cmd *cp = cmd;
1243
1244 LOG_DBG("");
1245
1246 broadcaster = remote_broadcaster_find(&cp->address, sys_get_le24(cp->broadcast_id));
1247 if (broadcaster == NULL) {
1248 LOG_ERR("Failed to find broadcaster");
1249
1250 return BTP_STATUS_FAILED;
1251 }
1252
1253 broadcaster->requested_bis_sync = sys_le32_to_cpu(cp->requested_bis_sync);
1254
1255 err = bt_bap_broadcast_sink_sync(broadcaster->sink, broadcaster->requested_bis_sync,
1256 broadcaster->sink_streams,
1257 broadcaster->sink_broadcast_code);
1258 if (err != 0) {
1259 LOG_DBG("Unable to sync to BISes, req_bis_sync %d, err %d",
1260 broadcaster->requested_bis_sync, err);
1261
1262 return BTP_STATUS_FAILED;
1263 }
1264
1265 return BTP_STATUS_SUCCESS;
1266 }
1267
bap_broadcast_assistant_discover_cb(struct bt_conn * conn,int err,uint8_t recv_state_count)1268 static void bap_broadcast_assistant_discover_cb(struct bt_conn *conn, int err,
1269 uint8_t recv_state_count)
1270 {
1271 LOG_DBG("err %d", err);
1272
1273 if (err != 0) {
1274 LOG_DBG("BASS discover failed (%d)", err);
1275 } else {
1276 LOG_DBG("BASS discover done with %u recv states", recv_state_count);
1277
1278 btp_send_scan_delegator_found_ev(conn);
1279 }
1280 }
1281
bap_broadcast_assistant_scan_cb(const struct bt_le_scan_recv_info * info,uint32_t broadcast_id)1282 static void bap_broadcast_assistant_scan_cb(const struct bt_le_scan_recv_info *info,
1283 uint32_t broadcast_id)
1284 {
1285 char le_addr[BT_ADDR_LE_STR_LEN];
1286
1287 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
1288 LOG_DBG("[DEVICE]: %s, broadcast_id 0x%06X, interval (ms) %u (0x%04x)), SID 0x%x, RSSI %i",
1289 le_addr, broadcast_id, BT_GAP_PER_ADV_INTERVAL_TO_MS(info->interval),
1290 info->interval, info->sid, info->rssi);
1291 }
1292
bap_broadcast_assistant_recv_state_cb(struct bt_conn * conn,int err,const struct bt_bap_scan_delegator_recv_state * state)1293 static void bap_broadcast_assistant_recv_state_cb(struct bt_conn *conn, int err,
1294 const struct bt_bap_scan_delegator_recv_state *state)
1295 {
1296 LOG_DBG("err: %d", err);
1297
1298 if (err != 0 || state == NULL) {
1299 return;
1300 }
1301
1302 btp_send_broadcast_receive_state_ev(conn, state);
1303 }
1304
bap_broadcast_assistant_recv_state_removed_cb(struct bt_conn * conn,uint8_t src_id)1305 static void bap_broadcast_assistant_recv_state_removed_cb(struct bt_conn *conn, uint8_t src_id)
1306 {
1307 LOG_DBG("");
1308 }
1309
bap_broadcast_assistant_scan_start_cb(struct bt_conn * conn,int err)1310 static void bap_broadcast_assistant_scan_start_cb(struct bt_conn *conn, int err)
1311 {
1312 LOG_DBG("err: %d", err);
1313 }
1314
bap_broadcast_assistant_scan_stop_cb(struct bt_conn * conn,int err)1315 static void bap_broadcast_assistant_scan_stop_cb(struct bt_conn *conn, int err)
1316 {
1317 LOG_DBG("err: %d", err);
1318 }
1319
bap_broadcast_assistant_add_src_cb(struct bt_conn * conn,int err)1320 static void bap_broadcast_assistant_add_src_cb(struct bt_conn *conn, int err)
1321 {
1322 LOG_DBG("err: %d", err);
1323 }
1324
bap_broadcast_assistant_mod_src_cb(struct bt_conn * conn,int err)1325 static void bap_broadcast_assistant_mod_src_cb(struct bt_conn *conn, int err)
1326 {
1327 LOG_DBG("err: %d", err);
1328 }
1329
bap_broadcast_assistant_broadcast_code_cb(struct bt_conn * conn,int err)1330 static void bap_broadcast_assistant_broadcast_code_cb(struct bt_conn *conn, int err)
1331 {
1332 LOG_DBG("err: %d", err);
1333 }
1334
bap_broadcast_assistant_rem_src_cb(struct bt_conn * conn,int err)1335 static void bap_broadcast_assistant_rem_src_cb(struct bt_conn *conn, int err)
1336 {
1337 LOG_DBG("err: %d", err);
1338 }
1339
1340 static struct bt_bap_broadcast_assistant_cb broadcast_assistant_cb = {
1341 .discover = bap_broadcast_assistant_discover_cb,
1342 .scan = bap_broadcast_assistant_scan_cb,
1343 .recv_state = bap_broadcast_assistant_recv_state_cb,
1344 .recv_state_removed = bap_broadcast_assistant_recv_state_removed_cb,
1345 .scan_start = bap_broadcast_assistant_scan_start_cb,
1346 .scan_stop = bap_broadcast_assistant_scan_stop_cb,
1347 .add_src = bap_broadcast_assistant_add_src_cb,
1348 .mod_src = bap_broadcast_assistant_mod_src_cb,
1349 .broadcast_code = bap_broadcast_assistant_broadcast_code_cb,
1350 .rem_src = bap_broadcast_assistant_rem_src_cb,
1351 };
1352
btp_bap_broadcast_discover_scan_delegators(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1353 uint8_t btp_bap_broadcast_discover_scan_delegators(const void *cmd, uint16_t cmd_len,
1354 void *rsp, uint16_t *rsp_len)
1355 {
1356 int err;
1357 struct bt_conn *conn;
1358 const struct btp_bap_discover_scan_delegators_cmd *cp = cmd;
1359
1360 LOG_DBG("");
1361
1362 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1363 if (!conn) {
1364 return BTP_STATUS_FAILED;
1365 }
1366
1367 err = bt_bap_broadcast_assistant_discover(conn);
1368
1369 return BTP_STATUS_VAL(err);
1370 }
1371
btp_bap_broadcast_assistant_scan_start(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1372 uint8_t btp_bap_broadcast_assistant_scan_start(const void *cmd, uint16_t cmd_len,
1373 void *rsp, uint16_t *rsp_len)
1374 {
1375 int err;
1376 struct bt_conn *conn;
1377 const struct btp_bap_broadcast_assistant_scan_start_cmd *cp = cmd;
1378
1379 LOG_DBG("");
1380
1381 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1382 if (!conn) {
1383 return BTP_STATUS_FAILED;
1384 }
1385
1386 err = bt_bap_broadcast_assistant_scan_start(conn, true);
1387
1388 return BTP_STATUS_VAL(err);
1389 }
1390
btp_bap_broadcast_assistant_scan_stop(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1391 uint8_t btp_bap_broadcast_assistant_scan_stop(const void *cmd, uint16_t cmd_len,
1392 void *rsp, uint16_t *rsp_len)
1393 {
1394 int err;
1395 struct bt_conn *conn;
1396 const struct btp_bap_broadcast_assistant_scan_stop_cmd *cp = cmd;
1397
1398 LOG_DBG("");
1399
1400 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1401 if (!conn) {
1402 return BTP_STATUS_FAILED;
1403 }
1404
1405 err = bt_bap_broadcast_assistant_scan_stop(conn);
1406
1407 return BTP_STATUS_VAL(err);
1408 }
1409
btp_bap_broadcast_assistant_add_src(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1410 uint8_t btp_bap_broadcast_assistant_add_src(const void *cmd, uint16_t cmd_len,
1411 void *rsp, uint16_t *rsp_len)
1412 {
1413 int err;
1414 const uint8_t *ptr;
1415 struct bt_conn *conn;
1416 const struct btp_bap_add_broadcast_src_cmd *cp = cmd;
1417 struct bt_bap_broadcast_assistant_add_src_param param = { 0 };
1418
1419 LOG_DBG("");
1420
1421 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1422 if (!conn) {
1423 return BTP_STATUS_FAILED;
1424 }
1425
1426 memset(delegator_subgroups, 0, sizeof(delegator_subgroups));
1427 bt_addr_le_copy(¶m.addr, &cp->broadcaster_address);
1428 param.adv_sid = cp->advertiser_sid;
1429 param.pa_sync = cp->padv_sync > 0 ? true : false;
1430 param.broadcast_id = sys_get_le24(cp->broadcast_id);
1431 param.pa_interval = sys_le16_to_cpu(cp->padv_interval);
1432 param.num_subgroups = MIN(cp->num_subgroups, CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
1433 param.subgroups = delegator_subgroups;
1434
1435 ptr = cp->subgroups;
1436 for (uint8_t i = 0; i < param.num_subgroups; i++) {
1437 struct bt_bap_bass_subgroup *subgroup = &delegator_subgroups[i];
1438
1439 subgroup->bis_sync = sys_get_le32(ptr);
1440 if (subgroup->bis_sync != BT_BAP_BIS_SYNC_NO_PREF) {
1441 /* For semantic purposes Zephyr API uses BIS Index bitfield
1442 * where BIT(1) means BIS Index 1
1443 */
1444 subgroup->bis_sync <<= 1;
1445 }
1446
1447 ptr += sizeof(subgroup->bis_sync);
1448 subgroup->metadata_len = *ptr;
1449 ptr += sizeof(subgroup->metadata_len);
1450 memcpy(subgroup->metadata, ptr, subgroup->metadata_len);
1451 ptr += subgroup->metadata_len;
1452 }
1453
1454 err = bt_bap_broadcast_assistant_add_src(conn, ¶m);
1455 if (err != 0) {
1456 LOG_DBG("err %d", err);
1457
1458 return BTP_STATUS_FAILED;
1459 }
1460
1461 return BTP_STATUS_SUCCESS;
1462 }
1463
btp_bap_broadcast_assistant_remove_src(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1464 uint8_t btp_bap_broadcast_assistant_remove_src(const void *cmd, uint16_t cmd_len,
1465 void *rsp, uint16_t *rsp_len)
1466 {
1467 int err;
1468 struct bt_conn *conn;
1469 const struct btp_bap_remove_broadcast_src_cmd *cp = cmd;
1470
1471 LOG_DBG("");
1472
1473 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1474 if (!conn) {
1475 return BTP_STATUS_FAILED;
1476 }
1477
1478 err = bt_bap_broadcast_assistant_rem_src(conn, cp->src_id);
1479
1480 return BTP_STATUS_VAL(err);
1481 }
1482
btp_bap_broadcast_assistant_modify_src(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1483 uint8_t btp_bap_broadcast_assistant_modify_src(const void *cmd, uint16_t cmd_len,
1484 void *rsp, uint16_t *rsp_len)
1485 {
1486 int err;
1487 const uint8_t *ptr;
1488 struct bt_conn *conn;
1489 const struct btp_bap_modify_broadcast_src_cmd *cp = cmd;
1490 struct bt_bap_broadcast_assistant_mod_src_param param = { 0 };
1491
1492 LOG_DBG("");
1493
1494 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1495 if (!conn) {
1496 return BTP_STATUS_FAILED;
1497 }
1498
1499 memset(delegator_subgroups, 0, sizeof(delegator_subgroups));
1500 param.src_id = cp->src_id;
1501 param.pa_sync = cp->padv_sync > 0 ? true : false;
1502 param.pa_interval = sys_le16_to_cpu(cp->padv_interval);
1503 param.num_subgroups = MIN(cp->num_subgroups, CONFIG_BT_BAP_BASS_MAX_SUBGROUPS);
1504 param.subgroups = delegator_subgroups;
1505
1506 ptr = cp->subgroups;
1507 for (uint8_t i = 0; i < param.num_subgroups; i++) {
1508 struct bt_bap_bass_subgroup *subgroup = &delegator_subgroups[i];
1509
1510 subgroup->bis_sync = sys_get_le32(ptr);
1511 if (subgroup->bis_sync != BT_BAP_BIS_SYNC_NO_PREF) {
1512 /* For semantic purposes Zephyr API uses BIS Index bitfield
1513 * where BIT(1) means BIS Index 1
1514 */
1515 subgroup->bis_sync <<= 1;
1516 }
1517
1518 ptr += sizeof(subgroup->bis_sync);
1519 subgroup->metadata_len = *ptr;
1520 ptr += sizeof(subgroup->metadata_len);
1521 memcpy(subgroup->metadata, ptr, subgroup->metadata_len);
1522 ptr += subgroup->metadata_len;
1523 }
1524
1525 err = bt_bap_broadcast_assistant_mod_src(conn, ¶m);
1526
1527 return BTP_STATUS_VAL(err);
1528 }
1529
btp_bap_broadcast_assistant_set_broadcast_code(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1530 uint8_t btp_bap_broadcast_assistant_set_broadcast_code(const void *cmd, uint16_t cmd_len,
1531 void *rsp, uint16_t *rsp_len)
1532 {
1533 int err;
1534 struct bt_conn *conn;
1535 const struct btp_bap_set_broadcast_code_cmd *cp = cmd;
1536
1537 LOG_DBG("");
1538
1539 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1540 if (!conn) {
1541 return BTP_STATUS_FAILED;
1542 }
1543
1544 err = bt_bap_broadcast_assistant_set_broadcast_code(conn, cp->src_id, cp->broadcast_code);
1545 if (err != 0) {
1546 LOG_DBG("err %d", err);
1547 return BTP_STATUS_FAILED;
1548 }
1549
1550 return BTP_STATUS_SUCCESS;
1551 }
1552
btp_bap_broadcast_assistant_send_past(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)1553 uint8_t btp_bap_broadcast_assistant_send_past(const void *cmd, uint16_t cmd_len,
1554 void *rsp, uint16_t *rsp_len)
1555 {
1556 int err;
1557 uint16_t service_data;
1558 struct bt_conn *conn;
1559 struct bt_le_per_adv_sync *pa_sync;
1560 const struct btp_bap_send_past_cmd *cp = cmd;
1561
1562 LOG_DBG("");
1563
1564 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &cp->address);
1565 if (!conn) {
1566 return BTP_STATUS_FAILED;
1567 }
1568
1569 pa_sync = tester_gap_padv_get();
1570 if (!pa_sync) {
1571 LOG_DBG("Could not send PAST to Scan Delegator");
1572
1573 return BTP_STATUS_FAILED;
1574 }
1575
1576 LOG_DBG("Sending PAST");
1577
1578 /* If octet 0 is set to 0, it means AdvA in PAST matches AdvA in ADV_EXT_IND.
1579 * Octet 1 shall be set to Source_ID.
1580 */
1581 service_data = cp->src_id << 8;
1582
1583 err = bt_le_per_adv_sync_transfer(pa_sync, conn, service_data);
1584 if (err != 0) {
1585 LOG_DBG("Could not transfer periodic adv sync: %d", err);
1586
1587 return BTP_STATUS_FAILED;
1588 }
1589
1590 return BTP_STATUS_SUCCESS;
1591 }
1592
1593 static bool broadcast_inited;
1594
btp_bap_broadcast_init(void)1595 int btp_bap_broadcast_init(void)
1596 {
1597 if (broadcast_inited) {
1598 return 0;
1599 }
1600
1601 broadcast_sink_reset();
1602
1603 /* For Broadcast Assistant role */
1604 bt_bap_broadcast_assistant_register_cb(&broadcast_assistant_cb);
1605
1606 broadcast_inited = true;
1607
1608 return 0;
1609 }
1610