1 /*
2 * Copyright 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "bt_bta_dm_test"
18
19 #include <base/test/bind_test_util.h>
20 #include <bluetooth/log.h>
21 #include <com_android_bluetooth_flags.h>
22 #include <flag_macros.h>
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 #include <sys/socket.h>
26
27 #include "bta/dm/bta_dm_device_search.h"
28 #include "bta/dm/bta_dm_device_search_int.h"
29 #include "bta/dm/bta_dm_disc.h"
30 #include "bta/dm/bta_dm_disc_int.h"
31 #include "bta/test/bta_test_fixtures.h"
32 #include "bta_api_data_types.h"
33 #include "stack/btm/neighbor_inquiry.h"
34 #include "types/bt_transport.h"
35
36 #define TEST_BT com::android::bluetooth::flags
37
38 using namespace bluetooth;
39
40 using ::testing::_;
41 using ::testing::Return;
42
43 namespace {
44 const RawAddress kRawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
45 }
46
47 // Test hooks
48 namespace bluetooth {
49 namespace legacy {
50 namespace testing {
51
52 void bta_dm_disc_init_search_cb(tBTA_DM_SEARCH_CB& bta_dm_search_cb);
53 bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, tBT_TRANSPORT transport);
54 tBTA_DM_SEARCH_CB& bta_dm_disc_search_cb();
55 void bta_dm_discover_next_device();
56 void bta_dm_sdp_find_services(tBTA_DM_SDP_STATE* state);
57 void bta_dm_inq_cmpl();
58 void bta_dm_inq_cmpl_cb(void* p_result);
59 void bta_dm_observe_cmpl_cb(void* p_result);
60 void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir, uint16_t eir_len);
61 void bta_dm_opportunistic_observe_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir,
62 uint16_t eir_len);
63 void bta_dm_queue_search(tBTA_DM_API_SEARCH& search);
64 void bta_dm_start_scan(uint8_t duration_sec);
65 } // namespace testing
66 } // namespace legacy
67 } // namespace bluetooth
68
69 class BtaInitializedTest : public BtaWithContextTest {
70 protected:
SetUp()71 void SetUp() override {
72 BtaWithContextTest::SetUp();
73 BTA_dm_init();
74 }
75
TearDown()76 void TearDown() override { BtaWithContextTest::TearDown(); }
77 };
78
TEST_F(BtaInitializedTest,nop)79 TEST_F(BtaInitializedTest, nop) {}
80
TEST_F(BtaInitializedTest,DumpsysBtaDmDisc)81 TEST_F(BtaInitializedTest, DumpsysBtaDmDisc) {
82 std::FILE* file = std::tmpfile();
83 DumpsysBtaDmDisc(fileno(file));
84 }
85
TEST_F(BtaInitializedTest,bta_dm_ble_csis_observe)86 TEST_F(BtaInitializedTest, bta_dm_ble_csis_observe) {
87 bta_dm_ble_csis_observe(true, [](tBTA_DM_SEARCH_EVT, tBTA_DM_SEARCH*) {});
88 }
89
TEST_F(BtaInitializedTest,bta_dm_ble_csis_observe__false)90 TEST_F(BtaInitializedTest, bta_dm_ble_csis_observe__false) {
91 bta_dm_ble_csis_observe(false, [](tBTA_DM_SEARCH_EVT, tBTA_DM_SEARCH*) {});
92 }
93
TEST_F(BtaInitializedTest,bta_dm_ble_scan)94 TEST_F(BtaInitializedTest, bta_dm_ble_scan) {
95 // bool start, uint8_t duration_sec
96 constexpr bool kStartLeScan = true;
97 constexpr bool kStopLeScan = false;
98 const uint8_t duration_in_seconds = 5;
99
100 bta_dm_ble_scan(kStartLeScan, duration_in_seconds);
101 bta_dm_ble_scan(kStopLeScan, duration_in_seconds);
102 }
103
TEST_F(BtaInitializedTest,bta_dm_disc_discover_next_device)104 TEST_F(BtaInitializedTest, bta_dm_disc_discover_next_device) { bta_dm_disc_discover_next_device(); }
105
TEST_F(BtaInitializedTest,bta_dm_disc_remove_device)106 TEST_F(BtaInitializedTest, bta_dm_disc_remove_device) { bta_dm_disc_remove_device(kRawAddress); }
107
TEST_F(BtaInitializedTest,bta_dm_discover_next_device)108 TEST_F(BtaInitializedTest, bta_dm_discover_next_device) {
109 bluetooth::legacy::testing::bta_dm_discover_next_device();
110 }
111
TEST_F(BtaInitializedTest,bta_dm_sdp_find_services)112 TEST_F(BtaInitializedTest, bta_dm_sdp_find_services) {
113 std::unique_ptr<tBTA_DM_SDP_STATE> state = std::make_unique<tBTA_DM_SDP_STATE>(tBTA_DM_SDP_STATE{
114 .bd_addr = kRawAddress,
115 .services_to_search = BTA_ALL_SERVICE_MASK,
116 .services_found = 0,
117 .service_index = 0,
118 });
119 bluetooth::legacy::testing::bta_dm_sdp_find_services(state.get());
120 }
121
TEST_F(BtaInitializedTest,bta_dm_inq_cmpl)122 TEST_F(BtaInitializedTest, bta_dm_inq_cmpl) { bluetooth::legacy::testing::bta_dm_inq_cmpl(); }
123
TEST_F(BtaInitializedTest,bta_dm_inq_cmpl_cb)124 TEST_F(BtaInitializedTest, bta_dm_inq_cmpl_cb) {
125 tBTM_INQUIRY_CMPL complete;
126 bluetooth::legacy::testing::bta_dm_inq_cmpl_cb(&complete);
127 }
128
TEST_F(BtaInitializedTest,bta_dm_observe_cmpl_cb)129 TEST_F(BtaInitializedTest, bta_dm_observe_cmpl_cb) {
130 tBTM_INQUIRY_CMPL complete;
131 bluetooth::legacy::testing::bta_dm_observe_cmpl_cb(&complete);
132 }
TEST_F(BtaInitializedTest,bta_dm_observe_results_cb)133 TEST_F(BtaInitializedTest, bta_dm_observe_results_cb) {
134 tBTM_INQ_RESULTS result;
135 const uint8_t p_eir[] = {0x0, 0x1, 0x2, 0x3};
136 uint16_t eir_len = sizeof(p_eir);
137 bluetooth::legacy::testing::bta_dm_observe_results_cb(&result, p_eir, eir_len);
138 }
139
TEST_F(BtaInitializedTest,bta_dm_opportunistic_observe_results_cb)140 TEST_F(BtaInitializedTest, bta_dm_opportunistic_observe_results_cb) {
141 tBTM_INQ_RESULTS result;
142 const uint8_t p_eir[] = {0x0, 0x1, 0x2, 0x3};
143 uint16_t eir_len = sizeof(p_eir);
144 bluetooth::legacy::testing::bta_dm_opportunistic_observe_results_cb(&result, p_eir, eir_len);
145 }
146
TEST_F(BtaInitializedTest,bta_dm_queue_search)147 TEST_F(BtaInitializedTest, bta_dm_queue_search) {
148 tBTA_DM_API_SEARCH search{};
149 bluetooth::legacy::testing::bta_dm_queue_search(search);
150
151 // Release the queued search
152 bta_dm_disc_stop();
153 }
154
TEST_F(BtaInitializedTest,bta_dm_read_remote_device_name)155 TEST_F(BtaInitializedTest, bta_dm_read_remote_device_name) {
156 EXPECT_CALL(mock_stack_rnr_interface_, BTM_ReadRemoteDeviceName(_, _, _))
157 .WillOnce(Return(tBTM_STATUS::BTM_CMD_STARTED));
158
159 bluetooth::legacy::testing::bta_dm_read_remote_device_name(kRawAddress, BT_TRANSPORT_BR_EDR);
160 }
161
TEST_F(BtaInitializedTest,bta_dm_start_scan)162 TEST_F(BtaInitializedTest, bta_dm_start_scan) {
163 const uint8_t duration_sec = 5;
164 bluetooth::legacy::testing::bta_dm_start_scan(duration_sec);
165 bluetooth::legacy::testing::bta_dm_start_scan(duration_sec);
166 }
167
TEST_F(BtaInitializedTest,bta_dm_disc_start_device_discovery)168 TEST_F(BtaInitializedTest, bta_dm_disc_start_device_discovery) {
169 bta_dm_disc_start_device_discovery(
170 [](tBTA_DM_SEARCH_EVT /*event*/, tBTA_DM_SEARCH* /*p_data*/) {});
171 }
172
TEST_F(BtaInitializedTest,bta_dm_disc_stop_device_discovery)173 TEST_F(BtaInitializedTest, bta_dm_disc_stop_device_discovery) {
174 bta_dm_disc_stop_device_discovery();
175 }
176
TEST_F(BtaInitializedTest,bta_dm_disc_start_service_discovery__BT_TRANSPORT_AUTO)177 TEST_F(BtaInitializedTest, bta_dm_disc_start_service_discovery__BT_TRANSPORT_AUTO) {
178 bta_dm_disc_start_service_discovery(
179 {nullptr, nullptr,
180 [](RawAddress, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {}},
181 kRawAddress, BT_TRANSPORT_AUTO);
182 }
183
184 // must be global, as capturing lambda can't be treated as function
185 int service_cb_call_cnt = 0;
186
TEST_F(BtaInitializedTest,bta_dm_disc_start_service_discovery__BT_TRANSPORT_BR_EDR)187 TEST_F(BtaInitializedTest, bta_dm_disc_start_service_discovery__BT_TRANSPORT_BR_EDR) {
188 bta_dm_disc_start(true);
189 int sdp_call_cnt = 0;
190 base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer =
191 base::BindLambdaForTesting([&](tBTA_DM_SDP_STATE* sdp_state) {
192 sdp_call_cnt++;
193 bta_dm_sdp_finished(sdp_state->bd_addr, BTA_SUCCESS, {}, {});
194 });
195
196 bta_dm_disc_override_sdp_performer_for_testing(sdp_performer);
197 service_cb_call_cnt = 0;
198
199 bta_dm_disc_start_service_discovery({nullptr, nullptr,
200 [](RawAddress /*addr*/, const std::vector<bluetooth::Uuid>&,
201 tBTA_STATUS) { service_cb_call_cnt++; }},
202 kRawAddress, BT_TRANSPORT_BR_EDR);
203
204 EXPECT_EQ(sdp_call_cnt, 1);
205 EXPECT_EQ(service_cb_call_cnt, 1);
206
207 bta_dm_disc_override_sdp_performer_for_testing({});
208 }
209
210 // must be global, as capturing lambda can't be treated as function
211 int gatt_service_cb_call_cnt = 0;
212
TEST_F(BtaInitializedTest,bta_dm_disc_start_service_discovery__BT_TRANSPORT_LE)213 TEST_F(BtaInitializedTest, bta_dm_disc_start_service_discovery__BT_TRANSPORT_LE) {
214 bta_dm_disc_start(true);
215 int gatt_call_cnt = 0;
216 base::RepeatingCallback<void(const RawAddress&)> gatt_performer =
217 base::BindLambdaForTesting([&](const RawAddress& bd_addr) {
218 gatt_call_cnt++;
219 bta_dm_gatt_finished(bd_addr, BTA_SUCCESS);
220 });
221 bta_dm_disc_override_gatt_performer_for_testing(gatt_performer);
222 gatt_service_cb_call_cnt = 0;
223
224 bta_dm_disc_start_service_discovery({[](RawAddress, std::vector<bluetooth::Uuid>&,
225 bool) { gatt_service_cb_call_cnt++; },
226 nullptr, nullptr},
227 kRawAddress, BT_TRANSPORT_LE);
228
229 EXPECT_EQ(gatt_call_cnt, 1);
230 EXPECT_EQ(gatt_service_cb_call_cnt, 1);
231
232 bta_dm_disc_override_gatt_performer_for_testing({});
233 }
234
235 // must be global, as capturing lambda can't be treated as function
236 int service_cb_both_call_cnt = 0;
237 int gatt_service_cb_both_call_cnt = 0;
238
239 /* This test exercises the usual service discovery flow when bonding to
240 * dual-mode, CTKD capable device on LE transport.
241 */
TEST_F_WITH_FLAGS(BtaInitializedTest,bta_dm_disc_both_transports_flag_disabled,REQUIRES_FLAGS_DISABLED (ACONFIG_FLAG (TEST_BT,bta_dm_discover_both)))242 TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_both_transports_flag_disabled,
243 REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(TEST_BT, bta_dm_discover_both))) {
244 bta_dm_disc_start(true);
245
246 std::promise<void> gatt_triggered;
247 int gatt_call_cnt = 0;
248 base::RepeatingCallback<void(const RawAddress&)> gatt_performer =
249 base::BindLambdaForTesting([&](const RawAddress& /*bd_addr*/) {
250 gatt_call_cnt++;
251 gatt_triggered.set_value();
252 });
253 bta_dm_disc_override_gatt_performer_for_testing(gatt_performer);
254
255 int sdp_call_cnt = 0;
256 base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer =
257 base::BindLambdaForTesting([&](tBTA_DM_SDP_STATE* /*sdp_state*/) { sdp_call_cnt++; });
258 bta_dm_disc_override_sdp_performer_for_testing(sdp_performer);
259
260 gatt_service_cb_both_call_cnt = 0;
261 service_cb_both_call_cnt = 0;
262
263 bta_dm_disc_start_service_discovery(
264 {[](RawAddress, std::vector<bluetooth::Uuid>&, bool) {}, nullptr,
265 [](RawAddress /*addr*/, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {
266 service_cb_both_call_cnt++;
267 }},
268 kRawAddress, BT_TRANSPORT_BR_EDR);
269 EXPECT_EQ(sdp_call_cnt, 1);
270
271 bta_dm_disc_start_service_discovery(
272 {[](RawAddress, std::vector<bluetooth::Uuid>&, bool) { gatt_service_cb_both_call_cnt++; },
273 nullptr, [](RawAddress /*addr*/, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {}},
274 kRawAddress, BT_TRANSPORT_LE);
275
276 // GATT discovery is queued, until SDP finishes
277 EXPECT_EQ(gatt_call_cnt, 0);
278
279 bta_dm_sdp_finished(kRawAddress, BTA_SUCCESS, {}, {});
280 EXPECT_EQ(service_cb_both_call_cnt, 1);
281
282 // SDP finished, wait until GATT is triggered.
283 EXPECT_EQ(std::future_status::ready,
284 gatt_triggered.get_future().wait_for(std::chrono::seconds(1)));
285 bta_dm_gatt_finished(kRawAddress, BTA_SUCCESS);
286 EXPECT_EQ(gatt_service_cb_both_call_cnt, 1);
287
288 bta_dm_disc_override_sdp_performer_for_testing({});
289 bta_dm_disc_override_gatt_performer_for_testing({});
290 }
291
292 /* This test exercises the usual service discovery flow when bonding to
293 * dual-mode, CTKD capable device on LE transport.
294 */
TEST_F_WITH_FLAGS(BtaInitializedTest,bta_dm_disc_both_transports_flag_enabled,REQUIRES_FLAGS_ENABLED (ACONFIG_FLAG (TEST_BT,bta_dm_discover_both)))295 TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_both_transports_flag_enabled,
296 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, bta_dm_discover_both))) {
297 bta_dm_disc_start(true);
298
299 int gatt_call_cnt = 0;
300 base::RepeatingCallback<void(const RawAddress&)> gatt_performer =
301 base::BindLambdaForTesting([&](const RawAddress& /*bd_addr*/) { gatt_call_cnt++; });
302 bta_dm_disc_override_gatt_performer_for_testing(gatt_performer);
303
304 int sdp_call_cnt = 0;
305 base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer =
306 base::BindLambdaForTesting([&](tBTA_DM_SDP_STATE* /*sdp_state*/) { sdp_call_cnt++; });
307 bta_dm_disc_override_sdp_performer_for_testing(sdp_performer);
308
309 gatt_service_cb_both_call_cnt = 0;
310 service_cb_both_call_cnt = 0;
311
312 bta_dm_disc_start_service_discovery(
313 {[](RawAddress, std::vector<bluetooth::Uuid>&, bool) { gatt_service_cb_both_call_cnt++; },
314 nullptr,
315 [](RawAddress /*addr*/, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {
316 service_cb_both_call_cnt++;
317 }},
318 kRawAddress, BT_TRANSPORT_BR_EDR);
319 EXPECT_EQ(sdp_call_cnt, 1);
320
321 bta_dm_disc_start_service_discovery(
322 {[](RawAddress, std::vector<bluetooth::Uuid>&, bool) { gatt_service_cb_both_call_cnt++; },
323 nullptr,
324 [](RawAddress /*addr*/, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {
325 service_cb_both_call_cnt++;
326 }},
327 kRawAddress, BT_TRANSPORT_LE);
328
329 // GATT discovery on same device is immediately started
330 EXPECT_EQ(gatt_call_cnt, 1);
331
332 // GATT finished first
333 bta_dm_gatt_finished(kRawAddress, BTA_SUCCESS);
334 EXPECT_EQ(gatt_service_cb_both_call_cnt, 1);
335
336 // SDP finishes too
337 bta_dm_sdp_finished(kRawAddress, BTA_SUCCESS, {}, {});
338 EXPECT_EQ(service_cb_both_call_cnt, 1);
339
340 bta_dm_disc_override_sdp_performer_for_testing({});
341 bta_dm_disc_override_gatt_performer_for_testing({});
342 }
343
TEST_F(BtaInitializedTest,init_bta_dm_search_cb__conn_id)344 TEST_F(BtaInitializedTest, init_bta_dm_search_cb__conn_id) {
345 // Set the global search block target field to some non-reset value
346 tBTA_DM_SEARCH_CB& search_cb = bluetooth::legacy::testing::bta_dm_disc_search_cb();
347 search_cb.name_discover_done = true;
348
349 bluetooth::legacy::testing::bta_dm_disc_init_search_cb(search_cb);
350
351 // Verify global search block field reset value is correct
352 ASSERT_EQ(search_cb.name_discover_done, false);
353 }
354