1 /*
2 * Copyright (c) 2023 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <stdbool.h>
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <string.h>
10
11 #include <zephyr/autoconf.h>
12 #include <zephyr/bluetooth/addr.h>
13 #include <zephyr/bluetooth/audio/audio.h>
14 #include <zephyr/bluetooth/audio/bap.h>
15 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
16 #include <zephyr/bluetooth/audio/cap.h>
17 #include <zephyr/bluetooth/audio/csip.h>
18 #include <zephyr/bluetooth/audio/micp.h>
19 #include <zephyr/bluetooth/audio/vcp.h>
20 #include <zephyr/bluetooth/bluetooth.h>
21 #include <zephyr/bluetooth/byteorder.h>
22 #include <zephyr/bluetooth/conn.h>
23 #include <zephyr/bluetooth/gap.h>
24 #include <zephyr/bluetooth/gatt.h>
25 #include <zephyr/bluetooth/hci_types.h>
26 #include <zephyr/bluetooth/iso.h>
27 #include <zephyr/bluetooth/uuid.h>
28 #include <zephyr/kernel.h>
29 #include <zephyr/net_buf.h>
30 #include <zephyr/sys/byteorder.h>
31 #include <zephyr/sys/printk.h>
32 #include <zephyr/sys/util.h>
33 #include <zephyr/sys/util_macro.h>
34
35 #include "bstests.h"
36 #include "common.h"
37 #include "bap_common.h"
38
39 #if defined(CONFIG_BT_CAP_COMMANDER)
40
41 #define SEM_TIMEOUT K_SECONDS(5)
42
43 extern enum bst_result_t bst_result;
44
45 static struct bt_conn *connected_conns[CONFIG_BT_MAX_CONN];
46 static volatile size_t connected_conn_cnt;
47
48 static struct bt_le_scan_recv_info broadcaster_info;
49 static bt_addr_le_t broadcaster_addr;
50 static struct bt_le_per_adv_sync *g_pa_sync;
51 static uint32_t broadcaster_broadcast_id;
52
53 static uint8_t received_base[UINT8_MAX];
54 static uint8_t received_base_size;
55 static uint8_t src_id[CONFIG_BT_MAX_CONN];
56
57 static struct k_sem sem_disconnected;
58 static struct k_sem sem_cas_discovered;
59 static struct k_sem sem_vcs_discovered;
60 static struct k_sem sem_mics_discovered;
61 static struct k_sem sem_bass_discovered;
62
63 CREATE_FLAG(flag_mtu_exchanged);
64 CREATE_FLAG(flag_volume_changed);
65 CREATE_FLAG(flag_volume_mute_changed);
66 CREATE_FLAG(flag_volume_offset_changed);
67 CREATE_FLAG(flag_microphone_mute_changed);
68 CREATE_FLAG(flag_microphone_gain_changed);
69
70 CREATE_FLAG(flag_broadcast_reception_start);
71 CREATE_FLAG(flag_broadcast_reception_stop);
72 CREATE_FLAG(flag_broadcaster_found);
73 CREATE_FLAG(flag_base_received);
74 CREATE_FLAG(flag_recv_state_updated_with_bis_sync);
75 CREATE_FLAG(flag_pa_synced);
76 CREATE_FLAG(flag_pa_sync_lost);
77 CREATE_FLAG(flag_syncable);
78
cap_discovery_complete_cb(struct bt_conn * conn,int err,const struct bt_csip_set_coordinator_set_member * member,const struct bt_csip_set_coordinator_csis_inst * csis_inst)79 static void cap_discovery_complete_cb(struct bt_conn *conn, int err,
80 const struct bt_csip_set_coordinator_set_member *member,
81 const struct bt_csip_set_coordinator_csis_inst *csis_inst)
82 {
83 if (err != 0) {
84 FAIL("Discover failed on %p: %d\n", (void *)conn, err);
85
86 return;
87 }
88
89 if (IS_ENABLED(CONFIG_BT_CAP_ACCEPTOR_SET_MEMBER)) {
90 if (csis_inst == NULL) {
91 FAIL("Failed to discover CAS CSIS");
92
93 return;
94 }
95
96 printk("Found CAS on %p with CSIS %p\n", (void *)conn, csis_inst);
97 } else {
98 printk("Found CAS on %p\n", (void *)conn);
99 }
100
101 k_sem_give(&sem_cas_discovered);
102 }
103
104 #if defined(CONFIG_BT_VCP_VOL_CTLR)
cap_volume_changed_cb(struct bt_conn * conn,int err)105 static void cap_volume_changed_cb(struct bt_conn *conn, int err)
106 {
107 if (err != 0) {
108 FAIL("Failed to change volume for conn %p: %d\n", conn, err);
109 return;
110 }
111
112 SET_FLAG(flag_volume_changed);
113 }
114
cap_volume_mute_changed_cb(struct bt_conn * conn,int err)115 static void cap_volume_mute_changed_cb(struct bt_conn *conn, int err)
116 {
117 if (err != 0) {
118 FAIL("Failed to change volume mute for conn %p: %d\n", conn, err);
119 return;
120 }
121
122 SET_FLAG(flag_volume_mute_changed);
123 }
124
125 #if defined(CONFIG_BT_VCP_VOL_CTLR_VOCS)
cap_volume_offset_changed_cb(struct bt_conn * conn,int err)126 static void cap_volume_offset_changed_cb(struct bt_conn *conn, int err)
127 {
128 if (err != 0) {
129 FAIL("Failed to change volume offset for conn %p: %d\n", conn, err);
130 return;
131 }
132
133 SET_FLAG(flag_volume_offset_changed);
134 }
135 #endif /* CONFIG_BT_VCP_VOL_CTLR_VOCS */
136 #endif /* CONFIG_BT_VCP_VOL_CTLR */
137
138 #if defined(CONFIG_BT_MICP_MIC_CTLR)
cap_microphone_mute_changed_cb(struct bt_conn * conn,int err)139 static void cap_microphone_mute_changed_cb(struct bt_conn *conn, int err)
140 {
141 if (err != 0) {
142 FAIL("Failed to change microphone mute for conn %p: %d\n", conn, err);
143 return;
144 }
145
146 SET_FLAG(flag_microphone_mute_changed);
147 }
148
149 #if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
cap_microphone_gain_changed_cb(struct bt_conn * conn,int err)150 static void cap_microphone_gain_changed_cb(struct bt_conn *conn, int err)
151 {
152 if (err != 0) {
153 FAIL("Failed to change microphone gain for conn %p: %d\n", conn, err);
154 return;
155 }
156
157 SET_FLAG(flag_microphone_gain_changed);
158 }
159 #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */
160 #endif /* CONFIG_BT_MICP_MIC_CTLR */
161
162 #if defined(CONFIG_BT_BAP_BROADCAST_ASSISTANT)
cap_broadcast_reception_start_cb(struct bt_conn * conn,int err)163 static void cap_broadcast_reception_start_cb(struct bt_conn *conn, int err)
164 {
165 if (err != 0) {
166 FAIL("Failed to perform broadcast reception start for conn %p: %d\n", conn, err);
167 return;
168 }
169
170 SET_FLAG(flag_broadcast_reception_start);
171 }
172
cap_broadcast_reception_stop_cb(struct bt_conn * conn,int err)173 static void cap_broadcast_reception_stop_cb(struct bt_conn *conn, int err)
174 {
175 if (err != 0) {
176 FAIL("Failed to perform broadcast reception stop for conn %p: %d\n", conn, err);
177 return;
178 }
179
180 SET_FLAG(flag_broadcast_reception_stop);
181 }
182 #endif /* CONFIG_BT_BAP_BROADCAST_ASSISTANT*/
183
184 static struct bt_cap_commander_cb cap_cb = {
185 .discovery_complete = cap_discovery_complete_cb,
186 #if defined(CONFIG_BT_VCP_VOL_CTLR)
187 .volume_changed = cap_volume_changed_cb,
188 .volume_mute_changed = cap_volume_mute_changed_cb,
189 #if defined(CONFIG_BT_VCP_VOL_CTLR_VOCS)
190 .volume_offset_changed = cap_volume_offset_changed_cb,
191 #endif /* CONFIG_BT_VCP_VOL_CTLR_VOCS */
192 #endif /* CONFIG_BT_VCP_VOL_CTLR */
193 #if defined(CONFIG_BT_MICP_MIC_CTLR)
194 .microphone_mute_changed = cap_microphone_mute_changed_cb,
195 #if defined(CONFIG_BT_MICP_MIC_CTLR_AICS)
196 .microphone_gain_changed = cap_microphone_gain_changed_cb,
197 #endif /* CONFIG_BT_MICP_MIC_CTLR_AICS */
198 #endif /* CONFIG_BT_MICP_MIC_CTLR */
199 #if defined(CONFIG_BT_BAP_BROADCAST_ASSISTANT)
200 .broadcast_reception_start = cap_broadcast_reception_start_cb,
201 .broadcast_reception_stop = cap_broadcast_reception_stop_cb,
202 #endif /* CONFIG_BT_BAP_BROADCAST_ASSISTANT*/
203 };
204
cap_vcp_discover_cb(struct bt_vcp_vol_ctlr * vol_ctlr,int err,uint8_t vocs_count,uint8_t aics_count)205 static void cap_vcp_discover_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err, uint8_t vocs_count,
206 uint8_t aics_count)
207 {
208 if (err != 0) {
209 FAIL("Failed to discover VCS: %d\n", err);
210
211 return;
212 }
213
214 printk("VCS for %p found with %u VOCS and %u AICS\n", vol_ctlr, vocs_count, aics_count);
215 k_sem_give(&sem_vcs_discovered);
216 }
217
cap_vcp_state_cb(struct bt_vcp_vol_ctlr * vol_ctlr,int err,uint8_t volume,uint8_t mute)218 static void cap_vcp_state_cb(struct bt_vcp_vol_ctlr *vol_ctlr, int err, uint8_t volume,
219 uint8_t mute)
220 {
221 if (err != 0) {
222 FAIL("VCP state cb err (%d)\n", err);
223 return;
224 }
225
226 printk("State for %p: volume %u, mute %u\n", vol_ctlr, volume, mute);
227 }
228
229 static struct bt_vcp_vol_ctlr_cb vcp_cb = {
230 .discover = cap_vcp_discover_cb,
231 .state = cap_vcp_state_cb,
232 };
233
cap_micp_discover_cb(struct bt_micp_mic_ctlr * mic_ctlr,int err,uint8_t aics_count)234 static void cap_micp_discover_cb(struct bt_micp_mic_ctlr *mic_ctlr, int err, uint8_t aics_count)
235 {
236 if (err != 0) {
237 FAIL("Failed to discover MICS: %d\n", err);
238
239 return;
240 }
241
242 printk("MICS for %p found with %u AICS\n", mic_ctlr, aics_count);
243 k_sem_give(&sem_mics_discovered);
244 }
245
246 static struct bt_micp_mic_ctlr_cb micp_cb = {
247 .discover = cap_micp_discover_cb,
248 };
249
att_mtu_updated(struct bt_conn * conn,uint16_t tx,uint16_t rx)250 static void att_mtu_updated(struct bt_conn *conn, uint16_t tx, uint16_t rx)
251 {
252 printk("MTU exchanged\n");
253 SET_FLAG(flag_mtu_exchanged);
254 }
255
256 static struct bt_gatt_cb gatt_callbacks = {
257 .att_mtu_updated = att_mtu_updated,
258 };
259
cap_disconnected_cb(struct bt_conn * conn,uint8_t reason)260 static void cap_disconnected_cb(struct bt_conn *conn, uint8_t reason)
261 {
262 k_sem_give(&sem_disconnected);
263 }
264
pa_sync_create(void)265 static int pa_sync_create(void)
266 {
267 struct bt_le_per_adv_sync_param create_params = {0};
268 int err;
269
270 bt_addr_le_copy(&create_params.addr, &broadcaster_addr);
271 create_params.options = 0;
272 create_params.sid = broadcaster_info.sid;
273 create_params.skip = PA_SYNC_SKIP;
274 create_params.timeout = interval_to_sync_timeout(broadcaster_info.interval);
275
276 err = bt_le_per_adv_sync_create(&create_params, &g_pa_sync);
277 return err;
278 }
279
scan_check_and_sync_broadcast(struct bt_data * data,void * user_data)280 static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data)
281 {
282 const struct bt_le_scan_recv_info *info = user_data;
283 char le_addr[BT_ADDR_LE_STR_LEN];
284 struct bt_uuid_16 adv_uuid;
285 uint32_t broadcast_id;
286
287 if (TEST_FLAG(flag_broadcaster_found)) {
288 /* no-op*/
289 printk("NO OP\n");
290 return false;
291 }
292
293 if (data->type != BT_DATA_SVC_DATA16) {
294 return true;
295 }
296
297 if (data->data_len < BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE) {
298 return true;
299 }
300
301 if (!bt_uuid_create(&adv_uuid.uuid, data->data, BT_UUID_SIZE_16)) {
302 return true;
303 }
304
305 if (bt_uuid_cmp(&adv_uuid.uuid, BT_UUID_BROADCAST_AUDIO)) {
306 return true;
307 }
308
309 broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16);
310
311 bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr));
312
313 printk("Found broadcaster with ID 0x%06X and addr %s and sid 0x%02X\n", broadcast_id,
314 le_addr, info->sid);
315 printk("Adv type %02X interval %u\n", info->adv_type, info->interval);
316
317 SET_FLAG(flag_broadcaster_found);
318
319 /* Store info for PA sync parameters */
320 memcpy(&broadcaster_info, info, sizeof(broadcaster_info));
321 bt_addr_le_copy(&broadcaster_addr, info->addr);
322 broadcaster_broadcast_id = broadcast_id;
323
324 /* Stop parsing */
325 return false;
326 }
327
broadcast_scan_recv(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad)328 static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad)
329 {
330 if (info->interval != 0U) {
331 bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)info);
332 }
333 }
334
335 static struct bt_le_scan_cb bap_scan_cb = {
336 .recv = broadcast_scan_recv,
337 };
338
bap_pa_sync_synced_cb(struct bt_le_per_adv_sync * sync,struct bt_le_per_adv_sync_synced_info * info)339 static void bap_pa_sync_synced_cb(struct bt_le_per_adv_sync *sync,
340 struct bt_le_per_adv_sync_synced_info *info)
341 {
342 if (sync == g_pa_sync) {
343 printk("PA sync %p synced for broadcast sink with broadcast ID 0x%06X\n", sync,
344 broadcaster_broadcast_id);
345 SET_FLAG(flag_pa_synced);
346 }
347 }
348
bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_term_info * info)349 static void bap_pa_sync_terminated_cb(struct bt_le_per_adv_sync *sync,
350 const struct bt_le_per_adv_sync_term_info *info)
351 {
352 if (sync == g_pa_sync) {
353 printk("CAP commander test PA sync %p lost with reason %u\n", sync, info->reason);
354 g_pa_sync = NULL;
355
356 SET_FLAG(flag_pa_sync_lost);
357 }
358 }
359
base_store(struct bt_data * data,void * user_data)360 static bool base_store(struct bt_data *data, void *user_data)
361 {
362 const struct bt_bap_base *base = bt_bap_base_get_base_from_ad(data);
363 uint8_t base_size;
364 int base_subgroup_count;
365
366 /* Base is NULL if the data does not contain a valid BASE */
367 if (base == NULL) {
368 return true;
369 }
370
371 /* Can not fit all the received subgroups with the size CONFIG_BT_BAP_BASS_MAX_SUBGROUPS */
372 base_subgroup_count = bt_bap_base_get_subgroup_count(base);
373 if (base_subgroup_count < 0 || base_subgroup_count > CONFIG_BT_BAP_BASS_MAX_SUBGROUPS) {
374 printk("Got invalid subgroup count: %d\n", base_subgroup_count);
375 return true;
376 }
377
378 base_size = data->data_len - BT_UUID_SIZE_16; /* the BASE comes after the UUID */
379
380 /* Compare BASE and copy if different */
381 if (base_size != received_base_size || memcmp(base, received_base, base_size) != 0) {
382 (void)memcpy(received_base, base, base_size);
383 received_base_size = base_size;
384 }
385
386 /* Stop parsing */
387 return false;
388 }
389
pa_recv(struct bt_le_per_adv_sync * sync,const struct bt_le_per_adv_sync_recv_info * info,struct net_buf_simple * buf)390 static void pa_recv(struct bt_le_per_adv_sync *sync,
391 const struct bt_le_per_adv_sync_recv_info *info, struct net_buf_simple *buf)
392 {
393 if (TEST_FLAG(flag_base_received)) {
394 return;
395 }
396
397 bt_data_parse(buf, base_store, NULL);
398 SET_FLAG(flag_base_received);
399 }
400
401 static struct bt_le_per_adv_sync_cb bap_pa_sync_cb = {
402 .synced = bap_pa_sync_synced_cb,
403 .term = bap_pa_sync_terminated_cb,
404 .recv = pa_recv,
405 };
406
bap_broadcast_assistant_discover_cb(struct bt_conn * conn,int err,uint8_t recv_state_count)407 static void bap_broadcast_assistant_discover_cb(struct bt_conn *conn, int err,
408 uint8_t recv_state_count)
409 {
410 if (err == 0) {
411 printk("BASS discover done with %u recv states\n", recv_state_count);
412 } else {
413 printk("BASS discover failed (%d)\n", err);
414 }
415
416 k_sem_give(&sem_bass_discovered);
417 }
418
bap_broadcast_assistant_add_src_cb(struct bt_conn * conn,int err)419 static void bap_broadcast_assistant_add_src_cb(struct bt_conn *conn, int err)
420 {
421 if (err == 0) {
422 printk("BASS add source successful\n");
423 } else {
424 printk("BASS add source failed (%d)\n", err);
425 }
426 }
427
metadata_entry(struct bt_data * data,void * user_data)428 static bool metadata_entry(struct bt_data *data, void *user_data)
429 {
430 char metadata[CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE];
431
432 (void)bin2hex(data->data, data->data_len, metadata, sizeof(metadata));
433
434 printk("\t\tMetadata length %u, type %u, data: %s\n", data->data_len, data->type, metadata);
435
436 return true;
437 }
438
439 static void
bap_broadcast_assistant_recv_state_cb(struct bt_conn * conn,int err,const struct bt_bap_scan_delegator_recv_state * state)440 bap_broadcast_assistant_recv_state_cb(struct bt_conn *conn, int err,
441 const struct bt_bap_scan_delegator_recv_state *state)
442 {
443 char le_addr[BT_ADDR_LE_STR_LEN];
444 char bad_code[BT_ISO_BROADCAST_CODE_SIZE * 2 + 1];
445 size_t acceptor_count = get_dev_cnt() - 2;
446
447 if (err != 0) {
448 FAIL("BASS recv state read failed (%d)\n", err);
449 return;
450 }
451
452 if (state == NULL) {
453 /* Empty receive state */
454 return;
455 }
456
457 bt_addr_le_to_str(&state->addr, le_addr, sizeof(le_addr));
458 (void)bin2hex(state->bad_code, BT_ISO_BROADCAST_CODE_SIZE, bad_code, sizeof(bad_code));
459 printk("BASS recv state: src_id %u, addr %s, sid %u, sync_state %u, "
460 "encrypt_state %u%s%s\n",
461 state->src_id, le_addr, state->adv_sid, state->pa_sync_state, state->encrypt_state,
462 state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE ? ", bad code" : "", bad_code);
463
464 if (state->encrypt_state == BT_BAP_BIG_ENC_STATE_BAD_CODE) {
465 FAIL("Encryption state is BT_BAP_BIG_ENC_STATE_BAD_CODE");
466 return;
467 }
468
469 for (size_t index = 0; index < acceptor_count; index++) {
470 if (conn == connected_conns[index]) {
471 src_id[index] = state->src_id;
472 }
473 }
474
475 for (uint8_t i = 0; i < state->num_subgroups; i++) {
476 const struct bt_bap_bass_subgroup *subgroup = &state->subgroups[i];
477 struct net_buf_simple buf;
478
479 printk("\t[%d]: BIS sync %u, metadata_len %u\n", i, subgroup->bis_sync,
480 subgroup->metadata_len);
481
482 net_buf_simple_init_with_data(&buf, (void *)subgroup->metadata,
483 subgroup->metadata_len);
484 bt_data_parse(&buf, metadata_entry, NULL);
485
486 if (subgroup->bis_sync != 0) {
487 SET_FLAG(flag_recv_state_updated_with_bis_sync);
488 }
489 }
490
491 #if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER)
492 if (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ) {
493 err = bt_le_per_adv_sync_transfer(g_pa_sync, conn, BT_UUID_BASS_VAL);
494 if (err != 0) {
495 FAIL("Could not transfer periodic adv sync: %d\n", err);
496 return;
497 }
498 }
499 #endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER */
500
501 if (state->pa_sync_state == BT_BAP_PA_STATE_SYNCED) {
502 }
503 }
504
505 static struct bt_bap_broadcast_assistant_cb ba_cbs = {
506 .discover = bap_broadcast_assistant_discover_cb,
507 .recv_state = bap_broadcast_assistant_recv_state_cb,
508 .add_src = bap_broadcast_assistant_add_src_cb,
509 };
510
check_audio_support_and_connect_cb(struct bt_data * data,void * user_data)511 static bool check_audio_support_and_connect_cb(struct bt_data *data, void *user_data)
512 {
513 char addr_str[BT_ADDR_LE_STR_LEN];
514 bt_addr_le_t *addr = user_data;
515 const struct bt_uuid *uuid;
516 uint16_t uuid_val;
517 int err;
518
519 printk("data->type %u\n", data->type);
520
521 if (data->type != BT_DATA_SVC_DATA16) {
522 return true; /* Continue parsing to next AD data type */
523 }
524
525 if (data->data_len < sizeof(uuid_val)) {
526 return true; /* Continue parsing to next AD data type */
527 }
528
529 /* We are looking for the CAS service data */
530 uuid_val = sys_get_le16(data->data);
531 uuid = BT_UUID_DECLARE_16(uuid_val);
532 if (bt_uuid_cmp(uuid, BT_UUID_CAS) != 0) {
533 return true; /* Continue parsing to next AD data type */
534 }
535
536 bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
537 printk("Device found: %s\n", addr_str);
538
539 printk("Stopping scan\n");
540 if (bt_le_scan_stop()) {
541 FAIL("Could not stop scan");
542 return false;
543 }
544
545 err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
546 BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, BT_GAP_INIT_CONN_INT_MIN,
547 0, BT_GAP_MS_TO_CONN_TIMEOUT(4000)),
548 &connected_conns[connected_conn_cnt]);
549 if (err != 0) {
550 FAIL("Could not connect to peer: %d", err);
551 }
552
553 return false; /* Stop parsing */
554 }
555
scan_recv_cb(const struct bt_le_scan_recv_info * info,struct net_buf_simple * buf)556 static void scan_recv_cb(const struct bt_le_scan_recv_info *info, struct net_buf_simple *buf)
557 {
558 struct bt_conn *conn;
559
560 conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, info->addr);
561 if (conn != NULL) {
562 /* Already connected to this device */
563 bt_conn_unref(conn);
564 return;
565 }
566
567 /* Check for connectable, extended advertising */
568 if (((info->adv_props & BT_GAP_ADV_PROP_EXT_ADV) != 0) &&
569 ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE)) != 0) {
570 /* Check for TMAS support in advertising data */
571 bt_data_parse(buf, check_audio_support_and_connect_cb, (void *)info->addr);
572 }
573 }
574
init(size_t acceptor_cnt)575 static void init(size_t acceptor_cnt)
576 {
577 static struct bt_le_scan_cb scan_callbacks = {
578 .recv = scan_recv_cb,
579 };
580 static struct bt_conn_cb conn_cb = {
581 .disconnected = cap_disconnected_cb,
582 };
583 int err;
584
585 err = bt_enable(NULL);
586 if (err != 0) {
587 FAIL("Bluetooth enable failed (err %d)\n", err);
588 return;
589 }
590
591 bt_gatt_cb_register(&gatt_callbacks);
592 err = bt_le_scan_cb_register(&scan_callbacks);
593 if (err != 0) {
594 FAIL("Failed to register scan callbacks (err %d)\n", err);
595 return;
596 }
597
598 bt_conn_cb_register(&conn_cb);
599
600 err = bt_cap_commander_register_cb(&cap_cb);
601 if (err != 0) {
602 FAIL("Failed to register CAP callbacks (err %d)\n", err);
603 return;
604 }
605
606 err = bt_vcp_vol_ctlr_cb_register(&vcp_cb);
607 if (err != 0) {
608 FAIL("Failed to register VCP callbacks (err %d)\n", err);
609 return;
610 }
611
612 err = bt_micp_mic_ctlr_cb_register(&micp_cb);
613 if (err != 0) {
614 FAIL("Failed to register MICP callbacks (err %d)\n", err);
615 return;
616 }
617
618 err = bt_bap_broadcast_assistant_register_cb(&ba_cbs);
619 if (err != 0) {
620 FAIL("Failed to register broadcast assistant callbacks (err %d)\n");
621 return;
622 }
623
624 bt_le_per_adv_sync_cb_register(&bap_pa_sync_cb);
625 bt_le_scan_cb_register(&bap_scan_cb);
626
627 k_sem_init(&sem_disconnected, 0, acceptor_cnt);
628 k_sem_init(&sem_cas_discovered, 0, acceptor_cnt);
629 k_sem_init(&sem_bass_discovered, 0, acceptor_cnt);
630 k_sem_init(&sem_vcs_discovered, 0, acceptor_cnt);
631 k_sem_init(&sem_mics_discovered, 0, acceptor_cnt);
632
633 UNSET_FLAG(flag_mtu_exchanged);
634 UNSET_FLAG(flag_volume_changed);
635 UNSET_FLAG(flag_volume_mute_changed);
636 UNSET_FLAG(flag_volume_offset_changed);
637 UNSET_FLAG(flag_microphone_mute_changed);
638 UNSET_FLAG(flag_microphone_gain_changed);
639
640 UNSET_FLAG(flag_broadcast_reception_start);
641 UNSET_FLAG(flag_broadcast_reception_stop);
642 UNSET_FLAG(flag_broadcaster_found);
643 UNSET_FLAG(flag_base_received);
644 UNSET_FLAG(flag_recv_state_updated_with_bis_sync);
645 UNSET_FLAG(flag_pa_synced);
646 UNSET_FLAG(flag_pa_sync_lost);
647 UNSET_FLAG(flag_syncable);
648 }
649
scan_and_connect(void)650 static void scan_and_connect(void)
651 {
652 int err;
653
654 UNSET_FLAG(flag_connected);
655
656 err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, NULL);
657 if (err != 0) {
658 FAIL("Scanning failed to start (err %d)\n", err);
659 return;
660 }
661
662 printk("Scanning successfully started\n");
663 WAIT_FOR_FLAG(flag_connected);
664 connected_conn_cnt++;
665 }
666
disconnect_acl(size_t acceptor_cnt)667 static void disconnect_acl(size_t acceptor_cnt)
668 {
669 k_sem_reset(&sem_disconnected);
670
671 for (size_t i = 0U; i < acceptor_cnt; i++) {
672 struct bt_conn *conn = connected_conns[i];
673 int err;
674
675 printk("Disconnecting %p\n", (void *)conn);
676
677 err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
678 if (err != 0) {
679 FAIL("Failed to disconnect %p (err %d)\n", (void *)conn, err);
680 return;
681 }
682 }
683
684 for (size_t i = 0U; i < acceptor_cnt; i++) {
685 const int err = k_sem_take(&sem_disconnected, SEM_TIMEOUT);
686
687 if (err == 0) {
688 connected_conn_cnt--;
689 } else {
690 const struct bt_conn *conn = connected_conns[i];
691
692 FAIL("Failed to take sem_disconnected for %p: %d", (void *)conn, err);
693 return;
694 }
695 }
696 }
697
discover_cas(size_t acceptor_cnt)698 static void discover_cas(size_t acceptor_cnt)
699 {
700 k_sem_reset(&sem_cas_discovered);
701
702 /* Do parallel discovery */
703 for (size_t i = 0U; i < acceptor_cnt; i++) {
704 struct bt_conn *conn = connected_conns[i];
705 int err;
706
707 printk("Discovering CAS on %p\n", (void *)conn);
708
709 err = bt_cap_commander_discover(conn);
710 if (err != 0) {
711 FAIL("Failed to discover CAS on %p: %d\n", (void *)conn, err);
712 return;
713 }
714 }
715
716 for (size_t i = 0U; i < acceptor_cnt; i++) {
717 const int err = k_sem_take(&sem_cas_discovered, SEM_TIMEOUT);
718
719 if (err != 0) {
720 const struct bt_conn *conn = connected_conns[i];
721
722 FAIL("Failed to take sem_cas_discovered for %p: %d", (void *)conn, err);
723 }
724 }
725 }
726
discover_bass(size_t acceptor_cnt)727 static void discover_bass(size_t acceptor_cnt)
728 {
729 k_sem_reset(&sem_bass_discovered);
730
731 if (acceptor_cnt > 1) {
732 FAIL("Current implementation does not support multiple connections for the "
733 "broadcast assistant");
734 return;
735 }
736
737 for (size_t i = 0U; i < acceptor_cnt; i++) {
738 int err;
739
740 err = bt_bap_broadcast_assistant_discover(connected_conns[i]);
741 if (err != 0) {
742 FAIL("Failed to discover BASS on the sink (err %d)\n", err);
743 return;
744 }
745 }
746
747 for (size_t i = 0U; i < acceptor_cnt; i++) {
748 const int err = k_sem_take(&sem_bass_discovered, SEM_TIMEOUT);
749
750 if (err != 0) {
751 FAIL("Failed to take sem_bass_discovered for %p: %d",
752 (void *)connected_conns[i], err);
753 }
754 }
755 }
756
pa_sync_to_broadcaster(void)757 static void pa_sync_to_broadcaster(void)
758 {
759 int err;
760
761 err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL);
762 if (err != 0) {
763 FAIL("Unable to start scan for broadcast sources: %d", err);
764 return;
765 }
766
767 printk("Searching for a broadcaster\n");
768 WAIT_FOR_FLAG(flag_broadcaster_found);
769
770 err = bt_le_scan_stop();
771 if (err != 0) {
772 FAIL("bt_le_scan_stop failed with %d\n", err);
773 return;
774 }
775
776 printk("Scan stopped, attempting to PA sync to the broadcaster with id 0x%06X\n",
777 broadcaster_broadcast_id);
778 err = pa_sync_create();
779 if (err != 0) {
780 FAIL("Could not create Broadcast PA sync: %d\n", err);
781 return;
782 }
783
784 WAIT_FOR_FLAG(flag_pa_synced); /* todo from bap_pa_sync_synced_cb, bap_pa_sync_cb */
785
786 printk("Broadcast source PA synced, waiting for BASE\n");
787 WAIT_FOR_FLAG(flag_base_received);
788 }
789
discover_vcs(size_t acceptor_cnt)790 static void discover_vcs(size_t acceptor_cnt)
791 {
792 k_sem_reset(&sem_vcs_discovered);
793
794 /* Do parallel discovery */
795 for (size_t i = 0U; i < acceptor_cnt; i++) {
796 struct bt_conn *conn = connected_conns[i];
797 struct bt_vcp_vol_ctlr *vol_ctlr;
798 int err;
799
800 printk("Discovering VCS on %p\n", (void *)conn);
801
802 err = bt_vcp_vol_ctlr_discover(conn, &vol_ctlr);
803 if (err != 0) {
804 FAIL("Failed to discover VCS on %p: %d\n", err);
805 return;
806 }
807 }
808
809 for (size_t i = 0U; i < acceptor_cnt; i++) {
810 const int err = k_sem_take(&sem_vcs_discovered, SEM_TIMEOUT);
811
812 if (err != 0) {
813 const struct bt_conn *conn = connected_conns[i];
814
815 FAIL("Failed to take sem_vcs_discovered for %p: %d", (void *)conn, err);
816 }
817 }
818 }
819
discover_mics(size_t acceptor_cnt)820 static void discover_mics(size_t acceptor_cnt)
821 {
822 k_sem_reset(&sem_mics_discovered);
823
824 for (size_t i = 0U; i < acceptor_cnt; i++) {
825 struct bt_micp_mic_ctlr *mic_ctlr;
826 int err;
827
828 err = bt_micp_mic_ctlr_discover(connected_conns[i], &mic_ctlr);
829 if (err != 0) {
830 FAIL("Failed to discover MICS: %d\n", err);
831 return;
832 }
833 }
834
835 for (size_t i = 0U; i < acceptor_cnt; i++) {
836 const int err = k_sem_take(&sem_mics_discovered, SEM_TIMEOUT);
837
838 if (err != 0) {
839 const struct bt_conn *conn = connected_conns[i];
840
841 FAIL("Failed to take sem_mics_discovered for %p: %d", (void *)conn, err);
842 }
843 }
844 }
845
test_change_volume(void)846 static void test_change_volume(void)
847 {
848 union bt_cap_set_member members[CONFIG_BT_MAX_CONN];
849 const struct bt_cap_commander_change_volume_param param = {
850 .type = BT_CAP_SET_TYPE_AD_HOC,
851 .members = members,
852 .count = connected_conn_cnt,
853 .volume = 177,
854 };
855 int err;
856
857 printk("Changing volume to %u\n", param.volume);
858 UNSET_FLAG(flag_volume_changed);
859
860 for (size_t i = 0U; i < param.count; i++) {
861 param.members[i].member = connected_conns[i];
862 }
863
864 err = bt_cap_commander_change_volume(¶m);
865 if (err != 0) {
866 FAIL("Failed to change volume: %d\n", err);
867 return;
868 }
869
870 WAIT_FOR_FLAG(flag_volume_changed);
871 printk("Volume changed to %u\n", param.volume);
872 }
873
test_change_volume_mute(bool mute)874 static void test_change_volume_mute(bool mute)
875 {
876 union bt_cap_set_member members[CONFIG_BT_MAX_CONN];
877 const struct bt_cap_commander_change_volume_mute_state_param param = {
878 .type = BT_CAP_SET_TYPE_AD_HOC,
879 .members = members,
880 .count = connected_conn_cnt,
881 .mute = mute,
882 };
883 int err;
884
885 printk("Changing volume mute state to %d\n", param.mute);
886 UNSET_FLAG(flag_volume_mute_changed);
887
888 for (size_t i = 0U; i < param.count; i++) {
889 param.members[i].member = connected_conns[i];
890 }
891
892 err = bt_cap_commander_change_volume_mute_state(¶m);
893 if (err != 0) {
894 FAIL("Failed to change volume mute: %d\n", err);
895 return;
896 }
897
898 WAIT_FOR_FLAG(flag_volume_mute_changed);
899 printk("Volume mute state changed to %d\n", param.mute);
900 }
901
test_change_volume_offset(void)902 static void test_change_volume_offset(void)
903 {
904 struct bt_cap_commander_change_volume_offset_member_param member_params[CONFIG_BT_MAX_CONN];
905 const struct bt_cap_commander_change_volume_offset_param param = {
906 .type = BT_CAP_SET_TYPE_AD_HOC,
907 .param = member_params,
908 .count = connected_conn_cnt,
909 };
910 int err;
911
912 printk("Changing volume offset\n");
913 UNSET_FLAG(flag_volume_offset_changed);
914
915 for (size_t i = 0U; i < param.count; i++) {
916 member_params[i].member.member = connected_conns[i];
917 member_params[i].offset = 100 + i;
918 }
919
920 err = bt_cap_commander_change_volume_offset(¶m);
921 if (err != 0) {
922 FAIL("Failed to change volume offset: %d\n", err);
923 return;
924 }
925
926 WAIT_FOR_FLAG(flag_volume_offset_changed);
927 printk("Volume offset changed\n");
928 }
929
test_change_microphone_mute(bool mute)930 static void test_change_microphone_mute(bool mute)
931 {
932 union bt_cap_set_member members[CONFIG_BT_MAX_CONN];
933 const struct bt_cap_commander_change_microphone_mute_state_param param = {
934 .type = BT_CAP_SET_TYPE_AD_HOC,
935 .members = members,
936 .count = connected_conn_cnt,
937 .mute = mute,
938 };
939 int err;
940
941 printk("Changing microphone mute state to %d\n", param.mute);
942 UNSET_FLAG(flag_microphone_mute_changed);
943
944 for (size_t i = 0U; i < param.count; i++) {
945 param.members[i].member = connected_conns[i];
946 }
947
948 err = bt_cap_commander_change_microphone_mute_state(¶m);
949 if (err != 0) {
950 FAIL("Failed to change microphone mute: %d\n", err);
951 return;
952 }
953
954 WAIT_FOR_FLAG(flag_microphone_mute_changed);
955 printk("Microphone mute state changed to %d\n", param.mute);
956 }
957
test_change_microphone_gain(void)958 static void test_change_microphone_gain(void)
959 {
960 struct bt_cap_commander_change_microphone_gain_setting_member_param
961 member_params[CONFIG_BT_MAX_CONN];
962 const struct bt_cap_commander_change_microphone_gain_setting_param param = {
963 .type = BT_CAP_SET_TYPE_AD_HOC,
964 .param = member_params,
965 .count = connected_conn_cnt,
966 };
967 int err;
968
969 printk("Changing microphone gain\n");
970 UNSET_FLAG(flag_microphone_gain_changed);
971
972 for (size_t i = 0U; i < param.count; i++) {
973 member_params[i].member.member = connected_conns[i];
974 member_params[i].gain = 10 + i;
975 }
976
977 err = bt_cap_commander_change_microphone_gain_setting(¶m);
978 if (err != 0) {
979 FAIL("Failed to change microphone gain: %d\n", err);
980 return;
981 }
982
983 WAIT_FOR_FLAG(flag_microphone_gain_changed);
984 printk("Microphone gain changed\n");
985 }
986
test_broadcast_reception_start(size_t acceptor_count)987 static void test_broadcast_reception_start(size_t acceptor_count)
988 {
989 struct bt_cap_commander_broadcast_reception_start_param reception_start_param = {0};
990 struct bt_cap_commander_broadcast_reception_start_member_param param[CONFIG_BT_MAX_CONN] = {
991 0};
992 int err;
993
994 reception_start_param.type = BT_CAP_SET_TYPE_AD_HOC;
995 reception_start_param.count = acceptor_count;
996 reception_start_param.param = param;
997
998 for (size_t i = 0; i < acceptor_count; i++) {
999 uint32_t bis_sync[CONFIG_BT_BAP_BASS_MAX_SUBGROUPS];
1000 size_t num_subgroups;
1001
1002 reception_start_param.param[i].member.member = connected_conns[i];
1003 bt_addr_le_copy(&reception_start_param.param[i].addr, &broadcaster_addr);
1004 reception_start_param.param[i].adv_sid = broadcaster_info.sid;
1005 reception_start_param.param[i].pa_interval = broadcaster_info.interval;
1006 reception_start_param.param[i].broadcast_id = broadcaster_broadcast_id;
1007 num_subgroups =
1008 bt_bap_base_get_subgroup_count((const struct bt_bap_base *)received_base);
1009 err = bt_bap_base_get_bis_indexes((const struct bt_bap_base *)received_base,
1010 bis_sync);
1011 if (err != 0) {
1012 FAIL("Could not populate subgroup information: %d\n", err);
1013 return;
1014 }
1015
1016 reception_start_param.param[i].num_subgroups = num_subgroups;
1017 for (size_t j = 0; j < num_subgroups; j++) {
1018 reception_start_param.param[i].subgroups[j].bis_sync = bis_sync[j];
1019 }
1020 }
1021
1022 err = bt_cap_commander_broadcast_reception_start(&reception_start_param);
1023 if (err != 0) {
1024 FAIL("Could not initiate broadcast reception start: %d\n", err);
1025 return;
1026 }
1027
1028 WAIT_FOR_FLAG(flag_broadcast_reception_start);
1029 }
1030
test_broadcast_reception_stop(size_t acceptor_count)1031 static void test_broadcast_reception_stop(size_t acceptor_count)
1032 {
1033 struct bt_cap_commander_broadcast_reception_stop_param reception_stop_param = {0};
1034 struct bt_cap_commander_broadcast_reception_stop_member_param param[CONFIG_BT_MAX_CONN] = {
1035 0};
1036
1037 int err;
1038
1039 reception_stop_param.type = BT_CAP_SET_TYPE_AD_HOC;
1040 reception_stop_param.param = param;
1041 reception_stop_param.count = acceptor_count;
1042 for (size_t i = 0; i < acceptor_count; i++) {
1043 uint8_t num_subgroups;
1044
1045 reception_stop_param.param[i].member.member = connected_conns[i];
1046
1047 reception_stop_param.param[i].src_id = src_id[i];
1048 num_subgroups =
1049 bt_bap_base_get_subgroup_count((const struct bt_bap_base *)received_base);
1050 reception_stop_param.param[i].num_subgroups = num_subgroups;
1051 }
1052 err = bt_cap_commander_broadcast_reception_stop(&reception_stop_param);
1053 if (err != 0) {
1054 FAIL("Could not initiate broadcast reception stop: %d\n", err);
1055 return;
1056 }
1057 WAIT_FOR_FLAG(flag_broadcast_reception_stop);
1058 }
1059
test_distribute_broadcast_code(size_t acceptor_count)1060 static void test_distribute_broadcast_code(size_t acceptor_count)
1061 {
1062 struct bt_cap_commander_distribute_broadcast_code_param distribute_broadcast_code_param = {
1063 0};
1064 struct bt_cap_commander_distribute_broadcast_code_member_param param[CONFIG_BT_MAX_CONN] = {
1065 0};
1066
1067 distribute_broadcast_code_param.type = BT_CAP_SET_TYPE_AD_HOC;
1068 distribute_broadcast_code_param.param = param;
1069 distribute_broadcast_code_param.count = acceptor_count;
1070 memcpy(distribute_broadcast_code_param.broadcast_code, BROADCAST_CODE,
1071 sizeof(BROADCAST_CODE));
1072 for (size_t i = 0; i < acceptor_count; i++) {
1073
1074 distribute_broadcast_code_param.param[i].member.member = connected_conns[i];
1075 distribute_broadcast_code_param.param[i].src_id = src_id[i];
1076 }
1077
1078 bt_cap_commander_distribute_broadcast_code(&distribute_broadcast_code_param);
1079 }
1080
test_main_cap_commander_capture_and_render(void)1081 static void test_main_cap_commander_capture_and_render(void)
1082 {
1083 const size_t acceptor_cnt = get_dev_cnt() - 1; /* Assume all other devices are acceptors
1084 */
1085 init(acceptor_cnt);
1086
1087 /* Connect to and do discovery on all CAP acceptors */
1088 for (size_t i = 0U; i < acceptor_cnt; i++) {
1089 scan_and_connect();
1090
1091 WAIT_FOR_FLAG(flag_mtu_exchanged);
1092 }
1093
1094 /* TODO: We should use CSIP to find set members */
1095 discover_cas(acceptor_cnt);
1096 discover_cas(acceptor_cnt); /* verify that we can discover twice */
1097
1098 if (IS_ENABLED(CONFIG_BT_CSIP_SET_COORDINATOR)) {
1099 if (IS_ENABLED(CONFIG_BT_VCP_VOL_CTLR)) {
1100 discover_vcs(acceptor_cnt);
1101
1102 test_change_volume();
1103
1104 test_change_volume_mute(true);
1105 test_change_volume_mute(false);
1106
1107 if (IS_ENABLED(CONFIG_BT_VCP_VOL_CTLR_VOCS)) {
1108 test_change_volume_offset();
1109 }
1110 }
1111
1112 if (IS_ENABLED(CONFIG_BT_MICP_MIC_CTLR)) {
1113 discover_mics(acceptor_cnt);
1114
1115 test_change_microphone_mute(true);
1116 test_change_microphone_mute(false);
1117
1118 if (IS_ENABLED(CONFIG_BT_MICP_MIC_CTLR_AICS)) {
1119 test_change_microphone_gain();
1120 }
1121 }
1122 }
1123
1124 /* Disconnect all CAP acceptors */
1125 disconnect_acl(acceptor_cnt);
1126
1127 PASS("CAP commander capture and rendering passed\n");
1128 }
1129
test_main_cap_commander_broadcast_reception(void)1130 static void test_main_cap_commander_broadcast_reception(void)
1131 {
1132 size_t acceptor_count;
1133
1134 /* The test consists of N devices
1135 * 1 device is the broadcast source
1136 * 1 device is the CAP commander
1137 * This leaves N - 2 devices for the acceptor
1138 */
1139 acceptor_count = get_dev_cnt() - 2;
1140 printk("Acceptor count: %d\n", acceptor_count);
1141
1142 init(acceptor_count);
1143
1144 for (size_t i = 0U; i < acceptor_count; i++) {
1145 scan_and_connect();
1146
1147 WAIT_FOR_FLAG(flag_mtu_exchanged);
1148 }
1149
1150 /* TODO: We should use CSIP to find set members */
1151 discover_cas(acceptor_count);
1152 discover_bass(acceptor_count);
1153
1154 pa_sync_to_broadcaster();
1155
1156 test_broadcast_reception_start(acceptor_count);
1157
1158 test_distribute_broadcast_code(acceptor_count);
1159
1160 backchannel_sync_wait_any(); /* wait for the acceptor to receive data */
1161
1162 backchannel_sync_wait_any(); /* wait for the acceptor to receive a metadata update */
1163
1164 test_broadcast_reception_stop(acceptor_count);
1165
1166 backchannel_sync_wait_any(); /* wait for the acceptor to stop reception */
1167
1168 /* Disconnect all CAP acceptors */
1169 disconnect_acl(acceptor_count);
1170
1171 PASS("Broadcast reception passed\n");
1172 }
1173
1174 static const struct bst_test_instance test_cap_commander[] = {
1175 {
1176 .test_id = "cap_commander_capture_and_render",
1177 .test_pre_init_f = test_init,
1178 .test_tick_f = test_tick,
1179 .test_main_f = test_main_cap_commander_capture_and_render,
1180 },
1181 {
1182 .test_id = "cap_commander_broadcast_reception",
1183 .test_post_init_f = test_init,
1184 .test_tick_f = test_tick,
1185 .test_main_f = test_main_cap_commander_broadcast_reception,
1186 },
1187 BSTEST_END_MARKER,
1188 };
1189
test_cap_commander_install(struct bst_test_list * tests)1190 struct bst_test_list *test_cap_commander_install(struct bst_test_list *tests)
1191 {
1192 return bst_add_tests(tests, test_cap_commander);
1193 }
1194
1195 #else /* !CONFIG_BT_CAP_COMMANDER */
1196
test_cap_commander_install(struct bst_test_list * tests)1197 struct bst_test_list *test_cap_commander_install(struct bst_test_list *tests)
1198 {
1199 return tests;
1200 }
1201
1202 #endif /* CONFIG_BT_CAP_COMMANDER */
1203