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/strings/stringprintf.h>
20 #include <base/test/bind_test_util.h>
21 #include <bluetooth/log.h>
22 #include <com_android_bluetooth_flags.h>
23 #include <flag_macros.h>
24 #include <gmock/gmock.h>
25 #include <gtest/gtest.h>
26 #include <sys/socket.h>
27
28 #include "bta/dm/bta_dm_device_search.h"
29 #include "bta/dm/bta_dm_device_search_int.h"
30 #include "bta/dm/bta_dm_disc.h"
31 #include "bta/dm/bta_dm_disc_int.h"
32 #include "bta/test/bta_test_fixtures.h"
33 #include "bta_api_data_types.h"
34 #include "stack/btm/neighbor_inquiry.h"
35 #include "stack/include/gatt_api.h"
36 #include "test/common/main_handler.h"
37 #include "types/bt_transport.h"
38
39 #define TEST_BT com::android::bluetooth::flags
40
41 using namespace bluetooth;
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,
54 tBT_TRANSPORT transport);
55 tBTA_DM_SEARCH_CB& bta_dm_disc_search_cb();
56 void bta_dm_discover_next_device();
57 void bta_dm_sdp_find_services(tBTA_DM_SDP_STATE* state);
58 void bta_dm_inq_cmpl();
59 void bta_dm_inq_cmpl_cb(void* p_result);
60 void bta_dm_observe_cmpl_cb(void* p_result);
61 void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir,
62 uint16_t eir_len);
63 void bta_dm_opportunistic_observe_results_cb(tBTM_INQ_RESULTS* p_inq,
64 const uint8_t* p_eir,
65 uint16_t eir_len);
66 void bta_dm_queue_search(tBTA_DM_API_SEARCH& search);
67 void bta_dm_start_scan(uint8_t duration_sec, bool low_latency_scan = false);
68 } // namespace testing
69 } // namespace legacy
70 } // namespace bluetooth
71
72 class BtaInitializedTest : public BtaWithContextTest {
73 protected:
SetUp()74 void SetUp() override {
75 BtaWithContextTest::SetUp();
76 BTA_dm_init();
77 }
78
TearDown()79 void TearDown() override { BtaWithContextTest::TearDown(); }
80 };
81
TEST_F(BtaInitializedTest,nop)82 TEST_F(BtaInitializedTest, nop) {}
83
TEST_F(BtaInitializedTest,DumpsysBtaDmDisc)84 TEST_F(BtaInitializedTest, DumpsysBtaDmDisc) {
85 std::FILE* file = std::tmpfile();
86 DumpsysBtaDmDisc(fileno(file));
87 }
88
TEST_F(BtaInitializedTest,bta_dm_ble_csis_observe)89 TEST_F(BtaInitializedTest, bta_dm_ble_csis_observe) {
90 bta_dm_ble_csis_observe(true, [](tBTA_DM_SEARCH_EVT, tBTA_DM_SEARCH*) {});
91 };
92
TEST_F(BtaInitializedTest,bta_dm_ble_csis_observe__false)93 TEST_F(BtaInitializedTest, bta_dm_ble_csis_observe__false) {
94 bta_dm_ble_csis_observe(false, [](tBTA_DM_SEARCH_EVT, tBTA_DM_SEARCH*) {});
95 };
96
TEST_F(BtaInitializedTest,bta_dm_ble_scan)97 TEST_F(BtaInitializedTest, bta_dm_ble_scan) {
98 // bool start, uint8_t duration_sec, bool low_latency_scan
99 constexpr bool kStartLeScan = true;
100 constexpr bool kStopLeScan = false;
101 const uint8_t duration_in_seconds = 5;
102 constexpr bool kLowLatencyScan = true;
103 constexpr bool kHighLatencyScan = false;
104
105 bta_dm_ble_scan(kStartLeScan, duration_in_seconds, kLowLatencyScan);
106 bta_dm_ble_scan(kStopLeScan, duration_in_seconds, kLowLatencyScan);
107
108 bta_dm_ble_scan(kStartLeScan, duration_in_seconds, kHighLatencyScan);
109 bta_dm_ble_scan(kStopLeScan, duration_in_seconds, kHighLatencyScan);
110 }
111
TEST_F(BtaInitializedTest,bta_dm_disc_discover_next_device)112 TEST_F(BtaInitializedTest, bta_dm_disc_discover_next_device) {
113 bta_dm_disc_discover_next_device();
114 }
115
TEST_F(BtaInitializedTest,bta_dm_disc_remove_device)116 TEST_F(BtaInitializedTest, bta_dm_disc_remove_device) {
117 bta_dm_disc_remove_device(kRawAddress);
118 }
119
TEST_F(BtaInitializedTest,bta_dm_discover_next_device)120 TEST_F(BtaInitializedTest, bta_dm_discover_next_device) {
121 bluetooth::legacy::testing::bta_dm_discover_next_device();
122 }
123
TEST_F(BtaInitializedTest,bta_dm_sdp_find_services)124 TEST_F(BtaInitializedTest, bta_dm_sdp_find_services) {
125 std::unique_ptr<tBTA_DM_SDP_STATE> state =
126 std::make_unique<tBTA_DM_SDP_STATE>(tBTA_DM_SDP_STATE{
127 .bd_addr = kRawAddress,
128 .services_to_search = BTA_ALL_SERVICE_MASK,
129 .services_found = 0,
130 .service_index = 0,
131 });
132 bluetooth::legacy::testing::bta_dm_sdp_find_services(state.get());
133 }
134
TEST_F(BtaInitializedTest,bta_dm_inq_cmpl)135 TEST_F(BtaInitializedTest, bta_dm_inq_cmpl) {
136 bluetooth::legacy::testing::bta_dm_inq_cmpl();
137 }
138
TEST_F(BtaInitializedTest,bta_dm_inq_cmpl_cb)139 TEST_F(BtaInitializedTest, bta_dm_inq_cmpl_cb) {
140 tBTM_INQUIRY_CMPL complete;
141 bluetooth::legacy::testing::bta_dm_inq_cmpl_cb(&complete);
142 }
143
TEST_F(BtaInitializedTest,bta_dm_observe_cmpl_cb)144 TEST_F(BtaInitializedTest, bta_dm_observe_cmpl_cb) {
145 tBTM_INQUIRY_CMPL complete;
146 bluetooth::legacy::testing::bta_dm_observe_cmpl_cb(&complete);
147 }
TEST_F(BtaInitializedTest,bta_dm_observe_results_cb)148 TEST_F(BtaInitializedTest, bta_dm_observe_results_cb) {
149 tBTM_INQ_RESULTS result;
150 const uint8_t p_eir[] = {0x0, 0x1, 0x2, 0x3};
151 uint16_t eir_len = sizeof(p_eir);
152 bluetooth::legacy::testing::bta_dm_observe_results_cb(&result, p_eir,
153 eir_len);
154 }
155
TEST_F(BtaInitializedTest,bta_dm_opportunistic_observe_results_cb)156 TEST_F(BtaInitializedTest, bta_dm_opportunistic_observe_results_cb) {
157 tBTM_INQ_RESULTS result;
158 const uint8_t p_eir[] = {0x0, 0x1, 0x2, 0x3};
159 uint16_t eir_len = sizeof(p_eir);
160 bluetooth::legacy::testing::bta_dm_opportunistic_observe_results_cb(
161 &result, p_eir, eir_len);
162 }
163
TEST_F(BtaInitializedTest,bta_dm_queue_search)164 TEST_F(BtaInitializedTest, bta_dm_queue_search) {
165 tBTA_DM_API_SEARCH search{};
166 bluetooth::legacy::testing::bta_dm_queue_search(search);
167
168 // Release the queued search
169 bta_dm_disc_stop();
170 }
171
TEST_F(BtaInitializedTest,bta_dm_read_remote_device_name)172 TEST_F(BtaInitializedTest, bta_dm_read_remote_device_name) {
173 bluetooth::legacy::testing::bta_dm_read_remote_device_name(
174 kRawAddress, BT_TRANSPORT_BR_EDR);
175 }
176
TEST_F(BtaInitializedTest,bta_dm_start_scan)177 TEST_F(BtaInitializedTest, bta_dm_start_scan) {
178 constexpr bool kLowLatencyScan = true;
179 constexpr bool kHighLatencyScan = false;
180 const uint8_t duration_sec = 5;
181 bluetooth::legacy::testing::bta_dm_start_scan(duration_sec, kLowLatencyScan);
182 bluetooth::legacy::testing::bta_dm_start_scan(duration_sec, kHighLatencyScan);
183 }
184
TEST_F(BtaInitializedTest,bta_dm_disc_start_device_discovery)185 TEST_F(BtaInitializedTest, bta_dm_disc_start_device_discovery) {
186 bta_dm_disc_start_device_discovery(
187 [](tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data) {});
188 }
189
TEST_F(BtaInitializedTest,bta_dm_disc_stop_device_discovery)190 TEST_F(BtaInitializedTest, bta_dm_disc_stop_device_discovery) {
191 bta_dm_disc_stop_device_discovery();
192 }
193
TEST_F(BtaInitializedTest,bta_dm_disc_start_service_discovery__BT_TRANSPORT_AUTO)194 TEST_F(BtaInitializedTest,
195 bta_dm_disc_start_service_discovery__BT_TRANSPORT_AUTO) {
196 bta_dm_disc_start_service_discovery(
197 {nullptr, nullptr, nullptr,
198 [](RawAddress, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {}},
199 kRawAddress, BT_TRANSPORT_AUTO);
200 }
201
202 // must be global, as capturing lambda can't be treated as function
203 int service_cb_call_cnt = 0;
204
TEST_F_WITH_FLAGS(BtaInitializedTest,bta_dm_disc_start_service_discovery__BT_TRANSPORT_BR_EDR,REQUIRES_FLAGS_ENABLED (ACONFIG_FLAG (TEST_BT,separate_service_and_device_discovery)))205 TEST_F_WITH_FLAGS(BtaInitializedTest,
206 bta_dm_disc_start_service_discovery__BT_TRANSPORT_BR_EDR,
207 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(
208 TEST_BT, separate_service_and_device_discovery))) {
209 bta_dm_disc_start(true);
210 int sdp_call_cnt = 0;
211 base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer =
212 base::BindLambdaForTesting([&](tBTA_DM_SDP_STATE* sdp_state) {
213 sdp_call_cnt++;
214 bta_dm_sdp_finished(sdp_state->bd_addr, BTA_SUCCESS, {}, {});
215 });
216
217 bta_dm_disc_override_sdp_performer_for_testing(sdp_performer);
218 service_cb_call_cnt = 0;
219
220 bta_dm_disc_start_service_discovery(
221 {nullptr, nullptr, nullptr,
222 [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {
223 service_cb_call_cnt++;
224 }},
225 kRawAddress, BT_TRANSPORT_BR_EDR);
226
227 EXPECT_EQ(sdp_call_cnt, 1);
228 EXPECT_EQ(service_cb_call_cnt, 1);
229
230 bta_dm_disc_override_sdp_performer_for_testing({});
231 }
232
233 // must be global, as capturing lambda can't be treated as function
234 int gatt_service_cb_call_cnt = 0;
235
TEST_F_WITH_FLAGS(BtaInitializedTest,bta_dm_disc_start_service_discovery__BT_TRANSPORT_LE,REQUIRES_FLAGS_ENABLED (ACONFIG_FLAG (TEST_BT,separate_service_and_device_discovery)))236 TEST_F_WITH_FLAGS(BtaInitializedTest,
237 bta_dm_disc_start_service_discovery__BT_TRANSPORT_LE,
238 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(
239 TEST_BT, separate_service_and_device_discovery))) {
240 bta_dm_disc_start(true);
241 int gatt_call_cnt = 0;
242 base::RepeatingCallback<void(const RawAddress&)> gatt_performer =
243 base::BindLambdaForTesting([&](const RawAddress& bd_addr) {
244 gatt_call_cnt++;
245 bta_dm_gatt_finished(bd_addr, BTA_SUCCESS);
246 });
247 bta_dm_disc_override_gatt_performer_for_testing(gatt_performer);
248 gatt_service_cb_call_cnt = 0;
249
250 bta_dm_disc_start_service_discovery(
251 {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) {
252 gatt_service_cb_call_cnt++;
253 },
254 nullptr, nullptr, nullptr},
255 kRawAddress, BT_TRANSPORT_LE);
256
257 EXPECT_EQ(gatt_call_cnt, 1);
258 EXPECT_EQ(gatt_service_cb_call_cnt, 1);
259
260 bta_dm_disc_override_gatt_performer_for_testing({});
261 }
262
263 // must be global, as capturing lambda can't be treated as function
264 int service_cb_both_call_cnt = 0;
265 int gatt_service_cb_both_call_cnt = 0;
266
267 /* This test exercises the usual service discovery flow when bonding to
268 * dual-mode, CTKD capable device on LE transport.
269 */
TEST_F_WITH_FLAGS(BtaInitializedTest,bta_dm_disc_both_transports_flag_disabled,REQUIRES_FLAGS_ENABLED (ACONFIG_FLAG (TEST_BT,separate_service_and_device_discovery)),REQUIRES_FLAGS_DISABLED (ACONFIG_FLAG (TEST_BT,bta_dm_discover_both)))270 TEST_F_WITH_FLAGS(
271 BtaInitializedTest, bta_dm_disc_both_transports_flag_disabled,
272 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT,
273 separate_service_and_device_discovery)),
274 REQUIRES_FLAGS_DISABLED(ACONFIG_FLAG(TEST_BT, bta_dm_discover_both))) {
275 bta_dm_disc_start(true);
276
277 std::promise<void> gatt_triggered;
278 int gatt_call_cnt = 0;
279 base::RepeatingCallback<void(const RawAddress&)> gatt_performer =
280 base::BindLambdaForTesting([&](const RawAddress& bd_addr) {
281 gatt_call_cnt++;
282 gatt_triggered.set_value();
283 });
284 bta_dm_disc_override_gatt_performer_for_testing(gatt_performer);
285
286 int sdp_call_cnt = 0;
287 base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer =
288 base::BindLambdaForTesting(
289 [&](tBTA_DM_SDP_STATE* sdp_state) { sdp_call_cnt++; });
290 bta_dm_disc_override_sdp_performer_for_testing(sdp_performer);
291
292 gatt_service_cb_both_call_cnt = 0;
293 service_cb_both_call_cnt = 0;
294
295 bta_dm_disc_start_service_discovery(
296 {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) {}, nullptr,
297 nullptr,
298 [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {
299 service_cb_both_call_cnt++;
300 }},
301 kRawAddress, BT_TRANSPORT_BR_EDR);
302 EXPECT_EQ(sdp_call_cnt, 1);
303
304 bta_dm_disc_start_service_discovery(
305 {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) {
306 gatt_service_cb_both_call_cnt++;
307 },
308 nullptr, nullptr,
309 [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {
310 }},
311 kRawAddress, BT_TRANSPORT_LE);
312
313 // GATT discovery is queued, until SDP finishes
314 EXPECT_EQ(gatt_call_cnt, 0);
315
316 bta_dm_sdp_finished(kRawAddress, BTA_SUCCESS, {}, {});
317 EXPECT_EQ(service_cb_both_call_cnt, 1);
318
319 // SDP finished, wait until GATT is triggered.
320 EXPECT_EQ(std::future_status::ready,
321 gatt_triggered.get_future().wait_for(std::chrono::seconds(1)));
322 bta_dm_gatt_finished(kRawAddress, BTA_SUCCESS);
323 EXPECT_EQ(gatt_service_cb_both_call_cnt, 1);
324
325 bta_dm_disc_override_sdp_performer_for_testing({});
326 bta_dm_disc_override_gatt_performer_for_testing({});
327 }
328
329 /* This test exercises the usual service discovery flow when bonding to
330 * dual-mode, CTKD capable device on LE transport.
331 */
TEST_F_WITH_FLAGS(BtaInitializedTest,bta_dm_disc_both_transports_flag_enabled,REQUIRES_FLAGS_ENABLED (ACONFIG_FLAG (TEST_BT,bta_dm_discover_both)))332 TEST_F_WITH_FLAGS(BtaInitializedTest, bta_dm_disc_both_transports_flag_enabled,
333 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT,
334 bta_dm_discover_both))) {
335 bta_dm_disc_start(true);
336
337 int gatt_call_cnt = 0;
338 base::RepeatingCallback<void(const RawAddress&)> gatt_performer =
339 base::BindLambdaForTesting(
340 [&](const RawAddress& bd_addr) { gatt_call_cnt++; });
341 bta_dm_disc_override_gatt_performer_for_testing(gatt_performer);
342
343 int sdp_call_cnt = 0;
344 base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer =
345 base::BindLambdaForTesting(
346 [&](tBTA_DM_SDP_STATE* sdp_state) { sdp_call_cnt++; });
347 bta_dm_disc_override_sdp_performer_for_testing(sdp_performer);
348
349 gatt_service_cb_both_call_cnt = 0;
350 service_cb_both_call_cnt = 0;
351
352 bta_dm_disc_start_service_discovery(
353 {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) {
354 gatt_service_cb_both_call_cnt++;
355 },
356 nullptr, nullptr,
357 [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {
358 service_cb_both_call_cnt++;
359 }},
360 kRawAddress, BT_TRANSPORT_BR_EDR);
361 EXPECT_EQ(sdp_call_cnt, 1);
362
363 bta_dm_disc_start_service_discovery(
364 {[](RawAddress, BD_NAME, std::vector<bluetooth::Uuid>&, bool) {
365 gatt_service_cb_both_call_cnt++;
366 },
367 nullptr, nullptr,
368 [](RawAddress addr, const std::vector<bluetooth::Uuid>&, tBTA_STATUS) {
369 service_cb_both_call_cnt++;
370 }},
371 kRawAddress, BT_TRANSPORT_LE);
372
373 // GATT discovery on same device is immediately started
374 EXPECT_EQ(gatt_call_cnt, 1);
375
376 // GATT finished first
377 bta_dm_gatt_finished(kRawAddress, BTA_SUCCESS);
378 EXPECT_EQ(gatt_service_cb_both_call_cnt, 1);
379
380 // SDP finishes too
381 bta_dm_sdp_finished(kRawAddress, BTA_SUCCESS, {}, {});
382 EXPECT_EQ(service_cb_both_call_cnt, 1);
383
384 bta_dm_disc_override_sdp_performer_for_testing({});
385 bta_dm_disc_override_gatt_performer_for_testing({});
386 }
387
TEST_F(BtaInitializedTest,init_bta_dm_search_cb__conn_id)388 TEST_F(BtaInitializedTest, init_bta_dm_search_cb__conn_id) {
389 // Set the global search block target field to some non-reset value
390 tBTA_DM_SEARCH_CB& search_cb =
391 bluetooth::legacy::testing::bta_dm_disc_search_cb();
392 search_cb.name_discover_done = true;
393
394 bluetooth::legacy::testing::bta_dm_disc_init_search_cb(search_cb);
395
396 // Verify global search block field reset value is correct
397 ASSERT_EQ(search_cb.name_discover_done, false);
398 }
399