1 /*
2 * Copyright (c) 2019 Bose Corporation
3 * Copyright (c) 2020-2025 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <stdbool.h>
9 #include <stddef.h>
10 #include <stdint.h>
11
12 #include <zephyr/autoconf.h>
13 #include <zephyr/bluetooth/addr.h>
14 #include <zephyr/bluetooth/audio/audio.h>
15 #include <zephyr/bluetooth/audio/bap.h>
16 #include <zephyr/bluetooth/audio/csip.h>
17 #include <zephyr/bluetooth/audio/tmap.h>
18 #include <zephyr/bluetooth/bluetooth.h>
19 #include <zephyr/bluetooth/byteorder.h>
20 #include <zephyr/bluetooth/conn.h>
21 #include <zephyr/bluetooth/gap.h>
22 #include <zephyr/bluetooth/uuid.h>
23 #include <zephyr/kernel.h>
24 #include <zephyr/net_buf.h>
25 #include <zephyr/sys/__assert.h>
26 #include <zephyr/sys/atomic_types.h>
27 #include <zephyr/sys/printk.h>
28 #include <zephyr/sys/util.h>
29 #include <zephyr/sys/util_macro.h>
30
31 #include "bs_cmd_line.h"
32 #include "bs_dynargs.h"
33 #include "bs_pc_backchannel.h"
34 #include "posix_native_task.h"
35 #include "bs_types.h"
36 #include "bsim_args_runner.h"
37 #include "bstests.h"
38 #include "common.h"
39
40 extern enum bst_result_t bst_result;
41 struct bt_conn *default_conn;
42 atomic_t flag_connected;
43 atomic_t flag_disconnected;
44 atomic_t flag_conn_updated;
45 volatile bt_security_t security_level;
46 #if defined(CONFIG_BT_CSIP_SET_MEMBER)
47 uint8_t csip_rsi[BT_CSIP_RSI_SIZE];
48 #endif /* CONFIG_BT_CSIP_SET_MEMBER */
49
50 static const struct bt_data connectable_ad[] = {
51 BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
52 BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
53 BT_DATA_BYTES(BT_DATA_UUID16_SOME, BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL),
54 BT_UUID_16_ENCODE(BT_UUID_CAS_VAL)),
55 BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_BASS_VAL),
56 BT_UUID_16_ENCODE(BT_UUID_PACS_VAL)),
57 #if defined(CONFIG_BT_CAP_ACCEPTOR)
58 BT_DATA_BYTES(BT_DATA_SVC_DATA16, BT_UUID_16_ENCODE(BT_UUID_CAS_VAL),
59 BT_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED),
60 #endif /* CONFIG_BT_CAP_ACCEPTOR */
61 #if defined(CONFIG_BT_BAP_UNICAST_SERVER)
62 BT_DATA_BYTES(BT_DATA_SVC_DATA16, BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL),
63 BT_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED, BT_BYTES_LIST_LE16(SINK_CONTEXT),
64 BT_BYTES_LIST_LE16(SOURCE_CONTEXT), 0x00,
65 /* Metadata length */),
66 #endif /* CONFIG_BT_BAP_UNICAST_SERVER */
67 #if defined(CONFIG_BT_BAP_SCAN_DELEGATOR)
68 BT_DATA_BYTES(BT_DATA_SVC_DATA16, BT_UUID_16_ENCODE(BT_UUID_BASS_VAL)),
69 #endif /* CONFIG_BT_BAP_SCAN_DELEGATOR */
70 #if defined(CONFIG_BT_CSIP_SET_MEMBER)
71 BT_DATA(BT_DATA_CSIS_RSI, csip_rsi, BT_CSIP_RSI_SIZE),
72 #endif /* CONFIG_BT_CSIP_SET_MEMBER */
73 #if defined(CONFIG_BT_TMAP)
74 BT_DATA_BYTES(BT_DATA_SVC_DATA16, BT_UUID_16_ENCODE(BT_UUID_TMAS_VAL),
75 BT_UUID_16_ENCODE(TMAP_ROLE_SUPPORTED)),
76 #endif /* CONFIG_BT_TMAP */
77 };
78
device_found(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad_buf)79 static void device_found(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad_buf)
80 {
81 char addr_str[BT_ADDR_LE_STR_LEN];
82 int err;
83
84 if (default_conn) {
85 return;
86 }
87
88 /* We're only interested in extended advertising connectable events */
89 if (((info->adv_props & BT_GAP_ADV_PROP_EXT_ADV) == 0U ||
90 (info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) == 0U)) {
91 return;
92 }
93
94 bt_addr_le_to_str(info->addr, addr_str, sizeof(addr_str));
95 printk("Device found: %s (RSSI %d)\n", addr_str, info->rssi);
96
97 /* connect only to devices in close proximity */
98 if (info->rssi < -70) {
99 FAIL("RSSI too low");
100 return;
101 }
102
103 printk("Stopping scan\n");
104 if (bt_le_scan_stop()) {
105 FAIL("Could not stop scan");
106 return;
107 }
108
109 err = bt_conn_le_create(info->addr, BT_CONN_LE_CREATE_CONN, BT_BAP_CONN_PARAM_RELAXED,
110 &default_conn);
111 if (err) {
112 FAIL("Could not connect to peer: %d", err);
113 }
114 }
115
116 struct bt_le_scan_cb common_scan_cb = {
117 .recv = device_found,
118 };
119
connected(struct bt_conn * conn,uint8_t err)120 static void connected(struct bt_conn *conn, uint8_t err)
121 {
122 char addr[BT_ADDR_LE_STR_LEN];
123
124 (void)bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
125
126 if (default_conn == NULL) {
127 default_conn = bt_conn_ref(conn);
128 }
129
130 if (err != 0) {
131 bt_conn_unref(default_conn);
132 default_conn = NULL;
133
134 FAIL("Failed to connect to %s (0x%02x)\n", addr, err);
135 return;
136 }
137
138 printk("Connected to %s (%p)\n", addr, conn);
139 SET_FLAG(flag_connected);
140 }
141
disconnected(struct bt_conn * conn,uint8_t reason)142 void disconnected(struct bt_conn *conn, uint8_t reason)
143 {
144 char addr[BT_ADDR_LE_STR_LEN];
145
146 if (conn != default_conn) {
147 return;
148 }
149
150 bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
151
152 printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);
153
154 bt_conn_unref(default_conn);
155 default_conn = NULL;
156 UNSET_FLAG(flag_connected);
157 UNSET_FLAG(flag_conn_updated);
158 SET_FLAG(flag_disconnected);
159
160 security_level = BT_SECURITY_L1;
161 }
162
conn_param_updated_cb(struct bt_conn * conn,uint16_t interval,uint16_t latency,uint16_t timeout)163 static void conn_param_updated_cb(struct bt_conn *conn, uint16_t interval, uint16_t latency,
164 uint16_t timeout)
165 {
166 printk("Connection parameter updated: %p 0x%04X (%u us), 0x%04X, 0x%04X\n", conn, interval,
167 BT_CONN_INTERVAL_TO_US(interval), latency, timeout);
168
169 SET_FLAG(flag_conn_updated);
170 }
171
security_changed_cb(struct bt_conn * conn,bt_security_t level,enum bt_security_err err)172 static void security_changed_cb(struct bt_conn *conn, bt_security_t level, enum bt_security_err err)
173 {
174 printk("Security changed: %p level %d err %d\n", conn, level, err);
175
176 if (err == BT_SECURITY_ERR_SUCCESS) {
177 security_level = level;
178 }
179 }
180
181 BT_CONN_CB_DEFINE(conn_callbacks) = {
182 .connected = connected,
183 .disconnected = disconnected,
184 .le_param_updated = conn_param_updated_cb,
185 .security_changed = security_changed_cb,
186 };
187
188
setup_connectable_adv(struct bt_le_ext_adv ** ext_adv)189 void setup_connectable_adv(struct bt_le_ext_adv **ext_adv)
190 {
191 int err;
192
193 /* Create a non-connectable advertising set */
194 err = bt_le_ext_adv_create(BT_BAP_ADV_PARAM_CONN_QUICK, NULL, ext_adv);
195 if (err != 0) {
196 FAIL("Unable to create extended advertising set: %d\n", err);
197 return;
198 }
199
200 err = bt_le_ext_adv_set_data(*ext_adv, connectable_ad, ARRAY_SIZE(connectable_ad), NULL, 0);
201 if (err != 0) {
202 FAIL("Unable to set extended advertising data: %d\n", err);
203
204 bt_le_ext_adv_delete(*ext_adv);
205
206 return;
207 }
208
209 err = bt_le_ext_adv_start(*ext_adv, BT_LE_EXT_ADV_START_DEFAULT);
210 if (err != 0) {
211 FAIL("Failed to start advertising set (err %d)\n", err);
212
213 bt_le_ext_adv_delete(*ext_adv);
214
215 return;
216 }
217
218 printk("Advertising started\n");
219 }
220
setup_broadcast_adv(struct bt_le_ext_adv ** adv)221 void setup_broadcast_adv(struct bt_le_ext_adv **adv)
222 {
223 struct bt_le_adv_param ext_adv_param = *BT_BAP_ADV_PARAM_BROADCAST_SLOW;
224 int err;
225
226 /* Zephyr Controller works best while Extended Advertising interval is a multiple
227 * of the ISO Interval minus 10 ms (max. advertising random delay). This is
228 * required to place the AUX_ADV_IND PDUs in a non-overlapping interval with the
229 * Broadcast ISO radio events.
230 */
231 ext_adv_param.interval_min -= BT_GAP_MS_TO_ADV_INTERVAL(10U);
232 ext_adv_param.interval_max -= BT_GAP_MS_TO_ADV_INTERVAL(10U);
233
234 /* Create a non-connectable advertising set */
235 err = bt_le_ext_adv_create(&ext_adv_param, NULL, adv);
236 if (err != 0) {
237 FAIL("Unable to create extended advertising set: %d\n", err);
238 return;
239 }
240
241 /* Set periodic advertising parameters */
242 err = bt_le_per_adv_set_param(*adv, BT_BAP_PER_ADV_PARAM_BROADCAST_SLOW);
243 if (err) {
244 FAIL("Failed to set periodic advertising parameters: %d\n", err);
245 return;
246 }
247 }
248
start_broadcast_adv(struct bt_le_ext_adv * adv)249 void start_broadcast_adv(struct bt_le_ext_adv *adv)
250 {
251 char addr_str[BT_ADDR_LE_STR_LEN];
252 struct bt_le_ext_adv_info info;
253 int err;
254
255 err = bt_le_ext_adv_get_info(adv, &info);
256 if (err != 0) {
257 FAIL("Failed to get adv info: %d\n", err);
258 return;
259 }
260
261 if (info.per_adv_state == BT_LE_PER_ADV_STATE_NONE) {
262 FAIL("Cannot start periodic advertising for non-periodic advertising set");
263 return;
264 }
265
266 if (info.per_adv_state == BT_LE_PER_ADV_STATE_DISABLED) {
267 /* Enable Periodic Advertising */
268 err = bt_le_per_adv_start(adv);
269 if (err != 0) {
270 FAIL("Failed to enable periodic advertising: %d\n", err);
271 return;
272 }
273 }
274
275 if (info.ext_adv_state == BT_LE_EXT_ADV_STATE_DISABLED) {
276 /* Start extended advertising */
277 err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
278 if (err != 0) {
279 FAIL("Failed to start extended advertising: %d\n", err);
280 return;
281 }
282 }
283
284 bt_addr_le_to_str(info.addr, addr_str, sizeof(addr_str));
285 printk("Started advertising with addr %s\n", addr_str);
286 }
287
test_tick(bs_time_t HW_device_time)288 void test_tick(bs_time_t HW_device_time)
289 {
290 if (bst_result != Passed) {
291 FAIL("test failed (not passed after %i seconds)\n", WAIT_SECONDS);
292 }
293 }
294
test_init(void)295 void test_init(void)
296 {
297 bst_ticker_set_next_tick_absolute(WAIT_TIME);
298 bst_result = In_progress;
299 }
300
301 #define SYNC_MSG_SIZE 1
302 static int32_t dev_cnt;
303 static uint backchannel_nums[255];
304 static uint chan_cnt;
305
register_more_cmd_args(void)306 static void register_more_cmd_args(void)
307 {
308 static bs_args_struct_t args_struct_toadd[] = {
309 {
310 .option = "D",
311 .name = "number_devices",
312 .type = 'i',
313 .dest = (void *)&dev_cnt,
314 .descript = "Number of devices which will connect in this phy",
315 .is_mandatory = true,
316 },
317 ARG_TABLE_ENDMARKER,
318 };
319
320 bs_add_extra_dynargs(args_struct_toadd);
321 }
322 NATIVE_TASK(register_more_cmd_args, PRE_BOOT_1, 100);
323
get_dev_cnt(void)324 uint16_t get_dev_cnt(void)
325 {
326 return (uint16_t)dev_cnt;
327 }
328
329 /**
330 * @brief Get the channel id based on remote device ID
331 *
332 * The is effectively a very simple hashing function to generate unique channel IDs from device IDs
333 *
334 * @param dev 16-bit device ID
335 *
336 * @return uint 32-bit channel ID
337 */
get_chan_num(uint16_t dev)338 static uint get_chan_num(uint16_t dev)
339 {
340 uint16_t self = (uint16_t)bsim_args_get_global_device_nbr();
341 uint channel_id;
342
343 if (self < dev) {
344 channel_id = (dev << 16) | self;
345 } else {
346 channel_id = (self << 16) | dev;
347 }
348
349 return channel_id;
350 }
351
352 /**
353 * @brief Calculate the sync timeout based on the PA interval
354 *
355 * Calculates the sync timeout, based on the PA interval and a pre-defined ratio.
356 * The return value is in N*10ms, conform the parameter for bt_le_per_adv_sync_create
357 *
358 * @param pa_interval PA interval
359 *
360 * @return uint16_t synchronization timeout (N * 10 ms)
361 */
interval_to_sync_timeout(uint16_t pa_interval)362 uint16_t interval_to_sync_timeout(uint16_t pa_interval)
363 {
364 uint16_t pa_timeout;
365
366 if (pa_interval == BT_BAP_PA_INTERVAL_UNKNOWN) {
367 /* Use maximum value to maximize chance of success */
368 pa_timeout = BT_GAP_PER_ADV_MAX_TIMEOUT;
369 } else {
370 uint32_t interval_us;
371 uint32_t timeout;
372
373 /* Add retries and convert to unit in 10's of ms */
374 interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(pa_interval);
375 timeout = BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us) *
376 PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO;
377
378 /* Enforce restraints */
379 pa_timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT, BT_GAP_PER_ADV_MAX_TIMEOUT);
380 }
381
382 return pa_timeout;
383 }
384
385 /**
386 * @brief Set up the backchannels between each pair of device
387 *
388 * Each pair of devices will get a unique channel
389 */
setup_backchannels(void)390 static void setup_backchannels(void)
391 {
392 __ASSERT_NO_MSG(dev_cnt > 0 && dev_cnt < ARRAY_SIZE(backchannel_nums));
393 const uint self = bsim_args_get_global_device_nbr();
394 uint device_numbers[dev_cnt];
395 uint *channels;
396
397 for (int32_t i = 0; i < dev_cnt; i++) {
398 backchannel_nums[chan_cnt] = get_chan_num((uint16_t)i);
399 device_numbers[chan_cnt++] = i;
400 }
401
402 channels = bs_open_back_channel(self, device_numbers, backchannel_nums, chan_cnt);
403 __ASSERT_NO_MSG(channels != NULL);
404 }
405 NATIVE_TASK(setup_backchannels, PRE_BOOT_3, 100);
406
get_chan_id_from_chan_num(uint chan_num)407 static uint get_chan_id_from_chan_num(uint chan_num)
408 {
409 for (uint i = 0; i < ARRAY_SIZE(backchannel_nums); i++) {
410 if (backchannel_nums[i] == chan_num) {
411 return i;
412 }
413 }
414
415 return 0;
416 }
417
backchannel_sync_send(uint dev)418 void backchannel_sync_send(uint dev)
419 {
420 const uint chan_id = get_chan_id_from_chan_num(get_chan_num((uint16_t)dev));
421 uint8_t sync_msg[SYNC_MSG_SIZE] = {0};
422
423 printk("Sending sync to %u\n", chan_id);
424 bs_bc_send_msg(chan_id, sync_msg, ARRAY_SIZE(sync_msg));
425 }
426
backchannel_sync_send_all(void)427 void backchannel_sync_send_all(void)
428 {
429 for (int32_t i = 0; i < dev_cnt; i++) {
430 const uint self = bsim_args_get_global_device_nbr();
431
432 if (i != self) { /* skip ourselves*/
433 backchannel_sync_send(i);
434 }
435 }
436 }
437
backchannel_sync_wait(uint dev)438 void backchannel_sync_wait(uint dev)
439 {
440 const uint chan_id = get_chan_id_from_chan_num(get_chan_num((uint16_t)dev));
441
442 printk("Waiting for sync to %u\n", chan_id);
443
444 while (true) {
445 if (bs_bc_is_msg_received(chan_id) > 0) {
446 uint8_t sync_msg[SYNC_MSG_SIZE];
447
448 bs_bc_receive_msg(chan_id, sync_msg, ARRAY_SIZE(sync_msg));
449 /* We don't really care about the content of the message */
450 break;
451 }
452
453 k_sleep(K_MSEC(1));
454 }
455 }
456
backchannel_sync_wait_all(void)457 void backchannel_sync_wait_all(void)
458 {
459 for (int32_t i = 0; i < dev_cnt; i++) {
460 const uint self = bsim_args_get_global_device_nbr();
461
462 if (i != self) { /* skip ourselves*/
463 backchannel_sync_wait(i);
464 }
465 }
466 }
467
backchannel_sync_wait_any(void)468 void backchannel_sync_wait_any(void)
469 {
470 while (true) {
471 for (int32_t i = 0; i < dev_cnt; i++) {
472 const uint self = bsim_args_get_global_device_nbr();
473
474 if (i != self) { /* skip ourselves*/
475 const uint chan_id =
476 get_chan_id_from_chan_num(get_chan_num((uint16_t)i));
477
478 if (bs_bc_is_msg_received(chan_id) > 0) {
479 uint8_t sync_msg[SYNC_MSG_SIZE];
480
481 bs_bc_receive_msg(chan_id, sync_msg, ARRAY_SIZE(sync_msg));
482 /* We don't really care about the content of the message */
483
484 return;
485 }
486 }
487 }
488
489 k_sleep(K_MSEC(100));
490 }
491 }
492
backchannel_sync_clear(uint dev)493 void backchannel_sync_clear(uint dev)
494 {
495 const uint chan_id = get_chan_id_from_chan_num(get_chan_num((uint16_t)dev));
496
497 while (bs_bc_is_msg_received(chan_id)) {
498 uint8_t sync_msg[SYNC_MSG_SIZE];
499
500 bs_bc_receive_msg(chan_id, sync_msg, ARRAY_SIZE(sync_msg));
501 /* We don't really care about the content of the message */
502 }
503 }
504
backchannel_sync_clear_all(void)505 void backchannel_sync_clear_all(void)
506 {
507 for (int32_t i = 0; i < dev_cnt; i++) {
508 const uint self = bsim_args_get_global_device_nbr();
509
510 if (i != self) { /* skip ourselves*/
511 backchannel_sync_clear(i);
512 }
513 }
514 }
515