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