1 /*
2 * Copyright (c) 2022-2025 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <errno.h>
7 #include <stdbool.h>
8 #include <stddef.h>
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <string.h>
12
13 #include <zephyr/autoconf.h>
14 #include <zephyr/bluetooth/addr.h>
15 #include <zephyr/bluetooth/audio/aics.h>
16 #include <zephyr/bluetooth/audio/audio.h>
17 #include <zephyr/bluetooth/audio/bap.h>
18 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
19 #include <zephyr/bluetooth/audio/cap.h>
20 #include <zephyr/bluetooth/audio/csip.h>
21 #include <zephyr/bluetooth/audio/lc3.h>
22 #include <zephyr/bluetooth/audio/pacs.h>
23 #include <zephyr/bluetooth/audio/micp.h>
24 #include <zephyr/bluetooth/audio/vcp.h>
25 #include <zephyr/bluetooth/bluetooth.h>
26 #include <zephyr/bluetooth/byteorder.h>
27 #include <zephyr/bluetooth/gap.h>
28 #include <zephyr/bluetooth/iso.h>
29 #include <zephyr/bluetooth/uuid.h>
30 #include <zephyr/kernel.h>
31 #include <zephyr/net_buf.h>
32 #include <zephyr/sys/byteorder.h>
33 #include <zephyr/sys/printk.h>
34 #include <zephyr/sys/util.h>
35 #include <zephyr/sys/util_macro.h>
36
37 #include "bap_stream_rx.h"
38 #include "bap_stream_tx.h"
39 #include "bstests.h"
40 #include "common.h"
41 #include "bap_common.h"
42
43 #if defined(CONFIG_BT_CAP_ACCEPTOR)
44 extern enum bst_result_t bst_result;
45
46 #define CAP_INITIATOR_DEV_ID 0 /* CAP initiator shall be ID 0 for these tests */
47
48 CREATE_FLAG(flag_broadcaster_found);
49 CREATE_FLAG(flag_broadcast_code);
50 CREATE_FLAG(flag_base_received);
51 CREATE_FLAG(flag_pa_synced);
52 CREATE_FLAG(flag_syncable);
53 CREATE_FLAG(flag_pa_sync_lost);
54 CREATE_FLAG(flag_pa_request);
55 CREATE_FLAG(flag_bis_sync_requested);
56 CREATE_FLAG(flag_base_metadata_updated);
57 CREATE_FLAG(flag_unicast_stream_configured);
58
59 static struct bt_bap_broadcast_sink *g_broadcast_sink;
60 static struct bt_le_scan_recv_info broadcaster_info;
61 static bt_addr_le_t broadcaster_addr;
62 static struct bt_le_per_adv_sync *pa_sync;
63 static uint32_t broadcaster_broadcast_id;
64 static struct audio_test_stream broadcast_sink_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT];
65 static bool expect_rx;
66
67 static const struct bt_bap_qos_cfg_pref unicast_qos_pref =
68 BT_BAP_QOS_CFG_PREF(true, BT_GAP_LE_PHY_2M, 0u, 60u, 20000u, 40000u, 20000u, 40000u);
69
70 static bool auto_start_sink_streams;
71
72 static K_SEM_DEFINE(sem_broadcast_started, 0U, ARRAY_SIZE(broadcast_sink_streams));
73 static K_SEM_DEFINE(sem_broadcast_stopped, 0U, ARRAY_SIZE(broadcast_sink_streams));
74
75 static uint32_t bis_index_bitfield;
76
77 #define UNICAST_CHANNEL_COUNT_1 BIT(0)
78
79 static struct audio_test_stream
80 unicast_streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT];
81
subgroup_data_func_cb(struct bt_data * data,void * user_data)82 static bool subgroup_data_func_cb(struct bt_data *data, void *user_data)
83 {
84 bool *stream_context_found = (bool *)user_data;
85
86 printk("type %u len %u\n", data->type, data->data_len);
87
88 if (!valid_metadata_type(data->type, data->data_len)) {
89 return false;
90 }
91
92 if (data->type == BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT) {
93 if (data->data_len != 2) { /* Stream context size */
94 return false;
95 }
96
97 *stream_context_found = true;
98 return false;
99 }
100
101 return true;
102 }
103
valid_subgroup_metadata_cb(const struct bt_bap_base_subgroup * subgroup,void * user_data)104 static bool valid_subgroup_metadata_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data)
105 {
106 static uint8_t metadata[CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE];
107 static size_t metadata_size;
108 bool stream_context_found = false;
109 uint8_t *meta;
110 int ret;
111
112 ret = bt_bap_base_get_subgroup_codec_meta(subgroup, &meta);
113 if (ret < 0) {
114 FAIL("Could not get subgroup meta: %d\n", ret);
115 return false;
116 }
117
118 if (TEST_FLAG(flag_base_received) &&
119 ((size_t)ret != metadata_size || memcmp(meta, metadata, metadata_size) != 0)) {
120 printk("Metadata updated\n");
121 SET_FLAG(flag_base_metadata_updated);
122 }
123
124 metadata_size = (size_t)ret;
125
126 ret = bt_audio_data_parse(meta, (size_t)ret, subgroup_data_func_cb, &stream_context_found);
127 if (ret != 0 && ret != -ECANCELED) {
128 return false;
129 }
130
131 if (!stream_context_found) {
132 printk("Subgroup did not have streaming context\n");
133 }
134
135 /* if this is false, the iterator will return early with an error */
136 return stream_context_found;
137 }
138
base_recv_cb(struct bt_bap_broadcast_sink * sink,const struct bt_bap_base * base,size_t base_size)139 static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base,
140 size_t base_size)
141 {
142 /* Create a mask for the maximum BIS we can sync to using the number of
143 * broadcast_sink_streams we have. We add an additional 1 since the bis indexes
144 * start from 1 and not 0.
145 */
146 const uint32_t bis_index_mask = BIT_MASK(ARRAY_SIZE(broadcast_sink_streams) + 1U);
147 uint32_t base_bis_index_bitfield = 0U;
148 int ret;
149
150 ret = bt_bap_base_get_subgroup_count(base);
151 if (ret < 0) {
152 FAIL("Failed to get subgroup count: %d\n", ret);
153 return;
154 }
155
156 printk("Received BASE with %d subgroups from broadcast sink %p\n", ret, sink);
157
158 if (ret == 0) {
159 FAIL("subgroup_count was 0");
160 return;
161 }
162
163 ret = bt_bap_base_foreach_subgroup(base, valid_subgroup_metadata_cb, NULL);
164 if (ret != 0) {
165 FAIL("Failed to parse subgroups: %d\n", ret);
166 return;
167 }
168
169 ret = bt_bap_base_get_bis_indexes(base, &base_bis_index_bitfield);
170 if (ret != 0) {
171 FAIL("Failed to BIS indexes: %d\n", ret);
172 return;
173 }
174
175 bis_index_bitfield = base_bis_index_bitfield & bis_index_mask;
176
177 SET_FLAG(flag_base_received);
178 }
179
syncable_cb(struct bt_bap_broadcast_sink * sink,const struct bt_iso_biginfo * biginfo)180 static void syncable_cb(struct bt_bap_broadcast_sink *sink, const struct bt_iso_biginfo *biginfo)
181 {
182 printk("Broadcast sink %p syncable with%s encryption\n",
183 sink, biginfo->encryption ? "" : "out");
184 SET_FLAG(flag_syncable);
185 }
186
187 static struct bt_bap_broadcast_sink_cb broadcast_sink_cbs = {
188 .base_recv = base_recv_cb,
189 .syncable = syncable_cb,
190 };
191
scan_check_and_sync_broadcast(struct bt_data * data,void * user_data)192 static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data)
193 {
194 const struct bt_le_scan_recv_info *info = user_data;
195 char le_addr[BT_ADDR_LE_STR_LEN];
196 struct bt_uuid_16 adv_uuid;
197 uint32_t broadcast_id;
198
199 if (TEST_FLAG(flag_broadcaster_found)) {
200 /* no-op*/
201 return false;
202 }
203
204 if (data->type != BT_DATA_SVC_DATA16) {
205 return true;
206 }
207
208 if (data->data_len < BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE) {
209 return true;
210 }
211
212 if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
213 return true;
214 }
215
216 if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO)) {
217 return true;
218 }
219
220 broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);
221
222 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
223
224 printk("Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X\n", broadcast_id,
225 le_addr, info->sid);
226
227 SET_FLAG(flag_broadcaster_found);
228
229 /* Store info for PA sync parameters */
230 memcpy(&broadcaster_info, info, sizeof(broadcaster_info));
231 bt_addr_le_copy(&broadcaster_addr, info->addr);
232 broadcaster_broadcast_id = broadcast_id;
233
234 /* Stop parsing */
235 return false;
236 }
237
broadcast_scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad)238 static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad)
239 {
240 if (info->interval != 0U) {
241 bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)info);
242 }
243 }
244
245 static struct bt_le_scan_cb bap_scan_cb = {
246 .recv = broadcast_scan_recv,
247 };
248
bap_pa_sync_synced_cb(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)249 static void bap_pa_sync_synced_cb(struct bt_le_per_adv_sync *sync,
250 struct bt_le_per_adv_sync_synced_info *info)
251 {
252 if (sync == pa_sync) {
253 printk("PA sync %p synced for broadcast sink with broadcast ID 0x%06X\n", sync,
254 broadcaster_broadcast_id);
255
256 SET_FLAG(flag_pa_synced);
257 }
258 }
259
bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)260 static void bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync,
261 const struct bt_le_per_adv_sync_term_info *info)
262 {
263 if (sync == pa_sync) {
264 printk("PA sync %p lost with reason %u\n", sync, info->reason);
265 pa_sync = NULL;
266
267 SET_FLAG(flag_pa_sync_lost);
268 }
269 }
270
271 static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = {
272 .synced = bap_pa_sync_synced_cb,
273 .term = bap_pa_sync_terminated_cb,
274 };
275
started_cb(struct bt_bap_stream * stream)276 static void started_cb(struct bt_bap_stream *stream)
277 {
278 struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
279
280 memset(&test_stream->last_info, 0, sizeof(test_stream->last_info));
281 test_stream->rx_cnt = 0U;
282 test_stream->valid_rx_cnt = 0U;
283 test_stream->seq_num = 0U;
284 test_stream->tx_cnt = 0U;
285
286 printk("Stream %p started\n", stream);
287 k_sem_give(&sem_broadcast_started);
288 }
289
stopped_cb(struct bt_bap_stream * stream,uint8_t reason)290 static void stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
291 {
292 printk("Stream %p stopped with reason 0x%02X\n", stream, reason);
293 k_sem_give(&sem_broadcast_stopped);
294 }
295
296 static struct bt_bap_stream_ops broadcast_stream_ops = {
297 .started = started_cb,
298 .stopped = stopped_cb,
299 .recv = bap_stream_rx_recv_cb,
300 };
301
unicast_stream_enabled_cb(struct bt_bap_stream * stream)302 static void unicast_stream_enabled_cb(struct bt_bap_stream *stream)
303 {
304 struct bt_bap_ep_info ep_info;
305 int err;
306
307 printk("Enabled: stream %p (auto_start_sink_streams %d)\n", stream,
308 auto_start_sink_streams);
309
310 err = bt_bap_ep_get_info(stream->ep, &ep_info);
311 if (err != 0) {
312 FAIL("Failed to get ep info: %d\n", err);
313 return;
314 }
315
316 if (auto_start_sink_streams && ep_info.dir == BT_AUDIO_DIR_SINK) {
317 /* Automatically do the receiver start ready operation */
318 err = bt_bap_stream_start(stream);
319
320 if (err != 0) {
321 FAIL("Failed to start stream: %d\n", err);
322 return;
323 }
324 }
325 }
326
unicast_stream_started(struct bt_bap_stream * stream)327 static void unicast_stream_started(struct bt_bap_stream *stream)
328 {
329 struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
330
331 memset(&test_stream->last_info, 0, sizeof(test_stream->last_info));
332 test_stream->rx_cnt = 0U;
333 test_stream->valid_rx_cnt = 0U;
334 test_stream->seq_num = 0U;
335 test_stream->tx_cnt = 0U;
336
337 printk("Started stream %p\n", stream);
338
339 if (bap_stream_tx_can_send(stream)) {
340 int err;
341
342 err = bap_stream_tx_register(stream);
343 if (err != 0) {
344 FAIL("Failed to register stream %p for TX: %d\n", stream, err);
345 return;
346 }
347 } else if (bap_stream_rx_can_recv(stream)) {
348 expect_rx = true;
349 }
350 }
351
unicast_stream_stopped(struct bt_bap_stream * stream,uint8_t reason)352 static void unicast_stream_stopped(struct bt_bap_stream *stream, uint8_t reason)
353 {
354 printk("Stopped stream %p with reason 0x%02X\n", stream, reason);
355
356 if (bap_stream_tx_can_send(stream)) {
357 int err;
358
359 err = bap_stream_tx_unregister(stream);
360 if (err != 0) {
361 FAIL("Failed to unregister stream %p for TX: %d\n", stream, err);
362 return;
363 }
364 }
365 }
366
367 static struct bt_bap_stream_ops unicast_stream_ops = {
368 .enabled = unicast_stream_enabled_cb,
369 .started = unicast_stream_started,
370 .stopped = unicast_stream_stopped,
371 .sent = bap_stream_tx_sent_cb,
372 .recv = bap_stream_rx_recv_cb,
373 };
374
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)375 static int pa_sync_req_cb(struct bt_conn *conn,
376 const struct bt_bap_scan_delegator_recv_state *recv_state,
377 bool past_avail, uint16_t pa_interval)
378 {
379 if (recv_state->pa_sync_state == BT_BAP_PA_STATE_SYNCED ||
380 recv_state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
381 /* Already syncing */
382 /* TODO: Terminate existing sync and then sync to new?*/
383 return -EALREADY;
384 }
385
386 printk("Sync request\n");
387
388 bt_addr_le_copy(&broadcaster_addr, &recv_state->addr);
389 broadcaster_info.sid = recv_state->adv_sid;
390 broadcaster_info.interval = pa_interval;
391
392 SET_FLAG(flag_pa_request);
393
394 return 0;
395 }
396
pa_sync_term_req_cb(struct bt_conn * conn,const struct bt_bap_scan_delegator_recv_state * recv_state)397 static int pa_sync_term_req_cb(struct bt_conn *conn,
398 const struct bt_bap_scan_delegator_recv_state *recv_state)
399 {
400 if (pa_sync == NULL || recv_state->pa_sync_state == BT_BAP_PA_STATE_NOT_SYNCED) {
401 return -EALREADY;
402 }
403
404 UNSET_FLAG(flag_pa_request);
405
406 return 0;
407 }
408
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])409 static int bis_sync_req_cb(struct bt_conn *conn,
410 const struct bt_bap_scan_delegator_recv_state *recv_state,
411 const uint32_t bis_sync_req[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS])
412 {
413 uint32_t total_bis = 0U;
414
415 broadcaster_broadcast_id = recv_state->broadcast_id;
416
417 for (int i = 0; i < recv_state->num_subgroups; i++) {
418 total_bis |= bis_sync_req[i];
419 }
420
421 if (total_bis != 0U) {
422 SET_FLAG(flag_bis_sync_requested);
423 } else {
424 UNSET_FLAG(flag_bis_sync_requested);
425 }
426
427 return 0;
428 }
429
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])430 static void broadcast_code_cb(struct bt_conn *conn,
431 const struct bt_bap_scan_delegator_recv_state *recv_state,
432 const uint8_t broadcast_code[BT_ISO_BROADCAST_CODE_SIZE])
433 {
434 printk("Broadcast code received for %p\n", recv_state);
435
436 if (memcmp(broadcast_code, BROADCAST_CODE, sizeof(BROADCAST_CODE)) != 0) {
437 FAIL("Failed to receive correct broadcast code\n");
438 return;
439 }
440
441 SET_FLAG(flag_broadcast_code);
442 }
443
444 static struct bt_bap_scan_delegator_cb scan_delegator_cbs = {
445 .pa_sync_req = pa_sync_req_cb,
446 .pa_sync_term_req = pa_sync_term_req_cb,
447 .bis_sync_req = bis_sync_req_cb,
448 .broadcast_code = broadcast_code_cb,
449 };
450
451 static struct bt_csip_set_member_svc_inst *csip_set_member;
452
unicast_stream_alloc(void)453 static struct bt_bap_stream *unicast_stream_alloc(void)
454 {
455 for (size_t i = 0; i < ARRAY_SIZE(unicast_streams); i++) {
456 struct bt_bap_stream *stream =
457 bap_stream_from_audio_test_stream(&unicast_streams[i]);
458
459 if (!stream->conn) {
460 return stream;
461 }
462 }
463
464 return NULL;
465 }
466
unicast_server_config(struct bt_conn * conn,const struct bt_bap_ep * ep,enum bt_audio_dir dir,const struct bt_audio_codec_cfg * codec_cfg,struct bt_bap_stream ** stream,struct bt_bap_qos_cfg_pref * const pref,struct bt_bap_ascs_rsp * rsp)467 static int unicast_server_config(struct bt_conn *conn, const struct bt_bap_ep *ep,
468 enum bt_audio_dir dir, const struct bt_audio_codec_cfg *codec_cfg,
469 struct bt_bap_stream **stream,
470 struct bt_bap_qos_cfg_pref *const pref,
471 struct bt_bap_ascs_rsp *rsp)
472 {
473 printk("ASE Codec Config: conn %p ep %p dir %u\n", conn, ep, dir);
474
475 print_codec_cfg(codec_cfg);
476
477 *stream = unicast_stream_alloc();
478 if (*stream == NULL) {
479 printk("No streams available\n");
480 *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_NO_MEM, BT_BAP_ASCS_REASON_NONE);
481
482 return -ENOMEM;
483 }
484
485 printk("ASE Codec Config stream %p\n", *stream);
486
487 SET_FLAG(flag_unicast_stream_configured);
488
489 *pref = unicast_qos_pref;
490
491 return 0;
492 }
493
unicast_server_reconfig(struct bt_bap_stream * stream,enum bt_audio_dir dir,const struct bt_audio_codec_cfg * codec_cfg,struct bt_bap_qos_cfg_pref * const pref,struct bt_bap_ascs_rsp * rsp)494 static int unicast_server_reconfig(struct bt_bap_stream *stream, enum bt_audio_dir dir,
495 const struct bt_audio_codec_cfg *codec_cfg,
496 struct bt_bap_qos_cfg_pref *const pref,
497 struct bt_bap_ascs_rsp *rsp)
498 {
499 printk("ASE Codec Reconfig: stream %p\n", stream);
500
501 print_codec_cfg(codec_cfg);
502
503 *pref = unicast_qos_pref;
504
505 *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_UNSUPPORTED, BT_BAP_ASCS_REASON_NONE);
506
507 /* We only support one QoS at the moment, reject changes */
508 return -ENOEXEC;
509 }
510
unicast_server_qos(struct bt_bap_stream * stream,const struct bt_bap_qos_cfg * qos,struct bt_bap_ascs_rsp * rsp)511 static int unicast_server_qos(struct bt_bap_stream *stream, const struct bt_bap_qos_cfg *qos,
512 struct bt_bap_ascs_rsp *rsp)
513 {
514 printk("QoS: stream %p qos %p\n", stream, qos);
515
516 print_qos(qos);
517
518 return 0;
519 }
520
ascs_data_func_cb(struct bt_data * data,void * user_data)521 static bool ascs_data_func_cb(struct bt_data *data, void *user_data)
522 {
523 struct bt_bap_ascs_rsp *rsp = (struct bt_bap_ascs_rsp *)user_data;
524
525 if (!BT_AUDIO_METADATA_TYPE_IS_KNOWN(data->type)) {
526 printk("Invalid metadata type %u or length %u\n", data->type, data->data_len);
527 *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED, data->type);
528 return false;
529 }
530
531 return true;
532 }
533
unicast_server_enable(struct bt_bap_stream * stream,const uint8_t meta[],size_t meta_len,struct bt_bap_ascs_rsp * rsp)534 static int unicast_server_enable(struct bt_bap_stream *stream, const uint8_t meta[],
535 size_t meta_len, struct bt_bap_ascs_rsp *rsp)
536 {
537 printk("Enable: stream %p meta_len %zu\n", stream, meta_len);
538
539 return bt_audio_data_parse(meta, meta_len, ascs_data_func_cb, rsp);
540 }
541
unicast_server_start(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)542 static int unicast_server_start(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
543 {
544 printk("Start: stream %p\n", stream);
545
546 return 0;
547 }
548
unicast_server_metadata(struct bt_bap_stream * stream,const uint8_t meta[],size_t meta_len,struct bt_bap_ascs_rsp * rsp)549 static int unicast_server_metadata(struct bt_bap_stream *stream, const uint8_t meta[],
550 size_t meta_len, struct bt_bap_ascs_rsp *rsp)
551 {
552 printk("Metadata: stream %p meta_len %zu\n", stream, meta_len);
553
554 return bt_audio_data_parse(meta, meta_len, ascs_data_func_cb, rsp);
555 }
556
unicast_server_disable(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)557 static int unicast_server_disable(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
558 {
559 printk("Disable: stream %p\n", stream);
560
561 return 0;
562 }
563
unicast_server_stop(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)564 static int unicast_server_stop(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
565 {
566 printk("Stop: stream %p\n", stream);
567
568 return 0;
569 }
570
unicast_server_release(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)571 static int unicast_server_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
572 {
573 printk("Release: stream %p\n", stream);
574
575 return 0;
576 }
577
578 static struct bt_bap_unicast_server_register_param param = {
579 CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT,
580 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT
581 };
582
583 static struct bt_bap_unicast_server_cb unicast_server_cbs = {
584 .config = unicast_server_config,
585 .reconfig = unicast_server_reconfig,
586 .qos = unicast_server_qos,
587 .enable = unicast_server_enable,
588 .start = unicast_server_start,
589 .metadata = unicast_server_metadata,
590 .disable = unicast_server_disable,
591 .stop = unicast_server_stop,
592 .release = unicast_server_release,
593 };
594
set_location(void)595 static void set_location(void)
596 {
597 int err;
598
599 if (IS_ENABLED(CONFIG_BT_PAC_SNK_LOC)) {
600 err = bt_pacs_set_location(BT_AUDIO_DIR_SINK,
601 BT_AUDIO_LOCATION_FRONT_CENTER);
602 if (err != 0) {
603 FAIL("Failed to set sink location (err %d)\n", err);
604 return;
605 }
606 }
607
608 if (IS_ENABLED(CONFIG_BT_PAC_SRC_LOC)) {
609 err = bt_pacs_set_location(BT_AUDIO_DIR_SOURCE,
610 BT_AUDIO_LOCATION_FRONT_LEFT |
611 BT_AUDIO_LOCATION_FRONT_RIGHT);
612 if (err != 0) {
613 FAIL("Failed to set source location (err %d)\n", err);
614 return;
615 }
616 }
617
618 printk("Location successfully set\n");
619 }
620
set_supported_contexts(void)621 static int set_supported_contexts(void)
622 {
623 int err;
624
625 if (IS_ENABLED(CONFIG_BT_PAC_SNK)) {
626 err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SINK, SINK_CONTEXT);
627 if (err != 0) {
628 printk("Failed to set sink supported contexts (err %d)\n",
629 err);
630
631 return err;
632 }
633 }
634
635 if (IS_ENABLED(CONFIG_BT_PAC_SRC)) {
636 err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SOURCE, SOURCE_CONTEXT);
637 if (err != 0) {
638 printk("Failed to set source supported contexts (err %d)\n",
639 err);
640
641 return err;
642 }
643 }
644
645 printk("Supported contexts successfully set\n");
646
647 return 0;
648 }
649
test_start_adv(void)650 void test_start_adv(void)
651 {
652 struct bt_le_ext_adv *ext_adv;
653
654 setup_connectable_adv(&ext_adv);
655 }
656
set_available_contexts(void)657 static void set_available_contexts(void)
658 {
659 int err;
660
661 err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SINK, SINK_CONTEXT);
662 if (IS_ENABLED(CONFIG_BT_PAC_SNK) && err != 0) {
663 FAIL("Failed to set sink available contexts (err %d)\n", err);
664 return;
665 }
666
667 err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE, SOURCE_CONTEXT);
668 if (IS_ENABLED(CONFIG_BT_PAC_SRC) && err != 0) {
669 FAIL("Failed to set source available contexts (err %d)\n", err);
670 return;
671 }
672
673 printk("Available contexts successfully set\n");
674 }
675
init(void)676 static void init(void)
677 {
678 const struct bt_csip_set_member_register_param csip_set_member_param = {
679 .set_size = 3,
680 .rank = 1,
681 .lockable = true,
682 /* Using the CSIP_SET_MEMBER test sample SIRK */
683 .sirk = { 0xcd, 0xcc, 0x72, 0xdd, 0x86, 0x8c, 0xcd, 0xce,
684 0x22, 0xfd, 0xa1, 0x21, 0x09, 0x7d, 0x7d, 0x45 },
685 };
686 static const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3(
687 BT_AUDIO_CODEC_CAP_FREQ_ANY, BT_AUDIO_CODEC_CAP_DURATION_ANY,
688 BT_AUDIO_CODEC_CAP_CHAN_COUNT_SUPPORT(1, 2), 30, 240, 2,
689 (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA));
690 const struct bt_pacs_register_param pacs_param = {
691 #if defined(CONFIG_BT_PAC_SNK)
692 .snk_pac = true,
693 #endif /* CONFIG_BT_PAC_SNK */
694 #if defined(CONFIG_BT_PAC_SNK_LOC)
695 .snk_loc = true,
696 #endif /* CONFIG_BT_PAC_SNK_LOC */
697 #if defined(CONFIG_BT_PAC_SRC)
698 .src_pac = true,
699 #endif /* CONFIG_BT_PAC_SRC */
700 #if defined(CONFIG_BT_PAC_SRC_LOC)
701 .src_loc = true,
702 #endif /* CONFIG_BT_PAC_SRC_LOC */
703 };
704 int err;
705
706 err = bt_enable(NULL);
707 if (err != 0) {
708 FAIL("Bluetooth enable failed (err %d)\n", err);
709 return;
710 }
711
712 printk("Bluetooth initialized\n");
713 bap_stream_tx_init();
714
715 err = bt_pacs_register(&pacs_param);
716 if (err) {
717 FAIL("Could not register PACS (err %d)\n", err);
718 return;
719 }
720
721 if (IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER)) {
722 err = bt_cap_acceptor_register(&csip_set_member_param, &csip_set_member);
723 if (err != 0) {
724 FAIL("CAP acceptor failed to register (err %d)\n", err);
725 return;
726 }
727 }
728
729 if (IS_ENABLED(CONFIG_BT_BAP_UNICAST_SERVER)) {
730 static struct bt_pacs_cap unicast_cap = {
731 .codec_cap = &codec_cap,
732 };
733
734 err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &unicast_cap);
735 if (err != 0) {
736 FAIL("Broadcast capability register failed (err %d)\n",
737 err);
738
739 return;
740 }
741
742 err = bt_pacs_cap_register(BT_AUDIO_DIR_SOURCE, &unicast_cap);
743 if (err != 0) {
744 FAIL("Broadcast capability register failed (err %d)\n", err);
745
746 return;
747 }
748
749 err = bt_bap_unicast_server_register(¶m);
750 if (err != 0) {
751 FAIL("Failed to register unicast server (err %d)\n", err);
752
753 return;
754 }
755
756 err = bt_bap_unicast_server_register_cb(&unicast_server_cbs);
757 if (err != 0) {
758 FAIL("Failed to register unicast server callbacks (err %d)\n",
759 err);
760
761 return;
762 }
763
764 for (size_t i = 0U; i < ARRAY_SIZE(unicast_streams); i++) {
765 bt_cap_stream_ops_register(
766 cap_stream_from_audio_test_stream(&unicast_streams[i]),
767 &unicast_stream_ops);
768 }
769 }
770
771 if (IS_ENABLED(CONFIG_BT_BAP_BROADCAST_SINK)) {
772 static struct bt_pacs_cap broadcast_cap = {
773 .codec_cap = &codec_cap,
774 };
775
776 err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &broadcast_cap);
777 if (err != 0) {
778 FAIL("Broadcast capability register failed (err %d)\n",
779 err);
780
781 return;
782 }
783
784 err = bt_bap_scan_delegator_register(&scan_delegator_cbs);
785 if (err != 0) {
786 FAIL("Scan deligator register failed (err %d)\n", err);
787
788 return;
789 }
790
791 bt_bap_broadcast_sink_register_cb(&broadcast_sink_cbs);
792 bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb);
793 bt_le_scan_cb_register(&bap_scan_cb);
794
795 UNSET_FLAG(flag_broadcaster_found);
796 UNSET_FLAG(flag_broadcast_code);
797 UNSET_FLAG(flag_base_received);
798 UNSET_FLAG(flag_pa_synced);
799 UNSET_FLAG(flag_pa_request);
800 UNSET_FLAG(flag_audio_received);
801 UNSET_FLAG(flag_base_metadata_updated);
802 UNSET_FLAG(flag_bis_sync_requested);
803
804 for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sink_streams); i++) {
805 bt_cap_stream_ops_register(
806 cap_stream_from_audio_test_stream(&broadcast_sink_streams[i]),
807 &broadcast_stream_ops);
808 }
809 }
810
811 if (IS_ENABLED(CONFIG_BT_PACS)) {
812 set_supported_contexts();
813 set_available_contexts();
814 set_location();
815 }
816
817 if (IS_ENABLED(CONFIG_BT_VCP_VOL_REND)) {
818 char output_desc[CONFIG_BT_VCP_VOL_REND_VOCS_INSTANCE_COUNT][16];
819 char input_desc[CONFIG_BT_VCP_VOL_REND_AICS_INSTANCE_COUNT][16];
820 struct bt_vcp_vol_rend_register_param vcp_param = {0};
821
822 for (size_t i = 0U; i < ARRAY_SIZE(vcp_param.vocs_param); i++) {
823 vcp_param.vocs_param[i].location_writable = true;
824 vcp_param.vocs_param[i].desc_writable = true;
825 snprintf(output_desc[i], sizeof(output_desc[i]), "Output %d", i + 1);
826 vcp_param.vocs_param[i].output_desc = output_desc[i];
827 vcp_param.vocs_param[i].cb = NULL;
828 }
829
830 for (size_t i = 0U; i < ARRAY_SIZE(vcp_param.aics_param); i++) {
831 vcp_param.aics_param[i].desc_writable = true;
832 snprintf(input_desc[i], sizeof(input_desc[i]), "VCP Input %d", i + 1);
833 vcp_param.aics_param[i].description = input_desc[i];
834 vcp_param.aics_param[i].type = BT_AICS_INPUT_TYPE_DIGITAL;
835 vcp_param.aics_param[i].status = true;
836 vcp_param.aics_param[i].gain_mode = BT_AICS_MODE_MANUAL;
837 vcp_param.aics_param[i].units = 1;
838 vcp_param.aics_param[i].min_gain = 0;
839 vcp_param.aics_param[i].max_gain = 100;
840 vcp_param.aics_param[i].cb = NULL;
841 }
842
843 vcp_param.step = 1;
844 vcp_param.mute = BT_VCP_STATE_UNMUTED;
845 vcp_param.volume = 100;
846 vcp_param.cb = NULL;
847 err = bt_vcp_vol_rend_register(&vcp_param);
848 if (err != 0) {
849 FAIL("Failed to register VCS (err %d)\n", err);
850
851 return;
852 }
853 }
854
855 if (IS_ENABLED(CONFIG_BT_MICP_MIC_DEV)) {
856 struct bt_micp_mic_dev_register_param micp_param = {0};
857
858 #if defined(CONFIG_BT_MICP_MIC_DEV_AICS)
859 char input_desc[CONFIG_BT_MICP_MIC_DEV_AICS_INSTANCE_COUNT][16];
860
861 for (int i = 0; i < ARRAY_SIZE(micp_param.aics_param); i++) {
862 micp_param.aics_param[i].desc_writable = true;
863 snprintf(input_desc[i], sizeof(input_desc[i]), "MICP Input %d", i + 1);
864 micp_param.aics_param[i].description = input_desc[i];
865 micp_param.aics_param[i].type = BT_AICS_INPUT_TYPE_DIGITAL;
866 micp_param.aics_param[i].status = true;
867 micp_param.aics_param[i].gain_mode = BT_AICS_MODE_MANUAL;
868 micp_param.aics_param[i].units = 1;
869 micp_param.aics_param[i].min_gain = 0;
870 micp_param.aics_param[i].max_gain = 100;
871 micp_param.aics_param[i].cb = NULL;
872 }
873 #endif /* CONFIG_BT_MICP_MIC_DEV_AICS */
874
875 err = bt_micp_mic_dev_register(&micp_param);
876 if (err != 0) {
877 FAIL("Failed to register MICS (err %d)\n", err);
878 return;
879 }
880 }
881 }
882
wait_for_data(void)883 static void wait_for_data(void)
884 {
885 printk("Waiting for data\n");
886 WAIT_FOR_FLAG(flag_audio_received);
887 printk("Data received\n");
888 }
889
test_cap_acceptor_unicast(void)890 static void test_cap_acceptor_unicast(void)
891 {
892 init();
893
894 test_start_adv();
895
896 auto_start_sink_streams = true;
897
898 WAIT_FOR_FLAG(flag_connected);
899
900 /* Wait until initiator is done starting streams */
901 backchannel_sync_wait(CAP_INITIATOR_DEV_ID);
902
903 if (expect_rx) {
904 wait_for_data();
905 }
906 /* let initiator know we have received what we wanted */
907 backchannel_sync_send(CAP_INITIATOR_DEV_ID);
908
909 PASS("CAP acceptor unicast passed\n");
910 }
911
test_cap_acceptor_unicast_timeout(void)912 static void test_cap_acceptor_unicast_timeout(void)
913 {
914 init();
915
916 test_start_adv();
917
918 auto_start_sink_streams = false; /* Cause unicast_audio_start timeout */
919
920 WAIT_FOR_FLAG(flag_connected);
921
922 PASS("CAP acceptor unicast passed\n");
923 }
924
pa_sync_create(void)925 static void pa_sync_create(void)
926 {
927 struct bt_le_per_adv_sync_param create_params = {0};
928 int err;
929
930 bt_addr_le_copy(&create_params.addr, &broadcaster_addr);
931 create_params.options = BT_LE_PER_ADV_SYNC_OPT_FILTER_DUPLICATE;
932 create_params.sid = broadcaster_info.sid;
933 create_params.skip = PA_SYNC_SKIP;
934 create_params.timeout = interval_to_sync_timeout(broadcaster_info.interval);
935
936 err = bt_le_per_adv_sync_create(&create_params, &pa_sync);
937 if (err != 0) {
938 FAIL("Could not create Broadcast PA sync: %d\n", err);
939 return;
940 }
941
942 printk("Broadcast source found, waiting for PA sync\n");
943 WAIT_FOR_FLAG(flag_pa_synced);
944 }
945
pa_sync_to_broadcaster(void)946 static void pa_sync_to_broadcaster(void)
947 {
948 int err;
949
950 printk("Scanning for broadcast sources\n");
951 err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL);
952 if (err != 0) {
953 FAIL("Unable to start scan for broadcast sources: %d", err);
954 return;
955 }
956
957 WAIT_FOR_FLAG(flag_broadcaster_found);
958
959 printk("Broadcast source found, stopping scan\n");
960 err = bt_le_scan_stop();
961 if (err != 0) {
962 FAIL("bt_le_scan_stop failed with %d\n", err);
963 return;
964 }
965
966 printk("Scan stopped, attempting to PA sync to the broadcaster with id 0x%06X\n",
967 broadcaster_broadcast_id);
968
969 pa_sync_create();
970 }
971
create_and_sync_sink(struct bt_bap_stream * bap_streams[],size_t * stream_count)972 static void create_and_sync_sink(struct bt_bap_stream *bap_streams[], size_t *stream_count)
973 {
974 int err;
975
976 printk("Creating the broadcast sink\n");
977 err = bt_bap_broadcast_sink_create(pa_sync, broadcaster_broadcast_id, &g_broadcast_sink);
978 if (err != 0) {
979 FAIL("Unable to create the sink: %d\n", err);
980 return;
981 }
982
983 printk("Broadcast source PA synced, waiting for BASE\n");
984 WAIT_FOR_FLAG(flag_base_received);
985 printk("BASE received\n");
986
987 printk("Waiting for BIG syncable\n");
988 WAIT_FOR_FLAG(flag_syncable);
989
990 for (size_t i = 0U; i < ARRAY_SIZE(broadcast_sink_streams); i++) {
991 bap_streams[i] = bap_stream_from_audio_test_stream(&broadcast_sink_streams[i]);
992 }
993
994 printk("Syncing the sink to 0x%08x\n", bis_index_bitfield);
995 *stream_count = 0;
996 for (int i = 1; i < BT_ISO_MAX_GROUP_ISO_COUNT; i++) {
997 if ((bis_index_bitfield & BIT(i)) != 0) {
998 *stream_count += 1;
999 }
1000 }
1001
1002 err = bt_bap_broadcast_sink_sync(g_broadcast_sink, bis_index_bitfield, bap_streams, NULL);
1003 if (err != 0) {
1004 FAIL("Unable to sync the sink: %d\n", err);
1005 return;
1006 }
1007
1008 /* Wait for all to be started */
1009 printk("Waiting for %zu streams to be started\n", *stream_count);
1010 for (size_t i = 0U; i < *stream_count; i++) {
1011 k_sem_take(&sem_broadcast_started, K_FOREVER);
1012 }
1013 }
1014
wait_for_broadcast_code(void)1015 static void wait_for_broadcast_code(void)
1016 {
1017 printk("Waiting for broadcast code\n");
1018 WAIT_FOR_FLAG(flag_broadcast_code);
1019 }
1020
wait_for_streams_stop(int stream_count)1021 static void wait_for_streams_stop(int stream_count)
1022 {
1023 /* The order of PA sync lost and BIG Sync lost is irrelevant
1024 * and depend on timeout parameters. We just wait for PA first, but
1025 * either way will work.
1026 */
1027 printk("Waiting for PA disconnected\n");
1028 WAIT_FOR_FLAG(flag_pa_sync_lost);
1029
1030 printk("Waiting for %zu streams to be stopped\n", stream_count);
1031 for (size_t i = 0U; i < stream_count; i++) {
1032 k_sem_take(&sem_broadcast_stopped, K_FOREVER);
1033 }
1034 }
1035
test_cap_acceptor_broadcast(void)1036 static void test_cap_acceptor_broadcast(void)
1037 {
1038 static struct bt_bap_stream *bap_streams[ARRAY_SIZE(broadcast_sink_streams)];
1039 size_t stream_count;
1040
1041 init();
1042
1043 pa_sync_to_broadcaster();
1044
1045 create_and_sync_sink(bap_streams, &stream_count);
1046
1047 wait_for_data();
1048 /* let other devices know we have received what we wanted */
1049 backchannel_sync_send_all();
1050
1051 wait_for_streams_stop(stream_count);
1052
1053 PASS("CAP acceptor broadcast passed\n");
1054 }
1055
test_cap_acceptor_broadcast_update(void)1056 static void test_cap_acceptor_broadcast_update(void)
1057 {
1058 static struct bt_bap_stream *bap_streams[ARRAY_SIZE(broadcast_sink_streams)];
1059 size_t stream_count;
1060
1061 init();
1062
1063 pa_sync_to_broadcaster();
1064
1065 create_and_sync_sink(bap_streams, &stream_count);
1066
1067 wait_for_data();
1068
1069 printk("Waiting for metadata update");
1070 WAIT_FOR_FLAG(flag_base_metadata_updated);
1071 backchannel_sync_send_all(); /* let other devices know we have received metadata */
1072 /* let other devices know we have received what we wanted */
1073 backchannel_sync_send_all();
1074
1075 wait_for_streams_stop(stream_count);
1076
1077 PASS("CAP acceptor broadcast passed\n");
1078 }
1079
test_cap_acceptor_broadcast_reception(void)1080 static void test_cap_acceptor_broadcast_reception(void)
1081 {
1082 static struct bt_bap_stream *bap_streams[ARRAY_SIZE(broadcast_sink_streams)];
1083 size_t stream_count;
1084 int err;
1085
1086 init();
1087
1088 test_start_adv();
1089
1090 WAIT_FOR_FLAG(flag_pa_request);
1091 WAIT_FOR_FLAG(flag_bis_sync_requested);
1092
1093 pa_sync_create();
1094
1095 create_and_sync_sink(bap_streams, &stream_count);
1096
1097 wait_for_broadcast_code();
1098 wait_for_data();
1099 /* let other devices know we have received what we wanted */
1100 backchannel_sync_send_all();
1101
1102 /* when flag_bis_sync_requested is unset the bis_sync for all subgroups were set to 0 */
1103 WAIT_FOR_UNSET_FLAG(flag_bis_sync_requested);
1104
1105 UNSET_FLAG(flag_syncable);
1106 err = bt_bap_broadcast_sink_stop(g_broadcast_sink);
1107 if (err != 0) {
1108 FAIL("Unable to stop the sink: %d\n", err);
1109 return;
1110 }
1111
1112 WAIT_FOR_FLAG(flag_syncable);
1113 /* Although in theory we can now sync, in practice we can not since all BIS-syncs are 0 */
1114 backchannel_sync_send_all(); /* signal that we have stopped listening */
1115
1116 wait_for_streams_stop(stream_count);
1117
1118 PASS("CAP acceptor broadcast reception passed\n");
1119 }
1120
test_cap_acceptor_capture_and_render(void)1121 static void test_cap_acceptor_capture_and_render(void)
1122 {
1123 init();
1124
1125 test_start_adv();
1126
1127 WAIT_FOR_FLAG(flag_connected);
1128
1129 PASS("CAP acceptor unicast passed\n");
1130 }
1131
1132 static const struct bst_test_instance test_cap_acceptor[] = {
1133 {
1134 .test_id = "cap_acceptor_unicast",
1135 .test_pre_init_f = test_init,
1136 .test_tick_f = test_tick,
1137 .test_main_f = test_cap_acceptor_unicast,
1138 },
1139 {
1140 .test_id = "cap_acceptor_unicast_timeout",
1141 .test_pre_init_f = test_init,
1142 .test_tick_f = test_tick,
1143 .test_main_f = test_cap_acceptor_unicast_timeout,
1144 },
1145 {
1146 .test_id = "cap_acceptor_broadcast",
1147 .test_pre_init_f = test_init,
1148 .test_tick_f = test_tick,
1149 .test_main_f = test_cap_acceptor_broadcast,
1150 },
1151 {
1152 .test_id = "cap_acceptor_broadcast_update",
1153 .test_pre_init_f = test_init,
1154 .test_tick_f = test_tick,
1155 .test_main_f = test_cap_acceptor_broadcast_update,
1156 },
1157 {
1158 .test_id = "cap_acceptor_broadcast_reception",
1159 .test_pre_init_f = test_init,
1160 .test_tick_f = test_tick,
1161 .test_main_f = test_cap_acceptor_broadcast_reception,
1162 },
1163 {
1164 .test_id = "cap_acceptor_capture_and_render",
1165 .test_pre_init_f = test_init,
1166 .test_tick_f = test_tick,
1167 .test_main_f = test_cap_acceptor_capture_and_render,
1168 },
1169 BSTEST_END_MARKER,
1170 };
1171
test_cap_acceptor_install(struct bst_test_list * tests)1172 struct bst_test_list *test_cap_acceptor_install(struct bst_test_list *tests)
1173 {
1174 return bst_add_tests(tests, test_cap_acceptor);
1175 }
1176
1177 #else /* !(CONFIG_BT_CAP_ACCEPTOR) */
1178
test_cap_acceptor_install(struct bst_test_list * tests)1179 struct bst_test_list *test_cap_acceptor_install(struct bst_test_list *tests)
1180 {
1181 return tests;
1182 }
1183
1184 #endif /* CONFIG_BT_CAP_ACCEPTOR */
1185