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