1 /*
2 * Copyright (c) 2024-2025 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/fff.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/bluetooth/bluetooth.h>
10 #include <zephyr/bluetooth/conn.h>
11
12 #include <host/conn_internal.h>
13
14 #include "mocks/addr_internal.h"
15 #include "mocks/att_internal.h"
16 #include "mocks/bt_str.h"
17 #include "mocks/buf_view.h"
18 #include "mocks/hci_core.h"
19 #include "mocks/id.h"
20 #include "mocks/kernel.h"
21 #include "mocks/l2cap_internal.h"
22 #include "mocks/scan.h"
23 #include "mocks/smp.h"
24 #include "mocks/spinlock.h"
25 #include "mocks/sys_clock.h"
26
27 DEFINE_FFF_GLOBALS;
28
fff_reset_rule_before(const struct ztest_unit_test * test,void * fixture)29 static void fff_reset_rule_before(const struct ztest_unit_test *test, void *fixture)
30 {
31 ADDR_INTERNAL_MOCKS_FFF_FAKES_LIST(RESET_FAKE);
32 ATT_INTERNAL_MOCKS_FFF_FAKES_LIST(RESET_FAKE);
33 BUF_VIEW_MOCKS_FFF_FAKES_LIST(RESET_FAKE);
34 HCI_CORE_MOCKS_FFF_FAKES_LIST(RESET_FAKE);
35 ID_MOCKS_FFF_FAKES_LIST(RESET_FAKE);
36 KERNEL_MOCKS_FFF_FAKES_LIST(RESET_FAKE);
37 L2CAP_INTERNAL_MOCKS_FFF_FAKES_LIST(RESET_FAKE);
38 SCAN_MOCKS_FFF_FAKES_LIST(RESET_FAKE);
39 SMP_MOCKS_FFF_FAKES_LIST(RESET_FAKE);
40 SPINLOCK_MOCKS_FFF_FAKES_LIST(RESET_FAKE);
41 SYS_CLOCK_MOCKS_FFF_FAKES_LIST(RESET_FAKE);
42 }
43
44 ZTEST_RULE(fff_reset_rule, fff_reset_rule_before, NULL);
45
46 ZTEST_SUITE(conn, NULL, NULL, NULL, NULL, NULL);
47
48 /*
49 * Test that bt_conn_le_create() returns -EINVAL if conn is not NULL and
50 * CONFIG_BT_CONN_CHECK_NULL_BEFORE_CREATE is enabled.
51 *
52 * The test must be compiled with and without CONFIG_BT_CONN_CHECK_NULL_BEFORE_CREATE
53 * to ensure that the -EINVAL error is returned only when this Kconfig option is enabled.
54 */
ZTEST(conn,test_bt_conn_le_create_check_null_conn)55 ZTEST(conn, test_bt_conn_le_create_check_null_conn)
56 {
57 bt_addr_le_t peer = {.a.val = {0x01}};
58 const struct bt_conn_le_create_param create_param = {
59 .options = BT_CONN_LE_OPT_NONE,
60 .interval = BT_GAP_SCAN_FAST_INTERVAL,
61 .window = BT_GAP_SCAN_FAST_WINDOW,
62 .interval_coded = 0,
63 .window_coded = 0,
64 .timeout = 100UL * MSEC_PER_SEC / 10,
65 };
66 struct bt_conn *conn;
67 int err;
68
69 /* Set conn to any non-NULL value to trigger the check. */
70 conn = (struct bt_conn *)1;
71
72 err = bt_conn_le_create(&peer, &create_param, BT_LE_CONN_PARAM_DEFAULT, &conn);
73 /* err must not be -EINVAL if CONFIG_BT_CONN_CHECK_NULL_BEFORE_CREATE is not enabled,
74 * otherwise -EAGAIN is returned.
75 *
76 * The printk is used to see what actually was compiled.
77 */
78 #if defined(CONFIG_BT_CONN_CHECK_NULL_BEFORE_CREATE)
79 printk("Expected error -EINVAL\n");
80 zassert_equal(err, -EINVAL, "Failed starting initiator (err %d)", err);
81 #else
82 printk("Expected error -EAGAIN\n");
83 zassert_equal(err, -EAGAIN, "Failed starting initiator (err %d)", err);
84 #endif
85
86 /* If the conn is NULL, next error must not be -EINVAL. */
87 conn = NULL;
88 err = bt_conn_le_create(&peer, &create_param, BT_LE_CONN_PARAM_DEFAULT, &conn);
89 zassert_not_equal(err, -EINVAL, "Failed starting initiator (err %d)", err);
90 }
91
92 /*
93 * Test that bt_conn_le_create_synced() returns -EINVAL if conn is not NULL and
94 * CONFIG_BT_CONN_CHECK_NULL_BEFORE_CREATE is enabled.
95 *
96 * The test must be compiled with and without CONFIG_BT_CONN_CHECK_NULL_BEFORE_CREATE
97 * to ensure that the -EINVAL error is returned only when this Kconfig option is enabled.
98 */
ZTEST(conn,test_bt_conn_le_create_synced_check_null_conn)99 ZTEST(conn, test_bt_conn_le_create_synced_check_null_conn)
100 {
101 bt_addr_le_t peer = {.a.val = {0x01}};
102 struct bt_le_conn_param conn_param = {
103 .interval_min = 0x30,
104 .interval_max = 0x30,
105 .latency = 0,
106 .timeout = 400,
107 };
108 struct bt_conn_le_create_synced_param synced_param = {
109 .peer = &peer,
110 };
111 struct bt_le_ext_adv *adv = NULL;
112 struct bt_conn *conn;
113 int err;
114
115 /* Set conn to any non-NULL value to trigger the check. */
116 conn = (struct bt_conn *)1;
117 err = bt_conn_le_create_synced(adv, &synced_param, &conn_param, &conn);
118
119 /* err must not be -EINVAL if CONFIG_BT_CONN_CHECK_NULL_BEFORE_CREATE is not enabled,
120 * otherwise -EAGAIN is returned.
121 *
122 * The printk is used to see what actually was compiled.
123 */
124 #if defined(CONFIG_BT_CONN_CHECK_NULL_BEFORE_CREATE)
125 printk("Expected error -EINVAL\n");
126 zassert_equal(err, -EINVAL, "Failed starting initiator (err %d)", err);
127 #else
128 printk("Expected error -EAGAIN\n");
129 zassert_equal(err, -EAGAIN, "Failed starting initiator (err %d)", err);
130 #endif
131
132 /* If the conn is NULL, next error must not be -EINVAL. */
133 conn = NULL;
134 err = bt_conn_le_create_synced(adv, &synced_param, &conn_param, &conn);
135 zassert_not_equal(err, -EINVAL, "Failed starting initiator (err %d)", err);
136 }
137
ZTEST(conn,test_bt_conn_is_type)138 ZTEST(conn, test_bt_conn_is_type)
139 {
140 struct bt_conn conn = {0};
141
142 conn.type = BT_CONN_TYPE_LE;
143 zassert_true(bt_conn_is_type(&conn, BT_CONN_TYPE_LE));
144 zassert_false(bt_conn_is_type(&conn, 0));
145 zassert_false(bt_conn_is_type(&conn, BT_CONN_TYPE_BR));
146 zassert_false(bt_conn_is_type(&conn, BT_CONN_TYPE_SCO));
147 zassert_false(bt_conn_is_type(&conn, BT_CONN_TYPE_ISO));
148
149 zassert_true(bt_conn_is_type(&conn, BT_CONN_TYPE_LE | BT_CONN_TYPE_BR));
150 zassert_true(bt_conn_is_type(&conn, BT_CONN_TYPE_LE | BT_CONN_TYPE_SCO));
151 zassert_true(bt_conn_is_type(&conn, BT_CONN_TYPE_LE | BT_CONN_TYPE_ISO));
152 zassert_true(bt_conn_is_type(&conn, BT_CONN_TYPE_ALL));
153
154 conn.type = BT_CONN_TYPE_BR;
155 zassert_true(bt_conn_is_type(&conn, BT_CONN_TYPE_BR));
156
157 conn.type = BT_CONN_TYPE_SCO;
158 zassert_true(bt_conn_is_type(&conn, BT_CONN_TYPE_SCO));
159
160 conn.type = BT_CONN_TYPE_ISO;
161 zassert_true(bt_conn_is_type(&conn, BT_CONN_TYPE_ISO));
162 }
163