1 /* main.c - Host long advertising receive */
2 
3 /*
4  * Copyright (c) 2021 Nordic Semiconductor ASA
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/fff.h>
10 #include <zephyr/kernel.h>
11 #include <zephyr/ztest.h>
12 
13 #include <errno.h>
14 #include <zephyr/tc_util.h>
15 
16 #include <zephyr/bluetooth/hci.h>
17 #include <zephyr/bluetooth/buf.h>
18 #include <zephyr/bluetooth/bluetooth.h>
19 #include <zephyr/drivers/bluetooth/hci_driver.h>
20 #include <zephyr/sys/byteorder.h>
21 
22 #define LOG_LEVEL CONFIG_BT_LOG_LEVEL
23 #include <zephyr/logging/log.h>
24 LOG_MODULE_REGISTER(host_test_app);
25 
26 DEFINE_FFF_GLOBALS;
27 
28 struct test_adv_report {
29 	uint8_t data[CONFIG_BT_EXT_SCAN_BUF_SIZE];
30 	uint8_t length;
31 	uint16_t evt_prop;
32 	bt_addr_le_t addr;
33 };
34 
35 #define COMPLETE BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE << 5
36 #define MORE_TO_COME BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL << 5
37 #define TRUNCATED BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE << 5
38 
39 /* Command handler structure for cmd_handle(). */
40 struct cmd_handler {
41 	uint16_t opcode; /* HCI command opcode */
42 	uint8_t len; /* HCI command response length */
43 	void (*handler)(struct net_buf *buf, struct net_buf **evt, uint8_t len, uint16_t opcode);
44 };
45 
46 /* Add event to net_buf. */
evt_create(struct net_buf * buf,uint8_t evt,uint8_t len)47 static void evt_create(struct net_buf *buf, uint8_t evt, uint8_t len)
48 {
49 	struct bt_hci_evt_hdr *hdr;
50 
51 	hdr = net_buf_add(buf, sizeof(*hdr));
52 	hdr->evt = evt;
53 	hdr->len = len;
54 }
55 
le_meta_evt_create(struct bt_hci_evt_le_meta_event * evt,uint8_t subevent)56 static void le_meta_evt_create(struct bt_hci_evt_le_meta_event *evt, uint8_t subevent)
57 {
58 	evt->subevent = subevent;
59 }
60 
adv_info_create(struct bt_hci_evt_le_ext_advertising_info * evt,uint16_t evt_type,const bt_addr_le_t * const addr,uint8_t length)61 static void adv_info_create(struct bt_hci_evt_le_ext_advertising_info *evt, uint16_t evt_type,
62 			    const bt_addr_le_t *const addr, uint8_t length)
63 {
64 	evt->evt_type = evt_type;
65 	bt_addr_le_copy(&evt->addr, addr);
66 	evt->prim_phy = 0;
67 	evt->sec_phy = 0;
68 	evt->sid = 0;
69 	evt->tx_power = 0;
70 	evt->rssi = 0;
71 	evt->interval = 0;
72 	bt_addr_le_copy(&evt->direct_addr, BT_ADDR_LE_NONE);
73 	evt->length = length;
74 }
75 
76 /* Create a command complete event. */
cmd_complete(struct net_buf ** buf,uint8_t plen,uint16_t opcode)77 static void *cmd_complete(struct net_buf **buf, uint8_t plen, uint16_t opcode)
78 {
79 	struct bt_hci_evt_cmd_complete *cc;
80 
81 	*buf = bt_buf_get_evt(BT_HCI_EVT_CMD_COMPLETE, false, K_FOREVER);
82 	evt_create(*buf, BT_HCI_EVT_CMD_COMPLETE, sizeof(*cc) + plen);
83 	cc = net_buf_add(*buf, sizeof(*cc));
84 	cc->ncmd = 1U;
85 	cc->opcode = sys_cpu_to_le16(opcode);
86 
87 	return net_buf_add(*buf, plen);
88 }
89 
90 /* Loop over handlers to try to handle the command given by opcode. */
cmd_handle_helper(uint16_t opcode,struct net_buf * cmd,struct net_buf ** evt,const struct cmd_handler * handlers,size_t num_handlers)91 static int cmd_handle_helper(uint16_t opcode, struct net_buf *cmd, struct net_buf **evt,
92 			     const struct cmd_handler *handlers, size_t num_handlers)
93 {
94 	for (size_t i = 0; i < num_handlers; i++) {
95 		const struct cmd_handler *handler = &handlers[i];
96 
97 		if (handler->opcode != opcode) {
98 			continue;
99 		}
100 
101 		if (handler->handler) {
102 			handler->handler(cmd, evt, handler->len, opcode);
103 
104 			return 0;
105 		}
106 	}
107 
108 	zassert_unreachable("opcode %X failed", opcode);
109 
110 	return -EINVAL;
111 }
112 
113 /* Lookup the command opcode and invoke handler. */
cmd_handle(struct net_buf * cmd,const struct cmd_handler * handlers,size_t num_handlers)114 static int cmd_handle(struct net_buf *cmd, const struct cmd_handler *handlers, size_t num_handlers)
115 {
116 	struct net_buf *evt = NULL;
117 	struct bt_hci_evt_cc_status *ccst;
118 	struct bt_hci_cmd_hdr *chdr;
119 	uint16_t opcode;
120 	int err;
121 
122 	chdr = net_buf_pull_mem(cmd, sizeof(*chdr));
123 	opcode = sys_le16_to_cpu(chdr->opcode);
124 
125 	err = cmd_handle_helper(opcode, cmd, &evt, handlers, num_handlers);
126 
127 	if (err == -EINVAL) {
128 		ccst = cmd_complete(&evt, sizeof(*ccst), opcode);
129 		ccst->status = BT_HCI_ERR_UNKNOWN_CMD;
130 	}
131 
132 	if (evt) {
133 		bt_recv_prio(evt);
134 	}
135 
136 	return err;
137 }
138 
139 /* Generic command complete with success status. */
generic_success(struct net_buf * buf,struct net_buf ** evt,uint8_t len,uint16_t opcode)140 static void generic_success(struct net_buf *buf, struct net_buf **evt, uint8_t len, uint16_t opcode)
141 {
142 	struct bt_hci_evt_cc_status *ccst;
143 
144 	ccst = cmd_complete(evt, len, opcode);
145 
146 	/* Fill any event parameters with zero */
147 	(void)memset(ccst, 0, len);
148 
149 	ccst->status = BT_HCI_ERR_SUCCESS;
150 }
151 
152 /* Bogus handler for BT_HCI_OP_READ_LOCAL_FEATURES. */
read_local_features(struct net_buf * buf,struct net_buf ** evt,uint8_t len,uint16_t opcode)153 static void read_local_features(struct net_buf *buf, struct net_buf **evt, uint8_t len,
154 				uint16_t opcode)
155 {
156 	struct bt_hci_rp_read_local_features *rp;
157 
158 	rp = cmd_complete(evt, sizeof(*rp), opcode);
159 	rp->status = 0x00;
160 	(void)memset(rp->features, 0xFF, sizeof(rp->features));
161 }
162 
163 /* Bogus handler for BT_HCI_OP_READ_SUPPORTED_COMMANDS. */
read_supported_commands(struct net_buf * buf,struct net_buf ** evt,uint8_t len,uint16_t opcode)164 static void read_supported_commands(struct net_buf *buf, struct net_buf **evt, uint8_t len,
165 				    uint16_t opcode)
166 {
167 	struct bt_hci_rp_read_supported_commands *rp;
168 
169 	rp = cmd_complete(evt, sizeof(*rp), opcode);
170 	(void)memset(rp->commands, 0xFF, sizeof(rp->commands));
171 	rp->status = 0x00;
172 }
173 
174 /* Bogus handler for BT_HCI_OP_LE_READ_LOCAL_FEATURES. */
le_read_local_features(struct net_buf * buf,struct net_buf ** evt,uint8_t len,uint16_t opcode)175 static void le_read_local_features(struct net_buf *buf, struct net_buf **evt, uint8_t len,
176 				   uint16_t opcode)
177 {
178 	struct bt_hci_rp_le_read_local_features *rp;
179 
180 	rp = cmd_complete(evt, sizeof(*rp), opcode);
181 	rp->status = 0x00;
182 	(void)memset(rp->features, 0xFF, sizeof(rp->features));
183 }
184 
185 /* Bogus handler for BT_HCI_OP_LE_READ_SUPP_STATES. */
le_read_supp_states(struct net_buf * buf,struct net_buf ** evt,uint8_t len,uint16_t opcode)186 static void le_read_supp_states(struct net_buf *buf, struct net_buf **evt, uint8_t len,
187 				uint16_t opcode)
188 {
189 	struct bt_hci_rp_le_read_supp_states *rp;
190 
191 	rp = cmd_complete(evt, sizeof(*rp), opcode);
192 	rp->status = 0x00;
193 	(void)memset(&rp->le_states, 0xFF, sizeof(rp->le_states));
194 }
195 
196 /* Setup handlers needed for bt_enable to function. */
197 static const struct cmd_handler cmds[] = {
198 	{ BT_HCI_OP_READ_LOCAL_VERSION_INFO, sizeof(struct bt_hci_rp_read_local_version_info),
199 	  generic_success },
200 	{ BT_HCI_OP_READ_SUPPORTED_COMMANDS, sizeof(struct bt_hci_rp_read_supported_commands),
201 	  read_supported_commands },
202 	{ BT_HCI_OP_READ_LOCAL_FEATURES, sizeof(struct bt_hci_rp_read_local_features),
203 	  read_local_features },
204 	{ BT_HCI_OP_READ_BD_ADDR, sizeof(struct bt_hci_rp_read_bd_addr), generic_success },
205 	{ BT_HCI_OP_SET_EVENT_MASK, sizeof(struct bt_hci_evt_cc_status), generic_success },
206 	{ BT_HCI_OP_LE_SET_EVENT_MASK, sizeof(struct bt_hci_evt_cc_status), generic_success },
207 	{ BT_HCI_OP_LE_READ_LOCAL_FEATURES, sizeof(struct bt_hci_rp_le_read_local_features),
208 	  le_read_local_features },
209 	{ BT_HCI_OP_LE_READ_SUPP_STATES, sizeof(struct bt_hci_rp_le_read_supp_states),
210 	  le_read_supp_states },
211 	{ BT_HCI_OP_LE_RAND, sizeof(struct bt_hci_rp_le_rand), generic_success },
212 	{ BT_HCI_OP_LE_SET_RANDOM_ADDRESS, sizeof(struct bt_hci_cp_le_set_random_address),
213 	  generic_success },
214 	{ BT_HCI_OP_RESET, 0, generic_success },
215 };
216 
217 /* HCI driver open. */
driver_open(void)218 static int driver_open(void)
219 {
220 	return 0;
221 }
222 
223 /*  HCI driver send.  */
driver_send(struct net_buf * buf)224 static int driver_send(struct net_buf *buf)
225 {
226 	zassert_true(cmd_handle(buf, cmds, ARRAY_SIZE(cmds)) == 0, "Unknown HCI command");
227 
228 	net_buf_unref(buf);
229 
230 	return 0;
231 }
232 
233 /* HCI driver structure. */
234 static const struct bt_hci_driver drv = {
235 	.name = "test",
236 	.bus = BT_HCI_DRIVER_BUS_VIRTUAL,
237 	.open = driver_open,
238 	.send = driver_send,
239 	.quirks = 0,
240 };
241 
242 struct bt_recv_job_data {
243 	struct k_work work; /* Work item */
244 	struct k_sem *sync; /* Semaphore to synchronize with */
245 	struct net_buf *buf; /* Net buffer to be passed to bt_recv() */
246 } job_data[CONFIG_BT_BUF_EVT_RX_COUNT];
247 
248 #define job(buf) (&job_data[net_buf_id(buf)])
249 
250 /* Work item handler for bt_recv() jobs. */
bt_recv_job_cb(struct k_work * item)251 static void bt_recv_job_cb(struct k_work *item)
252 {
253 	struct bt_recv_job_data *data = CONTAINER_OF(item, struct bt_recv_job_data, work);
254 
255 	/* Send net buffer to host */
256 	bt_recv(data->buf);
257 
258 	/* Wake up bt_recv_job_submit */
259 	k_sem_give(job(data->buf)->sync);
260 }
261 
262 /* Prepare a job to call bt_recv() to be submitted to the system workqueue. */
bt_recv_job_submit(struct net_buf * buf)263 static void bt_recv_job_submit(struct net_buf *buf)
264 {
265 	struct k_sem sync_sem;
266 
267 	/* Store the net buffer to be passed to bt_recv */
268 	job(buf)->buf = buf;
269 
270 	/* Initialize job work item/semaphore */
271 	k_work_init(&job(buf)->work, bt_recv_job_cb);
272 	k_sem_init(&sync_sem, 0, 1);
273 	job(buf)->sync = &sync_sem;
274 
275 	/* Make sure the buffer stays around until the command completes */
276 	buf = net_buf_ref(buf);
277 
278 	/* Submit the work item */
279 	k_work_submit(&job(buf)->work);
280 
281 	/* Wait for bt_recv_job_cb to be done */
282 	k_sem_take(&sync_sem, K_FOREVER);
283 
284 	net_buf_unref(buf);
285 }
286 
287 /* Semaphore to test if the prop callback was called. */
288 static K_SEM_DEFINE(prop_cb_sem, 0, 1);
289 
adv_report_evt(struct net_buf * buf,uint8_t data_len,uint16_t evt_type,const bt_addr_le_t * const addr)290 static void *adv_report_evt(struct net_buf *buf, uint8_t data_len, uint16_t evt_type,
291 			    const bt_addr_le_t *const addr)
292 {
293 	struct bt_hci_evt_le_meta_event *meta_evt;
294 	struct bt_hci_evt_le_ext_advertising_info *evt;
295 
296 	evt_create(buf, BT_HCI_EVT_LE_META_EVENT, sizeof(*meta_evt) + sizeof(*evt) + data_len + 1);
297 	meta_evt = net_buf_add(buf, sizeof(*meta_evt));
298 	le_meta_evt_create(meta_evt, BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT);
299 	net_buf_add_u8(buf, 1); /* Number of reports */
300 	evt = net_buf_add(buf, sizeof(*evt));
301 	adv_info_create(evt, evt_type, addr, data_len);
302 
303 	return net_buf_add(buf, data_len);
304 }
305 
306 /* Send a prop event report wit the given data. */
send_adv_report(const struct test_adv_report * report)307 static void send_adv_report(const struct test_adv_report *report)
308 {
309 	LOG_DBG("Sending adv report");
310 	struct net_buf *buf;
311 	uint8_t *adv_data;
312 
313 	buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
314 	adv_data = adv_report_evt(buf, report->length, report->evt_prop, &report->addr);
315 	memcpy(adv_data, &report->data, report->length);
316 
317 	/* Submit job */
318 	bt_recv_job_submit(buf);
319 }
320 
321 FAKE_VALUE_FUNC(struct test_adv_report, get_expected_report);
322 
scan_recv_cb(const struct bt_le_scan_recv_info * info,struct net_buf_simple * buf)323 static void scan_recv_cb(const struct bt_le_scan_recv_info *info, struct net_buf_simple *buf)
324 {
325 	ARG_UNUSED(info);
326 
327 	LOG_DBG("Received event with length %u", buf->len);
328 
329 	const struct test_adv_report expected = get_expected_report();
330 
331 	zassert_equal(buf->len, expected.length, "Lengths should be equal");
332 	zassert_mem_equal(buf->data, expected.data, buf->len, "Data should be equal");
333 }
334 
scan_timeout_cb(void)335 static void scan_timeout_cb(void)
336 {
337 	zassert_unreachable("Timeout should not happen");
338 }
339 
generate_sequence(uint8_t * dest,uint16_t len,uint8_t range_start,uint8_t range_end)340 static void generate_sequence(uint8_t *dest, uint16_t len, uint8_t range_start, uint8_t range_end)
341 {
342 	uint16_t written = 0;
343 	uint8_t value = range_start;
344 
345 	while (written < len) {
346 		*dest++ = value++;
347 		written++;
348 		if (value > range_end) {
349 			value = range_start;
350 		}
351 	}
352 }
353 
354 ZTEST_SUITE(long_adv_rx_tests, NULL, NULL, NULL, NULL, NULL);
355 
ZTEST(long_adv_rx_tests,test_host_long_adv_recv)356 ZTEST(long_adv_rx_tests, test_host_long_adv_recv)
357 {
358 	struct test_adv_report expected_reports[2];
359 
360 	/* Register the test HCI driver */
361 	bt_hci_driver_register(&drv);
362 
363 	/* Go! Wait until Bluetooth initialization is done  */
364 	zassert_true((bt_enable(NULL) == 0), "bt_enable failed");
365 
366 	static struct bt_le_scan_cb scan_callbacks = { .recv = scan_recv_cb,
367 						       .timeout = scan_timeout_cb };
368 	bt_le_scan_cb_register(&scan_callbacks);
369 	bt_addr_le_t addr_a;
370 	bt_addr_le_t addr_b;
371 	bt_addr_le_t addr_c;
372 	bt_addr_le_t addr_d;
373 
374 	bt_addr_le_create_static(&addr_a);
375 	bt_addr_le_create_static(&addr_b);
376 	bt_addr_le_create_static(&addr_c);
377 	bt_addr_le_create_static(&addr_d);
378 
379 	struct test_adv_report report_a_1 = { .length = 30, .evt_prop = MORE_TO_COME };
380 	struct test_adv_report report_a_2 = { .length = 30, .evt_prop = COMPLETE };
381 
382 	bt_addr_le_copy(&report_a_1.addr, &addr_a);
383 	bt_addr_le_copy(&report_a_2.addr, &addr_a);
384 
385 	struct test_adv_report report_b_1 = { .length = 30, .evt_prop = MORE_TO_COME };
386 	struct test_adv_report report_b_2 = { .length = 30, .evt_prop = COMPLETE };
387 
388 	bt_addr_le_copy(&report_b_1.addr, &addr_b);
389 	bt_addr_le_copy(&report_b_2.addr, &addr_b);
390 
391 	struct test_adv_report report_c = { .length = 30,
392 					    .evt_prop = COMPLETE | BT_HCI_LE_ADV_EVT_TYPE_LEGACY };
393 
394 	bt_addr_le_copy(&report_c.addr, &addr_c);
395 
396 	struct test_adv_report report_d = { .length = 30, .evt_prop = TRUNCATED };
397 
398 	bt_addr_le_copy(&report_c.addr, &addr_c);
399 
400 	struct test_adv_report report_a_combined = { .length = report_a_1.length +
401 							       report_a_2.length };
402 
403 	struct test_adv_report report_a_1_repeated = { .length = CONFIG_BT_EXT_SCAN_BUF_SIZE };
404 
405 	struct test_adv_report report_b_combined = { .length = report_b_1.length +
406 							       report_b_2.length };
407 
408 	generate_sequence(report_a_combined.data, report_a_combined.length, 'A', 'Z');
409 	generate_sequence(report_b_combined.data, report_b_combined.length, 'a', 'z');
410 	generate_sequence(report_c.data, report_c.length, '0', '9');
411 
412 	(void)memcpy(report_a_1.data, report_a_combined.data, report_a_1.length);
413 	(void)memcpy(report_a_2.data, &report_a_combined.data[report_a_1.length],
414 		     report_a_2.length);
415 
416 	for (int i = 0; i < report_a_1_repeated.length; i += report_a_1.length) {
417 		memcpy(&report_a_1_repeated.data[i], report_a_1.data,
418 		       MIN(report_a_1.length, (report_a_1_repeated.length - i)));
419 	}
420 
421 	(void)memcpy(report_b_1.data, report_b_combined.data, report_b_1.length);
422 	(void)memcpy(report_b_2.data, &report_b_combined.data[report_b_1.length],
423 		     report_b_2.length);
424 
425 	/* Check that non-interleaved fragmented adv reports work */
426 	expected_reports[0] = report_a_combined;
427 	expected_reports[1] = report_b_combined;
428 	SET_RETURN_SEQ(get_expected_report, expected_reports, 2);
429 	send_adv_report(&report_a_1);
430 	send_adv_report(&report_a_2);
431 	send_adv_report(&report_b_1);
432 	send_adv_report(&report_b_2);
433 	zassert_equal(2, get_expected_report_fake.call_count);
434 	RESET_FAKE(get_expected_report);
435 	FFF_RESET_HISTORY();
436 
437 	/* Check that legacy adv reports interleaved with fragmented adv reports work */
438 	expected_reports[0] = report_c;
439 	expected_reports[1] = report_a_combined;
440 	SET_RETURN_SEQ(get_expected_report, expected_reports, 2);
441 	send_adv_report(&report_a_1);
442 	send_adv_report(&report_c); /* Interleaved legacy adv report */
443 	send_adv_report(&report_a_2);
444 	zassert_equal(2, get_expected_report_fake.call_count);
445 	RESET_FAKE(get_expected_report);
446 	FFF_RESET_HISTORY();
447 
448 	/* Check that complete adv reports interleaved with fragmented adv reports work */
449 	expected_reports[0] = report_b_2;
450 	expected_reports[1] = report_a_combined;
451 	SET_RETURN_SEQ(get_expected_report, expected_reports, 2);
452 	send_adv_report(&report_a_1);
453 	send_adv_report(&report_b_2); /* Interleaved short extended adv report */
454 	send_adv_report(&report_a_2);
455 	zassert_equal(2, get_expected_report_fake.call_count);
456 	RESET_FAKE(get_expected_report);
457 	FFF_RESET_HISTORY();
458 
459 	/* Check that fragmented adv reports from one peer are received,
460 	 * and that interleaved fragmented adv reports from other peers are discarded
461 	 */
462 	expected_reports[0] = report_a_combined;
463 	expected_reports[1] = report_b_2;
464 	SET_RETURN_SEQ(get_expected_report, expected_reports, 2);
465 	send_adv_report(&report_a_1);
466 	send_adv_report(&report_b_1); /* Interleaved fragmented adv report, NOT SUPPORTED */
467 	send_adv_report(&report_a_2);
468 	send_adv_report(&report_b_2);
469 	zassert_equal(2, get_expected_report_fake.call_count);
470 	RESET_FAKE(get_expected_report);
471 	FFF_RESET_HISTORY();
472 
473 	/* Check that host discards the data if the controller keeps sending
474 	 * incomplete packets.
475 	 */
476 	expected_reports[0] = report_b_combined;
477 	SET_RETURN_SEQ(get_expected_report, expected_reports, 1);
478 	for (int i = 0; i < (2 + (CONFIG_BT_EXT_SCAN_BUF_SIZE / report_a_1.length)); i++) {
479 		send_adv_report(&report_a_1);
480 	}
481 	send_adv_report(&report_a_2);
482 
483 	/* Check that controller truncated reports do not generate events */
484 	send_adv_report(&report_d);
485 
486 	/* Check that reports from a different advertiser works after truncation */
487 	send_adv_report(&report_b_1);
488 	send_adv_report(&report_b_2);
489 	zassert_equal(1, get_expected_report_fake.call_count);
490 }
491