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 <string.h>
21 #include <errno.h>
22 #include "testutil/testutil.h"
23 #include "nimble/ble.h"
24 #include "nimble/hci_common.h"
25 #include "host/ble_hs_adv.h"
26 #include "host/ble_hs_test.h"
27 #include "ble_hs_test_util.h"
28
29 static struct ble_gap_event ble_gap_test_event;
30 static int ble_gap_test_conn_status;
31 static struct ble_gap_conn_desc ble_gap_test_conn_desc;
32 static void *ble_gap_test_conn_arg;
33 static struct ble_gap_upd_params ble_gap_test_conn_peer_params;
34 static struct ble_gap_upd_params ble_gap_test_conn_self_params;
35
36 static int ble_gap_test_disc_event_type;
37 static struct ble_gap_disc_desc ble_gap_test_disc_desc;
38 static void *ble_gap_test_disc_arg;
39
40 /*****************************************************************************
41 * $misc *
42 *****************************************************************************/
43
44 static void
ble_gap_test_util_reset_cb_info(void)45 ble_gap_test_util_reset_cb_info(void)
46 {
47 memset(&ble_gap_test_event, 0xff, sizeof ble_gap_test_event);
48 ble_gap_test_conn_status = -1;
49 memset(&ble_gap_test_conn_desc, 0xff, sizeof ble_gap_test_conn_desc);
50 ble_gap_test_conn_arg = (void *)-1;
51
52 ble_gap_test_disc_event_type = -1;
53 memset(&ble_gap_test_disc_desc, 0xff, sizeof ble_gap_test_disc_desc);
54 ble_gap_test_disc_arg = (void *)-1;
55 }
56
57 static void
ble_gap_test_util_init(void)58 ble_gap_test_util_init(void)
59 {
60 ble_hs_test_util_init();
61 ble_hs_test_util_set_static_rnd_addr((uint8_t[6]){ 1, 2, 3, 4, 5, 0xc0 });
62 ble_gap_test_util_reset_cb_info();
63 }
64
65 static int
ble_gap_test_util_disc_cb(struct ble_gap_event * event,void * arg)66 ble_gap_test_util_disc_cb(struct ble_gap_event *event, void *arg)
67 {
68 ble_gap_test_disc_event_type = event->type;
69 ble_gap_test_disc_arg = arg;
70
71 if (event->type == BLE_GAP_EVENT_DISC) {
72 ble_gap_test_disc_desc = event->disc;
73 }
74
75 return 0;
76 }
77
78 static int
ble_gap_test_util_connect_cb(struct ble_gap_event * event,void * arg)79 ble_gap_test_util_connect_cb(struct ble_gap_event *event, void *arg)
80 {
81 int *fail_reason;
82 int ret;
83
84 ble_gap_test_event = *event;
85 ble_gap_test_conn_arg = arg;
86
87 switch (event->type) {
88 case BLE_GAP_EVENT_CONNECT:
89 ble_gap_test_conn_status = event->connect.status;
90 ret = ble_gap_conn_find(event->connect.conn_handle,
91 &ble_gap_test_conn_desc);
92 TEST_ASSERT_FATAL(ble_gap_test_conn_status || ret == 0);
93 break;
94
95 case BLE_GAP_EVENT_DISCONNECT:
96 ble_gap_test_conn_status = event->disconnect.reason;
97 ble_gap_test_conn_desc = event->disconnect.conn;
98 break;
99
100 case BLE_GAP_EVENT_CONN_UPDATE:
101 ble_gap_test_conn_status = event->conn_update.status;
102 ret = ble_gap_conn_find(event->conn_update.conn_handle,
103 &ble_gap_test_conn_desc);
104 TEST_ASSERT_FATAL(ret == 0);
105 break;
106
107 case BLE_GAP_EVENT_TERM_FAILURE:
108 ble_gap_test_conn_status = event->term_failure.status;
109 ret = ble_gap_conn_find(event->term_failure.conn_handle,
110 &ble_gap_test_conn_desc);
111 TEST_ASSERT_FATAL(ret == 0);
112 break;
113
114 case BLE_GAP_EVENT_ADV_COMPLETE:
115 ble_gap_test_conn_arg = arg;
116 break;
117
118 case BLE_GAP_EVENT_CONN_UPDATE_REQ:
119 ble_gap_test_conn_peer_params = *event->conn_update_req.peer_params;
120 *event->conn_update_req.self_params = ble_gap_test_conn_self_params;
121 ret = ble_gap_conn_find(event->conn_update_req.conn_handle,
122 &ble_gap_test_conn_desc);
123 TEST_ASSERT_FATAL(ret == 0);
124
125 fail_reason = arg;
126 if (fail_reason == NULL) {
127 return 0;
128 } else {
129 return *fail_reason;
130 }
131 break;
132
133 case BLE_GAP_EVENT_MTU:
134 break;
135
136 default:
137 TEST_ASSERT_FATAL(0);
138 break;
139 }
140
141 return 0;
142 }
143
144 static int
ble_gap_test_util_copy_cb(struct ble_gap_event * event,void * arg)145 ble_gap_test_util_copy_cb(struct ble_gap_event *event, void *arg)
146 {
147 ble_gap_test_event = *event;
148 ble_gap_test_conn_arg = arg;
149
150 return 0;
151 }
152
153 static void
ble_gap_test_util_verify_tx_clear_wl(void)154 ble_gap_test_util_verify_tx_clear_wl(void)
155 {
156 uint8_t param_len;
157
158 ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
159 BLE_HCI_OCF_LE_CLEAR_WHITE_LIST,
160 ¶m_len);
161 TEST_ASSERT(param_len == 0);
162 }
163
164 static void
ble_gap_test_util_verify_tx_add_wl(ble_addr_t * addr)165 ble_gap_test_util_verify_tx_add_wl(ble_addr_t *addr)
166 {
167 uint8_t param_len;
168 uint8_t *param;
169 int i;
170
171 param = ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
172 BLE_HCI_OCF_LE_ADD_WHITE_LIST,
173 ¶m_len);
174 TEST_ASSERT(param_len == 7);
175 TEST_ASSERT(param[0] == addr->type);
176 for (i = 0; i < 6; i++) {
177 TEST_ASSERT(param[1 + i] == addr->val[i]);
178 }
179 }
180
181 static void
ble_gap_test_util_verify_tx_set_scan_params(uint8_t own_addr_type,uint8_t scan_type,uint16_t itvl,uint16_t scan_window,uint8_t filter_policy)182 ble_gap_test_util_verify_tx_set_scan_params(uint8_t own_addr_type,
183 uint8_t scan_type,
184 uint16_t itvl,
185 uint16_t scan_window,
186 uint8_t filter_policy)
187 {
188 uint8_t param_len;
189 uint8_t *param;
190
191 param = ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
192 BLE_HCI_OCF_LE_SET_SCAN_PARAMS,
193 ¶m_len);
194 TEST_ASSERT(param_len == BLE_HCI_SET_SCAN_PARAM_LEN);
195 TEST_ASSERT(param[0] == scan_type);
196 TEST_ASSERT(get_le16(param + 1) == itvl);
197 TEST_ASSERT(get_le16(param + 3) == scan_window);
198 TEST_ASSERT(param[5] == own_addr_type);
199 TEST_ASSERT(param[6] == filter_policy);
200 }
201
202 static void
ble_gap_test_util_verify_tx_scan_enable(uint8_t enable,uint8_t filter_duplicates)203 ble_gap_test_util_verify_tx_scan_enable(uint8_t enable,
204 uint8_t filter_duplicates)
205 {
206 uint8_t param_len;
207 uint8_t *param;
208
209 param = ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
210 BLE_HCI_OCF_LE_SET_SCAN_ENABLE,
211 ¶m_len);
212 TEST_ASSERT(param_len == BLE_HCI_SET_SCAN_ENABLE_LEN);
213 TEST_ASSERT(param[0] == enable);
214 TEST_ASSERT(param[1] == filter_duplicates);
215 }
216
217 static void
ble_hs_test_util_hci_verify_tx_create_conn_cancel(void)218 ble_hs_test_util_hci_verify_tx_create_conn_cancel(void)
219 {
220 uint8_t param_len;
221
222 ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
223 BLE_HCI_OCF_LE_CREATE_CONN_CANCEL,
224 ¶m_len);
225 TEST_ASSERT(param_len == 0);
226 }
227
228 static void
ble_gap_test_util_verify_tx_disconnect(void)229 ble_gap_test_util_verify_tx_disconnect(void)
230 {
231 uint8_t param_len;
232 uint8_t *param;
233
234 param = ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LINK_CTRL,
235 BLE_HCI_OCF_DISCONNECT_CMD,
236 ¶m_len);
237 TEST_ASSERT(param_len == BLE_HCI_DISCONNECT_CMD_LEN);
238 TEST_ASSERT(get_le16(param + 0) == 2);
239 TEST_ASSERT(param[2] == BLE_ERR_REM_USER_CONN_TERM);
240 }
241
242 static void
ble_gap_test_util_verify_tx_adv_params(void)243 ble_gap_test_util_verify_tx_adv_params(void)
244 {
245 uint8_t param_len;
246
247 ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
248 BLE_HCI_OCF_LE_SET_ADV_PARAMS,
249 ¶m_len);
250 TEST_ASSERT(param_len == BLE_HCI_SET_ADV_PARAM_LEN);
251
252 /* Note: Content of message verified in ble_hs_adv_test.c. */
253 }
254
255 static void
ble_gap_test_util_verify_tx_adv_data(void)256 ble_gap_test_util_verify_tx_adv_data(void)
257 {
258 uint8_t param_len;
259
260 ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
261 BLE_HCI_OCF_LE_SET_ADV_DATA,
262 ¶m_len);
263 /* Note: Content of message verified in ble_hs_adv_test.c. */
264 }
265
266 #if 0
267 static void
268 ble_gap_test_util_verify_tx_rsp_data(void)
269 {
270 uint8_t param_len;
271 uint8_t *param;
272
273 param = ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
274 BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA,
275 ¶m_len);
276 (void)param; /* XXX: Verify other fields. */
277 }
278 #endif
279
280 static void
ble_gap_test_util_verify_tx_adv_enable(int enabled)281 ble_gap_test_util_verify_tx_adv_enable(int enabled)
282 {
283 uint8_t param_len;
284 uint8_t *param;
285
286 param = ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
287 BLE_HCI_OCF_LE_SET_ADV_ENABLE,
288 ¶m_len);
289 TEST_ASSERT(param_len == BLE_HCI_SET_ADV_ENABLE_LEN);
290 TEST_ASSERT(param[0] == !!enabled);
291 }
292
293 static void
ble_gap_test_util_verify_tx_update_conn(struct ble_gap_upd_params * params)294 ble_gap_test_util_verify_tx_update_conn(struct ble_gap_upd_params *params)
295 {
296 uint8_t param_len;
297 uint8_t *param;
298
299 param = ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
300 BLE_HCI_OCF_LE_CONN_UPDATE,
301 ¶m_len);
302 TEST_ASSERT(param_len == BLE_HCI_CONN_UPDATE_LEN);
303 TEST_ASSERT(get_le16(param + 0) == 2);
304 TEST_ASSERT(get_le16(param + 2) == params->itvl_min);
305 TEST_ASSERT(get_le16(param + 4) == params->itvl_max);
306 TEST_ASSERT(get_le16(param + 6) == params->latency);
307 TEST_ASSERT(get_le16(param + 8) == params->supervision_timeout);
308 TEST_ASSERT(get_le16(param + 10) == params->min_ce_len);
309 TEST_ASSERT(get_le16(param + 12) == params->max_ce_len);
310 }
311
312 static void
ble_gap_test_util_verify_tx_params_reply_pos(void)313 ble_gap_test_util_verify_tx_params_reply_pos(void)
314 {
315 uint8_t param_len;
316 uint8_t *param;
317
318 param = ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
319 BLE_HCI_OCF_LE_REM_CONN_PARAM_RR,
320 ¶m_len);
321 TEST_ASSERT(param_len == BLE_HCI_CONN_PARAM_REPLY_LEN);
322 TEST_ASSERT(get_le16(param + 0) == 2);
323 TEST_ASSERT(get_le16(param + 2) == ble_gap_test_conn_self_params.itvl_min);
324 TEST_ASSERT(get_le16(param + 4) == ble_gap_test_conn_self_params.itvl_max);
325 TEST_ASSERT(get_le16(param + 6) == ble_gap_test_conn_self_params.latency);
326 TEST_ASSERT(get_le16(param + 8) ==
327 ble_gap_test_conn_self_params.supervision_timeout);
328 TEST_ASSERT(get_le16(param + 10) ==
329 ble_gap_test_conn_self_params.min_ce_len);
330 TEST_ASSERT(get_le16(param + 12) ==
331 ble_gap_test_conn_self_params.max_ce_len);
332 }
333
334 static void
ble_gap_test_util_verify_tx_params_reply_neg(uint8_t reason)335 ble_gap_test_util_verify_tx_params_reply_neg(uint8_t reason)
336 {
337 uint8_t param_len;
338 uint8_t *param;
339
340 param = ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
341 BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR,
342 ¶m_len);
343 TEST_ASSERT(param_len == BLE_HCI_CONN_PARAM_NEG_REPLY_LEN);
344 TEST_ASSERT(get_le16(param + 0) == 2);
345 TEST_ASSERT(param[2] == reason);
346 }
347
348 static void
ble_gap_test_util_rx_update_complete(uint8_t status,const struct ble_gap_upd_params * params)349 ble_gap_test_util_rx_update_complete(
350 uint8_t status,
351 const struct ble_gap_upd_params *params)
352 {
353 struct hci_le_conn_upd_complete evt;
354
355 evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE;
356 evt.status = status;
357 evt.connection_handle = 2;
358 evt.conn_itvl = params->itvl_max;
359 evt.conn_latency = params->latency;
360 evt.supervision_timeout = params->supervision_timeout;
361
362 ble_gap_rx_update_complete(&evt);
363 }
364
365 static int
ble_gap_test_util_rx_param_req(struct ble_gap_upd_params * params,int pos,int * cmd_idx,int cmd_fail_idx,uint8_t fail_status)366 ble_gap_test_util_rx_param_req(struct ble_gap_upd_params *params, int pos,
367 int *cmd_idx, int cmd_fail_idx,
368 uint8_t fail_status)
369 {
370 struct hci_le_conn_param_req evt;
371 uint16_t opcode;
372 uint8_t hci_status;
373
374 evt.subevent_code = BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ;
375 evt.connection_handle = 2;
376 evt.itvl_min = params->itvl_min;
377 evt.itvl_max = params->itvl_max;
378 evt.latency = params->latency;
379 evt.timeout = params->supervision_timeout;
380
381 if (pos) {
382 opcode = ble_hs_hci_util_opcode_join(
383 BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_REM_CONN_PARAM_RR);
384 } else {
385 opcode = ble_hs_hci_util_opcode_join(
386 BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR);
387 }
388 if (*cmd_idx == cmd_fail_idx) {
389 hci_status = fail_status;
390 } else {
391 hci_status = 0;
392 }
393 (*cmd_idx)++;
394
395 ble_hs_test_util_hci_ack_set(opcode, hci_status);
396 ble_gap_rx_param_req(&evt);
397
398 return hci_status;
399 }
400
401 /*****************************************************************************
402 * $white list *
403 *****************************************************************************/
404
405 static void
ble_gap_test_util_wl_set(ble_addr_t * addrs,int addrs_count,int cmd_fail_idx,uint8_t fail_status)406 ble_gap_test_util_wl_set(ble_addr_t *addrs, int addrs_count, int cmd_fail_idx,
407 uint8_t fail_status)
408 {
409 int cmd_idx;
410 int rc;
411 int i;
412
413 ble_gap_test_util_init();
414 cmd_idx = 0;
415
416 rc = ble_hs_test_util_wl_set(addrs, addrs_count, cmd_fail_idx,
417 fail_status);
418 TEST_ASSERT(rc == BLE_HS_HCI_ERR(fail_status));
419
420 /* Verify tx of clear white list command. */
421 ble_gap_test_util_verify_tx_clear_wl();
422 if (cmd_idx >= cmd_fail_idx) {
423 return;
424 }
425 cmd_idx++;
426
427 /* Verify tx of add white list commands. */
428 for (i = 0; i < addrs_count; i++) {
429 ble_gap_test_util_verify_tx_add_wl(addrs + i);
430 if (cmd_idx >= cmd_fail_idx) {
431 return;
432 }
433 cmd_idx++;
434 }
435 }
436
TEST_CASE(ble_gap_test_case_wl_bad_args)437 TEST_CASE(ble_gap_test_case_wl_bad_args)
438 {
439 int rc;
440
441 ble_gap_test_util_init();
442
443 /*** 0 white list entries. */
444 rc = ble_hs_test_util_wl_set(NULL, 0, 0, 0);
445 TEST_ASSERT(rc == BLE_HS_EINVAL);
446
447 /*** Invalid address type. */
448 rc = ble_hs_test_util_wl_set(
449 ((ble_addr_t[]) { {
450 5, { 1, 2, 3, 4, 5, 6 }
451 }, }),
452 1, 0, 0);
453 TEST_ASSERT(rc == BLE_HS_EINVAL);
454
455 /*** White-list-using connection in progress. */
456 rc = ble_hs_test_util_connect(BLE_OWN_ADDR_PUBLIC, NULL, 0, NULL,
457 ble_gap_test_util_connect_cb, NULL, 0);
458 TEST_ASSERT(rc == 0);
459
460 rc = ble_hs_test_util_wl_set(
461 ((ble_addr_t[]) { {
462 BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }
463 }, }),
464 1, 0, 0);
465 TEST_ASSERT(rc == BLE_HS_EBUSY);
466 }
467
TEST_CASE(ble_gap_test_case_wl_ctlr_fail)468 TEST_CASE(ble_gap_test_case_wl_ctlr_fail)
469 {
470 int i;
471
472 ble_addr_t addrs[] = {
473 { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } },
474 { BLE_ADDR_PUBLIC, { 2, 3, 4, 5, 6, 7 } },
475 { BLE_ADDR_PUBLIC, { 3, 4, 5, 6, 7, 8 } },
476 { BLE_ADDR_PUBLIC, { 4, 5, 6, 7, 8, 9 } },
477 };
478 int addrs_count = sizeof addrs / sizeof addrs[0];
479
480 for (i = 0; i < 5; i++) {
481 ble_gap_test_util_wl_set(addrs, addrs_count, i,
482 BLE_ERR_UNSPECIFIED);
483 }
484 }
485
TEST_CASE(ble_gap_test_case_wl_good)486 TEST_CASE(ble_gap_test_case_wl_good)
487 {
488 ble_addr_t addrs[] = {
489 { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } },
490 { BLE_ADDR_PUBLIC, { 2, 3, 4, 5, 6, 7 } },
491 { BLE_ADDR_PUBLIC, { 3, 4, 5, 6, 7, 8 } },
492 { BLE_ADDR_PUBLIC, { 4, 5, 6, 7, 8, 9 } },
493 };
494 int addrs_count = sizeof addrs / sizeof addrs[0];
495
496 ble_gap_test_util_wl_set(addrs, addrs_count, 0, 0);
497 }
498
TEST_SUITE(ble_gap_test_suite_wl)499 TEST_SUITE(ble_gap_test_suite_wl)
500 {
501 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
502
503 ble_gap_test_case_wl_good();
504 ble_gap_test_case_wl_bad_args();
505 ble_gap_test_case_wl_ctlr_fail();
506 }
507
508 /*****************************************************************************
509 * $discovery *
510 *****************************************************************************/
511
512 static int
ble_gap_test_util_disc(uint8_t own_addr_type,const struct ble_gap_disc_params * disc_params,struct ble_gap_disc_desc * desc,int cmd_fail_idx,uint8_t fail_status)513 ble_gap_test_util_disc(uint8_t own_addr_type,
514 const struct ble_gap_disc_params *disc_params,
515 struct ble_gap_disc_desc *desc, int cmd_fail_idx,
516 uint8_t fail_status)
517 {
518 int rc;
519
520 ble_gap_test_util_init();
521
522 TEST_ASSERT(!ble_gap_disc_active());
523
524 /* Begin the discovery procedure. */
525 rc = ble_hs_test_util_disc(own_addr_type, BLE_HS_FOREVER, disc_params,
526 ble_gap_test_util_disc_cb, NULL, cmd_fail_idx,
527 fail_status);
528 TEST_ASSERT(rc == BLE_HS_HCI_ERR(fail_status));
529 if (rc == 0) {
530 TEST_ASSERT(ble_gap_master_in_progress());
531 ble_gap_rx_adv_report(desc);
532 } else {
533 TEST_ASSERT(ble_gap_test_disc_event_type == -1);
534 }
535
536 if (cmd_fail_idx > 0) {
537 /* Verify tx of set scan parameters command. */
538 ble_gap_test_util_verify_tx_set_scan_params(
539 own_addr_type,
540 disc_params->passive ?
541 BLE_HCI_SCAN_TYPE_PASSIVE :
542 BLE_HCI_SCAN_TYPE_ACTIVE,
543 disc_params->itvl,
544 disc_params->window,
545 disc_params->filter_policy);
546 }
547
548 if (cmd_fail_idx > 1) {
549 /* Verify tx of scan enable command. */
550 ble_gap_test_util_verify_tx_scan_enable(
551 1, disc_params->filter_duplicates);
552 }
553
554 if (rc == 0) {
555 TEST_ASSERT(ble_gap_disc_active());
556 }
557
558 return rc;
559 }
560
TEST_CASE(ble_gap_test_case_disc_bad_args)561 TEST_CASE(ble_gap_test_case_disc_bad_args)
562 {
563 struct ble_gap_disc_params params;
564 int rc;
565
566 params.itvl = 0;
567 params.window = 0;
568 params.filter_policy = BLE_HCI_SCAN_FILT_NO_WL;
569 params.limited = 0;
570 params.passive = 0;
571 params.filter_duplicates = 0;
572
573 ble_gap_test_util_init();
574
575 /*** Invalid filter policy. */
576 params.filter_policy = 6;
577 rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, 0, ¶ms,
578 ble_gap_test_util_disc_cb, NULL);
579 TEST_ASSERT(rc == BLE_HS_EINVAL);
580 }
581
TEST_CASE(ble_gap_test_case_disc_good)582 TEST_CASE(ble_gap_test_case_disc_good)
583 {
584 uint8_t adv_data[32];
585 uint8_t flags;
586 uint8_t own_addr_type;
587 int passive;
588 int limited;
589 int rc;
590
591 struct ble_gap_disc_desc desc = {
592 .event_type = BLE_HCI_ADV_TYPE_ADV_IND,
593 .addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } },
594 .length_data = 0,
595 .rssi = 0,
596 .data = adv_data,
597 };
598 struct ble_gap_disc_params disc_params = {
599 .itvl = BLE_GAP_SCAN_SLOW_INTERVAL1,
600 .window = BLE_GAP_SCAN_SLOW_WINDOW1,
601 .filter_policy = BLE_HCI_CONN_FILT_NO_WL,
602 .limited = 0,
603 .passive = 0,
604 .filter_duplicates = 0,
605 };
606
607 flags = BLE_HS_ADV_F_DISC_LTD;
608 rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_FLAGS, 1, &flags,
609 desc.data, &desc.length_data,
610 sizeof adv_data);
611 TEST_ASSERT_FATAL(rc == 0);
612
613 for (own_addr_type = 0;
614 own_addr_type <= BLE_OWN_ADDR_RPA_RANDOM_DEFAULT;
615 own_addr_type++)
616 for (passive = 0; passive <= 1; passive++)
617 for (limited = 0; limited <= 1; limited++) {
618 disc_params.passive = passive;
619 disc_params.limited = limited;
620 ble_gap_test_util_disc(own_addr_type, &disc_params, &desc, -1, 0);
621
622 TEST_ASSERT(ble_gap_master_in_progress());
623 TEST_ASSERT(ble_gap_test_disc_event_type == BLE_GAP_EVENT_DISC);
624 TEST_ASSERT(ble_gap_test_disc_desc.event_type ==
625 BLE_HCI_ADV_TYPE_ADV_IND);
626 TEST_ASSERT(ble_gap_test_disc_desc.addr.type ==
627 BLE_ADDR_PUBLIC);
628 TEST_ASSERT(ble_gap_test_disc_desc.length_data == 3);
629 TEST_ASSERT(ble_gap_test_disc_desc.rssi == 0);
630 TEST_ASSERT(memcmp(ble_gap_test_disc_desc.addr.val, desc.addr.val,
631 6) == 0);
632 TEST_ASSERT(ble_gap_test_disc_arg == NULL);
633
634 }
635 }
636
TEST_CASE(ble_gap_test_case_disc_ltd_mismatch)637 TEST_CASE(ble_gap_test_case_disc_ltd_mismatch)
638 {
639 int rc;
640 struct ble_gap_disc_desc desc = {
641 .event_type = BLE_HCI_ADV_TYPE_ADV_IND,
642 .length_data = 3,
643 .rssi = 0,
644 .addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } },
645 .data = (uint8_t[BLE_HS_ADV_MAX_SZ]){
646 2,
647 BLE_HS_ADV_TYPE_FLAGS,
648 BLE_HS_ADV_F_DISC_GEN,
649 },
650 };
651 struct ble_gap_disc_params disc_params = {
652 .itvl = BLE_GAP_SCAN_SLOW_INTERVAL1,
653 .window = BLE_GAP_SCAN_SLOW_WINDOW1,
654 .filter_policy = BLE_HCI_CONN_FILT_NO_WL,
655 .limited = 1,
656 .passive = 0,
657 .filter_duplicates = 0,
658 };
659
660 rc = ble_gap_test_util_disc(BLE_OWN_ADDR_PUBLIC, &disc_params, &desc,
661 -1, 0);
662 TEST_ASSERT(rc == 0);
663 TEST_ASSERT(ble_gap_master_in_progress());
664
665 /* Verify that the report was ignored because of a mismatched LTD flag. */
666 TEST_ASSERT(ble_gap_test_disc_event_type == -1);
667
668 /* Stop the scan and swap the flags. */
669 rc = ble_hs_test_util_disc_cancel(0);
670 TEST_ASSERT(rc == 0);
671
672 desc.data[2] = BLE_HS_ADV_F_DISC_LTD;
673 disc_params.limited = 0;
674 rc = ble_gap_test_util_disc(BLE_OWN_ADDR_PUBLIC, &disc_params, &desc,
675 -1, 0);
676 TEST_ASSERT(rc == 0);
677 TEST_ASSERT(ble_gap_master_in_progress());
678
679 /* This time we should have reported the advertisement; general discovery
680 * hears everything.
681 */
682 TEST_ASSERT(ble_gap_test_disc_event_type == BLE_GAP_EVENT_DISC);
683
684 }
685
TEST_CASE(ble_gap_test_case_disc_hci_fail)686 TEST_CASE(ble_gap_test_case_disc_hci_fail)
687 {
688 int fail_idx;
689 int limited;
690 int rc;
691
692 struct ble_gap_disc_desc desc = {
693 .event_type = BLE_HCI_ADV_TYPE_ADV_IND,
694 .length_data = 0,
695 .rssi = 0,
696 .addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } },
697 .data = NULL,
698 };
699 struct ble_gap_disc_params disc_params = {
700 .itvl = BLE_GAP_SCAN_SLOW_INTERVAL1,
701 .window = BLE_GAP_SCAN_SLOW_WINDOW1,
702 .filter_policy = BLE_HCI_CONN_FILT_NO_WL,
703 .limited = 0,
704 .passive = 0,
705 .filter_duplicates = 0,
706 };
707
708 for (limited = 0; limited <= 1; limited++) {
709 disc_params.limited = limited;
710
711 for (fail_idx = 0; fail_idx < 2; fail_idx++) {
712 rc = ble_gap_test_util_disc(BLE_OWN_ADDR_PUBLIC, &disc_params,
713 &desc, fail_idx, BLE_ERR_UNSUPPORTED);
714 TEST_ASSERT(rc == BLE_HS_HCI_ERR(BLE_ERR_UNSUPPORTED));
715 TEST_ASSERT(!ble_gap_master_in_progress());
716 }
717 }
718 }
719
720 static void
ble_gap_test_util_disc_dflts_once(int limited)721 ble_gap_test_util_disc_dflts_once(int limited)
722 {
723 struct ble_gap_disc_params params;
724 uint16_t exp_window;
725 uint16_t exp_itvl;
726 int rc;
727
728 ble_gap_test_util_init();
729
730 memset(¶ms, 0, sizeof params);
731 params.limited = limited;
732
733 rc = ble_hs_test_util_disc(BLE_OWN_ADDR_PUBLIC, 0, ¶ms,
734 ble_gap_test_util_disc_cb, NULL, -1, 0);
735 TEST_ASSERT_FATAL(rc == 0);
736
737 if (limited) {
738 exp_itvl = BLE_GAP_LIM_DISC_SCAN_INT;
739 exp_window = BLE_GAP_LIM_DISC_SCAN_WINDOW;
740 } else {
741 exp_itvl = BLE_GAP_SCAN_FAST_INTERVAL_MIN;
742 exp_window = BLE_GAP_SCAN_FAST_WINDOW;
743 }
744 ble_gap_test_util_verify_tx_set_scan_params(
745 BLE_OWN_ADDR_PUBLIC,
746 BLE_HCI_SCAN_TYPE_ACTIVE,
747 exp_itvl,
748 exp_window,
749 BLE_HCI_SCAN_FILT_NO_WL);
750
751 ble_gap_test_util_verify_tx_scan_enable(1, 0);
752 }
753
TEST_CASE(ble_gap_test_case_disc_dflts)754 TEST_CASE(ble_gap_test_case_disc_dflts)
755 {
756 ble_gap_test_util_disc_dflts_once(0);
757 ble_gap_test_util_disc_dflts_once(1);
758 }
759
TEST_CASE(ble_gap_test_case_disc_already)760 TEST_CASE(ble_gap_test_case_disc_already)
761 {
762 static const struct ble_gap_disc_params disc_params = { 0 };
763 int rc;
764
765 ble_gap_test_util_init();
766
767 /* Start a discovery procedure. */
768 rc = ble_hs_test_util_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER,
769 &disc_params, ble_gap_test_util_disc_cb,
770 NULL, -1, 0);
771 TEST_ASSERT_FATAL(rc == 0);
772
773 /* Ensure host indicates BLE_HS_EALREADY if we try to discover. */
774 rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &disc_params,
775 ble_gap_test_util_disc_cb, NULL);
776 TEST_ASSERT(rc == BLE_HS_EALREADY);
777 }
778
TEST_CASE(ble_gap_test_case_disc_busy)779 TEST_CASE(ble_gap_test_case_disc_busy)
780 {
781 static const struct ble_gap_disc_params disc_params = { 0 };
782 static const ble_addr_t peer_addr = {
783 BLE_ADDR_PUBLIC,
784 { 1, 2, 3, 4, 5, 6 }
785 };
786 int rc;
787
788 ble_gap_test_util_init();
789
790 /* Start a connect procedure. */
791 rc = ble_hs_test_util_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr, 0, NULL,
792 ble_gap_test_util_connect_cb, NULL, 0);
793 TEST_ASSERT_FATAL(rc == 0);
794
795 /* Ensure host indicates BLE_HS_EBUSY if we try to discover. */
796 rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &disc_params,
797 ble_gap_test_util_disc_cb, NULL);
798 TEST_ASSERT(rc == BLE_HS_EBUSY);
799 }
800
TEST_SUITE(ble_gap_test_suite_disc)801 TEST_SUITE(ble_gap_test_suite_disc)
802 {
803 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
804
805 ble_gap_test_case_disc_bad_args();
806 ble_gap_test_case_disc_good();
807 ble_gap_test_case_disc_ltd_mismatch();
808 ble_gap_test_case_disc_hci_fail();
809 ble_gap_test_case_disc_dflts();
810 ble_gap_test_case_disc_already();
811 ble_gap_test_case_disc_busy();
812 }
813
814 /*****************************************************************************
815 * $direct connect *
816 *****************************************************************************/
817
TEST_CASE(ble_gap_test_case_conn_gen_good)818 TEST_CASE(ble_gap_test_case_conn_gen_good)
819 {
820 struct hci_le_conn_complete evt;
821 struct ble_gap_conn_params params;
822 int rc;
823
824 ble_addr_t peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }};
825
826 ble_gap_test_util_init();
827
828 TEST_ASSERT(!ble_gap_master_in_progress());
829 TEST_ASSERT(!ble_gap_conn_active());
830
831 params.scan_itvl = 0x12;
832 params.scan_window = 0x11;
833 params.itvl_min = 25;
834 params.itvl_max = 26;
835 params.latency = 1;
836 params.supervision_timeout = 20;
837 params.min_ce_len = 3;
838 params.max_ce_len = 4;
839
840 rc = ble_hs_test_util_connect(BLE_OWN_ADDR_PUBLIC,
841 &peer_addr, 0, ¶ms,
842 ble_gap_test_util_connect_cb, NULL, 0);
843 TEST_ASSERT(rc == 0);
844
845 TEST_ASSERT(ble_gap_master_in_progress());
846 TEST_ASSERT(ble_gap_conn_active());
847
848 TEST_ASSERT(ble_gap_master_in_progress());
849 TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == BLE_HS_ENOTCONN);
850
851 /* ble_gap_rx_conn_complete() will send extra HCI command, need phony
852 * ack */
853 ble_hs_test_util_hci_ack_set(ble_hs_hci_util_opcode_join(BLE_HCI_OGF_LE,
854 BLE_HCI_OCF_LE_RD_REM_FEAT), 0);
855
856 /* Receive connection complete event. */
857 memset(&evt, 0, sizeof evt);
858 evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
859 evt.status = BLE_ERR_SUCCESS;
860 evt.connection_handle = 2;
861 evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER;
862 memcpy(evt.peer_addr, peer_addr.val, 6);
863 rc = ble_gap_rx_conn_complete(&evt, 0);
864 TEST_ASSERT(rc == 0);
865
866 TEST_ASSERT(!ble_gap_master_in_progress());
867
868 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONNECT);
869 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
870 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
871 peer_addr.val, 6) == 0);
872
873 TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == 0);
874 }
875
TEST_CASE(ble_gap_test_case_conn_gen_bad_args)876 TEST_CASE(ble_gap_test_case_conn_gen_bad_args)
877 {
878 int rc;
879
880 ble_gap_test_util_init();
881
882 TEST_ASSERT(!ble_gap_master_in_progress());
883
884 /*** Invalid address type. */
885 rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC,
886 &((ble_addr_t) { 5, { 1, 2, 3, 4, 5, 6 }}), 0, NULL,
887 ble_gap_test_util_connect_cb, NULL);
888 TEST_ASSERT(rc == BLE_HS_EINVAL);
889 TEST_ASSERT(!ble_gap_master_in_progress());
890
891 /*** Connection already in progress. */
892 rc = ble_hs_test_util_connect(
893 BLE_OWN_ADDR_PUBLIC,
894 &((ble_addr_t) { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }}),
895 0, NULL, ble_gap_test_util_connect_cb,
896 NULL, 0);
897 TEST_ASSERT(rc == 0);
898 TEST_ASSERT(ble_gap_master_in_progress());
899
900 rc = ble_gap_connect(
901 BLE_OWN_ADDR_PUBLIC,
902 &((ble_addr_t) { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }}),
903 0, NULL, ble_gap_test_util_connect_cb, NULL);
904 TEST_ASSERT(rc == BLE_HS_EALREADY);
905 }
906
TEST_CASE(ble_gap_test_case_conn_gen_dflt_params)907 TEST_CASE(ble_gap_test_case_conn_gen_dflt_params)
908 {
909 static const ble_addr_t peer_addr = {
910 BLE_ADDR_PUBLIC,
911 { 2, 3, 8, 6, 6, 1 }
912 };
913 int rc;
914
915 ble_gap_test_util_init();
916
917 rc = ble_hs_test_util_connect(BLE_OWN_ADDR_PUBLIC,
918 &peer_addr, 0, NULL,
919 ble_gap_test_util_connect_cb, NULL, 0);
920 TEST_ASSERT(rc == 0);
921 }
922
TEST_CASE(ble_gap_test_case_conn_gen_already)923 TEST_CASE(ble_gap_test_case_conn_gen_already)
924 {
925 static const struct ble_gap_conn_params conn_params = { 0 };
926 static const ble_addr_t peer_addr = {
927 BLE_ADDR_PUBLIC,
928 { 1, 2, 3, 4, 5, 6 }
929 };
930 int rc;
931
932 ble_gap_test_util_init();
933
934 /* Start a connect procedure. */
935 rc = ble_hs_test_util_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr, 0, NULL,
936 ble_gap_test_util_connect_cb, NULL, 0);
937 TEST_ASSERT_FATAL(rc == 0);
938
939 /* Ensure host indicates BLE_HS_EALREADY if we try to connect. */
940 rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr, BLE_HS_FOREVER,
941 &conn_params, ble_gap_test_util_connect_cb, NULL);
942 TEST_ASSERT(rc == BLE_HS_EALREADY);
943 }
944
TEST_CASE(ble_gap_test_case_conn_gen_done)945 TEST_CASE(ble_gap_test_case_conn_gen_done)
946 {
947 static const struct ble_gap_conn_params conn_params = { 0 };
948 static const ble_addr_t peer_addr = {
949 BLE_ADDR_PUBLIC,
950 { 1, 2, 3, 4, 5, 6 }
951 };
952 int rc;
953
954 ble_gap_test_util_init();
955
956 /* Successfully connect to the peer. */
957 ble_hs_test_util_create_conn(2, peer_addr.val,
958 ble_gap_test_util_connect_cb, NULL);
959
960 /* Ensure host indicates BLE_HS_EDONE if we try to connect to the same
961 * peer.
962 */
963 rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr, BLE_HS_FOREVER,
964 &conn_params, ble_gap_test_util_connect_cb, NULL);
965 TEST_ASSERT(rc == BLE_HS_EDONE);
966 }
967
TEST_CASE(ble_gap_test_case_conn_gen_busy)968 TEST_CASE(ble_gap_test_case_conn_gen_busy)
969 {
970 static const struct ble_gap_disc_params disc_params = { 0 };
971 static const struct ble_gap_conn_params conn_params = { 0 };
972 static const ble_addr_t peer_addr = {
973 BLE_ADDR_PUBLIC,
974 { 1, 2, 3, 4, 5, 6 }
975 };
976 int rc;
977
978 ble_gap_test_util_init();
979
980 /* Start a discovery procedure. */
981 rc = ble_hs_test_util_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER,
982 &disc_params, ble_gap_test_util_disc_cb,
983 NULL, -1, 0);
984 TEST_ASSERT_FATAL(rc == 0);
985
986 /* Ensure host indicates BLE_HS_EBUSY if we try to connect. */
987 rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr, BLE_HS_FOREVER,
988 &conn_params, ble_gap_test_util_connect_cb, NULL);
989 TEST_ASSERT(rc == BLE_HS_EBUSY);
990 }
991
TEST_CASE(ble_gap_test_case_conn_gen_fail_evt)992 TEST_CASE(ble_gap_test_case_conn_gen_fail_evt)
993 {
994 static const ble_addr_t peer_addr = {BLE_ADDR_PUBLIC, {1, 2, 3, 4, 5, 6}};
995 struct hci_le_conn_complete evt;
996 struct hci_disconn_complete disc_evt;
997 int rc;
998
999 ble_gap_test_util_init();
1000
1001 /* Start a connect procedure. */
1002 rc = ble_hs_test_util_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr, 0, NULL,
1003 ble_gap_test_util_copy_cb, NULL, 0);
1004 TEST_ASSERT_FATAL(rc == 0);
1005
1006 /* Controller indicates failure via connect complete event. */
1007 memset(&evt, 0, sizeof evt);
1008 evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
1009 evt.status = BLE_ERR_SUCCESS;
1010 evt.connection_handle = 6;
1011 evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER;
1012 evt.peer_addr_type = BLE_ADDR_PUBLIC;
1013 memcpy(evt.peer_addr, peer_addr.val, 6);
1014
1015 rc = ble_gap_rx_conn_complete(&evt, 0);
1016 TEST_ASSERT_FATAL(rc == 0);
1017
1018 /* Ensure failed connect was reported to application. */
1019 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONNECT);
1020 TEST_ASSERT(ble_gap_test_event.connect.status ==
1021 BLE_HS_HCI_ERR(BLE_ERR_SUCCESS));
1022
1023 memset(&disc_evt, 0, sizeof disc_evt);
1024 disc_evt.connection_handle = 6;
1025 disc_evt.status = BLE_ERR_SUCCESS;
1026 disc_evt.reason = BLE_ERR_CONN_ESTABLISHMENT;
1027
1028 ble_gap_rx_disconn_complete(&disc_evt);
1029
1030 /* Ensure failed connect was reported to application. */
1031 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_DISCONNECT);
1032 TEST_ASSERT(ble_gap_test_event.disconnect.reason ==
1033 BLE_HS_HCI_ERR(BLE_ERR_CONN_ESTABLISHMENT));
1034 }
1035
TEST_SUITE(ble_gap_test_suite_conn_gen)1036 TEST_SUITE(ble_gap_test_suite_conn_gen)
1037 {
1038 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
1039
1040 ble_gap_test_case_conn_gen_good();
1041 ble_gap_test_case_conn_gen_bad_args();
1042 ble_gap_test_case_conn_gen_dflt_params();
1043 ble_gap_test_case_conn_gen_already();
1044 ble_gap_test_case_conn_gen_done();
1045 ble_gap_test_case_conn_gen_busy();
1046 ble_gap_test_case_conn_gen_fail_evt();
1047 }
1048
1049 /*****************************************************************************
1050 * $cancel *
1051 *****************************************************************************/
1052
1053 static void
ble_gap_test_util_conn_cancel(uint8_t hci_status)1054 ble_gap_test_util_conn_cancel(uint8_t hci_status)
1055 {
1056 struct hci_le_conn_complete evt;
1057 int rc;
1058
1059 /* Initiate cancel procedure. */
1060 rc = ble_hs_test_util_conn_cancel(hci_status);
1061 TEST_ASSERT(rc == BLE_HS_HCI_ERR(hci_status));
1062
1063 /* Verify tx of cancel create connection command. */
1064 ble_hs_test_util_hci_verify_tx_create_conn_cancel();
1065 if (rc != 0) {
1066 return;
1067 }
1068 TEST_ASSERT(ble_gap_master_in_progress());
1069
1070 /* Receive connection complete event. */
1071 memset(&evt, 0, sizeof evt);
1072 evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
1073 evt.status = BLE_ERR_UNK_CONN_ID;
1074 /* test if host correctly ignores other fields if status is error */
1075 evt.connection_handle = 0x0fff;
1076
1077 rc = ble_gap_rx_conn_complete(&evt, 0);
1078 TEST_ASSERT(rc == 0);
1079 TEST_ASSERT(!ble_gap_master_in_progress());
1080
1081 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONNECT);
1082 TEST_ASSERT(ble_gap_test_event.connect.status == BLE_HS_EAPP);
1083 }
1084
1085 static void
ble_gap_test_util_conn_and_cancel(uint8_t * peer_addr,uint8_t hci_status)1086 ble_gap_test_util_conn_and_cancel(uint8_t *peer_addr, uint8_t hci_status)
1087 {
1088 ble_addr_t addr = { BLE_ADDR_PUBLIC };
1089 int rc;
1090
1091 ble_gap_test_util_init();
1092
1093 memcpy(addr.val, peer_addr, 6);
1094
1095 /* Begin creating a connection. */
1096 rc = ble_hs_test_util_connect(BLE_OWN_ADDR_PUBLIC, &addr, 0, NULL,
1097 ble_gap_test_util_connect_cb, NULL, 0);
1098 TEST_ASSERT(rc == 0);
1099 TEST_ASSERT(ble_gap_master_in_progress());
1100
1101 /* Initiate cancel procedure. */
1102 ble_gap_test_util_conn_cancel(hci_status);
1103 TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == BLE_HS_ENOTCONN);
1104 }
1105
TEST_CASE(ble_gap_test_case_conn_cancel_bad_args)1106 TEST_CASE(ble_gap_test_case_conn_cancel_bad_args)
1107 {
1108 int rc;
1109
1110 ble_gap_test_util_init();
1111
1112 /* Initiate cancel procedure with no connection in progress. */
1113 TEST_ASSERT(!ble_gap_master_in_progress());
1114 rc = ble_hs_test_util_conn_cancel(0);
1115 TEST_ASSERT(rc == BLE_HS_EALREADY);
1116 }
1117
TEST_CASE(ble_gap_test_case_conn_cancel_good)1118 TEST_CASE(ble_gap_test_case_conn_cancel_good)
1119 {
1120 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
1121
1122 ble_gap_test_util_conn_and_cancel(peer_addr, 0);
1123
1124 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONNECT);
1125 TEST_ASSERT(ble_gap_test_event.connect.status == BLE_HS_EAPP);
1126 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == BLE_HS_CONN_HANDLE_NONE);
1127 }
1128
TEST_CASE(ble_gap_test_case_conn_cancel_ctlr_fail)1129 TEST_CASE(ble_gap_test_case_conn_cancel_ctlr_fail)
1130 {
1131 struct hci_le_conn_complete evt;
1132 int rc;
1133
1134 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
1135
1136 ble_gap_test_util_conn_and_cancel(peer_addr, BLE_ERR_REPEATED_ATTEMPTS);
1137
1138 /* Make sure the host didn't invoke the application callback. The cancel
1139 * failure was indicated via the return code from the gap call.
1140 */
1141 TEST_ASSERT(ble_gap_test_event.type == 0xff);
1142
1143 /* ble_gap_rx_conn_complete() will send extra HCI command, need phony
1144 * ack
1145 */
1146 ble_hs_test_util_hci_ack_set(ble_hs_hci_util_opcode_join(BLE_HCI_OGF_LE,
1147 BLE_HCI_OCF_LE_RD_REM_FEAT), 0);
1148
1149 /* Allow connection complete to succeed. */
1150 memset(&evt, 0, sizeof evt);
1151 evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
1152 evt.status = BLE_ERR_SUCCESS;
1153 evt.connection_handle = 2;
1154 evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER;
1155 memcpy(evt.peer_addr, peer_addr, 6);
1156 rc = ble_gap_rx_conn_complete(&evt, 0);
1157 TEST_ASSERT(rc == 0);
1158
1159 TEST_ASSERT(!ble_gap_master_in_progress());
1160
1161 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONNECT);
1162 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
1163 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
1164 peer_addr, 6) == 0);
1165
1166 TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == 0);
1167 }
1168
TEST_SUITE(ble_gap_test_suite_conn_cancel)1169 TEST_SUITE(ble_gap_test_suite_conn_cancel)
1170 {
1171 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
1172
1173 ble_gap_test_case_conn_cancel_good();
1174 ble_gap_test_case_conn_cancel_bad_args();
1175 ble_gap_test_case_conn_cancel_ctlr_fail();
1176 }
1177
1178 /*****************************************************************************
1179 * $terminate *
1180 *****************************************************************************/
1181
1182 static void
ble_gap_test_util_terminate(uint8_t * peer_addr,uint8_t hci_status)1183 ble_gap_test_util_terminate(uint8_t *peer_addr, uint8_t hci_status)
1184 {
1185 struct hci_disconn_complete evt;
1186 int rc;
1187
1188 ble_gap_test_util_init();
1189
1190 /* Create a connection. */
1191 ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb,
1192 NULL);
1193
1194 /* Reset the callback event code; we don't care about the successful
1195 * connection in this test.
1196 */
1197 ble_gap_test_event.type = -1;
1198
1199 /* Terminate the connection. */
1200 rc = ble_hs_test_util_conn_terminate(2, hci_status);
1201 TEST_ASSERT(rc == BLE_HS_HCI_ERR(hci_status));
1202 TEST_ASSERT(!ble_gap_master_in_progress());
1203
1204 /* Verify tx of disconnect command. */
1205 ble_gap_test_util_verify_tx_disconnect();
1206
1207 if (hci_status == 0) {
1208 /* Receive disconnection complete event. */
1209 evt.connection_handle = 2;
1210 evt.status = 0;
1211 evt.reason = BLE_ERR_CONN_TERM_LOCAL;
1212 ble_gap_rx_disconn_complete(&evt);
1213 }
1214 }
1215
TEST_CASE(ble_gap_test_case_conn_terminate_bad_args)1216 TEST_CASE(ble_gap_test_case_conn_terminate_bad_args)
1217 {
1218 int rc;
1219
1220 ble_gap_test_util_init();
1221
1222 /*** Nonexistent connection. */
1223 rc = ble_hs_test_util_conn_terminate(2, 0);
1224 TEST_ASSERT(rc == BLE_HS_ENOTCONN);
1225 }
1226
TEST_CASE(ble_gap_test_case_conn_terminate_good)1227 TEST_CASE(ble_gap_test_case_conn_terminate_good)
1228 {
1229 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
1230
1231 ble_gap_test_util_terminate(peer_addr, 0);
1232
1233 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_DISCONNECT);
1234 TEST_ASSERT(ble_gap_test_conn_status ==
1235 BLE_HS_HCI_ERR(BLE_ERR_CONN_TERM_LOCAL));
1236 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
1237 TEST_ASSERT(ble_gap_test_conn_desc.peer_id_addr.type ==
1238 BLE_ADDR_PUBLIC);
1239 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
1240 peer_addr, 6) == 0);
1241 TEST_ASSERT(ble_gap_test_conn_arg == NULL);
1242
1243 TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == BLE_HS_ENOTCONN);
1244 TEST_ASSERT(!ble_gap_master_in_progress());
1245 }
1246
TEST_CASE(ble_gap_test_case_conn_terminate_ctlr_fail)1247 TEST_CASE(ble_gap_test_case_conn_terminate_ctlr_fail)
1248 {
1249 struct hci_disconn_complete evt;
1250 int rc;
1251
1252 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
1253
1254 ble_gap_test_util_init();
1255
1256 /* Create a connection. */
1257 ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb,
1258 NULL);
1259
1260 /* Terminate the connection. */
1261 rc = ble_hs_test_util_conn_terminate(2, 0);
1262 TEST_ASSERT(rc == 0);
1263 TEST_ASSERT(!ble_gap_master_in_progress());
1264
1265 /* Verify tx of disconnect command. */
1266 ble_gap_test_util_verify_tx_disconnect();
1267
1268 /* Receive failed disconnection complete event. */
1269 evt.connection_handle = 2;
1270 evt.status = BLE_ERR_UNSUPPORTED;
1271 evt.reason = 0;
1272 ble_gap_rx_disconn_complete(&evt);
1273
1274 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_TERM_FAILURE);
1275 TEST_ASSERT(ble_gap_test_conn_status ==
1276 BLE_HS_HCI_ERR(BLE_ERR_UNSUPPORTED));
1277 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
1278 TEST_ASSERT(ble_gap_test_conn_desc.peer_id_addr.type ==
1279 BLE_ADDR_PUBLIC);
1280 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
1281 peer_addr, 6) == 0);
1282 TEST_ASSERT(ble_gap_test_conn_arg == NULL);
1283
1284 TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == 0);
1285 TEST_ASSERT(!ble_gap_master_in_progress());
1286 }
1287
TEST_CASE(ble_gap_test_case_conn_terminate_hci_fail)1288 TEST_CASE(ble_gap_test_case_conn_terminate_hci_fail)
1289 {
1290 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
1291
1292 ble_gap_test_util_terminate(peer_addr, BLE_ERR_REPEATED_ATTEMPTS);
1293
1294 TEST_ASSERT(ble_gap_test_event.type == 0xff);
1295 TEST_ASSERT(ble_hs_atomic_conn_flags(2, NULL) == 0);
1296 TEST_ASSERT(!ble_gap_master_in_progress());
1297 }
1298
TEST_SUITE(ble_gap_test_suite_conn_terminate)1299 TEST_SUITE(ble_gap_test_suite_conn_terminate)
1300 {
1301 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
1302
1303 ble_gap_test_case_conn_terminate_bad_args();
1304 ble_gap_test_case_conn_terminate_good();
1305 ble_gap_test_case_conn_terminate_ctlr_fail();
1306 ble_gap_test_case_conn_terminate_hci_fail();
1307 }
1308
1309 /*****************************************************************************
1310 * $conn find *
1311 *****************************************************************************/
1312
TEST_CASE(ble_gap_test_case_conn_find)1313 TEST_CASE(ble_gap_test_case_conn_find)
1314 {
1315
1316 struct ble_gap_conn_desc desc;
1317 struct ble_hs_conn *conn;
1318 uint8_t pub_addr[6];
1319 int rc;
1320
1321 /*** We are master; public addresses. */
1322 ble_gap_test_util_init();
1323
1324 ble_hs_test_util_create_rpa_conn(8,
1325 BLE_OWN_ADDR_PUBLIC,
1326 ((uint8_t[6]){0,0,0,0,0,0}),
1327 BLE_ADDR_PUBLIC,
1328 ((uint8_t[6]){2,3,4,5,6,7}),
1329 ((uint8_t[6]){0,0,0,0,0,0}),
1330 BLE_HS_TEST_CONN_FEAT_ALL,
1331 ble_gap_test_util_connect_cb,
1332 NULL);
1333
1334 rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, pub_addr, NULL);
1335 TEST_ASSERT_FATAL(rc == 0);
1336
1337 rc = ble_gap_conn_find(8, &desc);
1338 TEST_ASSERT_FATAL(rc == 0);
1339 TEST_ASSERT(desc.conn_handle == 8);
1340 TEST_ASSERT(desc.our_id_addr.type == BLE_ADDR_PUBLIC);
1341 TEST_ASSERT(desc.our_ota_addr.type == BLE_ADDR_PUBLIC);
1342 TEST_ASSERT(desc.peer_ota_addr.type == BLE_ADDR_PUBLIC);
1343 TEST_ASSERT(desc.role == BLE_GAP_ROLE_MASTER);
1344 TEST_ASSERT(memcmp(desc.our_ota_addr.val, pub_addr, 6) == 0);
1345 TEST_ASSERT(memcmp(desc.our_id_addr.val, pub_addr, 6) == 0);
1346 TEST_ASSERT(memcmp(desc.peer_ota_addr.val,
1347 ((uint8_t[6]){2,3,4,5,6,7}), 6) == 0);
1348 TEST_ASSERT(memcmp(desc.peer_id_addr.val,
1349 ((uint8_t[6]){2,3,4,5,6,7}), 6) == 0);
1350 TEST_ASSERT(desc.conn_itvl == BLE_GAP_INITIAL_CONN_ITVL_MAX);
1351 TEST_ASSERT(desc.conn_latency == BLE_GAP_INITIAL_CONN_LATENCY);
1352 TEST_ASSERT(desc.supervision_timeout ==
1353 BLE_GAP_INITIAL_SUPERVISION_TIMEOUT);
1354 TEST_ASSERT(desc.master_clock_accuracy == 0);
1355 TEST_ASSERT(!desc.sec_state.encrypted);
1356 TEST_ASSERT(!desc.sec_state.authenticated);
1357 TEST_ASSERT(!desc.sec_state.bonded);
1358
1359 /*** Swap roles. */
1360 ble_hs_lock();
1361 conn = ble_hs_conn_find(8);
1362 conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
1363 ble_hs_unlock();
1364
1365 rc = ble_gap_conn_find(8, &desc);
1366 TEST_ASSERT_FATAL(rc == 0);
1367 TEST_ASSERT(desc.role == BLE_GAP_ROLE_SLAVE);
1368
1369 /*** We are master; RPAs. */
1370 ble_gap_test_util_init();
1371
1372 ble_hs_test_util_create_rpa_conn(54,
1373 BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT,
1374 ((uint8_t[6]){0x40,1,2,3,4,5}),
1375 BLE_ADDR_RANDOM_ID,
1376 ((uint8_t[6]){3,4,5,6,7,8}),
1377 ((uint8_t[6]){0x50,1,2,3,4,5}),
1378 BLE_HS_TEST_CONN_FEAT_ALL,
1379 ble_gap_test_util_connect_cb,
1380 NULL);
1381
1382 rc = ble_gap_conn_find(54, &desc);
1383 TEST_ASSERT_FATAL(rc == 0);
1384 TEST_ASSERT(desc.conn_handle == 54);
1385 TEST_ASSERT(desc.our_id_addr.type == BLE_ADDR_PUBLIC);
1386 TEST_ASSERT(desc.our_ota_addr.type == BLE_ADDR_RANDOM);
1387 TEST_ASSERT(desc.peer_ota_addr.type == BLE_ADDR_RANDOM);
1388 TEST_ASSERT(desc.role == BLE_GAP_ROLE_MASTER);
1389 TEST_ASSERT(memcmp(desc.our_ota_addr.val,
1390 ((uint8_t[6]){0x40,1,2,3,4,5}), 6) == 0);
1391 TEST_ASSERT(memcmp(desc.our_id_addr.val, pub_addr, 6) == 0);
1392 TEST_ASSERT(memcmp(desc.peer_ota_addr.val,
1393 ((uint8_t[6]){0x50,1,2,3,4,5}), 6) == 0);
1394 TEST_ASSERT(memcmp(desc.peer_id_addr.val,
1395 ((uint8_t[6]){3,4,5,6,7,8}), 6) == 0);
1396 TEST_ASSERT(desc.conn_itvl == BLE_GAP_INITIAL_CONN_ITVL_MAX);
1397 TEST_ASSERT(desc.conn_latency == BLE_GAP_INITIAL_CONN_LATENCY);
1398 TEST_ASSERT(desc.supervision_timeout ==
1399 BLE_GAP_INITIAL_SUPERVISION_TIMEOUT);
1400 TEST_ASSERT(desc.master_clock_accuracy == 0);
1401 TEST_ASSERT(!desc.sec_state.encrypted);
1402 TEST_ASSERT(!desc.sec_state.authenticated);
1403 TEST_ASSERT(!desc.sec_state.bonded);
1404
1405 /*** Swap roles. */
1406 ble_hs_lock();
1407 conn = ble_hs_conn_find(54);
1408 conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
1409 ble_hs_unlock();
1410
1411 rc = ble_gap_conn_find(54, &desc);
1412 TEST_ASSERT_FATAL(rc == 0);
1413 TEST_ASSERT(desc.role == BLE_GAP_ROLE_SLAVE);
1414 }
1415
TEST_SUITE(ble_gap_test_suite_conn_find)1416 TEST_SUITE(ble_gap_test_suite_conn_find)
1417 {
1418 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
1419
1420 ble_gap_test_case_conn_find();
1421 }
1422
1423 /*****************************************************************************
1424 * $advertise *
1425 *****************************************************************************/
1426
1427 static void
ble_gap_test_util_adv(uint8_t own_addr_type,const ble_addr_t * peer_addr,uint8_t conn_mode,uint8_t disc_mode,int connect_status,int cmd_fail_idx,uint8_t fail_status)1428 ble_gap_test_util_adv(uint8_t own_addr_type,
1429 const ble_addr_t *peer_addr, uint8_t conn_mode,
1430 uint8_t disc_mode, int connect_status,
1431 int cmd_fail_idx, uint8_t fail_status)
1432 {
1433 struct hci_le_conn_complete evt;
1434 struct ble_gap_adv_params adv_params;
1435 struct ble_hs_adv_fields adv_fields;
1436 uint8_t hci_status;
1437 int cmd_idx;
1438 int rc;
1439
1440 ble_gap_test_util_init();
1441
1442 adv_params = ble_hs_test_util_adv_params;
1443 adv_params.conn_mode = conn_mode;
1444 adv_params.disc_mode = disc_mode;
1445
1446 TEST_ASSERT(!ble_gap_adv_active());
1447
1448 cmd_idx = 0;
1449
1450 memset(&adv_fields, 0, sizeof adv_fields);
1451 adv_fields.tx_pwr_lvl_is_present = 1;
1452 adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
1453
1454 rc = ble_hs_test_util_adv_set_fields(&adv_fields, cmd_fail_idx,
1455 fail_status);
1456 if (cmd_fail_idx < 2) {
1457 hci_status = fail_status;
1458 } else {
1459 hci_status = 0;
1460 }
1461 TEST_ASSERT_FATAL(rc == BLE_HS_HCI_ERR(hci_status));
1462 cmd_idx += 2;
1463
1464 if (rc == 0) {
1465 ble_gap_test_util_verify_tx_adv_data();
1466 }
1467
1468 if (fail_status == 0 || cmd_fail_idx >= cmd_idx) {
1469 rc = ble_hs_test_util_adv_start(own_addr_type,
1470 peer_addr, &adv_params, BLE_HS_FOREVER,
1471 ble_gap_test_util_connect_cb, NULL,
1472 cmd_fail_idx - cmd_idx, fail_status);
1473
1474 TEST_ASSERT(rc == BLE_HS_HCI_ERR(fail_status));
1475 cmd_idx++;
1476 }
1477
1478 if (fail_status == 0 || cmd_fail_idx >= cmd_idx) {
1479 /* Verify tx of set advertising params command. */
1480 ble_gap_test_util_verify_tx_adv_params();
1481 }
1482 cmd_idx++;
1483
1484 if (fail_status == 0 || cmd_fail_idx >= cmd_idx) {
1485 /* Verify tx of set advertise enable command. */
1486 ble_gap_test_util_verify_tx_adv_enable(1);
1487 }
1488 cmd_idx++;
1489
1490 if (connect_status != -1 &&
1491 (fail_status == 0 || cmd_fail_idx >= cmd_idx)) {
1492
1493 TEST_ASSERT(ble_gap_adv_active());
1494
1495 /* Receive a connection complete event. */
1496 if (conn_mode != BLE_GAP_CONN_MODE_NON) {
1497 if (connect_status == BLE_ERR_SUCCESS) {
1498 /*
1499 * ble_gap_rx_conn_complete() will send extra HCI command, need
1500 * phony ack
1501 */
1502 ble_hs_test_util_hci_ack_set(
1503 ble_hs_hci_util_opcode_join(BLE_HCI_OGF_LE,
1504 BLE_HCI_OCF_LE_RD_REM_FEAT),
1505 0);
1506 }
1507
1508 memset(&evt, 0, sizeof evt);
1509 evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
1510 evt.status = connect_status;
1511
1512 if (connect_status == BLE_ERR_SUCCESS) {
1513 evt.connection_handle = 2;
1514 evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE;
1515 memcpy(evt.peer_addr, peer_addr->val, 6);
1516 } else {
1517 /* test if host correctly ignores other fields if status is
1518 * error
1519 */
1520 evt.connection_handle = 0x0fff;
1521 }
1522
1523 rc = ble_gap_rx_conn_complete(&evt, 0);
1524 TEST_ASSERT(rc == 0);
1525
1526 if (connect_status == 0 ||
1527 connect_status == BLE_ERR_DIR_ADV_TMO) {
1528
1529 TEST_ASSERT(!ble_gap_adv_active());
1530 } else {
1531 TEST_ASSERT(ble_gap_adv_active());
1532 }
1533 }
1534 }
1535 }
1536
TEST_CASE(ble_gap_test_case_adv_bad_args)1537 TEST_CASE(ble_gap_test_case_adv_bad_args)
1538 {
1539 struct ble_gap_adv_params adv_params;
1540 ble_addr_t peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }};
1541 ble_addr_t peer_addr_inv = { 12, { 1, 2, 3, 4, 5, 6 }};
1542 int rc;
1543
1544 ble_gap_test_util_init();
1545
1546 TEST_ASSERT(!ble_gap_adv_active());
1547
1548 /*** Invalid discoverable mode. */
1549 adv_params = ble_hs_test_util_adv_params;
1550 adv_params.disc_mode = 43;
1551 rc = ble_hs_test_util_adv_start(BLE_OWN_ADDR_PUBLIC,
1552 &peer_addr, &adv_params, BLE_HS_FOREVER,
1553 ble_gap_test_util_connect_cb, NULL, 0, 0);
1554 TEST_ASSERT(rc == BLE_HS_EINVAL);
1555 TEST_ASSERT(!ble_gap_adv_active());
1556
1557 /*** Invalid connectable mode. */
1558 adv_params = ble_hs_test_util_adv_params;
1559 adv_params.conn_mode = 27;
1560 rc = ble_hs_test_util_adv_start(BLE_OWN_ADDR_PUBLIC,
1561 &peer_addr, &adv_params, BLE_HS_FOREVER,
1562 ble_gap_test_util_connect_cb, NULL, 0, 0);
1563 TEST_ASSERT(rc == BLE_HS_EINVAL);
1564 TEST_ASSERT(!ble_gap_adv_active());
1565
1566 /*** Invalid peer address type with directed advertisable mode. */
1567 adv_params = ble_hs_test_util_adv_params;
1568 adv_params.conn_mode = BLE_GAP_CONN_MODE_DIR;
1569 rc = ble_hs_test_util_adv_start(
1570 BLE_OWN_ADDR_PUBLIC,
1571 &peer_addr_inv, &adv_params, BLE_HS_FOREVER,
1572 ble_gap_test_util_connect_cb, NULL, 0, 0);
1573 TEST_ASSERT(rc == BLE_HS_EINVAL);
1574 TEST_ASSERT(!ble_gap_adv_active());
1575
1576 /*** Advertising already in progress. */
1577 adv_params = ble_hs_test_util_adv_params;
1578 rc = ble_hs_test_util_adv_start(BLE_OWN_ADDR_PUBLIC,
1579 &peer_addr, &adv_params, BLE_HS_FOREVER,
1580 ble_gap_test_util_connect_cb, NULL, 0, 0);
1581 TEST_ASSERT(rc == 0);
1582 TEST_ASSERT(ble_gap_adv_active());
1583
1584 rc = ble_hs_test_util_adv_start(BLE_OWN_ADDR_PUBLIC,
1585 &peer_addr, &adv_params, BLE_HS_FOREVER,
1586 ble_gap_test_util_connect_cb, NULL, 0, 0);
1587 TEST_ASSERT(rc == BLE_HS_EALREADY);
1588 TEST_ASSERT(ble_gap_adv_active());
1589 }
1590
1591 static void
ble_gap_test_util_adv_verify_dflt_params(uint8_t own_addr_type,const ble_addr_t * peer_addr,uint8_t conn_mode,uint8_t disc_mode)1592 ble_gap_test_util_adv_verify_dflt_params(uint8_t own_addr_type,
1593 const ble_addr_t *peer_addr,
1594 uint8_t conn_mode,
1595 uint8_t disc_mode)
1596 {
1597 struct ble_gap_adv_params adv_params;
1598 struct hci_adv_params hci_cmd;
1599 uint8_t *hci_buf;
1600 uint8_t hci_param_len;
1601 int rc;
1602
1603 ble_gap_test_util_init();
1604
1605 TEST_ASSERT(!ble_gap_adv_active());
1606
1607 adv_params = ble_hs_test_util_adv_params;
1608 adv_params.conn_mode = conn_mode;
1609 adv_params.disc_mode = disc_mode;
1610
1611 /* Let stack calculate all default parameters. */
1612 adv_params.itvl_min = 0;
1613 adv_params.itvl_max = 0;
1614 adv_params.channel_map = 0;
1615 adv_params.filter_policy = 0;
1616 adv_params.high_duty_cycle = 0;
1617
1618 rc = ble_hs_test_util_adv_start(BLE_OWN_ADDR_PUBLIC, peer_addr,
1619 &adv_params, BLE_HS_FOREVER,
1620 ble_gap_test_util_connect_cb, NULL, 0, 0);
1621 TEST_ASSERT_FATAL(rc == 0);
1622
1623 /* Ensure default parameters properly filled in. */
1624 hci_buf = ble_hs_test_util_hci_verify_tx(BLE_HCI_OGF_LE,
1625 BLE_HCI_OCF_LE_SET_ADV_PARAMS,
1626 &hci_param_len);
1627 TEST_ASSERT_FATAL(hci_buf != NULL);
1628 TEST_ASSERT_FATAL(hci_param_len == BLE_HCI_SET_ADV_PARAM_LEN);
1629
1630 hci_cmd.adv_itvl_min = get_le16(hci_buf + 0);
1631 hci_cmd.adv_itvl_max = get_le16(hci_buf + 2);
1632 hci_cmd.adv_type = hci_buf[4];
1633 hci_cmd.own_addr_type = hci_buf[5];
1634 hci_cmd.peer_addr_type = hci_buf[6];
1635 memcpy(hci_cmd.peer_addr, hci_buf + 7, 6);
1636 hci_cmd.adv_channel_map = hci_buf[13];
1637 hci_cmd.adv_filter_policy = hci_buf[14];
1638
1639 if (conn_mode == BLE_GAP_CONN_MODE_NON) {
1640 TEST_ASSERT(hci_cmd.adv_itvl_min == BLE_GAP_ADV_FAST_INTERVAL2_MIN);
1641 TEST_ASSERT(hci_cmd.adv_itvl_max == BLE_GAP_ADV_FAST_INTERVAL2_MAX);
1642 } else {
1643 TEST_ASSERT(hci_cmd.adv_itvl_min == BLE_GAP_ADV_FAST_INTERVAL1_MIN);
1644 TEST_ASSERT(hci_cmd.adv_itvl_max == BLE_GAP_ADV_FAST_INTERVAL1_MAX);
1645 }
1646
1647 if (conn_mode == BLE_GAP_CONN_MODE_NON) {
1648 if (disc_mode == BLE_GAP_DISC_MODE_NON) {
1649 TEST_ASSERT(hci_cmd.adv_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND);
1650 } else {
1651 TEST_ASSERT(hci_cmd.adv_type == BLE_HCI_ADV_TYPE_ADV_SCAN_IND);
1652 }
1653 } else if (conn_mode == BLE_GAP_CONN_MODE_UND) {
1654 TEST_ASSERT(hci_cmd.adv_type == BLE_HCI_ADV_TYPE_ADV_IND);
1655 } else {
1656 TEST_ASSERT(hci_cmd.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD);
1657 }
1658 }
1659
TEST_CASE(ble_gap_test_case_adv_dflt_params)1660 TEST_CASE(ble_gap_test_case_adv_dflt_params)
1661 {
1662 ble_addr_t peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }};
1663
1664 int d;
1665 int c;
1666
1667 for (c = BLE_GAP_CONN_MODE_NON; c < BLE_GAP_CONN_MODE_MAX; c++) {
1668 for (d = BLE_GAP_DISC_MODE_NON; d < BLE_GAP_DISC_MODE_MAX; d++) {
1669 ble_gap_test_util_adv_verify_dflt_params(
1670 BLE_OWN_ADDR_PUBLIC, &peer_addr, c, d);
1671 }
1672 }
1673 }
1674
TEST_CASE(ble_gap_test_case_adv_good)1675 TEST_CASE(ble_gap_test_case_adv_good)
1676 {
1677 ble_addr_t peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }};
1678 int d;
1679 int c;
1680
1681 for (c = BLE_GAP_CONN_MODE_NON; c < BLE_GAP_CONN_MODE_MAX; c++) {
1682 for (d = BLE_GAP_DISC_MODE_NON; d < BLE_GAP_DISC_MODE_MAX; d++) {
1683 ble_gap_test_util_adv(BLE_OWN_ADDR_PUBLIC,
1684 &peer_addr, c, d, BLE_ERR_SUCCESS, -1, 0);
1685
1686 if (c != BLE_GAP_CONN_MODE_NON) {
1687 TEST_ASSERT(!ble_gap_adv_active());
1688 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONNECT);
1689 TEST_ASSERT(ble_gap_test_conn_status == 0);
1690 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
1691 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
1692 peer_addr.val, 6) == 0);
1693 TEST_ASSERT(ble_gap_test_conn_arg == NULL);
1694 }
1695 }
1696 }
1697 }
1698
TEST_CASE(ble_gap_test_case_adv_ctlr_fail)1699 TEST_CASE(ble_gap_test_case_adv_ctlr_fail)
1700 {
1701 ble_addr_t peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }};
1702 int d;
1703 int c;
1704
1705 for (c = BLE_GAP_CONN_MODE_NON + 1; c < BLE_GAP_CONN_MODE_MAX; c++) {
1706 for (d = BLE_GAP_DISC_MODE_NON; d < BLE_GAP_DISC_MODE_MAX; d++) {
1707 ble_gap_test_util_adv(BLE_OWN_ADDR_PUBLIC,
1708 &peer_addr, c, d, BLE_ERR_DIR_ADV_TMO,
1709 -1, 0);
1710
1711 TEST_ASSERT(!ble_gap_adv_active());
1712 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_ADV_COMPLETE);
1713 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle ==
1714 BLE_HS_CONN_HANDLE_NONE);
1715 TEST_ASSERT(ble_gap_test_conn_arg == NULL);
1716 }
1717 }
1718 }
1719
TEST_CASE(ble_gap_test_case_adv_hci_fail)1720 TEST_CASE(ble_gap_test_case_adv_hci_fail)
1721 {
1722 ble_addr_t peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }};
1723 int fail_idx;
1724 int d;
1725 int c;
1726
1727 for (c = BLE_GAP_CONN_MODE_NON; c < BLE_GAP_CONN_MODE_MAX; c++) {
1728 for (d = BLE_GAP_DISC_MODE_NON; d < BLE_GAP_DISC_MODE_MAX; d++) {
1729 for (fail_idx = 0; fail_idx < 4; fail_idx++) {
1730 ble_gap_test_util_adv(BLE_OWN_ADDR_PUBLIC,
1731 &peer_addr,
1732 c, d, 0, fail_idx, BLE_ERR_UNSUPPORTED);
1733
1734 TEST_ASSERT(!ble_gap_adv_active());
1735 TEST_ASSERT(ble_gap_test_event.type == 0xff);
1736 }
1737 }
1738 }
1739 }
1740
TEST_SUITE(ble_gap_test_suite_adv)1741 TEST_SUITE(ble_gap_test_suite_adv)
1742 {
1743 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
1744
1745 ble_gap_test_case_adv_bad_args();
1746 ble_gap_test_case_adv_dflt_params();
1747 ble_gap_test_case_adv_good();
1748 ble_gap_test_case_adv_ctlr_fail();
1749 ble_gap_test_case_adv_hci_fail();
1750 }
1751
1752 /*****************************************************************************
1753 * $stop advertise *
1754 *****************************************************************************/
1755
1756 static void
ble_gap_test_util_stop_adv(const ble_addr_t * peer_addr,uint8_t conn_mode,uint8_t disc_mode,int cmd_fail_idx,uint8_t fail_status)1757 ble_gap_test_util_stop_adv(const ble_addr_t *peer_addr,
1758 uint8_t conn_mode, uint8_t disc_mode,
1759 int cmd_fail_idx, uint8_t fail_status)
1760 {
1761 uint8_t hci_status;
1762 int rc;
1763
1764 ble_gap_test_util_init();
1765
1766 /* Start advertising; don't rx a successful connection event. */
1767 ble_gap_test_util_adv(BLE_OWN_ADDR_PUBLIC, peer_addr,
1768 conn_mode, disc_mode, -1, -1, 0);
1769
1770 TEST_ASSERT(ble_gap_adv_active());
1771
1772 /* Stop advertising. */
1773 hci_status = cmd_fail_idx == 0 ? fail_status : 0;
1774
1775 rc = ble_hs_test_util_adv_stop(hci_status);
1776 TEST_ASSERT(rc == BLE_HS_HCI_ERR(hci_status));
1777
1778 /* Verify tx of advertising enable command. */
1779 ble_gap_test_util_verify_tx_adv_enable(0);
1780 }
1781
TEST_CASE(ble_gap_test_case_stop_adv_good)1782 TEST_CASE(ble_gap_test_case_stop_adv_good)
1783 {
1784 ble_addr_t peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }};
1785 int d;
1786 int c;
1787
1788 for (c = BLE_GAP_CONN_MODE_NON; c < BLE_GAP_CONN_MODE_MAX; c++) {
1789 for (d = BLE_GAP_DISC_MODE_NON; d < BLE_GAP_DISC_MODE_MAX; d++) {
1790 ble_gap_test_util_stop_adv(&peer_addr, c, d, -1, 0);
1791 TEST_ASSERT(!ble_gap_adv_active());
1792 TEST_ASSERT(ble_gap_test_event.type == 0xff);
1793 TEST_ASSERT(ble_gap_test_conn_status == -1);
1794 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == (uint16_t)-1);
1795 TEST_ASSERT(ble_gap_test_conn_arg == (void *)-1);
1796 }
1797 }
1798 }
1799
TEST_CASE(ble_gap_test_case_stop_adv_hci_fail)1800 TEST_CASE(ble_gap_test_case_stop_adv_hci_fail)
1801 {
1802 ble_addr_t peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }};
1803 int d;
1804 int c;
1805
1806 for (c = BLE_GAP_CONN_MODE_NON; c < BLE_GAP_CONN_MODE_MAX; c++) {
1807 for (d = BLE_GAP_DISC_MODE_NON; d < BLE_GAP_DISC_MODE_MAX; d++) {
1808 ble_gap_test_util_stop_adv(&peer_addr, c, d,
1809 0, BLE_ERR_UNSUPPORTED);
1810 TEST_ASSERT(ble_gap_adv_active());
1811 TEST_ASSERT(ble_gap_test_event.type == 0xff);
1812 TEST_ASSERT(ble_gap_test_conn_status == -1);
1813 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == (uint16_t)-1);
1814 TEST_ASSERT(ble_gap_test_conn_arg == (void *)-1);
1815 }
1816 }
1817 }
1818
TEST_SUITE(ble_gap_test_suite_stop_adv)1819 TEST_SUITE(ble_gap_test_suite_stop_adv)
1820 {
1821 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
1822
1823 ble_gap_test_case_stop_adv_good();
1824 ble_gap_test_case_stop_adv_hci_fail();
1825 }
1826
1827 /*****************************************************************************
1828 * $update connection *
1829 *****************************************************************************/
1830
1831 static void
ble_gap_test_util_update_verify_params(struct ble_gap_upd_params * params,uint8_t ble_hs_err)1832 ble_gap_test_util_update_verify_params(struct ble_gap_upd_params *params,
1833 uint8_t ble_hs_err)
1834 {
1835 int rc;
1836
1837 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
1838
1839 ble_gap_test_util_init();
1840
1841 ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb,
1842 NULL);
1843
1844 rc = ble_hs_test_util_conn_update(2, params, 0);
1845 TEST_ASSERT(rc == ble_hs_err);
1846 }
1847
1848 static void
ble_gap_test_util_update_no_l2cap(struct ble_gap_upd_params * params,int master,uint8_t hci_status,int event_status)1849 ble_gap_test_util_update_no_l2cap(struct ble_gap_upd_params *params,
1850 int master,
1851 uint8_t hci_status, int event_status)
1852 {
1853 struct ble_hs_conn *conn;
1854 int rc;
1855
1856 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
1857
1858 ble_gap_test_util_init();
1859
1860 ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb,
1861 NULL);
1862
1863 if (!master) {
1864 ble_hs_lock();
1865 conn = ble_hs_conn_find(2);
1866 TEST_ASSERT_FATAL(conn != NULL);
1867 conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
1868 ble_hs_unlock();
1869 }
1870
1871 /* Erase callback info reported during connection establishment; we only
1872 * care about updates.
1873 */
1874 ble_gap_test_util_reset_cb_info();
1875
1876 TEST_ASSERT(!ble_gap_master_in_progress());
1877
1878 rc = ble_hs_test_util_conn_update(2, params, hci_status);
1879 TEST_ASSERT(rc == BLE_HS_HCI_ERR(hci_status));
1880 TEST_ASSERT(!ble_gap_master_in_progress());
1881
1882 /* Verify tx of connection update command. */
1883 ble_gap_test_util_verify_tx_update_conn(params);
1884
1885 if (rc == 0) {
1886 TEST_ASSERT(ble_gap_dbg_update_active(2));
1887
1888 /* Attempt two duplicate updates; ensure BLE_HS_EALREADY gets returned
1889 * both times. Make sure initial update still completes successfully
1890 * (MYNEWT-702).
1891 */
1892 rc = ble_hs_test_util_conn_update(2, params, 0);
1893 TEST_ASSERT(rc == BLE_HS_EALREADY);
1894 rc = ble_hs_test_util_conn_update(2, params, 0);
1895 TEST_ASSERT(rc == BLE_HS_EALREADY);
1896
1897 /* Receive connection update complete event. */
1898 ble_gap_test_util_rx_update_complete(event_status, params);
1899
1900 TEST_ASSERT(!ble_gap_master_in_progress());
1901 TEST_ASSERT(!ble_gap_dbg_update_active(2));
1902
1903 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONN_UPDATE);
1904 TEST_ASSERT(ble_gap_test_conn_status == BLE_HS_HCI_ERR(event_status));
1905 if (event_status == 0) {
1906 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
1907 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
1908 peer_addr, 6) == 0);
1909 TEST_ASSERT(ble_gap_test_conn_desc.conn_itvl == params->itvl_max);
1910 TEST_ASSERT(ble_gap_test_conn_desc.conn_latency ==
1911 params->latency);
1912 TEST_ASSERT(ble_gap_test_conn_desc.supervision_timeout ==
1913 params->supervision_timeout);
1914 }
1915 } else {
1916 TEST_ASSERT(!ble_gap_master_in_progress());
1917 TEST_ASSERT(!ble_gap_dbg_update_active(2));
1918
1919 TEST_ASSERT(ble_gap_test_event.type == 0xff);
1920 }
1921 }
1922
1923 static void
ble_gap_test_util_update_l2cap(struct ble_gap_upd_params * params,uint16_t l2cap_result)1924 ble_gap_test_util_update_l2cap(struct ble_gap_upd_params *params,
1925 uint16_t l2cap_result)
1926 {
1927 struct ble_l2cap_sig_update_params l2cap_params;
1928 struct ble_hs_conn *conn;
1929 uint8_t id;
1930 int rc;
1931
1932 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
1933
1934 ble_gap_test_util_init();
1935
1936 ble_hs_test_util_create_conn_feat(2, peer_addr,
1937 BLE_HS_TEST_CONN_FEAT_NO_CONN_PARAM,
1938 ble_gap_test_util_connect_cb, NULL);
1939
1940 ble_hs_lock();
1941 conn = ble_hs_conn_find(2);
1942 TEST_ASSERT_FATAL(conn != NULL);
1943 conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
1944 ble_hs_unlock();
1945
1946 /* Erase callback info reported during connection establishment; we only
1947 * care about updates.
1948 */
1949 ble_gap_test_util_reset_cb_info();
1950
1951 rc = ble_hs_test_util_conn_update(2, params, 0xFF);
1952 TEST_ASSERT(rc == 0);
1953
1954 TEST_ASSERT(ble_gap_dbg_update_active(2));
1955
1956 l2cap_params.itvl_min = params->itvl_min;
1957 l2cap_params.itvl_max = params->itvl_max;
1958 l2cap_params.slave_latency = params->latency;
1959 l2cap_params.timeout_multiplier = params->supervision_timeout;
1960 id = ble_hs_test_util_verify_tx_l2cap_update_req(&l2cap_params);
1961
1962 /* Receive l2cap connection parameter update response. */
1963 ble_hs_test_util_rx_l2cap_update_rsp(2, id, l2cap_result);
1964 if (l2cap_result == BLE_L2CAP_SIG_UPDATE_RSP_RESULT_ACCEPT) {
1965 TEST_ASSERT(ble_gap_dbg_update_active(2));
1966
1967 /* Receive connection update complete event. */
1968 ble_gap_test_util_rx_update_complete(0, params);
1969 }
1970
1971 TEST_ASSERT(!ble_gap_dbg_update_active(2));
1972
1973 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONN_UPDATE);
1974 if (l2cap_result != BLE_L2CAP_SIG_UPDATE_RSP_RESULT_ACCEPT) {
1975 TEST_ASSERT(ble_gap_test_conn_status == BLE_HS_EREJECT);
1976 } else {
1977 TEST_ASSERT(ble_gap_test_conn_status == 0);
1978 TEST_ASSERT(ble_gap_test_conn_desc.conn_itvl == params->itvl_max);
1979 TEST_ASSERT(ble_gap_test_conn_desc.conn_latency == params->latency);
1980 TEST_ASSERT(ble_gap_test_conn_desc.supervision_timeout ==
1981 params->supervision_timeout);
1982 }
1983
1984 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
1985 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
1986 peer_addr, 6) == 0);
1987 }
1988
1989 static void
ble_gap_test_util_update_no_l2cap_tmo(struct ble_gap_upd_params * params,int master)1990 ble_gap_test_util_update_no_l2cap_tmo(struct ble_gap_upd_params *params,
1991 int master)
1992 {
1993 struct ble_hs_conn *conn;
1994 int rc;
1995
1996 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
1997
1998 ble_gap_test_util_init();
1999
2000 ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb,
2001 NULL);
2002
2003 if (!master) {
2004 ble_hs_lock();
2005 conn = ble_hs_conn_find(2);
2006 TEST_ASSERT_FATAL(conn != NULL);
2007 conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
2008 ble_hs_unlock();
2009 }
2010
2011 /* Erase callback info reported during connection establishment; we only
2012 * care about updates.
2013 */
2014 ble_gap_test_util_reset_cb_info();
2015
2016 TEST_ASSERT(!ble_gap_master_in_progress());
2017
2018 rc = ble_hs_test_util_conn_update(2, params, 0);
2019 TEST_ASSERT(rc == 0);
2020 TEST_ASSERT(!ble_gap_master_in_progress());
2021
2022 /* Verify tx of connection update command. */
2023 ble_gap_test_util_verify_tx_update_conn(params);
2024
2025 /* Ensure no update event reported. */
2026 TEST_ASSERT(ble_gap_test_event.type == 0xff);
2027
2028 /* Advance 29 seconds; ensure no timeout reported. */
2029 os_time_advance(29 * OS_TICKS_PER_SEC);
2030 ble_gap_timer();
2031 TEST_ASSERT(ble_gap_test_event.type == 0xff);
2032
2033 /* Advance 30th second; ensure timeout reported. */
2034 os_time_advance(1 * OS_TICKS_PER_SEC);
2035
2036 /* Timeout will result in a terminate HCI command being sent; schedule ack
2037 * from controller.
2038 */
2039 ble_hs_test_util_hci_ack_set_disconnect(0);
2040
2041 ble_gap_timer();
2042
2043 /* Verify terminate was sent. */
2044 ble_gap_test_util_verify_tx_disconnect();
2045
2046 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONN_UPDATE);
2047 TEST_ASSERT(ble_gap_test_conn_status == BLE_HS_ETIMEOUT);
2048 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
2049 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
2050 peer_addr, 6) == 0);
2051 }
2052
2053 static void
ble_gap_test_util_update_l2cap_tmo(struct ble_gap_upd_params * params,uint8_t hci_status,uint8_t event_status,int rx_l2cap)2054 ble_gap_test_util_update_l2cap_tmo(struct ble_gap_upd_params *params,
2055 uint8_t hci_status, uint8_t event_status,
2056 int rx_l2cap)
2057 {
2058 struct ble_l2cap_sig_update_params l2cap_params;
2059 struct ble_hs_conn *conn;
2060 uint8_t id;
2061 int rc;
2062
2063 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
2064
2065 ble_gap_test_util_init();
2066
2067 ble_hs_test_util_create_conn_feat(2, peer_addr,
2068 BLE_HS_TEST_CONN_FEAT_NO_CONN_PARAM,
2069 ble_gap_test_util_connect_cb, NULL);
2070
2071 ble_hs_lock();
2072 conn = ble_hs_conn_find(2);
2073 TEST_ASSERT_FATAL(conn != NULL);
2074 conn->bhc_flags &= ~BLE_HS_CONN_F_MASTER;
2075 ble_hs_unlock();
2076
2077 /* Erase callback info reported during connection establishment; we only
2078 * care about updates.
2079 */
2080 ble_gap_test_util_reset_cb_info();
2081
2082 rc = ble_hs_test_util_conn_update(2, params, 0xFF);
2083 TEST_ASSERT(rc == 0);
2084
2085 TEST_ASSERT(ble_gap_dbg_update_active(2));
2086
2087 if (rx_l2cap) {
2088 l2cap_params.itvl_min = params->itvl_min;
2089 l2cap_params.itvl_max = params->itvl_max;
2090 l2cap_params.slave_latency = params->latency;
2091 l2cap_params.timeout_multiplier = params->supervision_timeout;
2092 id = ble_hs_test_util_verify_tx_l2cap_update_req(&l2cap_params);
2093
2094 /* Receive l2cap connection parameter update response. */
2095 ble_hs_test_util_rx_l2cap_update_rsp(
2096 2, id, BLE_L2CAP_SIG_UPDATE_RSP_RESULT_ACCEPT);
2097 }
2098
2099 TEST_ASSERT(ble_gap_dbg_update_active(2));
2100
2101 /* Ensure no update event reported. */
2102 TEST_ASSERT(ble_gap_test_event.type == 0xff);
2103
2104 /* Advance 29 seconds; ensure no timeout reported. */
2105 os_time_advance(29 * OS_TICKS_PER_SEC);
2106 ble_gap_timer();
2107 ble_l2cap_sig_timer();
2108 TEST_ASSERT(ble_gap_test_event.type == 0xff);
2109
2110 /* Advance 30th second; ensure timeout reported. */
2111 os_time_advance(1 * OS_TICKS_PER_SEC);
2112
2113 /* Timeout will result in a terminate HCI command being sent; schedule ack
2114 * from controller.
2115 */
2116 ble_hs_test_util_hci_ack_set_disconnect(0);
2117
2118 ble_gap_timer();
2119 ble_l2cap_sig_timer();
2120
2121 /* Verify terminate was sent. */
2122 ble_gap_test_util_verify_tx_disconnect();
2123
2124 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONN_UPDATE);
2125 TEST_ASSERT(ble_gap_test_conn_status == BLE_HS_ETIMEOUT);
2126 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
2127 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
2128 peer_addr, 6) == 0);
2129 }
2130
2131 static void
ble_gap_test_util_update_peer(uint8_t status,struct ble_gap_upd_params * params)2132 ble_gap_test_util_update_peer(uint8_t status,
2133 struct ble_gap_upd_params *params)
2134 {
2135 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
2136
2137 ble_gap_test_util_init();
2138
2139 ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb,
2140 NULL);
2141
2142 TEST_ASSERT(!ble_gap_master_in_progress());
2143
2144 /* Receive connection update complete event. */
2145 ble_gap_test_util_rx_update_complete(status, params);
2146
2147 TEST_ASSERT(!ble_gap_master_in_progress());
2148
2149 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONN_UPDATE);
2150 TEST_ASSERT(ble_gap_test_conn_status == BLE_HS_HCI_ERR(status));
2151 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
2152 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
2153 peer_addr, 6) == 0);
2154
2155 if (status == 0) {
2156 TEST_ASSERT(ble_gap_test_conn_desc.conn_itvl == params->itvl_max);
2157 TEST_ASSERT(ble_gap_test_conn_desc.conn_latency == params->latency);
2158 TEST_ASSERT(ble_gap_test_conn_desc.supervision_timeout ==
2159 params->supervision_timeout);
2160 }
2161
2162 TEST_ASSERT(!ble_gap_dbg_update_active(2));
2163 }
2164
2165 static void
ble_gap_test_util_update_req_pos(struct ble_gap_upd_params * peer_params,struct ble_gap_upd_params * self_params,int cmd_fail_idx,uint8_t hci_status)2166 ble_gap_test_util_update_req_pos(struct ble_gap_upd_params *peer_params,
2167 struct ble_gap_upd_params *self_params,
2168 int cmd_fail_idx, uint8_t hci_status)
2169 {
2170 int cmd_idx;
2171 int rc;
2172
2173 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
2174
2175 ble_gap_test_util_init();
2176 cmd_idx = 0;
2177
2178 ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb,
2179 NULL);
2180
2181 TEST_ASSERT(!ble_gap_master_in_progress());
2182
2183 ble_gap_test_conn_self_params = *self_params;
2184 rc = ble_gap_test_util_rx_param_req(peer_params, 1, &cmd_idx, cmd_fail_idx,
2185 hci_status);
2186 if (rc != 0) {
2187 goto hci_fail;
2188 }
2189 TEST_ASSERT(!ble_gap_master_in_progress());
2190
2191 /* We don't maintain an update entry when the peer initiates. */
2192 TEST_ASSERT(!ble_gap_dbg_update_active(2));
2193
2194 /* Verify tx of connection parameters reply command. */
2195 ble_gap_test_util_verify_tx_params_reply_pos();
2196
2197 TEST_ASSERT(!ble_gap_master_in_progress());
2198 TEST_ASSERT(!ble_gap_dbg_update_active(2));
2199
2200 /* Receive connection update complete event. */
2201 ble_gap_test_util_rx_update_complete(0, self_params);
2202
2203 TEST_ASSERT(!ble_gap_master_in_progress());
2204 TEST_ASSERT(!ble_gap_dbg_update_active(2));
2205
2206 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONN_UPDATE);
2207 TEST_ASSERT(ble_gap_test_conn_status == 0);
2208 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
2209 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
2210 peer_addr, 6) == 0);
2211 TEST_ASSERT(ble_gap_test_conn_desc.conn_itvl == self_params->itvl_max);
2212 TEST_ASSERT(ble_gap_test_conn_desc.conn_latency == self_params->latency);
2213 TEST_ASSERT(ble_gap_test_conn_desc.supervision_timeout ==
2214 self_params->supervision_timeout);
2215
2216 return;
2217
2218 hci_fail:
2219 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONN_UPDATE);
2220 TEST_ASSERT(ble_gap_test_conn_status == BLE_HS_HCI_ERR(hci_status));
2221 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
2222 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
2223 peer_addr, 6) == 0);
2224 TEST_ASSERT(ble_gap_test_conn_desc.conn_itvl ==
2225 BLE_GAP_INITIAL_CONN_ITVL_MAX);
2226 TEST_ASSERT(ble_gap_test_conn_desc.conn_latency ==
2227 BLE_GAP_INITIAL_CONN_LATENCY);
2228 TEST_ASSERT(ble_gap_test_conn_desc.supervision_timeout ==
2229 BLE_GAP_INITIAL_SUPERVISION_TIMEOUT);
2230 }
2231
2232 static void
ble_gap_test_util_update_req_neg(struct ble_gap_upd_params * peer_params,int cmd_fail_idx,uint8_t hci_status)2233 ble_gap_test_util_update_req_neg(struct ble_gap_upd_params *peer_params,
2234 int cmd_fail_idx, uint8_t hci_status)
2235 {
2236 int cmd_idx;
2237 int reason;
2238 int rc;
2239
2240 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
2241
2242 ble_gap_test_util_init();
2243 cmd_idx = 0;
2244
2245 reason = BLE_ERR_UNSPECIFIED;
2246 ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb,
2247 &reason);
2248
2249 TEST_ASSERT(!ble_gap_master_in_progress());
2250 TEST_ASSERT(!ble_gap_dbg_update_active(2));
2251
2252 rc = ble_gap_test_util_rx_param_req(peer_params, 0, &cmd_idx, cmd_fail_idx,
2253 hci_status);
2254 if (rc != 0) {
2255 goto hci_fail;
2256 }
2257 TEST_ASSERT(!ble_gap_master_in_progress());
2258 TEST_ASSERT(!ble_gap_dbg_update_active(2));
2259
2260 /* Verify tx of connection parameters negative reply command. */
2261 ble_gap_test_util_verify_tx_params_reply_neg(reason);
2262
2263 TEST_ASSERT(!ble_gap_master_in_progress());
2264 TEST_ASSERT(!ble_gap_dbg_update_active(2));
2265
2266 return;
2267
2268 hci_fail:
2269 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONN_UPDATE);
2270 TEST_ASSERT(ble_gap_test_conn_status == BLE_HS_HCI_ERR(hci_status));
2271 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
2272 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
2273 peer_addr, 6) == 0);
2274 TEST_ASSERT(ble_gap_test_conn_desc.conn_itvl ==
2275 BLE_GAP_INITIAL_CONN_ITVL_MAX);
2276 TEST_ASSERT(ble_gap_test_conn_desc.conn_latency ==
2277 BLE_GAP_INITIAL_CONN_LATENCY);
2278 TEST_ASSERT(ble_gap_test_conn_desc.supervision_timeout ==
2279 BLE_GAP_INITIAL_SUPERVISION_TIMEOUT);
2280 }
2281
2282 static void
ble_gap_test_util_update_req_concurrent(struct ble_gap_upd_params * init_params,struct ble_gap_upd_params * peer_params,struct ble_gap_upd_params * self_params,int cmd_fail_idx,uint8_t fail_status)2283 ble_gap_test_util_update_req_concurrent(
2284 struct ble_gap_upd_params *init_params,
2285 struct ble_gap_upd_params *peer_params,
2286 struct ble_gap_upd_params *self_params,
2287 int cmd_fail_idx,
2288 uint8_t fail_status)
2289 {
2290 uint8_t hci_status;
2291 int cmd_idx;
2292 int rc;
2293
2294 uint8_t peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
2295
2296 ble_gap_test_util_init();
2297
2298 ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb,
2299 NULL);
2300
2301 TEST_ASSERT(!ble_gap_master_in_progress());
2302 TEST_ASSERT(!ble_gap_dbg_update_active(2));
2303
2304 hci_status = cmd_fail_idx == 0 ? fail_status : 0;
2305 rc = ble_hs_test_util_conn_update(2, init_params, hci_status);
2306 TEST_ASSERT(rc == BLE_HS_HCI_ERR(hci_status));
2307
2308 TEST_ASSERT(!ble_gap_master_in_progress());
2309
2310 /* Verify tx of connection update command. */
2311 ble_gap_test_util_verify_tx_update_conn(init_params);
2312
2313 if (rc == 0) {
2314 TEST_ASSERT(ble_gap_dbg_update_active(2));
2315 } else {
2316 TEST_ASSERT(!ble_gap_dbg_update_active(2));
2317 return;
2318 }
2319
2320 TEST_ASSERT(!ble_gap_master_in_progress());
2321 TEST_ASSERT(ble_gap_dbg_update_active(2));
2322
2323 /* Receive connection parameter update request from peer. */
2324 ble_gap_test_conn_self_params = *self_params;
2325 rc = ble_gap_test_util_rx_param_req(peer_params, 1, &cmd_idx, cmd_fail_idx,
2326 hci_status);
2327 if (rc != 0) {
2328 goto hci_fail;
2329 }
2330 TEST_ASSERT(!ble_gap_master_in_progress());
2331 TEST_ASSERT(ble_gap_dbg_update_active(2));
2332
2333 /* Verify tx of connection parameters reply command. */
2334 ble_gap_test_util_verify_tx_params_reply_pos();
2335
2336 TEST_ASSERT(!ble_gap_master_in_progress());
2337 TEST_ASSERT(ble_gap_dbg_update_active(2));
2338
2339 /* Receive connection update complete event. */
2340 ble_gap_test_util_rx_update_complete(0, self_params);
2341
2342 TEST_ASSERT(!ble_gap_master_in_progress());
2343 TEST_ASSERT(!ble_gap_dbg_update_active(2));
2344
2345 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONN_UPDATE);
2346 TEST_ASSERT(ble_gap_test_conn_status == 0);
2347 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
2348 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
2349 peer_addr, 6) == 0);
2350 TEST_ASSERT(ble_gap_test_conn_desc.conn_itvl == self_params->itvl_max);
2351 TEST_ASSERT(ble_gap_test_conn_desc.conn_latency == self_params->latency);
2352 TEST_ASSERT(ble_gap_test_conn_desc.supervision_timeout ==
2353 self_params->supervision_timeout);
2354
2355 return;
2356
2357 hci_fail:
2358 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONN_UPDATE);
2359 TEST_ASSERT(ble_gap_test_conn_status == BLE_HS_HCI_ERR(fail_status));
2360 TEST_ASSERT(ble_gap_test_conn_desc.conn_handle == 2);
2361 TEST_ASSERT(memcmp(ble_gap_test_conn_desc.peer_id_addr.val,
2362 peer_addr, 6) == 0);
2363 TEST_ASSERT(ble_gap_test_conn_desc.conn_itvl ==
2364 BLE_GAP_INITIAL_CONN_ITVL_MAX);
2365 TEST_ASSERT(ble_gap_test_conn_desc.conn_latency ==
2366 BLE_GAP_INITIAL_CONN_LATENCY);
2367 TEST_ASSERT(ble_gap_test_conn_desc.supervision_timeout ==
2368 BLE_GAP_INITIAL_SUPERVISION_TIMEOUT);
2369 }
2370
TEST_CASE(ble_gap_test_case_update_conn_good)2371 TEST_CASE(ble_gap_test_case_update_conn_good)
2372 {
2373 ble_gap_test_util_update_no_l2cap(
2374 ((struct ble_gap_upd_params[]) { {
2375 .itvl_min = 10,
2376 .itvl_max = 100,
2377 .supervision_timeout = 200,
2378 .min_ce_len = 123,
2379 .max_ce_len = 456,
2380 }}),
2381 1, 0, 0);
2382
2383 ble_gap_test_util_update_no_l2cap(
2384 ((struct ble_gap_upd_params[]) { {
2385 .itvl_min = 100,
2386 .itvl_max = 100,
2387 .supervision_timeout = 200,
2388 .min_ce_len = 554,
2389 .max_ce_len = 554,
2390 }}),
2391 1, 0, 0);
2392 }
2393
TEST_CASE(ble_gap_test_case_update_conn_verify_params)2394 TEST_CASE(ble_gap_test_case_update_conn_verify_params)
2395 {
2396 /* GOOD */
2397 ble_gap_test_util_update_verify_params(
2398 ((struct ble_gap_upd_params[]) { {
2399 .itvl_min = 100,
2400 .itvl_max = 100,
2401 .supervision_timeout = 200,
2402 .min_ce_len = 554,
2403 .max_ce_len = 554,
2404 }}),
2405 0);
2406
2407 /* BAD */
2408 ble_gap_test_util_update_verify_params(
2409 ((struct ble_gap_upd_params[]) { {
2410 .itvl_min = 1,
2411 .itvl_max = 100,
2412 .supervision_timeout = 200,
2413 .min_ce_len = 554,
2414 .max_ce_len = 554,
2415 }}),
2416 BLE_HS_EINVAL);
2417
2418 ble_gap_test_util_update_verify_params(
2419 ((struct ble_gap_upd_params[]) { {
2420 .itvl_min = 0x0C80 + 1,
2421 .itvl_max = 100,
2422 .supervision_timeout = 200,
2423 .min_ce_len = 554,
2424 .max_ce_len = 554,
2425 }}),
2426 BLE_HS_EINVAL);
2427
2428 ble_gap_test_util_update_verify_params(
2429 ((struct ble_gap_upd_params[]) { {
2430 .itvl_min = 100,
2431 .itvl_max = 50,
2432 .supervision_timeout = 200,
2433 .min_ce_len = 554,
2434 .max_ce_len = 554,
2435 }}),
2436 BLE_HS_EINVAL);
2437
2438 ble_gap_test_util_update_verify_params(
2439 ((struct ble_gap_upd_params[]) { {
2440 .itvl_min = 100,
2441 .itvl_max = 100,
2442 .supervision_timeout = 200,
2443 .latency = 0x01F4,
2444 .min_ce_len = 554,
2445 .max_ce_len = 554,
2446 }}),
2447 BLE_HS_EINVAL);
2448
2449 ble_gap_test_util_update_verify_params(
2450 ((struct ble_gap_upd_params[]) { {
2451 .itvl_min = 100,
2452 .itvl_max = 600,
2453 .supervision_timeout = 300,
2454 .latency = 1,
2455 .min_ce_len = 554,
2456 .max_ce_len = 554,
2457 }}),
2458 BLE_HS_EINVAL);
2459 }
2460
TEST_CASE(ble_gap_test_case_update_conn_bad)2461 TEST_CASE(ble_gap_test_case_update_conn_bad)
2462 {
2463 ble_gap_test_util_update_no_l2cap(
2464 ((struct ble_gap_upd_params[]) { {
2465 .itvl_min = 10,
2466 .itvl_max = 100,
2467 .supervision_timeout = 200,
2468 .min_ce_len = 123,
2469 .max_ce_len = 456,
2470 }}),
2471 1, 0, BLE_ERR_LMP_COLLISION);
2472 }
2473
TEST_CASE(ble_gap_test_case_update_conn_hci_fail)2474 TEST_CASE(ble_gap_test_case_update_conn_hci_fail)
2475 {
2476 ble_gap_test_util_update_no_l2cap(
2477 ((struct ble_gap_upd_params[]) { {
2478 .itvl_min = 10,
2479 .itvl_max = 100,
2480 .supervision_timeout = 200,
2481 .min_ce_len = 123,
2482 .max_ce_len = 456,
2483 }}),
2484 1, BLE_ERR_UNSUPPORTED, 0);
2485 }
2486
TEST_CASE(ble_gap_test_case_update_conn_l2cap)2487 TEST_CASE(ble_gap_test_case_update_conn_l2cap)
2488 {
2489 struct ble_gap_upd_params params = {
2490 .itvl_min = 10,
2491 .itvl_max = 100,
2492 .supervision_timeout = 200,
2493 .min_ce_len = 123,
2494 .max_ce_len = 456,
2495 };
2496
2497 /* Accepted L2CAP. */
2498 ble_gap_test_util_update_l2cap(¶ms,
2499 BLE_L2CAP_SIG_UPDATE_RSP_RESULT_ACCEPT);
2500
2501 /* Rejected L2CAP. */
2502 ble_gap_test_util_update_l2cap(¶ms,
2503 BLE_L2CAP_SIG_UPDATE_RSP_RESULT_REJECT);
2504 }
2505
TEST_CASE(ble_gap_test_case_update_peer_good)2506 TEST_CASE(ble_gap_test_case_update_peer_good)
2507 {
2508 ble_gap_test_util_update_peer(0,
2509 ((struct ble_gap_upd_params[]) { {
2510 .itvl_min = 10,
2511 .itvl_max = 100,
2512 .supervision_timeout = 0,
2513 .min_ce_len = 123,
2514 .max_ce_len = 456,
2515 }}));
2516
2517 ble_gap_test_util_update_peer(0,
2518 ((struct ble_gap_upd_params[]) { {
2519 .itvl_min = 100,
2520 .itvl_max = 100,
2521 .supervision_timeout = 100,
2522 .min_ce_len = 554,
2523 .max_ce_len = 554,
2524 }}));
2525 }
2526
TEST_CASE(ble_gap_test_case_update_req_good)2527 TEST_CASE(ble_gap_test_case_update_req_good)
2528 {
2529 ble_gap_test_util_update_req_pos(
2530 ((struct ble_gap_upd_params[]) { {
2531 .itvl_min = 50,
2532 .itvl_max = 500,
2533 .supervision_timeout = 800,
2534 .min_ce_len = 555,
2535 .max_ce_len = 888,
2536 }}),
2537 ((struct ble_gap_upd_params[]) { {
2538 .itvl_min = 10,
2539 .itvl_max = 100,
2540 .supervision_timeout = 200,
2541 .min_ce_len = 123,
2542 .max_ce_len = 456,
2543 }}),
2544 -1, 0);
2545
2546 ble_gap_test_util_update_req_pos(
2547 ((struct ble_gap_upd_params[]) { {
2548 .itvl_min = 50,
2549 .itvl_max = 500,
2550 .supervision_timeout = 800,
2551 .min_ce_len = 555,
2552 .max_ce_len = 888,
2553 }}),
2554 ((struct ble_gap_upd_params[]) { {
2555 .itvl_min = 100,
2556 .itvl_max = 100,
2557 .supervision_timeout = 200,
2558 .min_ce_len = 554,
2559 .max_ce_len = 554,
2560 }}),
2561 -1, 0);
2562 }
2563
TEST_CASE(ble_gap_test_case_update_req_hci_fail)2564 TEST_CASE(ble_gap_test_case_update_req_hci_fail)
2565 {
2566 ble_gap_test_util_update_req_pos(
2567 ((struct ble_gap_upd_params[]) { {
2568 .itvl_min = 50,
2569 .itvl_max = 500,
2570 .supervision_timeout = 800,
2571 .min_ce_len = 555,
2572 .max_ce_len = 888,
2573 }}),
2574 ((struct ble_gap_upd_params[]) { {
2575 .itvl_min = 10,
2576 .itvl_max = 100,
2577 .supervision_timeout = 200,
2578 .min_ce_len = 123,
2579 .max_ce_len = 456,
2580 }}),
2581 0, BLE_ERR_UNSUPPORTED);
2582 }
2583
TEST_CASE(ble_gap_test_case_update_req_reject)2584 TEST_CASE(ble_gap_test_case_update_req_reject)
2585 {
2586 ble_gap_test_util_update_req_neg(
2587 ((struct ble_gap_upd_params[]) { {
2588 .itvl_min = 50,
2589 .itvl_max = 500,
2590 .supervision_timeout = 800,
2591 .min_ce_len = 555,
2592 .max_ce_len = 888,
2593 }}),
2594 -1, 0);
2595
2596 ble_gap_test_util_update_req_neg(
2597 ((struct ble_gap_upd_params[]) { {
2598 .itvl_min = 50,
2599 .itvl_max = 500,
2600 .supervision_timeout = 800,
2601 .min_ce_len = 555,
2602 .max_ce_len = 888,
2603 }}),
2604 -1, 0);
2605 }
2606
TEST_CASE(ble_gap_test_case_update_concurrent_good)2607 TEST_CASE(ble_gap_test_case_update_concurrent_good)
2608 {
2609 ble_gap_test_util_update_req_concurrent(
2610 ((struct ble_gap_upd_params[]) { {
2611 .itvl_min = 10,
2612 .itvl_max = 100,
2613 .supervision_timeout = 200,
2614 .min_ce_len = 123,
2615 .max_ce_len = 456,
2616 }}),
2617 ((struct ble_gap_upd_params[]) { {
2618 .itvl_min = 50,
2619 .itvl_max = 500,
2620 .supervision_timeout = 800,
2621 .min_ce_len = 555,
2622 .max_ce_len = 888,
2623 }}),
2624 ((struct ble_gap_upd_params[]) { {
2625 .itvl_min = 10,
2626 .itvl_max = 100,
2627 .supervision_timeout = 200,
2628 .min_ce_len = 123,
2629 .max_ce_len = 456,
2630 }}),
2631 -1, 0);
2632
2633 ble_gap_test_util_update_req_concurrent(
2634 ((struct ble_gap_upd_params[]) { {
2635 .itvl_min = 10,
2636 .itvl_max = 100,
2637 .supervision_timeout = 200,
2638 .min_ce_len = 123,
2639 .max_ce_len = 456,
2640 }}),
2641 ((struct ble_gap_upd_params[]) { {
2642 .itvl_min = 50,
2643 .itvl_max = 500,
2644 .supervision_timeout = 800,
2645 .min_ce_len = 555,
2646 .max_ce_len = 888,
2647 }}),
2648 ((struct ble_gap_upd_params[]) { {
2649 .itvl_min = 20,
2650 .itvl_max = 200,
2651 .supervision_timeout = 350,
2652 .min_ce_len = 111,
2653 .max_ce_len = 222,
2654 }}),
2655 -1, 0);
2656 }
2657
TEST_CASE(ble_gap_test_case_update_concurrent_hci_fail)2658 TEST_CASE(ble_gap_test_case_update_concurrent_hci_fail)
2659 {
2660 ble_gap_test_util_update_req_concurrent(
2661 ((struct ble_gap_upd_params[]) { {
2662 .itvl_min = 10,
2663 .itvl_max = 100,
2664 .supervision_timeout = 200,
2665 .min_ce_len = 123,
2666 .max_ce_len = 456,
2667 }}),
2668 ((struct ble_gap_upd_params[]) { {
2669 .itvl_min = 50,
2670 .itvl_max = 500,
2671 .supervision_timeout = 800,
2672 .min_ce_len = 555,
2673 .max_ce_len = 888,
2674 }}),
2675 ((struct ble_gap_upd_params[]) { {
2676 .itvl_min = 20,
2677 .itvl_max = 200,
2678 .supervision_timeout = 350,
2679 .min_ce_len = 111,
2680 .max_ce_len = 222,
2681 }}),
2682 0, BLE_ERR_UNSUPPORTED);
2683
2684 ble_gap_test_util_update_req_concurrent(
2685 ((struct ble_gap_upd_params[]) { {
2686 .itvl_min = 10,
2687 .itvl_max = 100,
2688 .supervision_timeout = 200,
2689 .min_ce_len = 123,
2690 .max_ce_len = 456,
2691 }}),
2692 ((struct ble_gap_upd_params[]) { {
2693 .itvl_min = 50,
2694 .itvl_max = 500,
2695 .supervision_timeout = 800,
2696 .min_ce_len = 555,
2697 .max_ce_len = 888,
2698 }}),
2699 ((struct ble_gap_upd_params[]) { {
2700 .itvl_min = 20,
2701 .itvl_max = 200,
2702 .supervision_timeout = 350,
2703 .min_ce_len = 111,
2704 .max_ce_len = 222,
2705 }}),
2706 1, BLE_ERR_UNSUPPORTED);
2707 }
2708
TEST_SUITE(ble_gap_test_suite_update_conn)2709 TEST_SUITE(ble_gap_test_suite_update_conn)
2710 {
2711 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
2712
2713 ble_gap_test_case_update_conn_good();
2714 ble_gap_test_case_update_conn_bad();
2715 ble_gap_test_case_update_conn_hci_fail();
2716 ble_gap_test_case_update_conn_l2cap();
2717 ble_gap_test_case_update_peer_good();
2718 ble_gap_test_case_update_req_good();
2719 ble_gap_test_case_update_req_hci_fail();
2720 ble_gap_test_case_update_req_reject();
2721 ble_gap_test_case_update_concurrent_good();
2722 ble_gap_test_case_update_concurrent_hci_fail();
2723 ble_gap_test_case_update_conn_verify_params();
2724 }
2725
2726 /*****************************************************************************
2727 * $timeout *
2728 *****************************************************************************/
2729
2730 static void
ble_gap_test_util_conn_forever(void)2731 ble_gap_test_util_conn_forever(void)
2732 {
2733 int32_t ticks_from_now;
2734
2735 /* Initiate a connect procedure with no timeout. */
2736 ble_hs_test_util_connect(
2737 BLE_OWN_ADDR_PUBLIC,
2738 &((ble_addr_t) { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }}),
2739 BLE_HS_FOREVER,
2740 NULL, ble_gap_test_util_connect_cb,
2741 NULL, 0);
2742
2743 /* Ensure no pending GAP event. */
2744 ticks_from_now = ble_gap_timer();
2745 TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER);
2746
2747 /* Advance 100 seconds; ensure no timeout reported. */
2748 os_time_advance(100 * OS_TICKS_PER_SEC);
2749 ble_gap_timer();
2750 TEST_ASSERT(ble_gap_test_event.type == 0xff);
2751 TEST_ASSERT(ble_gap_conn_active());
2752 }
2753
2754 static void
ble_gap_test_util_conn_timeout(int32_t duration_ms)2755 ble_gap_test_util_conn_timeout(int32_t duration_ms)
2756 {
2757 struct hci_le_conn_complete evt;
2758 uint32_t duration_ticks;
2759 int32_t ticks_from_now;
2760 int rc;
2761
2762 TEST_ASSERT_FATAL(duration_ms != BLE_HS_FOREVER);
2763
2764 /* Initiate a connect procedure with the specified timeout. */
2765 ble_hs_test_util_connect(
2766 BLE_OWN_ADDR_PUBLIC,
2767 &((ble_addr_t) { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }}),
2768 duration_ms,
2769 NULL, ble_gap_test_util_connect_cb,
2770 NULL, 0);
2771
2772 /* Ensure next GAP event is at the expected time. */
2773 rc = os_time_ms_to_ticks(duration_ms, &duration_ticks);
2774 TEST_ASSERT_FATAL(rc == 0);
2775 ticks_from_now = ble_gap_timer();
2776 TEST_ASSERT(ticks_from_now == duration_ticks);
2777
2778 /* Advance duration ms; ensure timeout event does not get reported before
2779 * connection complete event rxed.
2780 */
2781 os_time_advance(duration_ms);
2782
2783 ble_hs_test_util_hci_ack_set(
2784 ble_hs_hci_util_opcode_join(BLE_HCI_OGF_LE,
2785 BLE_HCI_OCF_LE_CREATE_CONN_CANCEL),
2786 0);
2787
2788 TEST_ASSERT(ble_gap_test_event.type == 0xff);
2789
2790 ticks_from_now = ble_gap_timer();
2791 TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER);
2792
2793 /* Ensure cancel create connection command was sent. */
2794 ble_hs_test_util_hci_verify_tx_create_conn_cancel();
2795
2796 /* Ensure timer has been stopped. */
2797 ticks_from_now = ble_gap_timer();
2798 TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER);
2799
2800 /* Receive the connection complete event indicating a successful cancel. */
2801 memset(&evt, 0, sizeof evt);
2802 evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
2803 evt.status = BLE_ERR_UNK_CONN_ID;
2804 /* test if host correctly ignores other fields if status is error */
2805 evt.connection_handle = 0x0fff;
2806
2807 rc = ble_gap_rx_conn_complete(&evt, 0);
2808 TEST_ASSERT_FATAL(rc == 0);
2809
2810 /* Ensure the GAP event was triggered. */
2811 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_CONNECT);
2812 TEST_ASSERT(ble_gap_test_conn_status == BLE_HS_ETIMEOUT);
2813
2814 /* Clear GAP event for remainder of test. */
2815 ble_gap_test_util_reset_cb_info();
2816 }
2817
2818 static void
ble_gap_test_util_disc_forever(void)2819 ble_gap_test_util_disc_forever(void)
2820 {
2821 struct ble_gap_disc_params params;
2822 int32_t ticks_from_now;
2823
2824 memset(¶ms, 0, sizeof params);
2825
2826 /* Initiate a discovery procedure with no timeout. */
2827 ble_hs_test_util_disc(BLE_OWN_ADDR_PUBLIC,
2828 BLE_HS_FOREVER, ¶ms, ble_gap_test_util_disc_cb,
2829 NULL, -1, 0);
2830
2831 /* Ensure no pending GAP event. */
2832 ticks_from_now = ble_gap_timer();
2833 TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER);
2834
2835 /* Advance 100 seconds; ensure no timeout reported. */
2836 os_time_advance(100 * OS_TICKS_PER_SEC);
2837 TEST_ASSERT(ble_gap_test_disc_event_type == -1);
2838 TEST_ASSERT(ble_gap_disc_active());
2839 }
2840
2841 static void
ble_gap_test_util_disc_timeout(int32_t duration_ms)2842 ble_gap_test_util_disc_timeout(int32_t duration_ms)
2843 {
2844 struct ble_gap_disc_params params;
2845 uint32_t duration_ticks;
2846 int32_t ticks_from_now;
2847 int rc;
2848
2849 TEST_ASSERT_FATAL(duration_ms != BLE_HS_FOREVER);
2850
2851 memset(¶ms, 0, sizeof params);
2852
2853 /* Initiate a discovery procedure with the specified timeout. */
2854 ble_hs_test_util_disc(BLE_OWN_ADDR_PUBLIC,
2855 duration_ms, ¶ms, ble_gap_test_util_disc_cb,
2856 NULL, -1, 0);
2857
2858 /* Ensure next GAP event is at the expected time. */
2859 rc = os_time_ms_to_ticks(duration_ms, &duration_ticks);
2860 TEST_ASSERT_FATAL(rc == 0);
2861 ticks_from_now = ble_gap_timer();
2862 TEST_ASSERT(ticks_from_now == duration_ticks);
2863
2864 /* Advance duration ms; ensure timeout event was reported. */
2865 os_time_advance(duration_ms);
2866
2867 ble_hs_test_util_hci_ack_set(
2868 ble_hs_hci_util_opcode_join(BLE_HCI_OGF_LE,
2869 BLE_HCI_OCF_LE_SET_SCAN_ENABLE),
2870 0);
2871 ticks_from_now = ble_gap_timer();
2872 TEST_ASSERT(ticks_from_now == BLE_HS_FOREVER);
2873
2874 TEST_ASSERT(ble_gap_test_disc_event_type == BLE_GAP_EVENT_DISC_COMPLETE);
2875
2876 /* Clear GAP event for remainder of test. */
2877 ble_gap_test_util_reset_cb_info();
2878 }
2879
TEST_CASE(ble_gap_test_case_update_timeout)2880 TEST_CASE(ble_gap_test_case_update_timeout)
2881 {
2882 struct ble_gap_upd_params params = {
2883 .itvl_min = 10,
2884 .itvl_max = 100,
2885 .supervision_timeout = 200,
2886 .min_ce_len = 123,
2887 .max_ce_len = 456,
2888 };
2889
2890 /* No L2CAP. */
2891 ble_gap_test_util_update_no_l2cap_tmo(¶ms, 1);
2892
2893 /* L2CAP - Local unsupported; L2CAP timeout. */
2894 ble_gap_test_util_update_l2cap_tmo(¶ms, BLE_ERR_UNKNOWN_HCI_CMD, 0, 0);
2895
2896 /* L2CAP - Local unsupported; LL timeout. */
2897 ble_gap_test_util_update_l2cap_tmo(¶ms, BLE_ERR_UNKNOWN_HCI_CMD, 0, 1);
2898
2899 /* L2CAP - Remote unsupported; L2CAP timeout. */
2900 ble_gap_test_util_update_l2cap_tmo(¶ms, 0, BLE_ERR_UNSUPP_REM_FEATURE,
2901 0);
2902
2903 /* L2CAP - Remote unsupported; LL timeout. */
2904 ble_gap_test_util_update_l2cap_tmo(¶ms, 0, BLE_ERR_UNSUPP_REM_FEATURE,
2905 1);
2906 }
2907
TEST_CASE(ble_gap_test_case_conn_timeout_conn_forever)2908 TEST_CASE(ble_gap_test_case_conn_timeout_conn_forever)
2909 {
2910 ble_gap_test_util_init();
2911
2912 /* 30 ms. */
2913 ble_gap_test_util_conn_timeout(30);
2914
2915 /* No timeout. */
2916 ble_gap_test_util_conn_forever();
2917
2918 }
2919
TEST_CASE(ble_gap_test_case_conn_timeout_conn_timeout)2920 TEST_CASE(ble_gap_test_case_conn_timeout_conn_timeout)
2921 {
2922 ble_gap_test_util_init();
2923
2924 /* 30 ms. */
2925 ble_gap_test_util_conn_timeout(30);
2926
2927 /* 20 ms. */
2928 ble_gap_test_util_conn_timeout(20);
2929
2930 }
2931
TEST_CASE(ble_gap_test_case_conn_forever_conn_timeout)2932 TEST_CASE(ble_gap_test_case_conn_forever_conn_timeout)
2933 {
2934 ble_gap_test_util_init();
2935
2936 /* No timeout. */
2937 ble_gap_test_util_conn_forever();
2938
2939 /* Cancel connect procedure manually. */
2940 ble_gap_test_util_conn_cancel(0);
2941
2942 /* Clear GAP event for remainder of test. */
2943 ble_gap_test_util_reset_cb_info();
2944
2945 /* 30 ms. */
2946 ble_gap_test_util_conn_timeout(30);
2947 }
2948
TEST_CASE(ble_gap_test_case_disc_timeout_disc_forever)2949 TEST_CASE(ble_gap_test_case_disc_timeout_disc_forever)
2950 {
2951 ble_gap_test_util_init();
2952
2953 /* 30 ms. */
2954 ble_gap_test_util_disc_timeout(30);
2955
2956 /* No timeout. */
2957 ble_gap_test_util_disc_forever();
2958
2959 }
2960
TEST_CASE(ble_gap_test_case_disc_timeout_disc_timeout)2961 TEST_CASE(ble_gap_test_case_disc_timeout_disc_timeout)
2962 {
2963 ble_gap_test_util_init();
2964
2965 /* 30 ms. */
2966 ble_gap_test_util_disc_timeout(30);
2967
2968 /* 20 ms. */
2969 ble_gap_test_util_disc_timeout(20);
2970
2971 }
2972
TEST_CASE(ble_gap_test_case_disc_forever_disc_timeout)2973 TEST_CASE(ble_gap_test_case_disc_forever_disc_timeout)
2974 {
2975 ble_gap_test_util_init();
2976
2977 /* No timeout. */
2978 ble_gap_test_util_disc_forever();
2979
2980 /* Cancel discovery procedure manually. */
2981 ble_hs_test_util_disc_cancel(0);
2982
2983 /* 30 ms. */
2984 ble_gap_test_util_disc_timeout(30);
2985 }
2986
TEST_CASE(ble_gap_test_case_conn_timeout_disc_timeout)2987 TEST_CASE(ble_gap_test_case_conn_timeout_disc_timeout)
2988 {
2989 ble_gap_test_util_init();
2990
2991 /* 15 seconds. */
2992 ble_gap_test_util_conn_timeout(15000);
2993
2994 /* 1280 ms. */
2995 ble_gap_test_util_disc_timeout(1280);
2996 }
2997
TEST_SUITE(ble_gap_test_suite_timeout)2998 TEST_SUITE(ble_gap_test_suite_timeout)
2999 {
3000 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
3001
3002 ble_gap_test_case_conn_timeout_conn_forever();
3003 ble_gap_test_case_conn_timeout_conn_timeout();
3004 ble_gap_test_case_conn_forever_conn_timeout();
3005
3006 ble_gap_test_case_disc_timeout_disc_forever();
3007 ble_gap_test_case_disc_timeout_disc_timeout();
3008 ble_gap_test_case_disc_forever_disc_timeout();
3009
3010 ble_gap_test_case_conn_timeout_disc_timeout();
3011
3012 ble_gap_test_case_update_timeout();
3013 }
3014
TEST_CASE(ble_gap_test_case_mtu_us)3015 TEST_CASE(ble_gap_test_case_mtu_us)
3016 {
3017 const uint8_t peer_addr[6] = { 1,2,3,4,5,6 };
3018 int rc;
3019
3020 ble_gap_test_util_init();
3021
3022 ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb,
3023 NULL);
3024
3025 ble_att_set_preferred_mtu(200);
3026
3027 rc = ble_gattc_exchange_mtu(2, NULL, NULL);
3028 TEST_ASSERT_FATAL(rc == 0);
3029 ble_hs_test_util_verify_tx_mtu_cmd(1, 200);
3030
3031 rc = ble_hs_test_util_rx_att_mtu_cmd(2, 0, 123);
3032 TEST_ASSERT_FATAL(rc == 0);
3033 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_MTU);
3034 TEST_ASSERT(ble_gap_test_event.mtu.conn_handle == 2);
3035 TEST_ASSERT(ble_gap_test_event.mtu.channel_id == BLE_L2CAP_CID_ATT);
3036 TEST_ASSERT(ble_gap_test_event.mtu.value == 123);
3037 }
3038
TEST_CASE(ble_gap_test_case_mtu_peer)3039 TEST_CASE(ble_gap_test_case_mtu_peer)
3040 {
3041 const uint8_t peer_addr[6] = { 1,2,3,4,5,6 };
3042 int rc;
3043
3044 ble_gap_test_util_init();
3045
3046 ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb,
3047 NULL);
3048
3049 ble_att_set_preferred_mtu(200);
3050
3051 rc = ble_hs_test_util_rx_att_mtu_cmd(2, 1, 123);
3052 TEST_ASSERT_FATAL(rc == 0);
3053 ble_hs_test_util_verify_tx_mtu_cmd(0, 200);
3054
3055 TEST_ASSERT(ble_gap_test_event.type == BLE_GAP_EVENT_MTU);
3056 TEST_ASSERT(ble_gap_test_event.mtu.conn_handle == 2);
3057 TEST_ASSERT(ble_gap_test_event.mtu.channel_id == BLE_L2CAP_CID_ATT);
3058 TEST_ASSERT(ble_gap_test_event.mtu.value == 123);
3059 }
3060
TEST_SUITE(ble_gap_test_suite_mtu)3061 TEST_SUITE(ble_gap_test_suite_mtu)
3062 {
3063 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
3064
3065 ble_gap_test_case_mtu_us();
3066 ble_gap_test_case_mtu_peer();
3067 }
3068
3069 /*****************************************************************************
3070 * $set cb *
3071 *****************************************************************************/
3072
3073 static int
ble_gap_test_util_set_cb_event(struct ble_gap_event * event,void * arg)3074 ble_gap_test_util_set_cb_event(struct ble_gap_event *event, void *arg)
3075 {
3076 struct ble_gap_event *event_arg;
3077
3078 event_arg = arg;
3079
3080 *event_arg = *event;
3081
3082 return 0;
3083 }
3084
TEST_CASE(ble_gap_test_case_set_cb_good)3085 TEST_CASE(ble_gap_test_case_set_cb_good)
3086 {
3087 const uint8_t peer_addr[6] = { 1,2,3,4,5,6 };
3088 struct hci_disconn_complete disconn_evt;
3089 struct ble_gap_event event;
3090 int rc;
3091
3092 ble_gap_test_util_init();
3093
3094 ble_hs_test_util_create_conn(2, peer_addr, ble_gap_test_util_connect_cb,
3095 NULL);
3096
3097 /* Reconfigure the callback. */
3098 rc = ble_gap_set_event_cb(2, ble_gap_test_util_set_cb_event, &event);
3099 TEST_ASSERT_FATAL(rc == 0);
3100
3101 /* Terminate the connection and ensure the new callback gets called. */
3102 rc = ble_hs_test_util_conn_terminate(2, 0);
3103 TEST_ASSERT_FATAL(rc == 0);
3104
3105 disconn_evt.connection_handle = 2;
3106 disconn_evt.status = 0;
3107 disconn_evt.reason = BLE_ERR_REM_USER_CONN_TERM;
3108 ble_hs_test_util_hci_rx_disconn_complete_event(&disconn_evt);
3109
3110 TEST_ASSERT(event.type == BLE_GAP_EVENT_DISCONNECT);
3111 TEST_ASSERT(event.disconnect.reason ==
3112 BLE_HS_HCI_ERR(BLE_ERR_REM_USER_CONN_TERM));
3113 TEST_ASSERT(event.disconnect.conn.conn_handle == 2);
3114 }
3115
TEST_CASE(ble_gap_test_case_set_cb_bad)3116 TEST_CASE(ble_gap_test_case_set_cb_bad)
3117 {
3118 int rc;
3119
3120 ble_gap_test_util_init();
3121
3122 /* Ensure error is reported when specified connection doesn't exist. */
3123 rc = ble_gap_set_event_cb(123, ble_gap_test_util_set_cb_event, NULL);
3124 TEST_ASSERT(rc == BLE_HS_ENOTCONN);
3125 }
3126
TEST_SUITE(ble_gap_test_suite_set_cb)3127 TEST_SUITE(ble_gap_test_suite_set_cb)
3128 {
3129 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
3130
3131 ble_gap_test_case_set_cb_good();
3132 ble_gap_test_case_set_cb_bad();
3133 }
3134
3135 /*****************************************************************************
3136 * $all *
3137 *****************************************************************************/
3138
3139 int
ble_gap_test_all(void)3140 ble_gap_test_all(void)
3141 {
3142 ble_gap_test_suite_wl();
3143 ble_gap_test_suite_disc();
3144 ble_gap_test_suite_conn_gen();
3145 ble_gap_test_suite_conn_cancel();
3146 ble_gap_test_suite_conn_terminate();
3147 ble_gap_test_suite_conn_find();
3148 ble_gap_test_suite_adv();
3149 ble_gap_test_suite_stop_adv();
3150 ble_gap_test_suite_update_conn();
3151 ble_gap_test_suite_timeout();
3152 ble_gap_test_suite_mtu();
3153 ble_gap_test_suite_set_cb();
3154
3155 return tu_any_failed;
3156 }
3157