1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include <stddef.h>
21 #include <errno.h>
22 #include <string.h>
23 #include "nimble/hci_common.h"
24 #include "nimble/ble_hci_trans.h"
25 #include "host/ble_hs_test.h"
26 #include "testutil/testutil.h"
27 #include "ble_hs_test_util.h"
28
TEST_CASE(ble_hs_hci_test_event_bad)29 TEST_CASE(ble_hs_hci_test_event_bad)
30 {
31 uint8_t *buf;
32 int rc;
33
34 /*** Invalid event code. */
35 buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
36 TEST_ASSERT_FATAL(buf != NULL);
37
38 buf[0] = 0xff;
39 buf[1] = 0;
40 rc = ble_hs_hci_evt_process(buf);
41 TEST_ASSERT(rc == BLE_HS_ENOTSUP);
42 }
43
TEST_CASE(ble_hs_hci_test_rssi)44 TEST_CASE(ble_hs_hci_test_rssi)
45 {
46 uint8_t params[BLE_HCI_READ_RSSI_ACK_PARAM_LEN];
47 uint16_t opcode;
48 int8_t rssi;
49 int rc;
50
51 opcode = ble_hs_hci_util_opcode_join(BLE_HCI_OGF_STATUS_PARAMS,
52 BLE_HCI_OCF_RD_RSSI);
53
54 /*** Success. */
55 /* Connection handle. */
56 put_le16(params + 0, 1);
57
58 /* RSSI. */
59 params[2] = -8;
60
61 ble_hs_test_util_hci_ack_set_params(opcode, 0, params, sizeof params);
62
63 rc = ble_hs_hci_util_read_rssi(1, &rssi);
64 TEST_ASSERT_FATAL(rc == 0);
65 TEST_ASSERT(rssi == -8);
66
67 /*** Failure: incorrect connection handle. */
68 put_le16(params + 0, 99);
69
70 ble_hs_test_util_hci_ack_set_params(opcode, 0, params, sizeof params);
71
72 rc = ble_hs_hci_util_read_rssi(1, &rssi);
73 TEST_ASSERT(rc == BLE_HS_ECONTROLLER);
74
75 /*** Failure: params too short. */
76 ble_hs_test_util_hci_ack_set_params(opcode, 0, params, sizeof params - 1);
77 rc = ble_hs_hci_util_read_rssi(1, &rssi);
78 TEST_ASSERT(rc == BLE_HS_ECONTROLLER);
79
80 /*** Failure: params too long. */
81 ble_hs_test_util_hci_ack_set_params(opcode, 0, params, sizeof params + 1);
82 rc = ble_hs_hci_util_read_rssi(1, &rssi);
83 TEST_ASSERT(rc == BLE_HS_ECONTROLLER);
84 }
85
TEST_CASE(ble_hs_hci_acl_one_conn)86 TEST_CASE(ble_hs_hci_acl_one_conn)
87 {
88 struct ble_hs_test_util_hci_num_completed_pkts_entry ncpe[2];
89 struct hci_disconn_complete evt;
90 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
91 uint8_t data[256];
92 int rc;
93 int i;
94
95 memset(ncpe, 0, sizeof(ncpe));
96 for (i = 0; i < sizeof data; i++) {
97 data[i] = i;
98 }
99
100 ble_hs_test_util_init();
101
102 /* The controller has room for five 20-byte payloads (+ 4-byte header). */
103 rc = ble_hs_hci_set_buf_sz(24, 5);
104 TEST_ASSERT_FATAL(rc == 0);
105 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 5);
106
107 ble_hs_test_util_create_conn(1, peer_addr, NULL, NULL);
108
109 /* Ensure the ATT doesn't truncate our data packets. */
110 ble_hs_test_util_set_att_mtu(1, 256);
111
112 /* Send two 3-byte data packets. */
113 rc = ble_hs_test_util_gatt_write_no_rsp_flat(1, 100, data, 3);
114 TEST_ASSERT_FATAL(rc == 0);
115 rc = ble_hs_test_util_gatt_write_no_rsp_flat(1, 100, data, 3);
116 TEST_ASSERT_FATAL(rc == 0);
117 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 3);
118
119 /* Send fragmented packet (two fragments). */
120 rc = ble_hs_test_util_gatt_write_no_rsp_flat(1, 100, data, 25);
121 TEST_ASSERT_FATAL(rc == 0);
122 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 1);
123
124 ble_hs_test_util_prev_tx_queue_clear();
125
126 /* Receive a number-of-completed-packets event. Ensure available buffer
127 * count increases.
128 */
129 ncpe[0].handle_id = 1;
130 ncpe[0].num_pkts = 3;
131 ble_hs_test_util_hci_rx_num_completed_pkts_event(ncpe);
132 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 4);
133
134 /* Use all remaining buffers (four fragments). */
135 rc = ble_hs_test_util_gatt_write_no_rsp_flat(1, 100, data, 70);
136 TEST_ASSERT_FATAL(rc == 0);
137 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 0);
138
139 /* Attempt to transmit eight more fragments. */
140 rc = ble_hs_test_util_gatt_write_no_rsp_flat(1, 100, data, 160);
141 TEST_ASSERT_FATAL(rc == 0);
142 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 0);
143
144 /* Receive number-of-completed-packets: 5. */
145 ncpe[0].handle_id = 1;
146 ncpe[0].num_pkts = 5;
147 ble_hs_test_util_hci_rx_num_completed_pkts_event(ncpe);
148 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 0);
149
150 /* Receive number-of-completed-packets: 4. */
151 ncpe[0].handle_id = 1;
152 ncpe[0].num_pkts = 5;
153 ble_hs_test_util_hci_rx_num_completed_pkts_event(ncpe);
154 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 1);
155
156 /* Ensure the stalled fragments were sent in the expected order. */
157 ble_hs_test_util_verify_tx_write_cmd(100, data, 70);
158 ble_hs_test_util_verify_tx_write_cmd(100, data, 160);
159
160 /* Receive a disconnection-complete event. Ensure available buffer count
161 * increases.
162 */
163 evt.connection_handle = 1;
164 evt.status = 0;
165 evt.reason = BLE_ERR_CONN_TERM_LOCAL;
166 ble_hs_test_util_hci_rx_disconn_complete_event(&evt);
167 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 5);
168 }
169
TEST_CASE(ble_hs_hci_acl_two_conn)170 TEST_CASE(ble_hs_hci_acl_two_conn)
171 {
172 struct ble_hs_test_util_hci_num_completed_pkts_entry ncpe[2];
173 const struct ble_hs_conn *conn1;
174 const struct ble_hs_conn *conn2;
175 uint8_t peer_addr1[6] = { 1, 2, 3, 4, 5, 6 };
176 uint8_t peer_addr2[6] = { 2, 3, 4, 5, 6, 7 };
177 uint8_t data[256];
178 int rc;
179 int i;
180
181 memset(ncpe, 0, sizeof(ncpe));
182 for (i = 0; i < sizeof data; i++) {
183 data[i] = i;
184 }
185
186 ble_hs_test_util_init();
187
188 /* The controller has room for five 20-byte payloads (+ 4-byte header). */
189 rc = ble_hs_hci_set_buf_sz(24, 5);
190 TEST_ASSERT_FATAL(rc == 0);
191 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 5);
192
193 ble_hs_test_util_create_conn(1, peer_addr1, NULL, NULL);
194 ble_hs_test_util_create_conn(2, peer_addr2, NULL, NULL);
195
196 /* This test inspects the connection objects after unlocking the host
197 * mutex. It is not OK for real code to do this, but this test can assume
198 * the connection list is unchanging.
199 */
200 ble_hs_lock();
201 conn1 = ble_hs_conn_find_assert(1);
202 conn2 = ble_hs_conn_find_assert(2);
203 ble_hs_unlock();
204
205 /* Ensure the ATT doesn't truncate our data packets. */
206 ble_hs_test_util_set_att_mtu(1, 256);
207 ble_hs_test_util_set_att_mtu(2, 256);
208
209 /* Tx two fragments over connection 1. */
210 rc = ble_hs_test_util_gatt_write_no_rsp_flat(1, 100, data, 25);
211 TEST_ASSERT_FATAL(rc == 0);
212 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 3);
213 TEST_ASSERT_FATAL(!(conn1->bhc_flags & BLE_HS_CONN_F_TX_FRAG));
214
215 /* Tx two fragments over connection 2. */
216 rc = ble_hs_test_util_gatt_write_no_rsp_flat(2, 100, data + 10, 25);
217 TEST_ASSERT_FATAL(rc == 0);
218 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 1);
219 TEST_ASSERT_FATAL(!(conn1->bhc_flags & BLE_HS_CONN_F_TX_FRAG));
220
221 /* Tx four fragments over connection 2. */
222 rc = ble_hs_test_util_gatt_write_no_rsp_flat(2, 100, data + 20, 70);
223 TEST_ASSERT_FATAL(rc == 0);
224 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 0);
225 TEST_ASSERT_FATAL(conn2->bhc_flags & BLE_HS_CONN_F_TX_FRAG);
226
227 /* Tx four fragments over connection 1. */
228 rc = ble_hs_test_util_gatt_write_no_rsp_flat(1, 100, data + 30, 70);
229 TEST_ASSERT_FATAL(rc == 0);
230 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 0);
231 TEST_ASSERT_FATAL(!(conn1->bhc_flags & BLE_HS_CONN_F_TX_FRAG));
232
233 /**
234 * controller: (11 222)
235 * conn 1: 1111
236 * conn 2: 222
237 */
238
239 /* Receive number-of-completed-packets: conn=2, num-pkts=1. */
240 ncpe[0].handle_id = 2;
241 ncpe[0].num_pkts = 1;
242 ble_hs_test_util_hci_rx_num_completed_pkts_event(ncpe);
243
244 /**
245 * controller: (11 222)
246 * conn 1: 1111
247 * conn 2: 22
248 */
249 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 0);
250 TEST_ASSERT_FATAL(!(conn1->bhc_flags & BLE_HS_CONN_F_TX_FRAG));
251 TEST_ASSERT_FATAL(conn2->bhc_flags & BLE_HS_CONN_F_TX_FRAG);
252
253 /* Receive number-of-completed-packets: conn=1, num-pkts=1. */
254 ncpe[0].handle_id = 1;
255 ncpe[0].num_pkts = 1;
256 ble_hs_test_util_hci_rx_num_completed_pkts_event(ncpe);
257
258 /**
259 * controller: (1 2222)
260 * conn 1: 1111
261 * conn 2: 2
262 */
263 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 0);
264 TEST_ASSERT_FATAL(!(conn1->bhc_flags & BLE_HS_CONN_F_TX_FRAG));
265 TEST_ASSERT_FATAL(conn2->bhc_flags & BLE_HS_CONN_F_TX_FRAG);
266
267 /* Receive number-of-completed-packets: conn=1, num-pkts=1. */
268 ncpe[0].handle_id = 1;
269 ncpe[0].num_pkts = 1;
270 ble_hs_test_util_hci_rx_num_completed_pkts_event(ncpe);
271
272 /**
273 * controller: (22222)
274 * conn 1: 1111
275 * conn 2: -
276 */
277 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 0);
278 TEST_ASSERT_FATAL(!(conn1->bhc_flags & BLE_HS_CONN_F_TX_FRAG));
279 TEST_ASSERT_FATAL(!(conn2->bhc_flags & BLE_HS_CONN_F_TX_FRAG));
280
281 /* Receive number-of-completed-packets: conn=2, num-pkts=3. */
282 ncpe[0].handle_id = 2;
283 ncpe[0].num_pkts = 3;
284 ble_hs_test_util_hci_rx_num_completed_pkts_event(ncpe);
285
286 /**
287 * controller: (11122)
288 * conn 1: 1
289 * conn 2: -
290 */
291 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 0);
292 TEST_ASSERT_FATAL(conn1->bhc_flags & BLE_HS_CONN_F_TX_FRAG);
293 TEST_ASSERT_FATAL(!(conn2->bhc_flags & BLE_HS_CONN_F_TX_FRAG));
294
295 /* Receive number-of-completed-packets: conn=2, num-pkts=2. */
296 ncpe[0].handle_id = 2;
297 ncpe[0].num_pkts = 2;
298 ble_hs_test_util_hci_rx_num_completed_pkts_event(ncpe);
299
300 /**
301 * controller: (1111)
302 * conn 1: -
303 * conn 2: -
304 */
305 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 1);
306 TEST_ASSERT_FATAL(!(conn1->bhc_flags & BLE_HS_CONN_F_TX_FRAG));
307 TEST_ASSERT_FATAL(!(conn2->bhc_flags & BLE_HS_CONN_F_TX_FRAG));
308
309 /* Receive number-of-completed-packets: conn=1, num-pkts=4. */
310 ncpe[0].handle_id = 1;
311 ncpe[0].num_pkts = 4;
312 ble_hs_test_util_hci_rx_num_completed_pkts_event(ncpe);
313
314 /**
315 * controller: ()
316 * conn 1: -
317 * conn 2: -
318 */
319 TEST_ASSERT_FATAL(ble_hs_hci_avail_pkts == 5);
320 TEST_ASSERT_FATAL(!(conn1->bhc_flags & BLE_HS_CONN_F_TX_FRAG));
321 TEST_ASSERT_FATAL(!(conn2->bhc_flags & BLE_HS_CONN_F_TX_FRAG));
322
323 /*** Verify payloads. */
324 ble_hs_test_util_verify_tx_write_cmd(100, data, 25);
325 ble_hs_test_util_verify_tx_write_cmd(100, data + 10, 25);
326 ble_hs_test_util_verify_tx_write_cmd(100, data + 20, 70);
327 ble_hs_test_util_verify_tx_write_cmd(100, data + 30, 70);
328 }
329
TEST_SUITE(ble_hs_hci_suite)330 TEST_SUITE(ble_hs_hci_suite)
331 {
332 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
333
334 ble_hs_hci_test_event_bad();
335 ble_hs_hci_test_rssi();
336 ble_hs_hci_acl_one_conn();
337 ble_hs_hci_acl_two_conn();
338 }
339
340 int
ble_hs_hci_test_all(void)341 ble_hs_hci_test_all(void)
342 {
343 ble_hs_hci_suite();
344 return tu_any_failed;
345 }
346