1 /*
2  * Copyright (c) 2019 Bose Corporation
3  * Copyright (c) 2020-2021 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/bluetooth/addr.h>
13 #include <zephyr/bluetooth/audio/bap.h>
14 #include <zephyr/bluetooth/bluetooth.h>
15 #include <zephyr/bluetooth/conn.h>
16 #include <zephyr/bluetooth/gap.h>
17 #include <zephyr/kernel.h>
18 #include <zephyr/net_buf.h>
19 #include <zephyr/sys/__assert.h>
20 #include <zephyr/sys/atomic_types.h>
21 #include <zephyr/sys/printk.h>
22 #include <zephyr/sys/util.h>
23 
24 #include "bs_cmd_line.h"
25 #include "bs_dynargs.h"
26 #include "bs_pc_backchannel.h"
27 #include "posix_native_task.h"
28 #include "bs_types.h"
29 #include "bsim_args_runner.h"
30 #include "bstests.h"
31 #include "common.h"
32 
33 extern enum bst_result_t bst_result;
34 struct bt_conn *default_conn;
35 atomic_t flag_connected;
36 atomic_t flag_disconnected;
37 atomic_t flag_conn_updated;
38 atomic_t flag_audio_received;
39 volatile bt_security_t security_level;
40 
41 const struct bt_data ad[AD_SIZE] = {
42 	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR))
43 };
44 
device_found(const struct bt_le_scan_recv_info * info,struct net_buf_simple * ad_buf)45 static void device_found(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad_buf)
46 {
47 	char addr_str[BT_ADDR_LE_STR_LEN];
48 	int err;
49 
50 	if (default_conn) {
51 		return;
52 	}
53 
54 	/* We're only interested in connectable events */
55 	if ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) == 0) {
56 		return;
57 	}
58 
59 	bt_addr_le_to_str(info->addr, addr_str, sizeof(addr_str));
60 	printk("Device found: %s (RSSI %d)\n", addr_str, info->rssi);
61 
62 	/* connect only to devices in close proximity */
63 	if (info->rssi < -70) {
64 		FAIL("RSSI too low");
65 		return;
66 	}
67 
68 	printk("Stopping scan\n");
69 	if (bt_le_scan_stop()) {
70 		FAIL("Could not stop scan");
71 		return;
72 	}
73 
74 	err = bt_conn_le_create(info->addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT,
75 				&default_conn);
76 	if (err) {
77 		FAIL("Could not connect to peer: %d", err);
78 	}
79 }
80 
81 struct bt_le_scan_cb common_scan_cb = {
82 	.recv = device_found,
83 };
84 
connected(struct bt_conn * conn,uint8_t err)85 static void connected(struct bt_conn *conn, uint8_t err)
86 {
87 	char addr[BT_ADDR_LE_STR_LEN];
88 
89 	(void)bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
90 
91 	if (default_conn == NULL) {
92 		default_conn = bt_conn_ref(conn);
93 	}
94 
95 	if (err != 0) {
96 		bt_conn_unref(default_conn);
97 		default_conn = NULL;
98 
99 		FAIL("Failed to connect to %s (0x%02x)\n", addr, err);
100 		return;
101 	}
102 
103 	printk("Connected to %s (%p)\n", addr, conn);
104 	SET_FLAG(flag_connected);
105 }
106 
disconnected(struct bt_conn * conn,uint8_t reason)107 void disconnected(struct bt_conn *conn, uint8_t reason)
108 {
109 	char addr[BT_ADDR_LE_STR_LEN];
110 
111 	if (conn != default_conn) {
112 		return;
113 	}
114 
115 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
116 
117 	printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);
118 
119 	bt_conn_unref(default_conn);
120 	default_conn = NULL;
121 	UNSET_FLAG(flag_connected);
122 	UNSET_FLAG(flag_conn_updated);
123 	SET_FLAG(flag_disconnected);
124 
125 	security_level = BT_SECURITY_L1;
126 }
127 
conn_param_updated_cb(struct bt_conn * conn,uint16_t interval,uint16_t latency,uint16_t timeout)128 static void conn_param_updated_cb(struct bt_conn *conn, uint16_t interval, uint16_t latency,
129 				  uint16_t timeout)
130 {
131 	printk("Connection parameter updated: %p 0x%04X (%u us), 0x%04X, 0x%04X\n", conn, interval,
132 	       BT_CONN_INTERVAL_TO_US(interval), latency, timeout);
133 
134 	SET_FLAG(flag_conn_updated);
135 }
136 
security_changed_cb(struct bt_conn * conn,bt_security_t level,enum bt_security_err err)137 static void security_changed_cb(struct bt_conn *conn, bt_security_t level, enum bt_security_err err)
138 {
139 	printk("Security changed: %p level %d err %d\n", conn, level, err);
140 
141 	if (err == BT_SECURITY_ERR_SUCCESS) {
142 		security_level = level;
143 	}
144 }
145 
146 BT_CONN_CB_DEFINE(conn_callbacks) = {
147 	.connected = connected,
148 	.disconnected = disconnected,
149 	.le_param_updated = conn_param_updated_cb,
150 	.security_changed = security_changed_cb,
151 };
152 
test_tick(bs_time_t HW_device_time)153 void test_tick(bs_time_t HW_device_time)
154 {
155 	if (bst_result != Passed) {
156 		FAIL("test failed (not passed after %i seconds)\n", WAIT_SECONDS);
157 	}
158 }
159 
test_init(void)160 void test_init(void)
161 {
162 	bst_ticker_set_next_tick_absolute(WAIT_TIME);
163 	bst_result = In_progress;
164 }
165 
166 #define SYNC_MSG_SIZE 1
167 static int32_t dev_cnt;
168 static uint backchannel_nums[255];
169 static uint chan_cnt;
170 
register_more_cmd_args(void)171 static void register_more_cmd_args(void)
172 {
173 	static bs_args_struct_t args_struct_toadd[] = {
174 		{
175 			.option = "D",
176 			.name = "number_devices",
177 			.type = 'i',
178 			.dest = (void *)&dev_cnt,
179 			.descript = "Number of devices which will connect in this phy",
180 			.is_mandatory = true,
181 		},
182 		ARG_TABLE_ENDMARKER,
183 	};
184 
185 	bs_add_extra_dynargs(args_struct_toadd);
186 }
187 NATIVE_TASK(register_more_cmd_args, PRE_BOOT_1, 100);
188 
get_dev_cnt(void)189 uint16_t get_dev_cnt(void)
190 {
191 	return (uint16_t)dev_cnt;
192 }
193 
194 /**
195  * @brief Get the channel id based on remote device ID
196  *
197  * The is effectively a very simple hashing function to generate unique channel IDs from device IDs
198  *
199  * @param dev 16-bit device ID
200  *
201  * @return uint 32-bit channel ID
202  */
get_chan_num(uint16_t dev)203 static uint get_chan_num(uint16_t dev)
204 {
205 	uint16_t self = (uint16_t)bsim_args_get_global_device_nbr();
206 	uint channel_id;
207 
208 	if (self < dev) {
209 		channel_id = (dev << 16) | self;
210 	} else {
211 		channel_id = (self << 16) | dev;
212 	}
213 
214 	return channel_id;
215 }
216 
217 /**
218  * @brief Calculate the sync timeout based on the PA interval
219  *
220  * Calculates the sync timeout, based on the PA interval and a pre-defined ratio.
221  * The return value is in N*10ms, conform the parameter for bt_le_per_adv_sync_create
222  *
223  * @param pa_interval PA interval
224  *
225  * @return uint16_t synchronization timeout (N * 10 ms)
226  */
interval_to_sync_timeout(uint16_t pa_interval)227 uint16_t interval_to_sync_timeout(uint16_t pa_interval)
228 {
229 	uint16_t pa_timeout;
230 
231 	if (pa_interval == BT_BAP_PA_INTERVAL_UNKNOWN) {
232 		/* Use maximum value to maximize chance of success */
233 		pa_timeout = BT_GAP_PER_ADV_MAX_TIMEOUT;
234 	} else {
235 		uint32_t interval_us;
236 		uint32_t timeout;
237 
238 		/* Add retries and convert to unit in 10's of ms */
239 		interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(pa_interval);
240 		timeout = BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us) *
241 			  PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO;
242 
243 		/* Enforce restraints */
244 		pa_timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT, BT_GAP_PER_ADV_MAX_TIMEOUT);
245 	}
246 
247 	return pa_timeout;
248 }
249 
250 /**
251  * @brief Set up the backchannels between each pair of device
252  *
253  * Each pair of devices will get a unique channel
254  */
setup_backchannels(void)255 static void setup_backchannels(void)
256 {
257 	__ASSERT_NO_MSG(dev_cnt > 0 && dev_cnt < ARRAY_SIZE(backchannel_nums));
258 	const uint self = bsim_args_get_global_device_nbr();
259 	uint device_numbers[dev_cnt];
260 	uint *channels;
261 
262 	for (int32_t i = 0; i < dev_cnt; i++) {
263 		if (i != self) { /* skip ourselves*/
264 			backchannel_nums[chan_cnt] = get_chan_num((uint16_t)i);
265 			device_numbers[chan_cnt++] = i;
266 		}
267 	}
268 
269 	channels = bs_open_back_channel(self, device_numbers, backchannel_nums, chan_cnt);
270 	__ASSERT_NO_MSG(channels != NULL);
271 }
272 NATIVE_TASK(setup_backchannels, PRE_BOOT_3, 100);
273 
get_chan_id_from_chan_num(uint chan_num)274 static uint get_chan_id_from_chan_num(uint chan_num)
275 {
276 	for (uint i = 0; i < ARRAY_SIZE(backchannel_nums); i++) {
277 		if (backchannel_nums[i] == chan_num) {
278 			return i;
279 		}
280 	}
281 
282 	return 0;
283 }
284 
backchannel_sync_send(uint dev)285 void backchannel_sync_send(uint dev)
286 {
287 	const uint chan_id = get_chan_id_from_chan_num(get_chan_num((uint16_t)dev));
288 	uint8_t sync_msg[SYNC_MSG_SIZE] = {0};
289 
290 	printk("Sending sync to %u\n", chan_id);
291 	bs_bc_send_msg(chan_id, sync_msg, ARRAY_SIZE(sync_msg));
292 }
293 
backchannel_sync_send_all(void)294 void backchannel_sync_send_all(void)
295 {
296 	for (int32_t i = 0; i < dev_cnt; i++) {
297 		const uint self = bsim_args_get_global_device_nbr();
298 
299 		if (i != self) { /* skip ourselves*/
300 			backchannel_sync_send(i);
301 		}
302 	}
303 }
304 
backchannel_sync_wait(uint dev)305 void backchannel_sync_wait(uint dev)
306 {
307 	const uint chan_id = get_chan_id_from_chan_num(get_chan_num((uint16_t)dev));
308 
309 	printk("Waiting for sync to %u\n", chan_id);
310 
311 	while (true) {
312 		if (bs_bc_is_msg_received(chan_id) > 0) {
313 			uint8_t sync_msg[SYNC_MSG_SIZE];
314 
315 			bs_bc_receive_msg(chan_id, sync_msg, ARRAY_SIZE(sync_msg));
316 			/* We don't really care about the content of the message */
317 			break;
318 		}
319 
320 		k_sleep(K_MSEC(1));
321 	}
322 }
323 
backchannel_sync_wait_all(void)324 void backchannel_sync_wait_all(void)
325 {
326 	for (int32_t i = 0; i < dev_cnt; i++) {
327 		const uint self = bsim_args_get_global_device_nbr();
328 
329 		if (i != self) { /* skip ourselves*/
330 			backchannel_sync_wait(i);
331 		}
332 	}
333 }
334 
backchannel_sync_wait_any(void)335 void backchannel_sync_wait_any(void)
336 {
337 	while (true) {
338 		for (int32_t i = 0; i < dev_cnt; i++) {
339 			const uint self = bsim_args_get_global_device_nbr();
340 
341 			if (i != self) { /* skip ourselves*/
342 				const uint chan_id =
343 					get_chan_id_from_chan_num(get_chan_num((uint16_t)i));
344 
345 				if (bs_bc_is_msg_received(chan_id) > 0) {
346 					uint8_t sync_msg[SYNC_MSG_SIZE];
347 
348 					bs_bc_receive_msg(chan_id, sync_msg, ARRAY_SIZE(sync_msg));
349 					/* We don't really care about the content of the message */
350 
351 					return;
352 				}
353 			}
354 		}
355 
356 		k_sleep(K_MSEC(100));
357 	}
358 }
359 
backchannel_sync_clear(uint dev)360 void backchannel_sync_clear(uint dev)
361 {
362 	const uint chan_id = get_chan_id_from_chan_num(get_chan_num((uint16_t)dev));
363 
364 	while (bs_bc_is_msg_received(chan_id)) {
365 		uint8_t sync_msg[SYNC_MSG_SIZE];
366 
367 		bs_bc_receive_msg(chan_id, sync_msg, ARRAY_SIZE(sync_msg));
368 		/* We don't really care about the content of the message */
369 	}
370 }
371 
backchannel_sync_clear_all(void)372 void backchannel_sync_clear_all(void)
373 {
374 	for (int32_t i = 0; i < dev_cnt; i++) {
375 		const uint self = bsim_args_get_global_device_nbr();
376 
377 		if (i != self) { /* skip ourselves*/
378 			backchannel_sync_clear(i);
379 		}
380 	}
381 }
382