1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include <stddef.h>
21 #include <errno.h>
22 #include <string.h>
23 #include "testutil/testutil.h"
24 #include "host/ble_hs.h"
25 #include "host/ble_hs_test.h"
26 #include "ble_hs_test_util.h"
27
28 #define BHST_MAX_EVENTS 32
29
30 static struct ble_gap_event bhst_events[BHST_MAX_EVENTS];
31 static int bhst_num_events;
32
33 static struct ble_hs_stop_listener bhst_listener;
34 static struct os_sem bhst_sem;
35
36 static int
bhst_gap_event(struct ble_gap_event * event,void * arg)37 bhst_gap_event(struct ble_gap_event *event, void *arg)
38 {
39 TEST_ASSERT_FATAL(bhst_num_events < BHST_MAX_EVENTS);
40
41 bhst_events[bhst_num_events++] = *event;
42 return 0;
43 }
44
45 static void
bhst_stop_cb(int status,void * arg)46 bhst_stop_cb(int status, void *arg)
47 {
48 int rc;
49
50 rc = os_sem_release(&bhst_sem);
51 TEST_ASSERT_FATAL(rc == 0);
52 }
53
TEST_CASE_TASK(ble_hs_stop_test_new_procs)54 TEST_CASE_TASK(ble_hs_stop_test_new_procs)
55 {
56 static const struct ble_gap_disc_params disc_params;
57 static const struct ble_gap_adv_params adv_params;
58
59 static const ble_addr_t peer_addr = {
60 BLE_ADDR_PUBLIC,
61 { 1, 2, 3, 4, 5, 6 }
62 };
63
64 int rc;
65
66 rc = os_sem_init(&bhst_sem, 0);
67 TEST_ASSERT_FATAL(rc == 0);
68
69 /* Stop the host and wait for the stop procedure to complete. */
70 ble_hs_test_util_hci_ack_set(
71 BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADV_ENABLE), 0);
72
73 rc = ble_hs_stop(&bhst_listener, bhst_stop_cb, NULL);
74 TEST_ASSERT_FATAL(rc == 0);
75 rc = os_sem_pend(&bhst_sem, OS_TIMEOUT_NEVER);
76 TEST_ASSERT_FATAL(rc == 0);
77
78 /*** Ensure all GAP procedures fail. */
79
80 /* Advertise. */
81 rc = ble_hs_test_util_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, &adv_params,
82 BLE_HS_FOREVER, bhst_gap_event, NULL,
83 0, 0);
84 TEST_ASSERT(rc == BLE_HS_EDISABLED);
85
86 /* Discover. */
87 rc = ble_hs_test_util_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER,
88 &disc_params, bhst_gap_event, NULL, 0, 0);
89 TEST_ASSERT(rc == BLE_HS_EDISABLED);
90
91 /* Connect. */
92 rc = ble_hs_test_util_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr,
93 BLE_HS_FOREVER, NULL,
94 bhst_gap_event, NULL, 0);
95 TEST_ASSERT(rc == BLE_HS_EDISABLED);
96
97 /*** Restart stack; ensure GAP procedures succeed. */
98
99 ble_hs_test_util_hci_ack_set_startup();
100 ble_hs_sched_start();
101
102 /* Advertise. */
103 rc = ble_hs_test_util_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, &adv_params,
104 BLE_HS_FOREVER, bhst_gap_event, NULL,
105 0, 0);
106 TEST_ASSERT(rc == 0);
107
108 rc = ble_hs_test_util_adv_stop(0);
109 TEST_ASSERT(rc == 0);
110
111 /* Discover. */
112 rc = ble_hs_test_util_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER,
113 &disc_params, bhst_gap_event, NULL, 0, 0);
114 TEST_ASSERT(rc == 0);
115
116 rc = ble_hs_test_util_disc_cancel(0);
117 TEST_ASSERT(rc == 0);
118
119 /* Connect. */
120 rc = ble_hs_test_util_connect(BLE_OWN_ADDR_PUBLIC, &peer_addr,
121 BLE_HS_FOREVER, NULL,
122 bhst_gap_event, NULL, 0);
123 TEST_ASSERT(rc == 0);
124
125 rc = ble_hs_test_util_conn_cancel(0);
126 TEST_ASSERT(rc == 0);
127 }
128
TEST_CASE_TASK(ble_hs_stop_test_cur_procs)129 TEST_CASE_TASK(ble_hs_stop_test_cur_procs)
130 {
131 static const struct ble_gap_disc_params disc_params;
132 static const struct ble_gap_adv_params adv_params;
133
134 int rc;
135
136 rc = os_sem_init(&bhst_sem, 0);
137 TEST_ASSERT_FATAL(rc == 0);
138
139 /* Advertise. */
140 rc = ble_hs_test_util_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, &adv_params,
141 BLE_HS_FOREVER, bhst_gap_event, NULL,
142 0, 0);
143 TEST_ASSERT(rc == 0);
144
145 /* Discover. */
146 rc = ble_hs_test_util_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER,
147 &disc_params, bhst_gap_event, NULL, 0, 0);
148 TEST_ASSERT(rc == 0);
149
150 /* Preload the host with HCI acks for the cancel commands that will be sent
151 * automatically when the host stops.
152 */
153 ble_hs_test_util_hci_ack_set(
154 BLE_HS_TEST_UTIL_LE_OPCODE(BLE_HCI_OCF_LE_SET_ADV_ENABLE),
155 0);
156 ble_hs_test_util_hci_ack_append(
157 ble_hs_hci_util_opcode_join(BLE_HCI_OGF_LE,
158 BLE_HCI_OCF_LE_SET_SCAN_ENABLE),
159 0);
160
161 /* Stop the host and wait for the stop procedure to complete. */
162 bhst_num_events = 0;
163 rc = ble_hs_stop(&bhst_listener, bhst_stop_cb, NULL);
164 TEST_ASSERT_FATAL(rc == 0);
165 rc = os_sem_pend(&bhst_sem, OS_TIMEOUT_NEVER);
166 TEST_ASSERT_FATAL(rc == 0);
167
168 /* Ensure the GAP procedure cancellations were reported. */
169 TEST_ASSERT_FATAL(bhst_num_events == 2);
170 TEST_ASSERT(bhst_events[0].type == BLE_GAP_EVENT_ADV_COMPLETE);
171 TEST_ASSERT(bhst_events[0].adv_complete.reason == BLE_HS_EPREEMPTED);
172 TEST_ASSERT(bhst_events[1].type == BLE_GAP_EVENT_DISC_COMPLETE);
173 TEST_ASSERT(bhst_events[1].disc_complete.reason == BLE_HS_EPREEMPTED);
174 }
175
176 static void
bhst_pre_test(void * arg)177 bhst_pre_test(void *arg)
178 {
179 ble_hs_test_util_init_no_sysinit_no_start();
180
181 /* Preload the host with HCI acks for the startup sequence. */
182 ble_hs_test_util_hci_ack_set_startup();
183 }
184
TEST_SUITE(ble_hs_stop_test_suite)185 TEST_SUITE(ble_hs_stop_test_suite)
186 {
187 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
188 tu_suite_set_pre_test_cb(bhst_pre_test, NULL);
189
190 ble_hs_stop_test_new_procs();
191 ble_hs_stop_test_cur_procs();
192 }
193
194 int
ble_stop_test_all(void)195 ble_stop_test_all(void)
196 {
197 ble_hs_stop_test_suite();
198
199 return tu_any_failed;
200 }
201