1 /* btp_bap.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 <stdbool.h>
11 #include <stdint.h>
12 #include <stddef.h>
13
14 #include <zephyr/bluetooth/audio/audio.h>
15 #include <zephyr/bluetooth/audio/lc3.h>
16 #include <zephyr/bluetooth/audio/pacs.h>
17 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
18 #include <zephyr/kernel.h>
19 #include <zephyr/logging/log.h>
20 #include <zephyr/sys/util.h>
21 #include <zephyr/types.h>
22 #include <zephyr/sys/byteorder.h>
23
24 #include "btp/btp.h"
25 #include "btp_bap_audio_stream.h"
26 #include "btp_bap_unicast.h"
27 #include "btp_bap_broadcast.h"
28
29 #include <hci_core.h>
30
31 #define LOG_MODULE_NAME bttester_bap
32 LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);
33
34 #define SUPPORTED_SINK_CONTEXT BT_AUDIO_CONTEXT_TYPE_ANY
35 #define SUPPORTED_SOURCE_CONTEXT BT_AUDIO_CONTEXT_TYPE_ANY
36
37 #define AVAILABLE_SINK_CONTEXT SUPPORTED_SINK_CONTEXT
38 #define AVAILABLE_SOURCE_CONTEXT SUPPORTED_SOURCE_CONTEXT
39
40 static const struct bt_audio_codec_cap default_codec_cap = BT_AUDIO_CODEC_CAP_LC3(
41 BT_AUDIO_CODEC_CAP_FREQ_ANY, BT_AUDIO_CODEC_CAP_DURATION_7_5 |
42 BT_AUDIO_CODEC_CAP_DURATION_10, BT_AUDIO_CODEC_CAP_CHAN_COUNT_SUPPORT(1, 2), 26u, 155u, 1u,
43 BT_AUDIO_CONTEXT_TYPE_ANY);
44
45 static const struct bt_audio_codec_cap vendor_codec_cap = BT_AUDIO_CODEC_CAP(
46 0xff, 0xffff, 0xffff, BT_AUDIO_CODEC_CAP_LC3_DATA(BT_AUDIO_CODEC_CAP_FREQ_ANY,
47 BT_AUDIO_CODEC_CAP_DURATION_7_5 | BT_AUDIO_CODEC_CAP_DURATION_10,
48 BT_AUDIO_CODEC_CAP_CHAN_COUNT_SUPPORT(1, 2), 26u, 155, 1u),
49 BT_AUDIO_CODEC_CAP_LC3_META(BT_AUDIO_CONTEXT_TYPE_ANY));
50
51 static struct bt_pacs_cap cap_sink = {
52 .codec_cap = &default_codec_cap,
53 };
54
55 static struct bt_pacs_cap cap_source = {
56 .codec_cap = &default_codec_cap,
57 };
58
59 static struct bt_pacs_cap vendor_cap_sink = {
60 .codec_cap = &vendor_codec_cap,
61 };
62
63 static struct bt_pacs_cap vendor_cap_source = {
64 .codec_cap = &vendor_codec_cap,
65 };
66
btp_ascs_supported_commands(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)67 static uint8_t btp_ascs_supported_commands(const void *cmd, uint16_t cmd_len,
68 void *rsp, uint16_t *rsp_len)
69 {
70 struct btp_ascs_read_supported_commands_rp *rp = rsp;
71
72 *rsp_len = tester_supported_commands(BTP_SERVICE_ID_ASCS, rp->data);
73 *rsp_len += sizeof(*rp);
74
75 return BTP_STATUS_SUCCESS;
76 }
77
78 static const struct btp_handler ascs_handlers[] = {
79 {
80 .opcode = BTP_ASCS_READ_SUPPORTED_COMMANDS,
81 .index = BTP_INDEX_NONE,
82 .expect_len = 0,
83 .func = btp_ascs_supported_commands,
84 },
85 {
86 .opcode = BTP_ASCS_CONFIGURE_CODEC,
87 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
88 .func = btp_ascs_configure_codec,
89 },
90 {
91 .opcode = BTP_ASCS_CONFIGURE_QOS,
92 .expect_len = sizeof(struct btp_ascs_configure_qos_cmd),
93 .func = btp_ascs_configure_qos,
94 },
95 {
96 .opcode = BTP_ASCS_ENABLE,
97 .expect_len = sizeof(struct btp_ascs_enable_cmd),
98 .func = btp_ascs_enable,
99 },
100 {
101 .opcode = BTP_ASCS_RECEIVER_START_READY,
102 .expect_len = sizeof(struct btp_ascs_receiver_start_ready_cmd),
103 .func = btp_ascs_receiver_start_ready,
104 },
105 {
106 .opcode = BTP_ASCS_RECEIVER_STOP_READY,
107 .expect_len = sizeof(struct btp_ascs_receiver_stop_ready_cmd),
108 .func = btp_ascs_receiver_stop_ready,
109 },
110 {
111 .opcode = BTP_ASCS_DISABLE,
112 .expect_len = sizeof(struct btp_ascs_disable_cmd),
113 .func = btp_ascs_disable,
114 },
115 {
116 .opcode = BTP_ASCS_RELEASE,
117 .expect_len = sizeof(struct btp_ascs_release_cmd),
118 .func = btp_ascs_release,
119 },
120 {
121 .opcode = BTP_ASCS_UPDATE_METADATA,
122 .expect_len = sizeof(struct btp_ascs_update_metadata_cmd),
123 .func = btp_ascs_update_metadata,
124 },
125 {
126 .opcode = BTP_ASCS_ADD_ASE_TO_CIS,
127 .expect_len = sizeof(struct btp_ascs_add_ase_to_cis),
128 .func = btp_ascs_add_ase_to_cis,
129 },
130 {
131 .opcode = BTP_ASCS_PRECONFIGURE_QOS,
132 .expect_len = sizeof(struct btp_ascs_preconfigure_qos_cmd),
133 .func = btp_ascs_preconfigure_qos,
134 },
135 };
136
set_location(void)137 static int set_location(void)
138 {
139 int err;
140
141 err = bt_pacs_set_location(BT_AUDIO_DIR_SINK,
142 BT_AUDIO_LOCATION_FRONT_CENTER |
143 BT_AUDIO_LOCATION_FRONT_RIGHT);
144 if (err != 0) {
145 return err;
146 }
147
148 err = bt_pacs_set_location(BT_AUDIO_DIR_SOURCE,
149 (BT_AUDIO_LOCATION_FRONT_LEFT |
150 BT_AUDIO_LOCATION_FRONT_RIGHT));
151 if (err != 0) {
152 return err;
153 }
154
155 return 0;
156 }
157
set_available_contexts(void)158 static int set_available_contexts(void)
159 {
160 int err;
161
162 err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE,
163 AVAILABLE_SOURCE_CONTEXT);
164 if (err != 0) {
165 return err;
166 }
167
168 err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SINK,
169 AVAILABLE_SINK_CONTEXT);
170 if (err != 0) {
171 return err;
172 }
173
174 return 0;
175 }
176
set_supported_contexts(void)177 static int set_supported_contexts(void)
178 {
179 int err;
180
181 err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SOURCE,
182 SUPPORTED_SOURCE_CONTEXT);
183 if (err != 0) {
184 return err;
185 }
186
187 err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SINK,
188 SUPPORTED_SINK_CONTEXT);
189 if (err != 0) {
190 return err;
191 }
192
193 return 0;
194 }
195
pacs_supported_commands(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)196 static uint8_t pacs_supported_commands(const void *cmd, uint16_t cmd_len,
197 void *rsp, uint16_t *rsp_len)
198 {
199 struct btp_pacs_read_supported_commands_rp *rp = rsp;
200
201 *rsp_len = tester_supported_commands(BTP_SERVICE_ID_PACS, rp->data);
202 *rsp_len += sizeof(*rp);
203
204 return BTP_STATUS_SUCCESS;
205 }
206
pacs_update_characteristic(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)207 static uint8_t pacs_update_characteristic(const void *cmd, uint16_t cmd_len,
208 void *rsp, uint16_t *rsp_len)
209 {
210 const struct btp_pacs_update_characteristic_cmd *cp = cmd;
211 int err;
212
213 switch (cp->characteristic) {
214 case BTP_PACS_CHARACTERISTIC_SINK_PAC:
215 err = bt_pacs_cap_unregister(BT_AUDIO_DIR_SINK,
216 &cap_sink);
217 break;
218 case BTP_PACS_CHARACTERISTIC_SOURCE_PAC:
219 err = bt_pacs_cap_unregister(BT_AUDIO_DIR_SOURCE,
220 &cap_source);
221 break;
222 case BTP_PACS_CHARACTERISTIC_SINK_AUDIO_LOCATIONS:
223 err = bt_pacs_set_location(BT_AUDIO_DIR_SINK,
224 BT_AUDIO_LOCATION_FRONT_CENTER |
225 BT_AUDIO_LOCATION_BACK_CENTER);
226 break;
227 case BTP_PACS_CHARACTERISTIC_SOURCE_AUDIO_LOCATIONS:
228 err = bt_pacs_set_location(BT_AUDIO_DIR_SOURCE,
229 (BT_AUDIO_LOCATION_FRONT_LEFT |
230 BT_AUDIO_LOCATION_FRONT_RIGHT |
231 BT_AUDIO_LOCATION_FRONT_CENTER));
232 break;
233 case BTP_PACS_CHARACTERISTIC_AVAILABLE_AUDIO_CONTEXTS:
234 err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE,
235 BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED);
236 break;
237 case BTP_PACS_CHARACTERISTIC_SUPPORTED_AUDIO_CONTEXTS:
238 err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SOURCE,
239 SUPPORTED_SOURCE_CONTEXT |
240 BT_AUDIO_CONTEXT_TYPE_INSTRUCTIONAL);
241 break;
242 default:
243 return BTP_STATUS_FAILED;
244 }
245
246 return BTP_STATUS_VAL(err);
247 }
248
pacs_set_location(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)249 static uint8_t pacs_set_location(const void *cmd, uint16_t cmd_len,
250 void *rsp, uint16_t *rsp_len)
251 {
252 const struct btp_pacs_set_location_cmd *cp = cmd;
253 int err;
254
255 err = bt_pacs_set_location((enum bt_audio_dir)cp->dir,
256 (enum bt_audio_location)cp->location);
257
258 return (err) ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS;
259 }
260
pacs_set_available_contexts(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)261 static uint8_t pacs_set_available_contexts(const void *cmd, uint16_t cmd_len,
262 void *rsp, uint16_t *rsp_len)
263 {
264 const struct btp_pacs_set_available_contexts_cmd *cp = cmd;
265 int err;
266
267 err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SINK,
268 (enum bt_audio_context)cp->sink_contexts);
269 if (err) {
270 return BTP_STATUS_FAILED;
271 }
272 err = bt_pacs_set_available_contexts(BT_AUDIO_DIR_SOURCE,
273 (enum bt_audio_context)cp->source_contexts);
274
275 return (err) ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS;
276 }
277
pacs_set_supported_contexts(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)278 static uint8_t pacs_set_supported_contexts(const void *cmd, uint16_t cmd_len,
279 void *rsp, uint16_t *rsp_len)
280 {
281 const struct btp_pacs_set_supported_contexts_cmd *cp = cmd;
282 int err;
283
284 err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SINK,
285 (enum bt_audio_context)cp->sink_contexts);
286 if (err) {
287 return BTP_STATUS_FAILED;
288 }
289 err = bt_pacs_set_supported_contexts(BT_AUDIO_DIR_SOURCE,
290 (enum bt_audio_context)cp->source_contexts);
291
292 return (err) ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS;
293 }
294
295 static const struct btp_handler pacs_handlers[] = {
296 {
297 .opcode = BTP_PACS_READ_SUPPORTED_COMMANDS,
298 .index = BTP_INDEX_NONE,
299 .expect_len = 0,
300 .func = pacs_supported_commands,
301 },
302 {
303 .opcode = BTP_PACS_UPDATE_CHARACTERISTIC,
304 .expect_len = sizeof(struct btp_pacs_update_characteristic_cmd),
305 .func = pacs_update_characteristic,
306 },
307 {
308 .opcode = BTP_PACS_SET_LOCATION,
309 .expect_len = sizeof(struct btp_pacs_set_location_cmd),
310 .func = pacs_set_location
311 },
312 {
313 .opcode = BTP_PACS_SET_AVAILABLE_CONTEXTS,
314 .expect_len = sizeof(struct btp_pacs_set_available_contexts_cmd),
315 .func = pacs_set_available_contexts
316 },
317 {
318 .opcode = BTP_PACS_SET_SUPPORTED_CONTEXTS,
319 .expect_len = sizeof(struct btp_pacs_set_supported_contexts_cmd),
320 .func = pacs_set_supported_contexts
321 }
322 };
323
btp_bap_supported_commands(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)324 static uint8_t btp_bap_supported_commands(const void *cmd, uint16_t cmd_len,
325 void *rsp, uint16_t *rsp_len)
326 {
327 struct btp_bap_read_supported_commands_rp *rp = rsp;
328
329 *rsp_len = tester_supported_commands(BTP_SERVICE_ID_BAP, rp->data);
330 *rsp_len += sizeof(*rp);
331
332 return BTP_STATUS_SUCCESS;
333 }
334
btp_bap_audio_stream_send(const void * cmd,uint16_t cmd_len,void * rsp,uint16_t * rsp_len)335 uint8_t btp_bap_audio_stream_send(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
336 {
337 struct btp_bap_send_rp *rp = rsp;
338 const struct btp_bap_send_cmd *cp = cmd;
339
340 /* Always send dummy success for now until the command has be deprecated
341 * https://github.com/auto-pts/auto-pts/issues/1317
342 */
343 rp->data_len = cp->data_len;
344 *rsp_len = sizeof(*rp);
345
346 return BTP_STATUS_SUCCESS;
347 }
348
349 static const struct btp_handler bap_handlers[] = {
350 {
351 .opcode = BTP_BAP_READ_SUPPORTED_COMMANDS,
352 .index = BTP_INDEX_NONE,
353 .expect_len = 0,
354 .func = btp_bap_supported_commands,
355 },
356 {
357 .opcode = BTP_BAP_DISCOVER,
358 .expect_len = sizeof(struct btp_bap_discover_cmd),
359 .func = btp_bap_discover,
360 },
361 {
362 .opcode = BTP_BAP_SEND,
363 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
364 .func = btp_bap_audio_stream_send,
365 },
366 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_BROADCAST_SINK)
367 {
368 .opcode = BTP_BAP_BROADCAST_SOURCE_SETUP,
369 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
370 .func = btp_bap_broadcast_source_setup,
371 },
372 {
373 .opcode = BTP_BAP_BROADCAST_SOURCE_SETUP_V2,
374 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
375 .func = btp_bap_broadcast_source_setup_v2,
376 },
377 {
378 .opcode = BTP_BAP_BROADCAST_SOURCE_RELEASE,
379 .expect_len = sizeof(struct btp_bap_broadcast_source_release_cmd),
380 .func = btp_bap_broadcast_source_release,
381 },
382 {
383 .opcode = BTP_BAP_BROADCAST_ADV_START,
384 .expect_len = sizeof(struct btp_bap_broadcast_adv_start_cmd),
385 .func = btp_bap_broadcast_adv_start,
386 },
387 {
388 .opcode = BTP_BAP_BROADCAST_ADV_STOP,
389 .expect_len = sizeof(struct btp_bap_broadcast_adv_stop_cmd),
390 .func = btp_bap_broadcast_adv_stop,
391 },
392 {
393 .opcode = BTP_BAP_BROADCAST_SOURCE_START,
394 .expect_len = sizeof(struct btp_bap_broadcast_source_start_cmd),
395 .func = btp_bap_broadcast_source_start,
396 },
397 {
398 .opcode = BTP_BAP_BROADCAST_SOURCE_STOP,
399 .expect_len = sizeof(struct btp_bap_broadcast_source_stop_cmd),
400 .func = btp_bap_broadcast_source_stop,
401 },
402 {
403 .opcode = BTP_BAP_BROADCAST_SINK_SETUP,
404 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
405 .func = btp_bap_broadcast_sink_setup,
406 },
407 {
408 .opcode = BTP_BAP_BROADCAST_SINK_RELEASE,
409 .expect_len = sizeof(struct btp_bap_broadcast_sink_release_cmd),
410 .func = btp_bap_broadcast_sink_release,
411 },
412 {
413 .opcode = BTP_BAP_BROADCAST_SCAN_START,
414 .expect_len = sizeof(struct btp_bap_broadcast_scan_start_cmd),
415 .func = btp_bap_broadcast_scan_start,
416 },
417 {
418 .opcode = BTP_BAP_BROADCAST_SCAN_STOP,
419 .expect_len = sizeof(struct btp_bap_broadcast_scan_stop_cmd),
420 .func = btp_bap_broadcast_scan_stop,
421 },
422 {
423 .opcode = BTP_BAP_BROADCAST_SINK_SYNC,
424 .expect_len = sizeof(struct btp_bap_broadcast_sink_sync_cmd),
425 .func = btp_bap_broadcast_sink_sync,
426 },
427 {
428 .opcode = BTP_BAP_BROADCAST_SINK_STOP,
429 .expect_len = sizeof(struct btp_bap_broadcast_sink_stop_cmd),
430 .func = btp_bap_broadcast_sink_stop,
431 },
432 {
433 .opcode = BTP_BAP_BROADCAST_SINK_BIS_SYNC,
434 .expect_len = sizeof(struct btp_bap_broadcast_sink_bis_sync_cmd),
435 .func = btp_bap_broadcast_sink_bis_sync,
436 },
437 {
438 .opcode = BTP_BAP_DISCOVER_SCAN_DELEGATORS,
439 .expect_len = sizeof(struct btp_bap_discover_scan_delegators_cmd),
440 .func = btp_bap_broadcast_discover_scan_delegators,
441 },
442 {
443 .opcode = BTP_BAP_BROADCAST_ASSISTANT_SCAN_START,
444 .expect_len = sizeof(struct btp_bap_broadcast_assistant_scan_start_cmd),
445 .func = btp_bap_broadcast_assistant_scan_start,
446 },
447 {
448 .opcode = BTP_BAP_BROADCAST_ASSISTANT_SCAN_STOP,
449 .expect_len = sizeof(struct btp_bap_broadcast_assistant_scan_stop_cmd),
450 .func = btp_bap_broadcast_assistant_scan_stop,
451 },
452 {
453 .opcode = BTP_BAP_ADD_BROADCAST_SRC,
454 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
455 .func = btp_bap_broadcast_assistant_add_src,
456 },
457 {
458 .opcode = BTP_BAP_REMOVE_BROADCAST_SRC,
459 .expect_len = sizeof(struct btp_bap_remove_broadcast_src_cmd),
460 .func = btp_bap_broadcast_assistant_remove_src,
461 },
462 {
463 .opcode = BTP_BAP_MODIFY_BROADCAST_SRC,
464 .expect_len = BTP_HANDLER_LENGTH_VARIABLE,
465 .func = btp_bap_broadcast_assistant_modify_src,
466 },
467 {
468 .opcode = BTP_BAP_SET_BROADCAST_CODE,
469 .expect_len = sizeof(struct btp_bap_set_broadcast_code_cmd),
470 .func = btp_bap_broadcast_assistant_set_broadcast_code,
471 },
472 {
473 .opcode = BTP_BAP_SEND_PAST,
474 .expect_len = sizeof(struct btp_bap_send_past_cmd),
475 .func = btp_bap_broadcast_assistant_send_past,
476 },
477 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_BROADCAST_SINK */
478 };
479
tester_init_pacs(void)480 uint8_t tester_init_pacs(void)
481 {
482 const struct bt_pacs_register_param pacs_param = {
483 #if defined(CONFIG_BT_PAC_SNK)
484 .snk_pac = true,
485 #endif /* CONFIG_BT_PAC_SNK */
486 #if defined(CONFIG_BT_PAC_SNK_LOC)
487 .snk_loc = true,
488 #endif /* CONFIG_BT_PAC_SNK_LOC */
489 #if defined(CONFIG_BT_PAC_SRC)
490 .src_pac = true,
491 #endif /* CONFIG_BT_PAC_SRC */
492 #if defined(CONFIG_BT_PAC_SRC_LOC)
493 .src_loc = true,
494 #endif /* CONFIG_BT_PAC_SRC_LOC */
495 };
496 int err;
497
498 /* PACS shall be registered before ASCS in btp_bap_unicast_init */
499 err = bt_pacs_register(&pacs_param);
500 if (err != 0) {
501 LOG_DBG("Failed to register client callbacks: %d", err);
502 return BTP_STATUS_FAILED;
503 }
504
505 btp_bap_unicast_init();
506
507 bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &cap_sink);
508 bt_pacs_cap_register(BT_AUDIO_DIR_SOURCE, &cap_source);
509 bt_pacs_cap_register(BT_AUDIO_DIR_SINK, &vendor_cap_sink);
510 bt_pacs_cap_register(BT_AUDIO_DIR_SOURCE, &vendor_cap_source);
511
512 err = set_location();
513 if (err != 0) {
514 return BTP_STATUS_FAILED;
515 }
516
517 err = set_supported_contexts();
518 if (err != 0) {
519 return BTP_STATUS_FAILED;
520 }
521
522 err = set_available_contexts();
523 if (err != 0) {
524 return BTP_STATUS_FAILED;
525 }
526
527 tester_register_command_handlers(BTP_SERVICE_ID_PACS, pacs_handlers,
528 ARRAY_SIZE(pacs_handlers));
529
530 return BTP_STATUS_SUCCESS;
531 }
532
tester_unregister_pacs(void)533 uint8_t tester_unregister_pacs(void)
534 {
535 return BTP_STATUS_SUCCESS;
536 }
537
tester_init_ascs(void)538 uint8_t tester_init_ascs(void)
539 {
540 int err;
541
542 err = btp_bap_unicast_init();
543 if (err != 0) {
544 return BTP_STATUS_FAILED;
545 }
546
547 tester_register_command_handlers(BTP_SERVICE_ID_ASCS, ascs_handlers,
548 ARRAY_SIZE(ascs_handlers));
549
550 return BTP_STATUS_SUCCESS;
551 }
552
tester_unregister_ascs(void)553 uint8_t tester_unregister_ascs(void)
554 {
555 return BTP_STATUS_SUCCESS;
556 }
557
tester_init_bap(void)558 uint8_t tester_init_bap(void)
559 {
560 int err;
561
562 err = btp_bap_unicast_init();
563 if (err != 0) {
564 return BTP_STATUS_FAILED;
565 }
566
567 err = btp_bap_broadcast_init();
568 if (err != 0) {
569 return BTP_STATUS_FAILED;
570 }
571
572 btp_bap_audio_stream_tx_init();
573
574 tester_register_command_handlers(BTP_SERVICE_ID_BAP, bap_handlers,
575 ARRAY_SIZE(bap_handlers));
576
577 return BTP_STATUS_SUCCESS;
578 }
579
tester_unregister_bap(void)580 uint8_t tester_unregister_bap(void)
581 {
582 return BTP_STATUS_SUCCESS;
583 }
584