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 "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 int
ble_hs_conn_test_util_any()30 ble_hs_conn_test_util_any()
31 {
32 struct ble_hs_conn *conn;
33
34 ble_hs_lock();
35 conn = ble_hs_conn_first();
36 ble_hs_unlock();
37
38 return conn != NULL;
39 }
40
TEST_CASE(ble_hs_conn_test_direct_connect_success)41 TEST_CASE(ble_hs_conn_test_direct_connect_success)
42 {
43 struct hci_le_conn_complete evt;
44 struct ble_l2cap_chan *chan;
45 struct ble_hs_conn *conn;
46 ble_addr_t addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }};
47 int rc;
48
49 ble_hs_test_util_init();
50
51 /* Ensure no current or pending connections. */
52 TEST_ASSERT(!ble_gap_master_in_progress());
53 TEST_ASSERT(!ble_hs_conn_test_util_any());
54
55 /* Initiate connection. */
56 rc = ble_hs_test_util_connect(BLE_OWN_ADDR_PUBLIC,
57 &addr, 0, NULL, NULL, NULL, 0);
58 TEST_ASSERT(rc == 0);
59
60 TEST_ASSERT(ble_gap_master_in_progress());
61
62 /* ble_gap_rx_conn_complete() will send extra HCI command, need phony ack */
63 ble_hs_test_util_hci_ack_set(ble_hs_hci_util_opcode_join(BLE_HCI_OGF_LE,
64 BLE_HCI_OCF_LE_RD_REM_FEAT), 0);
65
66 /* Receive successful connection complete event. */
67 memset(&evt, 0, sizeof evt);
68 evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
69 evt.status = BLE_ERR_SUCCESS;
70 evt.connection_handle = 2;
71 evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER;
72 memcpy(evt.peer_addr, addr.val, 6);
73 rc = ble_gap_rx_conn_complete(&evt, 0);
74 TEST_ASSERT(rc == 0);
75 TEST_ASSERT(!ble_gap_master_in_progress());
76
77 ble_hs_lock();
78
79 conn = ble_hs_conn_first();
80 TEST_ASSERT_FATAL(conn != NULL);
81 TEST_ASSERT(conn->bhc_handle == 2);
82 TEST_ASSERT(memcmp(conn->bhc_peer_addr.val, addr.val, 6) == 0);
83
84 chan = ble_hs_conn_chan_find_by_scid(conn, BLE_L2CAP_CID_ATT);
85 TEST_ASSERT_FATAL(chan != NULL);
86 TEST_ASSERT(chan->my_mtu == MYNEWT_VAL(BLE_ATT_PREFERRED_MTU));
87 TEST_ASSERT(chan->peer_mtu == 0);
88
89 ble_hs_unlock();
90 }
91
TEST_CASE(ble_hs_conn_test_direct_connectable_success)92 TEST_CASE(ble_hs_conn_test_direct_connectable_success)
93 {
94 struct hci_le_conn_complete evt;
95 struct ble_gap_adv_params adv_params;
96 struct ble_l2cap_chan *chan;
97 struct ble_hs_conn *conn;
98 ble_addr_t addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }};
99 int rc;
100
101 ble_hs_test_util_init();
102
103 /* Ensure no current or pending connections. */
104 TEST_ASSERT(!ble_gap_master_in_progress());
105 TEST_ASSERT(!ble_gap_adv_active());
106 TEST_ASSERT(!ble_hs_conn_test_util_any());
107
108 /* Initiate advertising. */
109 adv_params = ble_hs_test_util_adv_params;
110 adv_params.conn_mode = BLE_GAP_CONN_MODE_DIR;
111 rc = ble_hs_test_util_adv_start(BLE_OWN_ADDR_PUBLIC,
112 &addr, &adv_params, BLE_HS_FOREVER,
113 NULL, NULL, 0, 0);
114 TEST_ASSERT(rc == 0);
115
116 TEST_ASSERT(!ble_gap_master_in_progress());
117 TEST_ASSERT(ble_gap_adv_active());
118
119 /* ble_gap_rx_conn_complete() will send extra HCI command, need phony ack */
120 ble_hs_test_util_hci_ack_set(ble_hs_hci_util_opcode_join(BLE_HCI_OGF_LE,
121 BLE_HCI_OCF_LE_RD_REM_FEAT), 0);
122
123 /* Receive successful connection complete event. */
124 memset(&evt, 0, sizeof evt);
125 evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
126 evt.status = BLE_ERR_SUCCESS;
127 evt.connection_handle = 2;
128 evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE;
129 memcpy(evt.peer_addr, addr.val, 6);
130 rc = ble_gap_rx_conn_complete(&evt, 0);
131 TEST_ASSERT(rc == 0);
132 TEST_ASSERT(!ble_gap_master_in_progress());
133 TEST_ASSERT(!ble_gap_adv_active());
134
135 ble_hs_lock();
136
137 conn = ble_hs_conn_first();
138 TEST_ASSERT_FATAL(conn != NULL);
139 TEST_ASSERT(conn->bhc_handle == 2);
140 TEST_ASSERT(memcmp(conn->bhc_peer_addr.val, addr.val, 6) == 0);
141
142 chan = ble_hs_conn_chan_find_by_scid(conn, BLE_L2CAP_CID_ATT);
143 TEST_ASSERT_FATAL(chan != NULL);
144 TEST_ASSERT(chan->my_mtu == MYNEWT_VAL(BLE_ATT_PREFERRED_MTU));
145 TEST_ASSERT(chan->peer_mtu == 0);
146
147 ble_hs_unlock();
148 }
149
TEST_CASE(ble_hs_conn_test_undirect_connectable_success)150 TEST_CASE(ble_hs_conn_test_undirect_connectable_success)
151 {
152 struct ble_hs_adv_fields adv_fields;
153 struct hci_le_conn_complete evt;
154 struct ble_gap_adv_params adv_params;
155 struct ble_l2cap_chan *chan;
156 struct ble_hs_conn *conn;
157 ble_addr_t addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 }};
158 int rc;
159
160 ble_hs_test_util_init();
161
162 /* Ensure no current or pending connections. */
163 TEST_ASSERT(!ble_gap_master_in_progress());
164 TEST_ASSERT(!ble_gap_adv_active());
165 TEST_ASSERT(!ble_hs_conn_test_util_any());
166
167 /* Initiate advertising. */
168 memset(&adv_fields, 0, sizeof adv_fields);
169 adv_fields.tx_pwr_lvl_is_present = 1;
170 rc = ble_hs_test_util_adv_set_fields(&adv_fields, 0, 0);
171 TEST_ASSERT_FATAL(rc == 0);
172
173 adv_params = ble_hs_test_util_adv_params;
174 adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
175 rc = ble_hs_test_util_adv_start(BLE_OWN_ADDR_PUBLIC,
176 &addr, &adv_params,
177 BLE_HS_FOREVER,
178 NULL, NULL, 0, 0);
179 TEST_ASSERT(rc == 0);
180
181 TEST_ASSERT(!ble_gap_master_in_progress());
182 TEST_ASSERT(ble_gap_adv_active());
183
184 /* ble_gap_rx_conn_complete() will send extra HCI command, need phony ack */
185 ble_hs_test_util_hci_ack_set(ble_hs_hci_util_opcode_join(BLE_HCI_OGF_LE,
186 BLE_HCI_OCF_LE_RD_REM_FEAT), 0);
187
188 /* Receive successful connection complete event. */
189 memset(&evt, 0, sizeof evt);
190 evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
191 evt.status = BLE_ERR_SUCCESS;
192 evt.connection_handle = 2;
193 evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE;
194 memcpy(evt.peer_addr, addr.val, 6);
195 rc = ble_gap_rx_conn_complete(&evt, 0);
196 TEST_ASSERT(rc == 0);
197 TEST_ASSERT(!ble_gap_master_in_progress());
198 TEST_ASSERT(!ble_gap_adv_active());
199
200 ble_hs_lock();
201
202 conn = ble_hs_conn_first();
203 TEST_ASSERT_FATAL(conn != NULL);
204 TEST_ASSERT(conn->bhc_handle == 2);
205 TEST_ASSERT(memcmp(conn->bhc_peer_addr.val, addr.val, 6) == 0);
206
207 chan = ble_hs_conn_chan_find_by_scid(conn, BLE_L2CAP_CID_ATT);
208 TEST_ASSERT_FATAL(chan != NULL);
209 TEST_ASSERT(chan->my_mtu == MYNEWT_VAL(BLE_ATT_PREFERRED_MTU));
210 TEST_ASSERT(chan->peer_mtu == 0);
211
212 ble_hs_unlock();
213 }
214
TEST_SUITE(conn_suite)215 TEST_SUITE(conn_suite)
216 {
217 tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
218
219 ble_hs_conn_test_direct_connect_success();
220 ble_hs_conn_test_direct_connectable_success();
221 ble_hs_conn_test_undirect_connectable_success();
222 }
223
224 int
ble_hs_conn_test_all(void)225 ble_hs_conn_test_all(void)
226 {
227 conn_suite();
228
229 return tu_any_failed;
230 }
231