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