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