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"
18
19 #include "bta/dm/bta_dm_disc.h"
20
21 #include <base/functional/bind.h>
22 #include <base/strings/stringprintf.h>
23 #include <bluetooth/log.h>
24 #include <com_android_bluetooth_flags.h>
25
26 #include <cstddef>
27 #include <cstdint>
28 #include <string>
29 #include <variant>
30 #include <vector>
31
32 #include "bta/dm/bta_dm_disc_int.h"
33 #include "bta/dm/bta_dm_disc_legacy.h"
34 #include "bta/include/bta_gatt_api.h"
35 #include "com_android_bluetooth_flags.h"
36 #include "common/circular_buffer.h"
37 #include "common/init_flags.h"
38 #include "common/strings.h"
39 #include "internal_include/bt_target.h"
40 #include "main/shim/dumpsys.h"
41 #include "os/logging/log_adapter.h"
42 #include "osi/include/allocator.h"
43 #include "stack/btm/btm_dev.h"
44 #include "stack/include/bt_name.h"
45 #include "stack/include/bt_uuid16.h"
46 #include "stack/include/btm_client_interface.h"
47 #include "stack/include/btm_log_history.h"
48 #include "stack/include/gap_api.h" // GAP_BleReadPeerPrefConnParams
49 #include "stack/include/hidh_api.h"
50 #include "stack/include/main_thread.h"
51 #include "stack/include/sdp_status.h"
52 #include "types/raw_address.h"
53
54 #ifdef TARGET_FLOSS
55 #include "stack/include/srvc_api.h"
56 #endif
57
58 using bluetooth::Uuid;
59 using namespace bluetooth::legacy::stack::sdp;
60 using namespace bluetooth;
61
62 static void btm_dm_start_gatt_discovery(const RawAddress& bd_addr);
63
64 namespace {
65 constexpr char kBtmLogTag[] = "SDP";
66
67 tBTA_DM_SERVICE_DISCOVERY_CB bta_dm_discovery_cb;
68 base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> default_sdp_performer =
69 base::Bind(bta_dm_sdp_find_services);
70 base::RepeatingCallback<void(const RawAddress&)> default_gatt_performer =
71 base::Bind(btm_dm_start_gatt_discovery);
72 base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> sdp_performer =
73 default_sdp_performer;
74 base::RepeatingCallback<void(const RawAddress&)> gatt_performer =
75 default_gatt_performer;
76
is_same_device(const RawAddress & a,const RawAddress & b)77 static bool is_same_device(const RawAddress& a, const RawAddress& b) {
78 if (a == b) return true;
79
80 auto devA = btm_find_dev(a);
81 if (devA != nullptr && devA == btm_find_dev(b)) {
82 return true;
83 }
84
85 return false;
86 }
87 } // namespace
88
89 static void bta_dm_disc_sm_execute(tBTA_DM_DISC_EVT event,
90 std::unique_ptr<tBTA_DM_MSG> msg);
post_disc_evt(tBTA_DM_DISC_EVT event,std::unique_ptr<tBTA_DM_MSG> msg)91 static void post_disc_evt(tBTA_DM_DISC_EVT event,
92 std::unique_ptr<tBTA_DM_MSG> msg) {
93 if (do_in_main_thread(FROM_HERE, base::BindOnce(&bta_dm_disc_sm_execute,
94 event, std::move(msg))) !=
95 BT_STATUS_SUCCESS) {
96 log::error("post_disc_evt failed");
97 }
98 }
99
100 static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status);
101 static void bta_dm_disable_disc(void);
102 static void bta_dm_gattc_register(void);
103 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
104 static void bta_dm_execute_queued_discovery_request();
105 static void bta_dm_close_gatt_conn();
106
107 namespace {
108
109 struct gatt_interface_t {
110 void (*BTA_GATTC_CancelOpen)(tGATT_IF client_if, const RawAddress& remote_bda,
111 bool is_direct);
112 void (*BTA_GATTC_Refresh)(const RawAddress& remote_bda);
113 void (*BTA_GATTC_GetGattDb)(uint16_t conn_id, uint16_t start_handle,
114 uint16_t end_handle, btgatt_db_element_t** db,
115 int* count);
116 void (*BTA_GATTC_AppRegister)(tBTA_GATTC_CBACK* p_client_cb,
117 BtaAppRegisterCallback cb, bool eatt_support);
118 void (*BTA_GATTC_Close)(uint16_t conn_id);
119 void (*BTA_GATTC_ServiceSearchRequest)(uint16_t conn_id,
120 const bluetooth::Uuid* p_srvc_uuid);
121 void (*BTA_GATTC_Open)(tGATT_IF client_if, const RawAddress& remote_bda,
122 tBTM_BLE_CONN_TYPE connection_type,
123 bool opportunistic);
124 } default_gatt_interface = {
125 .BTA_GATTC_CancelOpen =
__anon788b21910302(tGATT_IF client_if, const RawAddress& remote_bda, bool is_direct) 126 [](tGATT_IF client_if, const RawAddress& remote_bda, bool is_direct) {
127 BTA_GATTC_CancelOpen(client_if, remote_bda, is_direct);
128 },
129 .BTA_GATTC_Refresh =
__anon788b21910402(const RawAddress& remote_bda) 130 [](const RawAddress& remote_bda) { BTA_GATTC_Refresh(remote_bda); },
131 .BTA_GATTC_GetGattDb =
132 [](uint16_t conn_id, uint16_t start_handle, uint16_t end_handle,
__anon788b21910502(uint16_t conn_id, uint16_t start_handle, uint16_t end_handle, btgatt_db_element_t** db, int* count) 133 btgatt_db_element_t** db, int* count) {
134 BTA_GATTC_GetGattDb(conn_id, start_handle, end_handle, db, count);
135 },
136 .BTA_GATTC_AppRegister =
137 [](tBTA_GATTC_CBACK* p_client_cb, BtaAppRegisterCallback cb,
__anon788b21910602(tBTA_GATTC_CBACK* p_client_cb, BtaAppRegisterCallback cb, bool eatt_support) 138 bool eatt_support) {
139 BTA_GATTC_AppRegister(p_client_cb, cb, eatt_support);
140 },
__anon788b21910702(uint16_t conn_id) 141 .BTA_GATTC_Close = [](uint16_t conn_id) { BTA_GATTC_Close(conn_id); },
142 .BTA_GATTC_ServiceSearchRequest =
__anon788b21910802(uint16_t conn_id, const bluetooth::Uuid* p_srvc_uuid) 143 [](uint16_t conn_id, const bluetooth::Uuid* p_srvc_uuid) {
144 if (p_srvc_uuid) {
145 BTA_GATTC_ServiceSearchRequest(conn_id, *p_srvc_uuid);
146 } else {
147 BTA_GATTC_ServiceSearchAllRequest(conn_id);
148 }
149 },
150 .BTA_GATTC_Open =
151 [](tGATT_IF client_if, const RawAddress& remote_bda,
__anon788b21910902(tGATT_IF client_if, const RawAddress& remote_bda, tBTM_BLE_CONN_TYPE connection_type, bool opportunistic) 152 tBTM_BLE_CONN_TYPE connection_type, bool opportunistic) {
153 BTA_GATTC_Open(client_if, remote_bda, connection_type, opportunistic);
154 },
155 };
156
157 gatt_interface_t* gatt_interface = &default_gatt_interface;
158
get_gatt_interface()159 gatt_interface_t& get_gatt_interface() { return *gatt_interface; }
160
161 } // namespace
162
bta_dm_disc_disable_search_and_disc()163 void bta_dm_disc_disable_search_and_disc() {
164 if (com::android::bluetooth::flags::separate_service_and_device_discovery()) {
165 log::info("No one should be calling this when flag is enabled");
166 return;
167 }
168 bta_dm_disc_legacy::bta_dm_disc_disable_search_and_disc();
169 }
170
bta_dm_disc_disable_disc()171 void bta_dm_disc_disable_disc() {
172 if (!com::android::bluetooth::flags::
173 separate_service_and_device_discovery()) {
174 log::info("no-op when flag is disabled");
175 return;
176 }
177 bta_dm_disable_disc();
178 }
179
bta_dm_disc_gatt_cancel_open(const RawAddress & bd_addr)180 void bta_dm_disc_gatt_cancel_open(const RawAddress& bd_addr) {
181 if (!com::android::bluetooth::flags::
182 separate_service_and_device_discovery()) {
183 bta_dm_disc_legacy::bta_dm_disc_gatt_cancel_open(bd_addr);
184 return;
185 }
186 get_gatt_interface().BTA_GATTC_CancelOpen(0, bd_addr, false);
187 }
188
bta_dm_disc_gatt_refresh(const RawAddress & bd_addr)189 void bta_dm_disc_gatt_refresh(const RawAddress& bd_addr) {
190 if (!com::android::bluetooth::flags::
191 separate_service_and_device_discovery()) {
192 bta_dm_disc_legacy::bta_dm_disc_gatt_refresh(bd_addr);
193 return;
194 }
195 get_gatt_interface().BTA_GATTC_Refresh(bd_addr);
196 }
197
bta_dm_disc_remove_device(const RawAddress & bd_addr)198 void bta_dm_disc_remove_device(const RawAddress& bd_addr) {
199 if (!com::android::bluetooth::flags::
200 separate_service_and_device_discovery()) {
201 bta_dm_disc_legacy::bta_dm_disc_remove_device(bd_addr);
202 return;
203 }
204 if (bta_dm_discovery_cb.service_discovery_state == BTA_DM_DISCOVER_ACTIVE &&
205 bta_dm_discovery_cb.peer_bdaddr == bd_addr) {
206 log::info(
207 "Device removed while service discovery was pending, conclude the "
208 "service disvovery");
209 bta_dm_gatt_disc_complete((uint16_t)GATT_INVALID_CONN_ID,
210 (tGATT_STATUS)GATT_ERROR);
211 }
212 }
213
bta_dm_disc_gattc_register()214 void bta_dm_disc_gattc_register() {
215 if (!com::android::bluetooth::flags::
216 separate_service_and_device_discovery()) {
217 bta_dm_disc_legacy::bta_dm_disc_gattc_register();
218 return;
219 }
220 bta_dm_gattc_register();
221 }
222
bta_dm_discovery_set_state(tBTA_DM_SERVICE_DISCOVERY_STATE state)223 static void bta_dm_discovery_set_state(tBTA_DM_SERVICE_DISCOVERY_STATE state) {
224 bta_dm_discovery_cb.service_discovery_state = state;
225 }
bta_dm_discovery_get_state()226 static tBTA_DM_SERVICE_DISCOVERY_STATE bta_dm_discovery_get_state() {
227 return bta_dm_discovery_cb.service_discovery_state;
228 }
229
230 // TODO. Currently we did nothing
bta_dm_discovery_cancel()231 static void bta_dm_discovery_cancel() {}
232
233 /*******************************************************************************
234 *
235 * Function bta_dm_disable_search_and_disc
236 *
237 * Description Cancels an ongoing search or discovery for devices in case
238 * of a Bluetooth disable
239 *
240 * Returns void
241 *
242 ******************************************************************************/
bta_dm_disable_disc(void)243 static void bta_dm_disable_disc(void) {
244 switch (bta_dm_discovery_get_state()) {
245 case BTA_DM_DISCOVER_IDLE:
246 break;
247 case BTA_DM_DISCOVER_ACTIVE:
248 default:
249 log::debug(
250 "Discovery state machine is not idle so issuing discovery cancel "
251 "current "
252 "state:{}",
253 bta_dm_state_text(bta_dm_discovery_get_state()));
254 bta_dm_discovery_cancel();
255 }
256 }
257
bta_dm_sdp_finished(RawAddress bda,tBTA_STATUS result,std::vector<bluetooth::Uuid> uuids,std::vector<bluetooth::Uuid> gatt_uuids)258 void bta_dm_sdp_finished(RawAddress bda, tBTA_STATUS result,
259 std::vector<bluetooth::Uuid> uuids,
260 std::vector<bluetooth::Uuid> gatt_uuids) {
261 bta_dm_disc_sm_execute(BTA_DM_DISCOVERY_RESULT_EVT,
262 std::make_unique<tBTA_DM_MSG>(tBTA_DM_SVC_RES{
263 .bd_addr = bda,
264 .uuids = uuids,
265 .gatt_uuids = gatt_uuids,
266 .result = result,
267 }));
268 }
269
270 /* Callback from sdp with discovery status */
bta_dm_sdp_callback(const RawAddress &,tSDP_STATUS sdp_status)271 void bta_dm_sdp_callback(const RawAddress& /* bd_addr */,
272 tSDP_STATUS sdp_status) {
273 log::info("{}", bta_dm_state_text(bta_dm_discovery_get_state()));
274
275 if (bta_dm_discovery_get_state() == BTA_DM_DISCOVER_IDLE) {
276 return;
277 }
278
279 do_in_main_thread(FROM_HERE,
280 base::BindOnce(&bta_dm_sdp_result, sdp_status,
281 bta_dm_discovery_cb.sdp_state.get()));
282 }
283
284 /** Callback of peer's DIS reply. This is only called for floss */
285 #if TARGET_FLOSS
bta_dm_sdp_received_di(const RawAddress & bd_addr,tSDP_DI_GET_RECORD & di_record)286 void bta_dm_sdp_received_di(const RawAddress& bd_addr,
287 tSDP_DI_GET_RECORD& di_record) {
288 bta_dm_discovery_cb.service_search_cbacks.on_did_received(
289 bd_addr, di_record.rec.vendor_id_source, di_record.rec.vendor,
290 di_record.rec.product, di_record.rec.version);
291 }
292
bta_dm_read_dis_cmpl(const RawAddress & addr,tDIS_VALUE * p_dis_value)293 static void bta_dm_read_dis_cmpl(const RawAddress& addr,
294 tDIS_VALUE* p_dis_value) {
295 if (!p_dis_value) {
296 log::warn("read DIS failed");
297 } else {
298 bta_dm_discovery_cb.service_search_cbacks.on_did_received(
299 addr, p_dis_value->pnp_id.vendor_id_src, p_dis_value->pnp_id.vendor_id,
300 p_dis_value->pnp_id.product_id, p_dis_value->pnp_id.product_version);
301 }
302
303 if (!bta_dm_discovery_cb.transports) {
304 bta_dm_execute_queued_discovery_request();
305 }
306 }
307 #endif
308
309 /*******************************************************************************
310 *
311 * Function bta_dm_disc_result
312 *
313 * Description Service discovery result when discovering services on a
314 * device
315 *
316 * Returns void
317 *
318 ******************************************************************************/
bta_dm_disc_result(tBTA_DM_SVC_RES & disc_result)319 static void bta_dm_disc_result(tBTA_DM_SVC_RES& disc_result) {
320 log::verbose("");
321
322 /* if any BR/EDR service discovery has been done, report the event */
323 if (!disc_result.is_gatt_over_ble) {
324 bta_dm_discovery_cb.transports &= ~BT_TRANSPORT_BR_EDR;
325
326 auto& r = disc_result;
327 if (!r.gatt_uuids.empty()) {
328 log::info("Sending GATT services discovered using SDP");
329 // send GATT result back to app, if any
330 bta_dm_discovery_cb.service_search_cbacks.on_gatt_results(
331 r.bd_addr, BD_NAME{}, r.gatt_uuids, /* transport_le */ false);
332 }
333 bta_dm_discovery_cb.service_search_cbacks.on_service_discovery_results(
334 r.bd_addr, r.uuids, r.result);
335 } else {
336 bta_dm_discovery_cb.transports &= ~BT_TRANSPORT_LE;
337 GAP_BleReadPeerPrefConnParams(bta_dm_discovery_cb.peer_bdaddr);
338
339 bta_dm_discovery_cb.service_search_cbacks.on_gatt_results(
340 bta_dm_discovery_cb.peer_bdaddr, BD_NAME{}, disc_result.gatt_uuids,
341 /* transport_le */ true);
342 }
343
344 if (!bta_dm_discovery_cb.transports) {
345 bta_dm_discovery_set_state(BTA_DM_DISCOVER_IDLE);
346 }
347
348 #if TARGET_FLOSS
349 if (bta_dm_discovery_cb.conn_id != GATT_INVALID_CONN_ID &&
350 DIS_ReadDISInfo(bta_dm_discovery_cb.peer_bdaddr, bta_dm_read_dis_cmpl,
351 DIS_ATTR_PNP_ID_BIT)) {
352 return;
353 }
354 #endif
355
356 if (!bta_dm_discovery_cb.transports) {
357 bta_dm_execute_queued_discovery_request();
358 }
359 }
360
361 /*******************************************************************************
362 *
363 * Function bta_dm_queue_disc
364 *
365 * Description Queues discovery command
366 *
367 * Returns void
368 *
369 ******************************************************************************/
bta_dm_queue_disc(tBTA_DM_API_DISCOVER & discovery)370 static void bta_dm_queue_disc(tBTA_DM_API_DISCOVER& discovery) {
371 log::info("bta_dm_discovery: queuing service discovery to {} [{}]",
372 discovery.bd_addr, bt_transport_text(discovery.transport));
373 bta_dm_discovery_cb.pending_discovery_queue.push(discovery);
374 }
375
bta_dm_execute_queued_discovery_request()376 static void bta_dm_execute_queued_discovery_request() {
377 if (bta_dm_discovery_cb.pending_discovery_queue.empty()) {
378 bta_dm_discovery_cb.sdp_state.reset();
379 log::info("No more service discovery queued");
380 return;
381 }
382
383 tBTA_DM_API_DISCOVER pending_discovery =
384 bta_dm_discovery_cb.pending_discovery_queue.front();
385 bta_dm_discovery_cb.pending_discovery_queue.pop();
386 log::info("Start pending discovery {} [{}]", pending_discovery.bd_addr,
387 pending_discovery.transport);
388 post_disc_evt(
389 BTA_DM_API_DISCOVER_EVT,
390 std::make_unique<tBTA_DM_MSG>(tBTA_DM_API_DISCOVER{pending_discovery}));
391 }
392
393 /*******************************************************************************
394 *
395 * Function bta_dm_determine_discovery_transport
396 *
397 * Description Starts name and service discovery on the device
398 *
399 * Returns void
400 *
401 ******************************************************************************/
bta_dm_determine_discovery_transport(const RawAddress & remote_bd_addr)402 static tBT_TRANSPORT bta_dm_determine_discovery_transport(
403 const RawAddress& remote_bd_addr) {
404 tBT_DEVICE_TYPE dev_type;
405 tBLE_ADDR_TYPE addr_type;
406
407 get_btm_client_interface().peer.BTM_ReadDevInfo(remote_bd_addr, &dev_type,
408 &addr_type);
409 if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM) {
410 return BT_TRANSPORT_LE;
411 } else if (dev_type == BT_DEVICE_TYPE_DUMO) {
412 if (get_btm_client_interface().peer.BTM_IsAclConnectionUp(
413 remote_bd_addr, BT_TRANSPORT_BR_EDR)) {
414 return BT_TRANSPORT_BR_EDR;
415 } else if (get_btm_client_interface().peer.BTM_IsAclConnectionUp(
416 remote_bd_addr, BT_TRANSPORT_LE)) {
417 return BT_TRANSPORT_LE;
418 }
419 }
420 return BT_TRANSPORT_BR_EDR;
421 }
422
423 /* Discovers services on a remote device */
bta_dm_discover_services(tBTA_DM_API_DISCOVER & discover)424 static void bta_dm_discover_services(tBTA_DM_API_DISCOVER& discover) {
425 bta_dm_gattc_register();
426
427 RawAddress bd_addr = discover.bd_addr;
428 tBT_TRANSPORT transport = (discover.transport == BT_TRANSPORT_AUTO)
429 ? bta_dm_determine_discovery_transport(bd_addr)
430 : discover.transport;
431
432 log::info("starting service discovery to: {}, transport: {}", bd_addr,
433 bt_transport_text(transport));
434
435 bta_dm_discovery_cb.service_search_cbacks = discover.cbacks;
436
437 bta_dm_discovery_cb.peer_bdaddr = bd_addr;
438
439 /* Classic mouses with this attribute should not start SDP here, because the
440 SDP has been done during bonding. SDP request here will interleave with
441 connections to the Control or Interrupt channels */
442 if (HID_HostSDPDisable(bd_addr)) {
443 log::info("peer:{} with HIDSDPDisable attribute.", bd_addr);
444
445 /* service discovery is done for this device */
446 bta_dm_disc_sm_execute(BTA_DM_DISCOVERY_RESULT_EVT,
447 std::make_unique<tBTA_DM_MSG>(tBTA_DM_SVC_RES{
448 .bd_addr = bd_addr, .result = BTA_SUCCESS}));
449 return;
450 }
451
452 BTM_LogHistory(
453 kBtmLogTag, bd_addr, "Discovery started ",
454 base::StringPrintf("Transport:%s", bt_transport_text(transport).c_str()));
455
456 if (transport == BT_TRANSPORT_LE) {
457 if (bta_dm_discovery_cb.transports & BT_TRANSPORT_LE) {
458 log::info("won't start GATT discovery - already started {}", bd_addr);
459 return;
460 } else {
461 log::info("starting GATT discovery on {}", bd_addr);
462 /* start GATT for service discovery */
463 bta_dm_discovery_cb.transports |= BT_TRANSPORT_LE;
464 gatt_performer.Run(bd_addr);
465 return;
466 }
467 }
468
469 // transport == BT_TRANSPORT_BR_EDR
470 if (bta_dm_discovery_cb.transports & BT_TRANSPORT_BR_EDR) {
471 log::info("won't start SDP - already started {}", bd_addr);
472 } else {
473 log::info("starting SDP discovery on {}", bd_addr);
474 bta_dm_discovery_cb.transports |= BT_TRANSPORT_BR_EDR;
475
476 bta_dm_discovery_cb.sdp_state =
477 std::make_unique<tBTA_DM_SDP_STATE>(tBTA_DM_SDP_STATE{
478 .bd_addr = bd_addr,
479 .services_to_search = BTA_ALL_SERVICE_MASK,
480 .services_found = 0,
481 .service_index = 0,
482 });
483 sdp_performer.Run(bta_dm_discovery_cb.sdp_state.get());
484 }
485 }
486
bta_dm_disc_override_sdp_performer_for_testing(base::RepeatingCallback<void (tBTA_DM_SDP_STATE *)> test_sdp_performer)487 void bta_dm_disc_override_sdp_performer_for_testing(
488 base::RepeatingCallback<void(tBTA_DM_SDP_STATE*)> test_sdp_performer) {
489 if (test_sdp_performer.is_null()) {
490 sdp_performer = default_sdp_performer;
491 } else {
492 sdp_performer = test_sdp_performer;
493 }
494 }
bta_dm_disc_override_gatt_performer_for_testing(base::RepeatingCallback<void (const RawAddress &)> test_gatt_performer)495 void bta_dm_disc_override_gatt_performer_for_testing(
496 base::RepeatingCallback<void(const RawAddress&)> test_gatt_performer) {
497 if (test_gatt_performer.is_null()) {
498 gatt_performer = default_gatt_performer;
499 } else {
500 gatt_performer = test_gatt_performer;
501 }
502 }
503
504 #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
505 #define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000
506 #endif
507
508 /*******************************************************************************
509 *
510 * Function bta_dm_gattc_register
511 *
512 * Description Register with GATTC in DM if BLE is needed.
513 *
514 *
515 * Returns void
516 *
517 ******************************************************************************/
bta_dm_gattc_register(void)518 static void bta_dm_gattc_register(void) {
519 if (bta_dm_discovery_cb.client_if != BTA_GATTS_INVALID_IF) {
520 // Already registered
521 return;
522 }
523 get_gatt_interface().BTA_GATTC_AppRegister(
524 bta_dm_gattc_callback, base::Bind([](uint8_t client_id, uint8_t status) {
525 tGATT_STATUS gatt_status = static_cast<tGATT_STATUS>(status);
526 if (static_cast<tGATT_STATUS>(status) == GATT_SUCCESS) {
527 log::info(
528 "Registered device discovery search gatt client tGATT_IF:{}",
529 client_id);
530 bta_dm_discovery_cb.client_if = client_id;
531 } else {
532 log::warn(
533 "Failed to register device discovery search gatt client "
534 "gatt_status:{} previous tGATT_IF:{}",
535 bta_dm_discovery_cb.client_if, status);
536 bta_dm_discovery_cb.client_if = BTA_GATTS_INVALID_IF;
537 }
538 }),
539 false);
540 }
541
gatt_close_timer_cb(void *)542 static void gatt_close_timer_cb(void*) {
543 bta_dm_disc_sm_execute(BTA_DM_DISC_CLOSE_TOUT_EVT, nullptr);
544 }
545
bta_dm_gatt_finished(RawAddress bda,tBTA_STATUS result,std::vector<bluetooth::Uuid> gatt_uuids)546 void bta_dm_gatt_finished(RawAddress bda, tBTA_STATUS result,
547 std::vector<bluetooth::Uuid> gatt_uuids) {
548 bta_dm_disc_sm_execute(BTA_DM_DISCOVERY_RESULT_EVT,
549 std::make_unique<tBTA_DM_MSG>(tBTA_DM_SVC_RES{
550 .bd_addr = bda,
551 .is_gatt_over_ble = true,
552 .gatt_uuids = gatt_uuids,
553 .result = result,
554 }));
555 }
556
557 /*******************************************************************************
558 *
559 * Function bta_dm_gatt_disc_complete
560 *
561 * Description This function process the GATT service search complete.
562 *
563 * Parameters:
564 *
565 ******************************************************************************/
bta_dm_gatt_disc_complete(uint16_t conn_id,tGATT_STATUS status)566 static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) {
567 bool sdp_pending = bta_dm_discovery_cb.transports & BT_TRANSPORT_BR_EDR;
568 bool le_pending = bta_dm_discovery_cb.transports & BT_TRANSPORT_LE;
569
570 log::verbose("conn_id = {}, status = {}, sdp_pending = {}, le_pending = {}",
571 conn_id, status, sdp_pending, le_pending);
572
573 if (com::android::bluetooth::flags::bta_dm_discover_both() && sdp_pending &&
574 !le_pending) {
575 /* LE Service discovery finished, and services were reported, but SDP is not
576 * finished yet. gatt_close_timer closed the connection, and we received
577 * this callback because of disconnnection */
578 return;
579 }
580
581 std::vector<Uuid> gatt_services;
582
583 if (conn_id != GATT_INVALID_CONN_ID && status == GATT_SUCCESS) {
584 btgatt_db_element_t* db = NULL;
585 int count = 0;
586 get_gatt_interface().BTA_GATTC_GetGattDb(conn_id, 0x0000, 0xFFFF, &db,
587 &count);
588 if (count != 0) {
589 for (int i = 0; i < count; i++) {
590 // we process service entries only
591 if (db[i].type == BTGATT_DB_PRIMARY_SERVICE) {
592 gatt_services.push_back(db[i].uuid);
593 }
594 }
595 osi_free(db);
596 }
597 log::info("GATT services discovered using LE Transport, count: {}",
598 gatt_services.size());
599 }
600
601 /* no more services to be discovered */
602 bta_dm_gatt_finished(bta_dm_discovery_cb.peer_bdaddr,
603 (status == GATT_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE,
604 std::move(gatt_services));
605
606 if (conn_id != GATT_INVALID_CONN_ID) {
607 bta_dm_discovery_cb.pending_close_bda = bta_dm_discovery_cb.peer_bdaddr;
608 // Gatt will be close immediately if bluetooth.gatt.delay_close.enabled is
609 // set to false. If property is true / unset there will be a delay
610 if (bta_dm_discovery_cb.gatt_close_timer != nullptr) {
611 /* start a GATT channel close delay timer */
612 alarm_set_on_mloop(bta_dm_discovery_cb.gatt_close_timer,
613 BTA_DM_GATT_CLOSE_DELAY_TOUT, gatt_close_timer_cb, 0);
614 } else {
615 bta_dm_disc_sm_execute(BTA_DM_DISC_CLOSE_TOUT_EVT, nullptr);
616 }
617 } else {
618 bta_dm_discovery_cb.conn_id = GATT_INVALID_CONN_ID;
619
620 if (com::android::bluetooth::flags::bta_dm_disc_stuck_in_cancelling_fix()) {
621 log::info(
622 "Discovery complete for invalid conn ID. Will pick up next job");
623 bta_dm_discovery_set_state(BTA_DM_DISCOVER_IDLE);
624 bta_dm_execute_queued_discovery_request();
625 }
626 }
627 }
628
629 /*******************************************************************************
630 *
631 * Function bta_dm_close_gatt_conn
632 *
633 * Description This function close the GATT connection after delay
634 *timeout.
635 *
636 * Parameters:
637 *
638 ******************************************************************************/
bta_dm_close_gatt_conn()639 static void bta_dm_close_gatt_conn() {
640 if (bta_dm_discovery_cb.conn_id != GATT_INVALID_CONN_ID)
641 BTA_GATTC_Close(bta_dm_discovery_cb.conn_id);
642
643 bta_dm_discovery_cb.pending_close_bda = RawAddress::kEmpty;
644 bta_dm_discovery_cb.conn_id = GATT_INVALID_CONN_ID;
645 }
646 /*******************************************************************************
647 *
648 * Function btm_dm_start_gatt_discovery
649 *
650 * Description This is GATT initiate the service search by open a GATT
651 * connection first.
652 *
653 * Parameters:
654 *
655 ******************************************************************************/
btm_dm_start_gatt_discovery(const RawAddress & bd_addr)656 static void btm_dm_start_gatt_discovery(const RawAddress& bd_addr) {
657 constexpr bool kUseOpportunistic = true;
658
659 /* connection is already open */
660 if (bta_dm_discovery_cb.pending_close_bda == bd_addr &&
661 bta_dm_discovery_cb.conn_id != GATT_INVALID_CONN_ID) {
662 bta_dm_discovery_cb.pending_close_bda = RawAddress::kEmpty;
663 alarm_cancel(bta_dm_discovery_cb.gatt_close_timer);
664 get_gatt_interface().BTA_GATTC_ServiceSearchRequest(
665 bta_dm_discovery_cb.conn_id, nullptr);
666 } else {
667 if (get_btm_client_interface().peer.BTM_IsAclConnectionUp(
668 bd_addr, BT_TRANSPORT_LE)) {
669 log::debug(
670 "Use existing gatt client connection for discovery peer:{} "
671 "transport:{} opportunistic:{:c}",
672 bd_addr, bt_transport_text(BT_TRANSPORT_LE),
673 (kUseOpportunistic) ? 'T' : 'F');
674 get_gatt_interface().BTA_GATTC_Open(bta_dm_discovery_cb.client_if,
675 bd_addr, BTM_BLE_DIRECT_CONNECTION,
676 kUseOpportunistic);
677 } else {
678 log::debug(
679 "Opening new gatt client connection for discovery peer:{} "
680 "transport:{} opportunistic:{:c}",
681 bd_addr, bt_transport_text(BT_TRANSPORT_LE),
682 (!kUseOpportunistic) ? 'T' : 'F');
683 get_gatt_interface().BTA_GATTC_Open(bta_dm_discovery_cb.client_if,
684 bd_addr, BTM_BLE_DIRECT_CONNECTION,
685 !kUseOpportunistic);
686 }
687 }
688 }
689
690 /*******************************************************************************
691 *
692 * Function bta_dm_proc_open_evt
693 *
694 * Description process BTA_GATTC_OPEN_EVT in DM.
695 *
696 * Parameters:
697 *
698 ******************************************************************************/
bta_dm_proc_open_evt(tBTA_GATTC_OPEN * p_data)699 static void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) {
700 log::verbose(
701 "DM Search state= {} bta_dm_discovery_cb.peer_dbaddr:{} connected_bda={}",
702 bta_dm_discovery_get_state(), bta_dm_discovery_cb.peer_bdaddr,
703 p_data->remote_bda);
704
705 log::debug("BTA_GATTC_OPEN_EVT conn_id = {} client_if={} status = {}",
706 p_data->conn_id, p_data->client_if, p_data->status);
707
708 bta_dm_discovery_cb.conn_id = p_data->conn_id;
709
710 if (p_data->status == GATT_SUCCESS) {
711 get_gatt_interface().BTA_GATTC_ServiceSearchRequest(p_data->conn_id,
712 nullptr);
713 } else {
714 bta_dm_gatt_disc_complete(GATT_INVALID_CONN_ID, p_data->status);
715 }
716 }
717
718 /*******************************************************************************
719 *
720 * Function bta_dm_gattc_callback
721 *
722 * Description This is GATT client callback function used in DM.
723 *
724 * Parameters:
725 *
726 ******************************************************************************/
bta_dm_gattc_callback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)727 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
728 log::verbose("bta_dm_gattc_callback event = {}", event);
729
730 switch (event) {
731 case BTA_GATTC_OPEN_EVT:
732 bta_dm_proc_open_evt(&p_data->open);
733 break;
734
735 case BTA_GATTC_SEARCH_CMPL_EVT:
736 if (bta_dm_discovery_get_state() == BTA_DM_DISCOVER_ACTIVE) {
737 bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id,
738 p_data->search_cmpl.status);
739 }
740 break;
741
742 case BTA_GATTC_CLOSE_EVT:
743 log::info("BTA_GATTC_CLOSE_EVT reason = {}", p_data->close.reason);
744
745 if (p_data->close.remote_bda == bta_dm_discovery_cb.peer_bdaddr) {
746 bta_dm_discovery_cb.conn_id = GATT_INVALID_CONN_ID;
747 }
748
749 if (bta_dm_discovery_get_state() == BTA_DM_DISCOVER_ACTIVE) {
750 /* in case of disconnect before search is completed */
751 if (p_data->close.remote_bda == bta_dm_discovery_cb.peer_bdaddr) {
752 bta_dm_gatt_disc_complete((uint16_t)GATT_INVALID_CONN_ID,
753 (tGATT_STATUS)GATT_ERROR);
754 }
755 }
756 break;
757
758 case BTA_GATTC_CANCEL_OPEN_EVT:
759 case BTA_GATTC_CFG_MTU_EVT:
760 case BTA_GATTC_CONGEST_EVT:
761 case BTA_GATTC_CONN_UPDATE_EVT:
762 case BTA_GATTC_DEREG_EVT:
763 case BTA_GATTC_ENC_CMPL_CB_EVT:
764 case BTA_GATTC_EXEC_EVT:
765 case BTA_GATTC_NOTIF_EVT:
766 case BTA_GATTC_PHY_UPDATE_EVT:
767 case BTA_GATTC_SEARCH_RES_EVT:
768 case BTA_GATTC_SRVC_CHG_EVT:
769 case BTA_GATTC_SRVC_DISC_DONE_EVT:
770 case BTA_GATTC_SUBRATE_CHG_EVT:
771 break;
772 }
773 }
774
775 namespace bluetooth {
776 namespace legacy {
777 namespace testing {
778
bta_dm_determine_discovery_transport(const RawAddress & bd_addr)779 tBT_TRANSPORT bta_dm_determine_discovery_transport(const RawAddress& bd_addr) {
780 return ::bta_dm_determine_discovery_transport(bd_addr);
781 }
782
bta_dm_sdp_result(tSDP_STATUS sdp_status,tBTA_DM_SDP_STATE * state)783 void bta_dm_sdp_result(tSDP_STATUS sdp_status, tBTA_DM_SDP_STATE* state) {
784 ::bta_dm_sdp_result(sdp_status, state);
785 }
786
787 } // namespace testing
788 } // namespace legacy
789 } // namespace bluetooth
790
791 namespace {
792 constexpr char kTimeFormatString[] = "%Y-%m-%d %H:%M:%S";
793
794 constexpr unsigned MillisPerSecond = 1000;
EpochMillisToString(long long time_ms)795 std::string EpochMillisToString(long long time_ms) {
796 time_t time_sec = time_ms / MillisPerSecond;
797 struct tm tm;
798 localtime_r(&time_sec, &tm);
799 std::string s = bluetooth::common::StringFormatTime(kTimeFormatString, tm);
800 return base::StringPrintf(
801 "%s.%03u", s.c_str(),
802 static_cast<unsigned int>(time_ms % MillisPerSecond));
803 }
804
805 } // namespace
806
807 struct tDISCOVERY_STATE_HISTORY {
808 const tBTA_DM_SERVICE_DISCOVERY_STATE state;
809 const tBTA_DM_DISC_EVT event;
ToStringtDISCOVERY_STATE_HISTORY810 std::string ToString() const {
811 return base::StringPrintf("state:%25s event:%s",
812 bta_dm_state_text(state).c_str(),
813 bta_dm_event_text(event).c_str());
814 }
815 };
816
817 bluetooth::common::TimestampedCircularBuffer<tDISCOVERY_STATE_HISTORY>
818 discovery_state_history_(50 /*history size*/);
819
bta_dm_disc_sm_execute(tBTA_DM_DISC_EVT event,std::unique_ptr<tBTA_DM_MSG> msg)820 static void bta_dm_disc_sm_execute(tBTA_DM_DISC_EVT event,
821 std::unique_ptr<tBTA_DM_MSG> msg) {
822 log::info("state:{}, event:{}[0x{:x}]",
823 bta_dm_state_text(bta_dm_discovery_get_state()),
824 bta_dm_event_text(event), event);
825 discovery_state_history_.Push({
826 .state = bta_dm_discovery_get_state(),
827 .event = event,
828 });
829
830 switch (bta_dm_discovery_get_state()) {
831 case BTA_DM_DISCOVER_IDLE:
832 switch (event) {
833 case BTA_DM_API_DISCOVER_EVT:
834 bta_dm_discovery_set_state(BTA_DM_DISCOVER_ACTIVE);
835 log::assert_that(std::holds_alternative<tBTA_DM_API_DISCOVER>(*msg),
836 "bad message type: {}", msg->index());
837
838 bta_dm_discover_services(std::get<tBTA_DM_API_DISCOVER>(*msg));
839 break;
840 case BTA_DM_DISC_CLOSE_TOUT_EVT:
841 bta_dm_close_gatt_conn();
842 break;
843 default:
844 log::info("Received unexpected event {}[0x{:x}] in state {}",
845 bta_dm_event_text(event), event,
846 bta_dm_state_text(bta_dm_discovery_get_state()));
847 }
848 break;
849
850 case BTA_DM_DISCOVER_ACTIVE:
851 switch (event) {
852 case BTA_DM_DISCOVERY_RESULT_EVT:
853 log::assert_that(std::holds_alternative<tBTA_DM_SVC_RES>(*msg),
854 "bad message type: {}", msg->index());
855
856 bta_dm_disc_result(std::get<tBTA_DM_SVC_RES>(*msg));
857 break;
858 case BTA_DM_API_DISCOVER_EVT: {
859 log::assert_that(std::holds_alternative<tBTA_DM_API_DISCOVER>(*msg),
860 "bad message type: {}", msg->index());
861
862 auto req = std::get<tBTA_DM_API_DISCOVER>(*msg);
863 if (com::android::bluetooth::flags::bta_dm_discover_both() &&
864 is_same_device(req.bd_addr, bta_dm_discovery_cb.peer_bdaddr)) {
865 bta_dm_discover_services(std::get<tBTA_DM_API_DISCOVER>(*msg));
866 } else {
867 bta_dm_queue_disc(std::get<tBTA_DM_API_DISCOVER>(*msg));
868 }
869 } break;
870 case BTA_DM_DISC_CLOSE_TOUT_EVT:
871 bta_dm_close_gatt_conn();
872 break;
873 default:
874 log::info("Received unexpected event {}[0x{:x}] in state {}",
875 bta_dm_event_text(event), event,
876 bta_dm_state_text(bta_dm_discovery_get_state()));
877 }
878 break;
879 }
880 }
881
bta_dm_disc_init_discovery_cb(tBTA_DM_SERVICE_DISCOVERY_CB & bta_dm_discovery_cb)882 static void bta_dm_disc_init_discovery_cb(
883 tBTA_DM_SERVICE_DISCOVERY_CB& bta_dm_discovery_cb) {
884 bta_dm_discovery_cb = {};
885 bta_dm_discovery_cb.service_discovery_state = BTA_DM_DISCOVER_IDLE;
886 bta_dm_discovery_cb.conn_id = GATT_INVALID_CONN_ID;
887 }
888
bta_dm_disc_reset()889 static void bta_dm_disc_reset() {
890 alarm_free(bta_dm_discovery_cb.gatt_close_timer);
891 bta_dm_disc_init_discovery_cb(::bta_dm_discovery_cb);
892 }
893
bta_dm_disc_start(bool delay_close_gatt)894 void bta_dm_disc_start(bool delay_close_gatt) {
895 if (!com::android::bluetooth::flags::
896 separate_service_and_device_discovery()) {
897 bta_dm_disc_legacy::bta_dm_disc_start(delay_close_gatt);
898 return;
899 }
900 bta_dm_disc_reset();
901 bta_dm_discovery_cb.gatt_close_timer =
902 delay_close_gatt ? alarm_new("bta_dm_search.gatt_close_timer") : nullptr;
903 bta_dm_discovery_cb.pending_discovery_queue = {};
904 }
905
bta_dm_disc_acl_down(const RawAddress & bd_addr,tBT_TRANSPORT transport)906 void bta_dm_disc_acl_down(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
907 if (!com::android::bluetooth::flags::
908 separate_service_and_device_discovery()) {
909 bta_dm_disc_legacy::bta_dm_disc_acl_down(bd_addr, transport);
910 return;
911 }
912 }
913
bta_dm_disc_stop()914 void bta_dm_disc_stop() {
915 if (!com::android::bluetooth::flags::
916 separate_service_and_device_discovery()) {
917 bta_dm_disc_legacy::bta_dm_disc_stop();
918 return;
919 }
920 bta_dm_disc_reset();
921 }
922
bta_dm_disc_start_service_discovery(service_discovery_callbacks cbacks,const RawAddress & bd_addr,tBT_TRANSPORT transport)923 void bta_dm_disc_start_service_discovery(service_discovery_callbacks cbacks,
924 const RawAddress& bd_addr,
925 tBT_TRANSPORT transport) {
926 if (!com::android::bluetooth::flags::
927 separate_service_and_device_discovery()) {
928 bta_dm_disc_legacy::bta_dm_disc_start_service_discovery(cbacks, bd_addr,
929 transport);
930 return;
931 }
932 bta_dm_disc_sm_execute(
933 BTA_DM_API_DISCOVER_EVT,
934 std::make_unique<tBTA_DM_MSG>(tBTA_DM_API_DISCOVER{
935 .bd_addr = bd_addr, .cbacks = cbacks, .transport = transport}));
936 }
937
938 #define DUMPSYS_TAG "shim::legacy::bta::dm"
DumpsysBtaDmDisc(int fd)939 void DumpsysBtaDmDisc(int fd) {
940 if (!com::android::bluetooth::flags::
941 separate_service_and_device_discovery()) {
942 bta_dm_disc_legacy::DumpsysBtaDmDisc(fd);
943 return;
944 }
945 auto copy = discovery_state_history_.Pull();
946 LOG_DUMPSYS(fd, " last %zu discovery state transitions", copy.size());
947 for (const auto& it : copy) {
948 LOG_DUMPSYS(fd, " %s %s", EpochMillisToString(it.timestamp).c_str(),
949 it.entry.ToString().c_str());
950 }
951 LOG_DUMPSYS(fd, " current bta_dm_discovery_state:%s",
952 bta_dm_state_text(bta_dm_discovery_get_state()).c_str());
953 }
954 #undef DUMPSYS_TAG
955
956 namespace bluetooth {
957 namespace legacy {
958 namespace testing {
959
bta_dm_discovery_cb()960 tBTA_DM_SERVICE_DISCOVERY_CB& bta_dm_discovery_cb() {
961 return ::bta_dm_discovery_cb;
962 }
963
964 } // namespace testing
965 } // namespace legacy
966 } // namespace bluetooth
967