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