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