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