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