1 /*
2 * Copyright (c) 2021-2023 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 <stdint.h>
10 #include <string.h>
11
12 #include <zephyr/autoconf.h>
13 #include <zephyr/bluetooth/audio/audio.h>
14 #include <zephyr/bluetooth/audio/bap.h>
15 #include <zephyr/bluetooth/audio/pacs.h>
16 #include <zephyr/bluetooth/bluetooth.h>
17 #include <zephyr/bluetooth/byteorder.h>
18 #include <zephyr/bluetooth/conn.h>
19 #include <zephyr/bluetooth/gap.h>
20 #include <zephyr/bluetooth/hci_types.h>
21 #include <zephyr/bluetooth/iso.h>
22 #include <zephyr/bluetooth/uuid.h>
23 #include <zephyr/kernel.h>
24 #include <zephyr/net_buf.h>
25 #include <zephyr/sys/printk.h>
26 #include <zephyr/sys/util.h>
27 #include <zephyr/sys/util_macro.h>
28
29 #include "bap_common.h"
30 #include "bap_stream_rx.h"
31 #include "bap_stream_tx.h"
32 #include "bstests.h"
33 #include "common.h"
34
35 #if defined(CONFIG_BT_BAP_UNICAST_SERVER)
36
37 extern enum bst_result_t bst_result;
38
39 #define CHANNEL_COUNT_1 BIT(0)
40
41 #define PREF_CONTEXT (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)
42
43 static const struct bt_audio_codec_cap lc3_codec_cap = {
44 .path_id = BT_ISO_DATA_PATH_HCI,
45 .id = BT_HCI_CODING_FORMAT_LC3,
46 .cid = 0x0000U,
47 .vid = 0x0000U,
48 .data_len = (3 + 1) + (2 + 1) + (2 + 1) + (5 + 1) + (2 + 1),
49 .data = {
50 BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CAP_TYPE_FREQ,
51 BT_BYTES_LIST_LE16(BT_AUDIO_CODEC_CAP_FREQ_16KHZ)),
52 BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CAP_TYPE_DURATION,
53 BT_AUDIO_CODEC_CAP_DURATION_10),
54 BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CAP_TYPE_CHAN_COUNT, CHANNEL_COUNT_1),
55 BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CAP_TYPE_FRAME_LEN,
56 BT_BYTES_LIST_LE16(40U), BT_BYTES_LIST_LE16(40U)),
57 BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_CAP_TYPE_FRAME_COUNT, 1U),
58 },
59 .meta_len = (5 + 1) + (LONG_META_LEN + 1U),
60 .meta = {
61 BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PREF_CONTEXT,
62 BT_BYTES_LIST_LE32(PREF_CONTEXT)),
63 BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_VENDOR, LONG_META),
64 },
65 };
66
67 static struct audio_test_stream
68 test_streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT + CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT];
69
70 static const struct bt_bap_qos_cfg_pref qos_pref =
71 BT_BAP_QOS_CFG_PREF(true, BT_GAP_LE_PHY_2M, 0x02, 10, 40000, 40000, 40000, 40000);
72
73 static uint8_t unicast_server_addata[] = {
74 BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL), /* ASCS UUID */
75 BT_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED, /* Target Announcement */
76 BT_BYTES_LIST_LE16(PREF_CONTEXT),
77 BT_BYTES_LIST_LE16(PREF_CONTEXT),
78 0x00, /* Metadata length */
79 };
80
81 static const struct bt_data unicast_server_ad[] = {
82 BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
83 BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL)),
84 BT_DATA(BT_DATA_SVC_DATA16, unicast_server_addata, ARRAY_SIZE(unicast_server_addata)),
85 };
86 static struct bt_le_ext_adv *ext_adv;
87
88 CREATE_FLAG(flag_stream_configured);
89 CREATE_FLAG(flag_stream_started);
print_ase_info(struct bt_bap_ep * ep,void * user_data)90 static void print_ase_info(struct bt_bap_ep *ep, void *user_data)
91 {
92 struct bt_bap_ep_info info;
93
94 bt_bap_ep_get_info(ep, &info);
95 printk("ASE info: id %u state %u dir %u\n", info.id, info.state, info.dir);
96 }
97
stream_alloc(void)98 static struct bt_bap_stream *stream_alloc(void)
99 {
100 for (size_t i = 0; i < ARRAY_SIZE(test_streams); i++) {
101 struct bt_bap_stream *stream = bap_stream_from_audio_test_stream(&test_streams[i]);
102
103 if (!stream->conn) {
104 return stream;
105 }
106 }
107
108 return NULL;
109 }
110
lc3_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)111 static int lc3_config(struct bt_conn *conn, const struct bt_bap_ep *ep, enum bt_audio_dir dir,
112 const struct bt_audio_codec_cfg *codec_cfg, struct bt_bap_stream **stream,
113 struct bt_bap_qos_cfg_pref *const pref, struct bt_bap_ascs_rsp *rsp)
114 {
115 printk("ASE Codec Config: conn %p ep %p dir %u\n", conn, ep, dir);
116
117 print_codec_cfg(codec_cfg);
118
119 *stream = stream_alloc();
120 if (*stream == NULL) {
121 printk("No test_streams available\n");
122 *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_NO_MEM, BT_BAP_ASCS_REASON_NONE);
123 return -ENOMEM;
124 }
125
126 printk("ASE Codec Config stream %p\n", *stream);
127
128 bt_bap_unicast_server_foreach_ep(conn, print_ase_info, NULL);
129
130 SET_FLAG(flag_stream_configured);
131
132 *pref = qos_pref;
133
134 return 0;
135 }
136
lc3_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)137 static int lc3_reconfig(struct bt_bap_stream *stream, enum bt_audio_dir dir,
138 const struct bt_audio_codec_cfg *codec_cfg,
139 struct bt_bap_qos_cfg_pref *const pref, struct bt_bap_ascs_rsp *rsp)
140 {
141 printk("ASE Codec Reconfig: stream %p\n", stream);
142
143 print_codec_cfg(codec_cfg);
144 *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_UNSUPPORTED, BT_BAP_ASCS_REASON_NONE);
145
146 /* We only support one QoS at the moment, reject changes */
147 return -ENOEXEC;
148 }
149
lc3_qos(struct bt_bap_stream * stream,const struct bt_bap_qos_cfg * qos,struct bt_bap_ascs_rsp * rsp)150 static int lc3_qos(struct bt_bap_stream *stream, const struct bt_bap_qos_cfg *qos,
151 struct bt_bap_ascs_rsp *rsp)
152 {
153 struct audio_test_stream *test_stream = audio_test_stream_from_bap_stream(stream);
154
155 printk("QoS: stream %p qos %p\n", stream, qos);
156
157 print_qos(qos);
158
159 test_stream->tx_sdu_size = qos->sdu;
160
161 return 0;
162 }
163
lc3_enable(struct bt_bap_stream * stream,const uint8_t meta[],size_t meta_len,struct bt_bap_ascs_rsp * rsp)164 static int lc3_enable(struct bt_bap_stream *stream, const uint8_t meta[], size_t meta_len,
165 struct bt_bap_ascs_rsp *rsp)
166 {
167 printk("Enable: stream %p meta_len %zu\n", stream, meta_len);
168
169 return 0;
170 }
171
lc3_start(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)172 static int lc3_start(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
173 {
174 printk("Start: stream %p\n", stream);
175
176 return 0;
177 }
178
data_func_cb(struct bt_data * data,void * user_data)179 static bool data_func_cb(struct bt_data *data, void *user_data)
180 {
181 struct bt_bap_ascs_rsp *rsp = (struct bt_bap_ascs_rsp *)user_data;
182
183 if (!BT_AUDIO_METADATA_TYPE_IS_KNOWN(data->type)) {
184 printk("Invalid metadata type %u or length %u\n", data->type, data->data_len);
185 *rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_METADATA_REJECTED, data->type);
186 return false;
187 }
188
189 return true;
190 }
191
lc3_metadata(struct bt_bap_stream * stream,const uint8_t meta[],size_t meta_len,struct bt_bap_ascs_rsp * rsp)192 static int lc3_metadata(struct bt_bap_stream *stream, const uint8_t meta[], size_t meta_len,
193 struct bt_bap_ascs_rsp *rsp)
194 {
195 printk("Metadata: stream %p meta_len %zu\n", stream, meta_len);
196
197 return bt_audio_data_parse(meta, meta_len, data_func_cb, rsp);
198 }
199
lc3_disable(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)200 static int lc3_disable(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
201 {
202 printk("Disable: stream %p\n", stream);
203
204 return 0;
205 }
206
lc3_stop(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)207 static int lc3_stop(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
208 {
209 printk("Stop: stream %p\n", stream);
210
211 return 0;
212 }
213
lc3_release(struct bt_bap_stream * stream,struct bt_bap_ascs_rsp * rsp)214 static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp)
215 {
216 printk("Release: stream %p\n", stream);
217
218 return 0;
219 }
220
221 static struct bt_bap_unicast_server_register_param param = {
222 CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT,
223 CONFIG_BT_ASCS_MAX_ASE_SRC_COUNT
224 };
225
226 static const struct bt_bap_unicast_server_cb unicast_server_cb = {
227 .config = lc3_config,
228 .reconfig = lc3_reconfig,
229 .qos = lc3_qos,
230 .enable = lc3_enable,
231 .start = lc3_start,
232 .metadata = lc3_metadata,
233 .disable = lc3_disable,
234 .stop = lc3_stop,
235 .release = lc3_release,
236 };
237
stream_enabled_cb(struct bt_bap_stream * stream)238 static void stream_enabled_cb(struct bt_bap_stream *stream)
239 {
240 struct bt_bap_ep_info ep_info;
241 int err;
242
243 printk("Enabled: stream %p\n", stream);
244
245 err = bt_bap_ep_get_info(stream->ep, &ep_info);
246 if (err != 0) {
247 FAIL("Failed to get ep info: %d\n", err);
248 return;
249 }
250
251 if (ep_info.dir == BT_AUDIO_DIR_SINK) {
252 /* Automatically do the receiver start ready operation */
253 err = bt_bap_stream_start(stream);
254
255 if (err != 0) {
256 FAIL("Failed to start stream: %d\n", err);
257 return;
258 }
259 }
260 }
261
stream_started_cb(struct bt_bap_stream * stream)262 static void stream_started_cb(struct bt_bap_stream *stream)
263 {
264 printk("Started: stream %p\n", stream);
265
266 if (bap_stream_tx_can_send(stream)) {
267 int err;
268
269 err = bap_stream_tx_register(stream);
270 if (err != 0) {
271 FAIL("Failed to register stream %p for TX: %d\n", stream, err);
272 return;
273 }
274 }
275
276 SET_FLAG(flag_stream_started);
277 }
278
stream_stopped_cb(struct bt_bap_stream * stream,uint8_t reason)279 static void stream_stopped_cb(struct bt_bap_stream *stream, uint8_t reason)
280 {
281 printk("Stopped stream %p with reason 0x%02X\n", stream, reason);
282
283 if (bap_stream_tx_can_send(stream)) {
284 int err;
285
286 err = bap_stream_tx_unregister(stream);
287 if (err != 0) {
288 FAIL("Failed to unregister stream %p for TX: %d\n", stream, err);
289 return;
290 }
291 }
292 }
293
294 static struct bt_bap_stream_ops stream_ops = {
295 .enabled = stream_enabled_cb,
296 .started = stream_started_cb,
297 .stopped = stream_stopped_cb,
298 .recv = bap_stream_rx_recv_cb,
299 .sent = bap_stream_tx_sent_cb,
300 };
301
transceive_test_streams(void)302 static void transceive_test_streams(void)
303 {
304 struct bt_bap_stream *source_stream = NULL;
305 struct bt_bap_stream *sink_stream = NULL;
306 struct bt_bap_ep_info info;
307 int err;
308
309 for (size_t i = 0U; i < ARRAY_SIZE(test_streams); i++) {
310 struct bt_bap_stream *stream = bap_stream_from_audio_test_stream(&test_streams[i]);
311
312 if (stream->ep == NULL) {
313 break;
314 }
315
316 while (true) {
317 err = bt_bap_ep_get_info(stream->ep, &info);
318 if (err != 0) {
319 FAIL("Failed to get endpoint info for stream[%zu] %p: %d\n", i,
320 stream, err);
321 return;
322 }
323
324 /* Ensure that all configured test_streams are in the streaming state before
325 * starting TX and RX
326 */
327 if (info.state == BT_BAP_EP_STATE_STREAMING) {
328 break;
329 }
330
331 k_sleep(K_MSEC(100));
332 }
333
334 if (info.dir == BT_AUDIO_DIR_SINK && sink_stream == NULL) {
335 sink_stream = stream;
336 } else if (info.dir == BT_AUDIO_DIR_SOURCE && source_stream == NULL) {
337 source_stream = stream;
338 }
339 }
340
341 if (source_stream != NULL) {
342 struct audio_test_stream *test_stream =
343 audio_test_stream_from_bap_stream(source_stream);
344
345 /* Keep sending until we reach the minimum expected */
346 while (test_stream->tx_cnt < MIN_SEND_COUNT) {
347 k_sleep(K_MSEC(100));
348 }
349 }
350
351 if (sink_stream != NULL) {
352 printk("Waiting for data\n");
353 WAIT_FOR_FLAG(flag_audio_received);
354 }
355 }
356
set_location(void)357 static void set_location(void)
358 {
359 int err;
360
361 if (IS_ENABLED(CONFIG_BT_PAC_SNK_LOC)) {
362 err = bt_pacs_set_location(BT_AUDIO_DIR_SINK, BT_AUDIO_LOCATION_FRONT_CENTER);
363 if (err != 0) {
364 FAIL("Failed to set sink location (err %d)\n", err);
365 return;
366 }
367 }
368
369 if (IS_ENABLED(CONFIG_BT_PAC_SRC_LOC)) {
370 err = bt_pacs_set_location(BT_AUDIO_DIR_SOURCE, (BT_AUDIO_LOCATION_FRONT_LEFT |
371 BT_AUDIO_LOCATION_FRONT_RIGHT));
372 if (err != 0) {
373 FAIL("Failed to set source location (err %d)\n", err);
374 return;
375 }
376 }
377
378 printk("Location successfully set\n");
379 }
380
set_available_contexts(void)381 static void set_available_contexts(void)
382 {
383 int err;
384
385 err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SINK,
386 BT_AUDIO_CONTEXT_TYPE_MEDIA |
387 BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL);
388 if (IS_ENABLED(CONFIG_BT_PAC_SNK) && err != 0) {
389 FAIL("Failed to set sink supported contexts (err %d)\n", err);
390 return;
391 }
392
393 err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SINK,
394 BT_AUDIO_CONTEXT_TYPE_MEDIA |
395 BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL);
396 if (IS_ENABLED(CONFIG_BT_PAC_SNK) && err != 0) {
397 FAIL("Failed to set sink available contexts (err %d)\n", err);
398 return;
399 }
400
401 err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SOURCE,
402 BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS);
403 if (IS_ENABLED(CONFIG_BT_PAC_SRC) && err != 0) {
404 FAIL("Failed to set source supported contexts (err %d)\n", err);
405 return;
406 }
407
408 err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE,
409 BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS);
410 if (IS_ENABLED(CONFIG_BT_PAC_SRC) && err != 0) {
411 FAIL("Failed to set source available contexts (err %d)\n", err);
412 return;
413 }
414
415 printk("Available contexts successfully set\n");
416 }
417
init(void)418 static void init(void)
419 {
420 static struct bt_pacs_cap cap = {
421 .codec_cap = &lc3_codec_cap,
422 };
423 int err;
424
425 err = bt_enable(NULL);
426 if (err != 0) {
427 FAIL("Bluetooth enable failed (err %d)\n", err);
428 return;
429 }
430
431 printk("Bluetooth initialized\n");
432 bap_stream_tx_init();
433
434 err = bt_bap_unicast_server_register(¶m);
435 if (err != 0) {
436 FAIL("Failed to register unicast server (err %d)\n", err);
437
438 return;
439 }
440
441 bt_bap_unicast_server_register_cb(&unicast_server_cb);
442
443 err = bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap);
444 if (err != 0) {
445 FAIL("Failed to register capabilities: %d", err);
446 return;
447 }
448
449 err = bt_pacs_cap_register(BT_AUDIO_DIR_SOURCE, &cap);
450 if (err != 0) {
451 FAIL("Failed to register capabilities: %d", err);
452 return;
453 }
454
455 set_location();
456 set_available_contexts();
457
458 for (size_t i = 0; i < ARRAY_SIZE(test_streams); i++) {
459 bt_bap_stream_cb_register(bap_stream_from_audio_test_stream(&test_streams[i]),
460 &stream_ops);
461 }
462
463 /* Create a connectable advertising set */
464 err = bt_le_ext_adv_create(BT_LE_EXT_ADV_CONN, NULL, &ext_adv);
465 if (err != 0) {
466 FAIL("Failed to create advertising set (err %d)\n", err);
467 return;
468 }
469
470 err = bt_le_ext_adv_set_data(ext_adv, unicast_server_ad, ARRAY_SIZE(unicast_server_ad),
471 NULL, 0);
472 if (err != 0) {
473 FAIL("Failed to set advertising data (err %d)\n", err);
474 return;
475 }
476
477 err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT);
478 if (err != 0) {
479 FAIL("Failed to start advertising set (err %d)\n", err);
480 return;
481 }
482 printk("Advertising started\n");
483 }
484
test_main(void)485 static void test_main(void)
486 {
487 init();
488
489 /* TODO: When babblesim supports ISO, wait for audio stream to pass */
490
491 WAIT_FOR_FLAG(flag_connected);
492 WAIT_FOR_FLAG(flag_stream_configured);
493
494
495 WAIT_FOR_FLAG(flag_stream_started);
496 transceive_test_streams();
497 WAIT_FOR_UNSET_FLAG(flag_connected);
498 PASS("Unicast server passed\n");
499 }
500
restart_adv_cb(struct k_work * work)501 static void restart_adv_cb(struct k_work *work)
502 {
503 int err;
504
505 printk("Restarting ext_adv after disconnect\n");
506
507 err = bt_le_ext_adv_start(ext_adv, BT_LE_EXT_ADV_START_DEFAULT);
508 if (err != 0) {
509 if (err != -EALREADY) {
510 FAIL("Failed to start advertising set (err %d)\n", err);
511 return;
512 }
513 }
514 }
515
516 static K_WORK_DEFINE(restart_adv_work, restart_adv_cb);
517
acl_disconnected(struct bt_conn * conn,uint8_t reason)518 static void acl_disconnected(struct bt_conn *conn, uint8_t reason)
519 {
520 if (conn != default_conn) {
521 return;
522 }
523
524 k_work_submit(&restart_adv_work);
525 }
526
test_main_acl_disconnect(void)527 static void test_main_acl_disconnect(void)
528 {
529 struct bt_le_ext_adv *dummy_ext_adv[CONFIG_BT_MAX_CONN - 1];
530 static struct bt_conn_cb conn_callbacks = {
531 .disconnected = acl_disconnected,
532 };
533
534 init();
535
536 stream_ops.recv = NULL; /* We do not care about data in this test */
537
538 /* Create CONFIG_BT_MAX_CONN - 1 dummy advertising sets, to ensure that we only have 1 free
539 * connection when attempting to restart advertising, which should ensure that the
540 * bt_conn object is properly unref'ed by the stack
541 */
542 for (size_t i = 0U; i < ARRAY_SIZE(dummy_ext_adv); i++) {
543 const struct bt_le_adv_param param = BT_LE_ADV_PARAM_INIT(
544 (BT_LE_ADV_OPT_EXT_ADV | BT_LE_ADV_OPT_CONN), BT_GAP_ADV_SLOW_INT_MAX,
545 BT_GAP_ADV_SLOW_INT_MAX, NULL);
546 int err;
547
548 err = bt_le_ext_adv_create(¶m, NULL, &dummy_ext_adv[i]);
549 if (err != 0) {
550 FAIL("Failed to create advertising set[%zu] (err %d)\n", i, err);
551 return;
552 }
553
554 err = bt_le_ext_adv_start(dummy_ext_adv[i], BT_LE_EXT_ADV_START_DEFAULT);
555 if (err != 0) {
556 FAIL("Failed to start advertising set[%zu] (err %d)\n", i, err);
557 return;
558 }
559 }
560
561 bt_conn_cb_register(&conn_callbacks);
562
563 WAIT_FOR_FLAG(flag_connected);
564 WAIT_FOR_FLAG(flag_stream_configured);
565
566 /* The client will reconnect */
567 WAIT_FOR_UNSET_FLAG(flag_connected);
568 WAIT_FOR_FLAG(flag_connected);
569 PASS("Unicast server ACL disconnect passed\n");
570 }
571
572 static const struct bst_test_instance test_unicast_server[] = {
573 {
574 .test_id = "unicast_server",
575 .test_pre_init_f = test_init,
576 .test_tick_f = test_tick,
577 .test_main_f = test_main,
578 },
579 {
580 .test_id = "unicast_server_acl_disconnect",
581 .test_pre_init_f = test_init,
582 .test_tick_f = test_tick,
583 .test_main_f = test_main_acl_disconnect,
584 },
585 BSTEST_END_MARKER,
586 };
587
test_unicast_server_install(struct bst_test_list * tests)588 struct bst_test_list *test_unicast_server_install(struct bst_test_list *tests)
589 {
590 return bst_add_tests(tests, test_unicast_server);
591 }
592
593 #else /* !(CONFIG_BT_BAP_UNICAST_SERVER) */
594
test_unicast_server_install(struct bst_test_list * tests)595 struct bst_test_list *test_unicast_server_install(struct bst_test_list *tests)
596 {
597 return tests;
598 }
599
600 #endif /* CONFIG_BT_BAP_UNICAST_SERVER */
601