1 /* Copyright (c) 2024 Nordic Semiconductor ASA
2  * SPDX-License-Identifier: Apache-2.0
3  */
4 
5 #include <zephyr/bluetooth/addr.h>
6 #include <zephyr/bluetooth/bluetooth.h>
7 #include <zephyr/kernel.h>
8 #include <zephyr/logging/log.h>
9 #include <zephyr/sys/atomic.h>
10 #include <zephyr/sys/atomic_builtin.h>
11 
12 #include "testlib/log_utils.h"
13 #include "babblekit/flags.h"
14 #include "babblekit/testcase.h"
15 
16 LOG_MODULE_REGISTER(dut, LOG_LEVEL_DBG);
17 
18 extern unsigned long runtime_log_level;
19 
device_found(const bt_addr_le_t * addr,int8_t rssi,uint8_t type,struct net_buf_simple * ad)20 static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
21 			 struct net_buf_simple *ad)
22 {
23 	char addr_str[BT_ADDR_LE_STR_LEN];
24 
25 	k_msleep(500); /* simulate a slow memcpy (or user processing the scan data) */
26 
27 	bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
28 	LOG_DBG("Device found: %s (RSSI %d), type %u, AD data len %u", addr_str, rssi, type,
29 		ad->len);
30 }
31 
32 #define BT_LE_SCAN_ACTIVE_CONTINUOUS_WITH_DUPLICATES                                               \
33 	BT_LE_SCAN_PARAM(BT_LE_SCAN_TYPE_ACTIVE, 0, BT_GAP_SCAN_FAST_INTERVAL_MIN,                 \
34 			 BT_GAP_SCAN_FAST_WINDOW)
35 
entrypoint_dut(void)36 void entrypoint_dut(void)
37 {
38 	/* Test purpose:
39 	 *
40 	 * Verifies that the host can handle running out of HCI RX buffers.
41 	 *
42 	 * To test this, we use a scanner with privacy enabled and sleep a bit
43 	 * when we get every advertising report. This sleep period simulates a
44 	 * slow "memcpy" operation on actual hardware. In effect, this uses up
45 	 * the event buffer pools.
46 	 *
47 	 * A short RPA timeout is used to prompt the host into periodically
48 	 * sending a bunch of commands to the controller. Those commands should
49 	 * not fail.
50 	 *
51 	 * Note: This test only fails by the stack crashing.
52 	 *
53 	 * It is a regression test for
54 	 * https://github.com/zephyrproject-rtos/zephyr/issues/78223
55 	 *
56 	 * Two devices:
57 	 * - `dut`: active-scans with privacy ON
58 	 * - `peer`: bog-standard advertiser
59 	 *
60 	 * [verdict]
61 	 * - dut is able to run for a long enough time without triggering asserts
62 	 */
63 	int err;
64 
65 	TEST_START("DUT");
66 
67 	/* Set the log level given by the `log_level` CLI argument */
68 	bt_testlib_log_level_set("dut", runtime_log_level);
69 
70 	err = bt_enable(NULL);
71 	TEST_ASSERT(!err, "Bluetooth init failed (err %d)\n", err);
72 
73 	LOG_DBG("Bluetooth initialised");
74 
75 	err = bt_le_scan_start(BT_LE_SCAN_ACTIVE_CONTINUOUS_WITH_DUPLICATES, device_found);
76 	TEST_ASSERT(!err, "Scanner setup failed (err %d)\n", err);
77 	LOG_DBG("Explicit scanner started");
78 
79 	/* 40 seconds ought to be enough for anyone */
80 	k_sleep(K_SECONDS(40));
81 
82 	TEST_PASS_AND_EXIT("DUT passed");
83 }
84