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