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