1 /*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <stddef.h>
9 #include <zephyr/ztest.h>
10
11 #include <zephyr/bluetooth/bluetooth.h>
12 #include <zephyr/bluetooth/hci.h>
13 #include <zephyr/sys/byteorder.h>
14 #include <host/hci_core.h>
15
16 #include <bt_common.h>
17 #include <bt_conn_common.h>
18 #include "test_cte_set_rx_params.h"
19
20 struct ut_bt_df_conn_cte_request_data {
21 uint8_t cte_request_interval;
22 uint8_t requested_cte_length;
23 uint8_t requested_cte_type;
24 };
25
26 static uint16_t g_conn_handle;
27
28 static struct ut_bt_df_conn_cte_request_data g_data;
29
30 /* Macros delivering common values for unit tests */
31 #define CONN_HANDLE_INVALID (CONFIG_BT_MAX_CONN + 1)
32 #define CONN_PERIPH_LATENCY 7 /* arbitrary latency value */
33 #define REQUEST_INTERVAL_OK (CONN_PERIPH_LATENCY)
34 #define REQUEST_INTERVAL_TOO_LOW (CONN_PERIPH_LATENCY - 1)
35
36 /* CTE length is stored in 1 octet. If BT Core spec. extends the max value to UINT8_MAX
37 * expected failures may not be checked. If storage size is increased, tests shall be updated.
38 */
39 BUILD_ASSERT(BT_HCI_LE_CTE_LEN_MAX < UINT8_MAX,
40 "Can't test expected failures for CTE length value longer than or "
41 "equal to UINT8_MAX.");
42 #define REQUEST_CTE_LEN_TOO_LONG (BT_HCI_LE_CTE_LEN_MAX + 1)
43
44 BUILD_ASSERT(BT_HCI_LE_CTE_LEN_MIN > 0x0,
45 "Can't test expected failures for CTE length value smaller or equal to zero");
46 #define REQUEST_CTE_LEN_TOO_SHORT (BT_HCI_LE_CTE_LEN_MIN - 1)
47
48 /* Arbitrary value different than values allowed BT Core spec. */
49 #define REQUEST_CTE_TYPE_INVALID 0xFF
50
51 /* @brief Function sends HCI_LE_Set_Connectionless_CTE_Sampling_Enable
52 * to controller.
53 *
54 * @param conn_handle Connection instance handle.
55 * @param data CTE request data.
56 * @param enable Enable or disable CTE request.
57 *
58 * @return Zero if success, non-zero value in case of failure.
59 */
send_conn_cte_req_enable(uint16_t conn_handle,const struct ut_bt_df_conn_cte_request_data * data,bool enable)60 int send_conn_cte_req_enable(uint16_t conn_handle,
61 const struct ut_bt_df_conn_cte_request_data *data, bool enable)
62 {
63 struct bt_hci_cp_le_conn_cte_req_enable *cp;
64 struct net_buf *buf;
65
66 buf = bt_hci_cmd_create(BT_HCI_OP_LE_CONN_CTE_REQ_ENABLE, sizeof(*cp));
67 if (!buf) {
68 return -ENOBUFS;
69 }
70
71 cp = net_buf_add(buf, sizeof(*cp));
72 (void)memset(cp, 0, sizeof(*cp));
73 cp->handle = sys_cpu_to_le16(conn_handle);
74 cp->enable = enable ? 1 : 0;
75 if (data != NULL) {
76 cp->cte_request_interval = data->cte_request_interval;
77 cp->requested_cte_length = data->requested_cte_length;
78 cp->requested_cte_type = data->requested_cte_type;
79 }
80
81 return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CONN_CTE_REQ_ENABLE, buf, NULL);
82 }
83
ZTEST(test_hci_set_conn_cte_rx_params_with_conn_set,test_set_conn_cte_req_enable_invalid_conn_handle)84 ZTEST(test_hci_set_conn_cte_rx_params_with_conn_set,
85 test_set_conn_cte_req_enable_invalid_conn_handle)
86 {
87 int err;
88
89 err = send_conn_cte_req_enable(CONN_HANDLE_INVALID, &g_data, true);
90 zassert_equal(err, -EIO,
91 "Unexpected error value for CTE request enable with wrong conn handle");
92 }
93
ZTEST(test_hci_set_conn_cte_rx_params_with_conn_set,test_set_conn_cte_req_enable_before_set_rx_params)94 ZTEST(test_hci_set_conn_cte_rx_params_with_conn_set,
95 test_set_conn_cte_req_enable_before_set_rx_params)
96 {
97 int err;
98
99 err = send_conn_cte_req_enable(g_conn_handle, &g_data, true);
100 zassert_equal(err, -EACCES,
101 "Unexpected error value for CTE request enable before set rx params");
102 }
103
ZTEST(test_hci_set_conn_cte_rx_params_with_rx_param_set,test_set_conn_cte_req_enable_with_too_short_interval)104 ZTEST(test_hci_set_conn_cte_rx_params_with_rx_param_set,
105 test_set_conn_cte_req_enable_with_too_short_interval)
106 {
107 int err;
108
109 g_data.cte_request_interval = REQUEST_INTERVAL_TOO_LOW;
110
111 err = send_conn_cte_req_enable(g_conn_handle, &g_data, true);
112 zassert_equal(err, -EACCES,
113 "Unexpected error value for CTE request enable with too short request"
114 " interval");
115 }
116
ZTEST(test_hci_set_conn_cte_rx_params_with_rx_param_set,test_set_conn_cte_req_enable_with_too_long_requested_length)117 ZTEST(test_hci_set_conn_cte_rx_params_with_rx_param_set,
118 test_set_conn_cte_req_enable_with_too_long_requested_length)
119 {
120 int err;
121
122 g_data.requested_cte_length = REQUEST_CTE_LEN_TOO_LONG;
123
124 err = send_conn_cte_req_enable(g_conn_handle, &g_data, true);
125 zassert_equal(err, -EIO,
126 "Unexpected error value for CTE request enable with too long requested CTE"
127 " length");
128 }
129
ZTEST(test_hci_set_conn_cte_rx_params_with_rx_param_set,test_set_conn_cte_req_enable_with_too_short_requested_length)130 ZTEST(test_hci_set_conn_cte_rx_params_with_rx_param_set,
131 test_set_conn_cte_req_enable_with_too_short_requested_length)
132 {
133 int err;
134
135 g_data.requested_cte_length = REQUEST_CTE_LEN_TOO_SHORT;
136
137 err = send_conn_cte_req_enable(g_conn_handle, &g_data, true);
138 zassert_equal(err, -EIO,
139 "Unexpected error value for CTE request enable with too short requested CTE"
140 " length");
141 }
142
ZTEST(test_hci_set_conn_cte_rx_params_with_rx_param_set,test_set_conn_cte_req_enable_with_invalid_cte_type)143 ZTEST(test_hci_set_conn_cte_rx_params_with_rx_param_set,
144 test_set_conn_cte_req_enable_with_invalid_cte_type)
145 {
146 int err;
147
148 g_data.requested_cte_type = REQUEST_CTE_LEN_TOO_LONG;
149
150 err = send_conn_cte_req_enable(g_conn_handle, &g_data, true);
151 zassert_equal(err, -EIO,
152 "Unexpected error value for CTE request enable with invalid CTE type");
153 }
154
ZTEST(test_hci_set_conn_cte_rx_params_with_rx_param_set,test_set_conn_cte_req_enable)155 ZTEST(test_hci_set_conn_cte_rx_params_with_rx_param_set, test_set_conn_cte_req_enable)
156 {
157 int err;
158
159 err = send_conn_cte_req_enable(g_conn_handle, &g_data, true);
160 zassert_equal(err, 0, "Unexpected error value for CTE request enable");
161 }
162
ZTEST(test_hci_set_conn_cte_rx_params_with_cte_req_set,test_set_conn_cte_req_disable)163 ZTEST(test_hci_set_conn_cte_rx_params_with_cte_req_set, test_set_conn_cte_req_disable)
164 {
165 int err;
166
167 err = send_conn_cte_req_enable(g_conn_handle, NULL, false);
168 zassert_equal(err, 0, "Unexpected error value for CTE request disable");
169 }
cte_req_params_set(void)170 static void cte_req_params_set(void)
171 {
172 g_data.cte_request_interval = REQUEST_INTERVAL_OK;
173 g_data.requested_cte_length = BT_HCI_LE_CTE_LEN_MAX;
174 g_data.requested_cte_type = BT_HCI_LE_AOD_CTE_2US;
175 }
176
connection_setup(void * data)177 static void connection_setup(void *data)
178 {
179 cte_req_params_set();
180
181 g_conn_handle = ut_bt_create_connection();
182 }
183
connection_teardown(void * data)184 static void connection_teardown(void *data) { ut_bt_destroy_connection(g_conn_handle); }
185
cte_rx_param_setup(void * data)186 static void cte_rx_param_setup(void *data)
187 {
188 /* Arbitrary antenna IDs. May be random for test purposes. */
189 static uint8_t ant_ids[] = { 0x1, 0x2, 0x3, 0x4, 0x5 };
190
191 /* Use arbitrary values that allow enable CTE receive and sampling. */
192 struct ut_bt_df_conn_cte_rx_params cte_rx_params = {
193 .slot_durations = BT_HCI_LE_ANTENNA_SWITCHING_SLOT_1US,
194 .switch_pattern_len = ARRAY_SIZE(ant_ids),
195 .ant_ids = ant_ids
196 };
197
198 cte_req_params_set();
199
200 g_conn_handle = ut_bt_create_connection();
201 ut_bt_set_periph_latency(g_conn_handle, CONN_PERIPH_LATENCY);
202
203 send_set_conn_cte_rx_params(g_conn_handle, &cte_rx_params, true);
204 }
205
cte_req_setup(void * data)206 static void cte_req_setup(void *data)
207 {
208 cte_rx_param_setup(data);
209
210 send_conn_cte_req_enable(g_conn_handle, &g_data, true);
211 }
212
cte_rx_param_teardown(void * data)213 static void cte_rx_param_teardown(void *data)
214 {
215 connection_teardown(data);
216
217 send_set_conn_cte_rx_params(g_conn_handle, NULL, false);
218 }
219
cte_req_teardown(void * data)220 static void cte_req_teardown(void *data)
221 {
222 send_conn_cte_req_enable(g_conn_handle, NULL, false);
223
224 cte_rx_param_teardown(data);
225 }
226
227 ZTEST_SUITE(test_hci_set_conn_cte_rx_params_with_conn_set, NULL, ut_bt_setup, connection_setup,
228 connection_teardown, ut_bt_teardown);
229 ZTEST_SUITE(test_hci_set_conn_cte_rx_params_with_rx_param_set, NULL, ut_bt_setup,
230 cte_rx_param_setup, cte_rx_param_teardown, ut_bt_teardown);
231 ZTEST_SUITE(test_hci_set_conn_cte_rx_params_with_cte_req_set, NULL, ut_bt_setup, cte_req_setup,
232 cte_req_teardown, ut_bt_teardown);
233