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