1 /*
2 * Copyright 2024 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_sd"
18
19 #include "bta/dm/bta_dm_device_search.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 #include <stddef.h>
26
27 #include <cstdint>
28 #include <string>
29 #include <variant>
30 #include <vector>
31
32 #include "bta/dm/bta_dm_device_search_int.h"
33 #include "bta/dm/bta_dm_disc_legacy.h"
34 #include "bta/include/bta_gatt_api.h"
35 #include "bta/include/bta_sdp_api.h"
36 #include "btif/include/btif_config.h"
37 #include "com_android_bluetooth_flags.h"
38 #include "common/circular_buffer.h"
39 #include "common/init_flags.h"
40 #include "common/strings.h"
41 #include "device/include/interop.h"
42 #include "internal_include/bt_target.h"
43 #include "main/shim/dumpsys.h"
44 #include "os/logging/log_adapter.h"
45 #include "osi/include/allocator.h"
46 #include "stack/btm/btm_int_types.h" // TimestampedStringCircularBuffer
47 #include "stack/btm/neighbor_inquiry.h"
48 #include "stack/include/bt_dev_class.h"
49 #include "stack/include/bt_name.h"
50 #include "stack/include/bt_uuid16.h"
51 #include "stack/include/btm_client_interface.h"
52 #include "stack/include/btm_inq.h"
53 #include "stack/include/btm_log_history.h"
54 #include "stack/include/btm_sec_api.h" // BTM_IsRemoteNameKnown
55 #include "stack/include/gap_api.h" // GAP_BleReadPeerPrefConnParams
56 #include "stack/include/hidh_api.h"
57 #include "stack/include/main_thread.h"
58 #include "stack/include/sdp_status.h"
59 #include "stack/sdp/sdpint.h" // is_sdp_pbap_pce_disabled
60 #include "storage/config_keys.h"
61 #include "types/raw_address.h"
62
63 using namespace bluetooth;
64
65 namespace {
66 constexpr char kBtmLogTag[] = "DEV_SEARCH";
67
68 tBTA_DM_SEARCH_CB bta_dm_search_cb;
69 } // namespace
70
71 static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir,
72 uint16_t eir_len);
73 static void bta_dm_inq_cmpl();
74 static void bta_dm_inq_cmpl_cb(void* p_result);
75 static void bta_dm_search_cmpl();
76 static void bta_dm_discover_next_device(void);
77 static void bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME* p);
78
79 static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr,
80 tBT_TRANSPORT transport);
81 static void bta_dm_discover_name(const RawAddress& remote_bd_addr);
82 static void bta_dm_execute_queued_search_request();
83 static void bta_dm_search_cancel_notify();
84 static void bta_dm_disable_search();
85
86 static void bta_dm_search_sm_execute(tBTA_DM_DEV_SEARCH_EVT event,
87 std::unique_ptr<tBTA_DM_SEARCH_MSG> msg);
88 static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq,
89 const uint8_t* p_eir, uint16_t eir_len);
90 static void bta_dm_observe_cmpl_cb(void* p_result);
91
bta_dm_search_set_state(tBTA_DM_DEVICE_SEARCH_STATE state)92 static void bta_dm_search_set_state(tBTA_DM_DEVICE_SEARCH_STATE state) {
93 bta_dm_search_cb.search_state = state;
94 }
bta_dm_search_get_state()95 static tBTA_DM_DEVICE_SEARCH_STATE bta_dm_search_get_state() {
96 return bta_dm_search_cb.search_state;
97 }
98
post_search_evt(tBTA_DM_DEV_SEARCH_EVT event,std::unique_ptr<tBTA_DM_SEARCH_MSG> msg)99 static void post_search_evt(tBTA_DM_DEV_SEARCH_EVT event,
100 std::unique_ptr<tBTA_DM_SEARCH_MSG> msg) {
101 if (do_in_main_thread(FROM_HERE, base::BindOnce(&bta_dm_search_sm_execute,
102 event, std::move(msg))) !=
103 BT_STATUS_SUCCESS) {
104 log::error("post_search_evt failed");
105 }
106 }
107
bta_dm_disc_disable_search()108 void bta_dm_disc_disable_search() {
109 if (!com::android::bluetooth::flags::
110 separate_service_and_device_discovery()) {
111 log::info("no-op when flag is disabled");
112 return;
113 }
114 bta_dm_disable_search();
115 }
116
117 /*******************************************************************************
118 *
119 * Function bta_dm_search_start
120 *
121 * Description Starts an inquiry
122 *
123 *
124 * Returns void
125 *
126 ******************************************************************************/
bta_dm_search_start(tBTA_DM_API_SEARCH & search)127 static void bta_dm_search_start(tBTA_DM_API_SEARCH& search) {
128 if (get_btm_client_interface().db.BTM_ClearInqDb(nullptr) != BTM_SUCCESS) {
129 log::warn("Unable to clear inquiry database for device discovery");
130 }
131 /* save search params */
132 bta_dm_search_cb.p_device_search_cback = search.p_cback;
133
134 const tBTM_STATUS btm_status =
135 BTM_StartInquiry(bta_dm_inq_results_cb, bta_dm_inq_cmpl_cb);
136 switch (btm_status) {
137 case BTM_CMD_STARTED:
138 // Completion callback will be executed when controller inquiry
139 // timer pops or is cancelled by the user
140 break;
141 default:
142 log::warn("Unable to start device discovery search btm_status:{}",
143 btm_status_text(btm_status));
144 // Not started so completion callback is executed now
145 bta_dm_inq_cmpl();
146 break;
147 }
148 }
149
150 /*******************************************************************************
151 *
152 * Function bta_dm_search_cancel
153 *
154 * Description Cancels an ongoing search for devices
155 *
156 *
157 * Returns void
158 *
159 ******************************************************************************/
bta_dm_search_cancel()160 static void bta_dm_search_cancel() {
161 if (BTM_IsInquiryActive()) {
162 BTM_CancelInquiry();
163 bta_dm_search_cancel_notify();
164 bta_dm_search_cmpl();
165 }
166 /* If no Service Search going on then issue cancel remote name in case it is
167 active */
168 else if (!bta_dm_search_cb.name_discover_done) {
169 if (get_btm_client_interface().peer.BTM_CancelRemoteDeviceName() !=
170 BTM_CMD_STARTED) {
171 log::warn("Unable to cancel RNR");
172 }
173 /* bta_dm_search_cmpl is called when receiving the remote name cancel evt */
174 if (!com::android::bluetooth::flags::
175 bta_dm_defer_device_discovery_state_change_until_rnr_complete()) {
176 bta_dm_search_cmpl();
177 }
178 } else {
179 bta_dm_inq_cmpl();
180 }
181 }
182
183 /*******************************************************************************
184 *
185 * Function bta_dm_inq_cmpl_cb
186 *
187 * Description Inquiry complete callback from BTM
188 *
189 * Returns void
190 *
191 ******************************************************************************/
bta_dm_inq_cmpl_cb(void *)192 static void bta_dm_inq_cmpl_cb(void* /* p_result */) {
193 log::verbose("");
194
195 bta_dm_inq_cmpl();
196 }
197
198 /*******************************************************************************
199 *
200 * Function bta_dm_inq_results_cb
201 *
202 * Description Inquiry results callback from BTM
203 *
204 * Returns void
205 *
206 ******************************************************************************/
bta_dm_inq_results_cb(tBTM_INQ_RESULTS * p_inq,const uint8_t * p_eir,uint16_t eir_len)207 static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir,
208 uint16_t eir_len) {
209 tBTA_DM_SEARCH result;
210 tBTM_INQ_INFO* p_inq_info;
211 uint16_t service_class;
212
213 result.inq_res.bd_addr = p_inq->remote_bd_addr;
214
215 // Pass the original address to GattService#onScanResult
216 result.inq_res.original_bda = p_inq->original_bda;
217
218 result.inq_res.dev_class = p_inq->dev_class;
219 BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class);
220 result.inq_res.is_limited =
221 (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? true : false;
222 result.inq_res.rssi = p_inq->rssi;
223
224 result.inq_res.ble_addr_type = p_inq->ble_addr_type;
225 result.inq_res.inq_result_type = p_inq->inq_result_type;
226 result.inq_res.device_type = p_inq->device_type;
227 result.inq_res.flag = p_inq->flag;
228 result.inq_res.include_rsi = p_inq->include_rsi;
229 result.inq_res.clock_offset = p_inq->clock_offset;
230
231 /* application will parse EIR to find out remote device name */
232 result.inq_res.p_eir = const_cast<uint8_t*>(p_eir);
233 result.inq_res.eir_len = eir_len;
234
235 result.inq_res.ble_evt_type = p_inq->ble_evt_type;
236
237 p_inq_info =
238 get_btm_client_interface().db.BTM_InqDbRead(p_inq->remote_bd_addr);
239 if (p_inq_info != NULL) {
240 /* initialize remt_name_not_required to false so that we get the name by
241 * default */
242 result.inq_res.remt_name_not_required = false;
243 }
244
245 if (bta_dm_search_cb.p_device_search_cback)
246 bta_dm_search_cb.p_device_search_cback(BTA_DM_INQ_RES_EVT, &result);
247
248 if (p_inq_info) {
249 /* application indicates if it knows the remote name, inside the callback
250 copy that to the inquiry data base*/
251 if (result.inq_res.remt_name_not_required)
252 p_inq_info->appl_knows_rem_name = true;
253 }
254 }
255
256 /*******************************************************************************
257 *
258 * Function bta_dm_remname_cback
259 *
260 * Description Remote name complete call back from BTM
261 *
262 * Returns void
263 *
264 ******************************************************************************/
bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME * p_remote_name)265 static void bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME* p_remote_name) {
266 log::assert_that(p_remote_name != nullptr,
267 "assert failed: p_remote_name != nullptr");
268
269 log::info(
270 "Remote name request complete peer:{} btm_status:{} hci_status:{} "
271 "name[0]:{:c} length:{}",
272 p_remote_name->bd_addr, btm_status_text(p_remote_name->status),
273 hci_error_code_text(p_remote_name->hci_status),
274 p_remote_name->remote_bd_name[0],
275 strnlen((const char*)p_remote_name->remote_bd_name, BD_NAME_LEN));
276
277 if (bta_dm_search_cb.peer_bdaddr != p_remote_name->bd_addr) {
278 // if we got a different response, maybe ignore it
279 // we will have made a request directly from BTM_ReadRemoteDeviceName so we
280 // expect a dedicated response for us
281 if (p_remote_name->hci_status == HCI_ERR_CONNECTION_EXISTS) {
282 log::info(
283 "Assume command failed due to disconnection hci_status:{} peer:{}",
284 hci_error_code_text(p_remote_name->hci_status),
285 p_remote_name->bd_addr);
286 } else {
287 log::info(
288 "Ignored remote name response for the wrong address exp:{} act:{}",
289 bta_dm_search_cb.peer_bdaddr, p_remote_name->bd_addr);
290 return;
291 }
292 }
293
294 /* remote name discovery is done but it could be failed */
295 bta_dm_search_cb.name_discover_done = true;
296 bd_name_copy(bta_dm_search_cb.peer_name, p_remote_name->remote_bd_name);
297
298 auto msg = std::make_unique<tBTA_DM_SEARCH_MSG>(tBTA_DM_REMOTE_NAME{});
299 auto& rmt_name_msg = std::get<tBTA_DM_REMOTE_NAME>(*msg);
300 rmt_name_msg.bd_addr = bta_dm_search_cb.peer_bdaddr;
301 rmt_name_msg.hci_status = p_remote_name->hci_status;
302 bd_name_copy(rmt_name_msg.bd_name, p_remote_name->remote_bd_name);
303
304 post_search_evt(BTA_DM_REMT_NAME_EVT, std::move(msg));
305 }
306
307 /*******************************************************************************
308 *
309 * Function bta_dm_read_remote_device_name
310 *
311 * Description Initiate to get remote device name
312 *
313 * Returns true if started to get remote name
314 *
315 ******************************************************************************/
bta_dm_read_remote_device_name(const RawAddress & bd_addr,tBT_TRANSPORT transport)316 static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr,
317 tBT_TRANSPORT transport) {
318 tBTM_STATUS btm_status;
319
320 log::verbose("");
321
322 bta_dm_search_cb.peer_bdaddr = bd_addr;
323 bta_dm_search_cb.peer_name[0] = 0;
324
325 btm_status = get_btm_client_interface().peer.BTM_ReadRemoteDeviceName(
326 bta_dm_search_cb.peer_bdaddr, bta_dm_remname_cback, transport);
327
328 if (btm_status == BTM_CMD_STARTED) {
329 log::verbose("BTM_ReadRemoteDeviceName is started");
330
331 return (true);
332 } else if (btm_status == BTM_BUSY) {
333 log::verbose("BTM_ReadRemoteDeviceName is busy");
334
335 return (true);
336 } else {
337 log::warn("BTM_ReadRemoteDeviceName returns 0x{:02X}", btm_status);
338
339 return (false);
340 }
341 }
342
343 /*******************************************************************************
344 *
345 * Function bta_dm_inq_cmpl
346 *
347 * Description Process the inquiry complete event from BTM
348 *
349 * Returns void
350 *
351 ******************************************************************************/
bta_dm_inq_cmpl()352 static void bta_dm_inq_cmpl() {
353 if (bta_dm_search_get_state() == BTA_DM_SEARCH_CANCELLING) {
354 bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
355 bta_dm_execute_queued_search_request();
356 return;
357 }
358
359 if (bta_dm_search_get_state() != BTA_DM_SEARCH_ACTIVE) {
360 return;
361 }
362
363 log::verbose("bta_dm_inq_cmpl");
364
365 bta_dm_search_cb.p_btm_inq_info =
366 get_btm_client_interface().db.BTM_InqDbFirst();
367 if (bta_dm_search_cb.p_btm_inq_info != NULL) {
368 /* start name discovery from the first device on inquiry result
369 */
370 bta_dm_search_cb.name_discover_done = false;
371 bta_dm_search_cb.peer_name[0] = 0;
372 bta_dm_discover_name(
373 bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
374 } else {
375 bta_dm_search_cmpl();
376 }
377 }
378
bta_dm_remote_name_cmpl(const tBTA_DM_REMOTE_NAME & remote_name_msg)379 static void bta_dm_remote_name_cmpl(
380 const tBTA_DM_REMOTE_NAME& remote_name_msg) {
381 BTM_LogHistory(kBtmLogTag, remote_name_msg.bd_addr, "Remote name completed",
382 base::StringPrintf(
383 "status:%s state:%s name:\"%s\"",
384 hci_status_code_text(remote_name_msg.hci_status).c_str(),
385 bta_dm_state_text(bta_dm_search_get_state()).c_str(),
386 PRIVATE_NAME(remote_name_msg.bd_name)));
387
388 tBTM_INQ_INFO* p_btm_inq_info =
389 get_btm_client_interface().db.BTM_InqDbRead(remote_name_msg.bd_addr);
390 if (!bd_name_is_empty(remote_name_msg.bd_name) && p_btm_inq_info) {
391 p_btm_inq_info->appl_knows_rem_name = true;
392 }
393
394 // Callback with this property
395 if (bta_dm_search_cb.p_device_search_cback != nullptr) {
396 tBTA_DM_SEARCH search_data = {
397 .name_res = {.bd_addr = remote_name_msg.bd_addr, .bd_name = {}},
398 };
399 if (remote_name_msg.hci_status == HCI_SUCCESS) {
400 bd_name_copy(search_data.name_res.bd_name, remote_name_msg.bd_name);
401 }
402 bta_dm_search_cb.p_device_search_cback(BTA_DM_NAME_READ_EVT, &search_data);
403 } else {
404 log::warn("Received remote name complete without callback");
405 }
406
407 switch (bta_dm_search_get_state()) {
408 case BTA_DM_SEARCH_ACTIVE:
409 bta_dm_discover_name(bta_dm_search_cb.peer_bdaddr);
410 break;
411 case BTA_DM_SEARCH_IDLE:
412 case BTA_DM_SEARCH_CANCELLING:
413 log::warn("Received remote name request in state:{}",
414 bta_dm_state_text(bta_dm_search_get_state()));
415 break;
416 }
417 }
418
bta_dm_search_cmpl()419 static void bta_dm_search_cmpl() {
420 bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
421
422 if (bta_dm_search_cb.p_device_search_cback) {
423 bta_dm_search_cb.p_device_search_cback(BTA_DM_DISC_CMPL_EVT, nullptr);
424 }
425
426 bta_dm_execute_queued_search_request();
427 }
428
bta_dm_execute_queued_search_request()429 static void bta_dm_execute_queued_search_request() {
430 if (!bta_dm_search_cb.p_pending_search) return;
431
432 log::info("Start pending search");
433 post_search_evt(BTA_DM_API_SEARCH_EVT,
434 std::move(bta_dm_search_cb.p_pending_search));
435 bta_dm_search_cb.p_pending_search.reset();
436 }
437
438 /*******************************************************************************
439 *
440 * Function bta_dm_search_clear_queue
441 *
442 * Description Clears the queue if API search cancel is called
443 *
444 * Returns void
445 *
446 ******************************************************************************/
bta_dm_search_clear_queue()447 static void bta_dm_search_clear_queue() {
448 bta_dm_search_cb.p_pending_search.reset();
449 }
450
451 /*******************************************************************************
452 *
453 * Function bta_dm_search_cancel_notify
454 *
455 * Description Notify application that search has been cancelled
456 *
457 * Returns void
458 *
459 ******************************************************************************/
bta_dm_search_cancel_notify()460 static void bta_dm_search_cancel_notify() {
461 if (bta_dm_search_cb.p_device_search_cback) {
462 bta_dm_search_cb.p_device_search_cback(BTA_DM_SEARCH_CANCEL_CMPL_EVT, NULL);
463 }
464 switch (bta_dm_search_get_state()) {
465 case BTA_DM_SEARCH_ACTIVE:
466 case BTA_DM_SEARCH_CANCELLING:
467 if (!bta_dm_search_cb.name_discover_done) {
468 if (get_btm_client_interface().peer.BTM_CancelRemoteDeviceName() !=
469 BTM_CMD_STARTED) {
470 log::warn("Unable to cancel RNR");
471 }
472 }
473 break;
474 case BTA_DM_SEARCH_IDLE:
475 // Nothing to do
476 break;
477 }
478 }
479
480 /*******************************************************************************
481 *
482 * Function bta_dm_discover_next_device
483 *
484 * Description Starts discovery on the next device in Inquiry data base
485 *
486 * Returns void
487 *
488 ******************************************************************************/
bta_dm_discover_next_device(void)489 static void bta_dm_discover_next_device(void) {
490 log::verbose("bta_dm_discover_next_device");
491
492 /* searching next device on inquiry result */
493 bta_dm_search_cb.p_btm_inq_info = get_btm_client_interface().db.BTM_InqDbNext(
494 bta_dm_search_cb.p_btm_inq_info);
495 if (bta_dm_search_cb.p_btm_inq_info != NULL) {
496 bta_dm_search_cb.name_discover_done = false;
497 bta_dm_search_cb.peer_name[0] = 0;
498 bta_dm_discover_name(
499 bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
500 } else {
501 post_search_evt(BTA_DM_SEARCH_CMPL_EVT, nullptr);
502 }
503 }
504
505 /*TODO: this function is duplicated, make it common ?*/
bta_dm_determine_discovery_transport(const RawAddress & remote_bd_addr)506 static tBT_TRANSPORT bta_dm_determine_discovery_transport(
507 const RawAddress& remote_bd_addr) {
508 tBT_DEVICE_TYPE dev_type;
509 tBLE_ADDR_TYPE addr_type;
510
511 get_btm_client_interface().peer.BTM_ReadDevInfo(remote_bd_addr, &dev_type,
512 &addr_type);
513 if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM) {
514 return BT_TRANSPORT_LE;
515 } else if (dev_type == BT_DEVICE_TYPE_DUMO) {
516 if (get_btm_client_interface().peer.BTM_IsAclConnectionUp(
517 remote_bd_addr, BT_TRANSPORT_BR_EDR)) {
518 return BT_TRANSPORT_BR_EDR;
519 } else if (get_btm_client_interface().peer.BTM_IsAclConnectionUp(
520 remote_bd_addr, BT_TRANSPORT_LE)) {
521 return BT_TRANSPORT_LE;
522 }
523 }
524 return BT_TRANSPORT_BR_EDR;
525 }
526
bta_dm_discover_name(const RawAddress & remote_bd_addr)527 static void bta_dm_discover_name(const RawAddress& remote_bd_addr) {
528 const tBT_TRANSPORT transport =
529 bta_dm_determine_discovery_transport(remote_bd_addr);
530
531 log::verbose("BDA: {}", remote_bd_addr);
532
533 bta_dm_search_cb.peer_bdaddr = remote_bd_addr;
534
535 log::verbose(
536 "name_discover_done = {} p_btm_inq_info 0x{} state = {}, transport={}",
537 bta_dm_search_cb.name_discover_done,
538 fmt::ptr(bta_dm_search_cb.p_btm_inq_info), bta_dm_search_get_state(),
539 transport);
540
541 if (bta_dm_search_cb.p_btm_inq_info) {
542 log::verbose("appl_knows_rem_name {}",
543 bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name);
544 }
545 if (((bta_dm_search_cb.p_btm_inq_info) &&
546 (bta_dm_search_cb.p_btm_inq_info->results.device_type ==
547 BT_DEVICE_TYPE_BLE) &&
548 (bta_dm_search_get_state() == BTA_DM_SEARCH_ACTIVE)) ||
549 (transport == BT_TRANSPORT_LE &&
550 interop_match_addr(INTEROP_DISABLE_NAME_REQUEST,
551 &bta_dm_search_cb.peer_bdaddr))) {
552 /* Do not perform RNR for LE devices at inquiry complete*/
553 bta_dm_search_cb.name_discover_done = true;
554 }
555 // If we already have the name we can skip getting the name
556 if (BTM_IsRemoteNameKnown(remote_bd_addr, transport) &&
557 bluetooth::common::init_flags::sdp_skip_rnr_if_known_is_enabled()) {
558 log::debug(
559 "Security record already known skipping read remote name peer:{}",
560 remote_bd_addr);
561 bta_dm_search_cb.name_discover_done = true;
562 }
563
564 /* if name discovery is not done and application needs remote name */
565 if ((!bta_dm_search_cb.name_discover_done) &&
566 ((bta_dm_search_cb.p_btm_inq_info == NULL) ||
567 (bta_dm_search_cb.p_btm_inq_info &&
568 (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name)))) {
569 if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr,
570 transport)) {
571 BTM_LogHistory(kBtmLogTag, bta_dm_search_cb.peer_bdaddr,
572 "Read remote name",
573 base::StringPrintf("Transport:%s",
574 bt_transport_text(transport).c_str()));
575 return;
576 } else {
577 log::error("Unable to start read remote device name");
578 }
579
580 /* starting name discovery failed */
581 bta_dm_search_cb.name_discover_done = true;
582 }
583
584 /* name discovery is done for this device */
585 if (bta_dm_search_get_state() == BTA_DM_SEARCH_ACTIVE) {
586 // if p_btm_inq_info is nullptr, there is no more inquiry results to
587 // discover name for
588 if (bta_dm_search_cb.p_btm_inq_info) {
589 bta_dm_discover_next_device();
590 } else {
591 log::info("end of parsing inquiry result");
592 }
593 } else {
594 log::info("name discovery finished in bad state: {}",
595 bta_dm_state_text(bta_dm_search_get_state()));
596 }
597 }
598
599 /*******************************************************************************
600 *
601 * Function bta_dm_is_search_request_queued
602 *
603 * Description Checks if there is a queued search request
604 *
605 * Returns bool
606 *
607 ******************************************************************************/
bta_dm_is_search_request_queued()608 bool bta_dm_is_search_request_queued() {
609 if (!com::android::bluetooth::flags::
610 separate_service_and_device_discovery()) {
611 return bta_dm_disc_legacy::bta_dm_is_search_request_queued();
612 }
613 return bta_dm_search_cb.p_pending_search != NULL;
614 }
615
616 /*******************************************************************************
617 *
618 * Function bta_dm_queue_search
619 *
620 * Description Queues search command
621 *
622 * Returns void
623 *
624 ******************************************************************************/
bta_dm_queue_search(tBTA_DM_API_SEARCH & search)625 static void bta_dm_queue_search(tBTA_DM_API_SEARCH& search) {
626 if (bta_dm_search_cb.p_pending_search) {
627 log::warn("Overwrote previous device discovery inquiry scan request");
628 }
629 bta_dm_search_cb.p_pending_search.reset(new tBTA_DM_SEARCH_MSG(search));
630 log::info("Queued device discovery inquiry scan request");
631 }
632
633 /*******************************************************************************
634 *
635 * Function bta_dm_observe_results_cb
636 *
637 * Description Callback for BLE Observe result
638 *
639 *
640 * Returns void
641 *
642 ******************************************************************************/
bta_dm_observe_results_cb(tBTM_INQ_RESULTS * p_inq,const uint8_t * p_eir,uint16_t eir_len)643 static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq,
644 const uint8_t* p_eir, uint16_t eir_len) {
645 tBTA_DM_SEARCH result;
646 tBTM_INQ_INFO* p_inq_info;
647 log::verbose("bta_dm_observe_results_cb");
648
649 result.inq_res.bd_addr = p_inq->remote_bd_addr;
650 result.inq_res.original_bda = p_inq->original_bda;
651 result.inq_res.rssi = p_inq->rssi;
652 result.inq_res.ble_addr_type = p_inq->ble_addr_type;
653 result.inq_res.inq_result_type = p_inq->inq_result_type;
654 result.inq_res.device_type = p_inq->device_type;
655 result.inq_res.flag = p_inq->flag;
656 result.inq_res.ble_evt_type = p_inq->ble_evt_type;
657 result.inq_res.ble_primary_phy = p_inq->ble_primary_phy;
658 result.inq_res.ble_secondary_phy = p_inq->ble_secondary_phy;
659 result.inq_res.ble_advertising_sid = p_inq->ble_advertising_sid;
660 result.inq_res.ble_tx_power = p_inq->ble_tx_power;
661 result.inq_res.ble_periodic_adv_int = p_inq->ble_periodic_adv_int;
662
663 /* application will parse EIR to find out remote device name */
664 result.inq_res.p_eir = const_cast<uint8_t*>(p_eir);
665 result.inq_res.eir_len = eir_len;
666
667 p_inq_info =
668 get_btm_client_interface().db.BTM_InqDbRead(p_inq->remote_bd_addr);
669 if (p_inq_info != NULL) {
670 /* initialize remt_name_not_required to false so that we get the name by
671 * default */
672 result.inq_res.remt_name_not_required = false;
673 }
674
675 if (p_inq_info) {
676 /* application indicates if it knows the remote name, inside the callback
677 copy that to the inquiry data base*/
678 if (result.inq_res.remt_name_not_required)
679 p_inq_info->appl_knows_rem_name = true;
680 }
681 }
682
683 /*******************************************************************************
684 *
685 * Function bta_dm_opportunistic_observe_results_cb
686 *
687 * Description Callback for BLE Observe result
688 *
689 *
690 * Returns void
691 *
692 ******************************************************************************/
bta_dm_opportunistic_observe_results_cb(tBTM_INQ_RESULTS * p_inq,const uint8_t * p_eir,uint16_t eir_len)693 static void bta_dm_opportunistic_observe_results_cb(tBTM_INQ_RESULTS* p_inq,
694 const uint8_t* p_eir,
695 uint16_t eir_len) {
696 tBTA_DM_SEARCH result;
697 tBTM_INQ_INFO* p_inq_info;
698
699 result.inq_res.bd_addr = p_inq->remote_bd_addr;
700 result.inq_res.rssi = p_inq->rssi;
701 result.inq_res.ble_addr_type = p_inq->ble_addr_type;
702 result.inq_res.inq_result_type = p_inq->inq_result_type;
703 result.inq_res.device_type = p_inq->device_type;
704 result.inq_res.flag = p_inq->flag;
705 result.inq_res.ble_evt_type = p_inq->ble_evt_type;
706 result.inq_res.ble_primary_phy = p_inq->ble_primary_phy;
707 result.inq_res.ble_secondary_phy = p_inq->ble_secondary_phy;
708 result.inq_res.ble_advertising_sid = p_inq->ble_advertising_sid;
709 result.inq_res.ble_tx_power = p_inq->ble_tx_power;
710 result.inq_res.ble_periodic_adv_int = p_inq->ble_periodic_adv_int;
711
712 /* application will parse EIR to find out remote device name */
713 result.inq_res.p_eir = const_cast<uint8_t*>(p_eir);
714 result.inq_res.eir_len = eir_len;
715
716 p_inq_info =
717 get_btm_client_interface().db.BTM_InqDbRead(p_inq->remote_bd_addr);
718 if (p_inq_info != NULL) {
719 /* initialize remt_name_not_required to false so that we get the name by
720 * default */
721 result.inq_res.remt_name_not_required = false;
722 }
723
724 if (bta_dm_search_cb.p_csis_scan_cback)
725 bta_dm_search_cb.p_csis_scan_cback(BTA_DM_INQ_RES_EVT, &result);
726
727 if (p_inq_info) {
728 /* application indicates if it knows the remote name, inside the callback
729 copy that to the inquiry data base*/
730 if (result.inq_res.remt_name_not_required)
731 p_inq_info->appl_knows_rem_name = true;
732 }
733 }
734
735 /*******************************************************************************
736 *
737 * Function bta_dm_observe_cmpl_cb
738 *
739 * Description Callback for BLE Observe complete
740 *
741 *
742 * Returns void
743 *
744 ******************************************************************************/
bta_dm_observe_cmpl_cb(void * p_result)745 static void bta_dm_observe_cmpl_cb(void* p_result) {
746 log::verbose("bta_dm_observe_cmpl_cb");
747
748 if (bta_dm_search_cb.p_csis_scan_cback) {
749 auto num_resps = ((tBTM_INQUIRY_CMPL*)p_result)->num_resp;
750 tBTA_DM_SEARCH data{.observe_cmpl{.num_resps = num_resps}};
751 bta_dm_search_cb.p_csis_scan_cback(BTA_DM_OBSERVE_CMPL_EVT, &data);
752 }
753 }
754
bta_dm_start_scan(uint8_t duration_sec,bool low_latency_scan=false)755 static void bta_dm_start_scan(uint8_t duration_sec,
756 bool low_latency_scan = false) {
757 tBTM_STATUS status = get_btm_client_interface().ble.BTM_BleObserve(
758 true, duration_sec, bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb,
759 low_latency_scan);
760
761 if (status != BTM_CMD_STARTED) {
762 log::warn("BTM_BleObserve failed. status {}", status);
763 if (bta_dm_search_cb.p_csis_scan_cback) {
764 tBTA_DM_SEARCH data{.observe_cmpl = {.num_resps = 0}};
765 bta_dm_search_cb.p_csis_scan_cback(BTA_DM_OBSERVE_CMPL_EVT, &data);
766 }
767 }
768 }
769
bta_dm_ble_scan(bool start,uint8_t duration_sec,bool low_latency_scan=false)770 void bta_dm_ble_scan(bool start, uint8_t duration_sec,
771 bool low_latency_scan = false) {
772 if (!start) {
773 if (get_btm_client_interface().ble.BTM_BleObserve(
774 false, 0, NULL, NULL, false) != BTM_CMD_STARTED) {
775 log::warn("Unable to start ble observe");
776 }
777 return;
778 }
779
780 bta_dm_start_scan(duration_sec, low_latency_scan);
781 }
782
bta_dm_ble_csis_observe(bool observe,tBTA_DM_SEARCH_CBACK * p_cback)783 void bta_dm_ble_csis_observe(bool observe, tBTA_DM_SEARCH_CBACK* p_cback) {
784 if (!observe) {
785 bta_dm_search_cb.p_csis_scan_cback = NULL;
786 BTM_BleOpportunisticObserve(false, NULL);
787 return;
788 }
789
790 /* Save the callback to be called when a scan results are available */
791 bta_dm_search_cb.p_csis_scan_cback = p_cback;
792 BTM_BleOpportunisticObserve(true, bta_dm_opportunistic_observe_results_cb);
793 }
794
795 namespace bluetooth {
796 namespace legacy {
797 namespace testing {
798
bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME * p)799 void bta_dm_remname_cback(const tBTM_REMOTE_DEV_NAME* p) {
800 ::bta_dm_remname_cback(p);
801 }
802
bta_dm_remote_name_cmpl(const tBTA_DM_REMOTE_NAME & remote_name_msg)803 void bta_dm_remote_name_cmpl(const tBTA_DM_REMOTE_NAME& remote_name_msg) {
804 ::bta_dm_remote_name_cmpl(remote_name_msg);
805 }
806
807 } // namespace testing
808 } // namespace legacy
809 } // namespace bluetooth
810
811 namespace {
812 constexpr size_t kSearchStateHistorySize = 50;
813 constexpr char kTimeFormatString[] = "%Y-%m-%d %H:%M:%S";
814
815 constexpr unsigned MillisPerSecond = 1000;
EpochMillisToString(long long time_ms)816 std::string EpochMillisToString(long long time_ms) {
817 time_t time_sec = time_ms / MillisPerSecond;
818 struct tm tm;
819 localtime_r(&time_sec, &tm);
820 std::string s = bluetooth::common::StringFormatTime(kTimeFormatString, tm);
821 return base::StringPrintf(
822 "%s.%03u", s.c_str(),
823 static_cast<unsigned int>(time_ms % MillisPerSecond));
824 }
825
826 } // namespace
827
828 struct tSEARCH_STATE_HISTORY {
829 const tBTA_DM_DEVICE_SEARCH_STATE state;
830 const tBTA_DM_DEV_SEARCH_EVT event;
ToStringtSEARCH_STATE_HISTORY831 std::string ToString() const {
832 return base::StringPrintf("state:%25s event:%s",
833 bta_dm_state_text(state).c_str(),
834 bta_dm_event_text(event).c_str());
835 }
836 };
837
838 bluetooth::common::TimestampedCircularBuffer<tSEARCH_STATE_HISTORY>
839 search_state_history_(kSearchStateHistorySize);
840
841 /*******************************************************************************
842 *
843 * Function bta_dm_search_sm_execute
844 *
845 * Description State machine event handling function for DM
846 *
847 *
848 * Returns void
849 *
850 ******************************************************************************/
bta_dm_search_sm_execute(tBTA_DM_DEV_SEARCH_EVT event,std::unique_ptr<tBTA_DM_SEARCH_MSG> msg)851 static void bta_dm_search_sm_execute(tBTA_DM_DEV_SEARCH_EVT event,
852 std::unique_ptr<tBTA_DM_SEARCH_MSG> msg) {
853 log::info("state:{}, event:{}[0x{:x}]",
854 bta_dm_state_text(bta_dm_search_get_state()),
855 bta_dm_event_text(event), event);
856 search_state_history_.Push({
857 .state = bta_dm_search_get_state(),
858 .event = event,
859 });
860
861 switch (bta_dm_search_get_state()) {
862 case BTA_DM_SEARCH_IDLE:
863 switch (event) {
864 case BTA_DM_API_SEARCH_EVT:
865 bta_dm_search_set_state(BTA_DM_SEARCH_ACTIVE);
866 log::assert_that(std::holds_alternative<tBTA_DM_API_SEARCH>(*msg),
867 "bad message type: {}", msg->index());
868
869 bta_dm_search_start(std::get<tBTA_DM_API_SEARCH>(*msg));
870 break;
871 case BTA_DM_API_SEARCH_CANCEL_EVT:
872 bta_dm_search_clear_queue();
873 bta_dm_search_cancel_notify();
874 break;
875 default:
876 log::info("Received unexpected event {}[0x{:x}] in state {}",
877 bta_dm_event_text(event), event,
878 bta_dm_state_text(bta_dm_search_get_state()));
879 }
880 break;
881 case BTA_DM_SEARCH_ACTIVE:
882 switch (event) {
883 case BTA_DM_REMT_NAME_EVT:
884 log::assert_that(std::holds_alternative<tBTA_DM_REMOTE_NAME>(*msg),
885 "bad message type: {}", msg->index());
886
887 bta_dm_remote_name_cmpl(std::get<tBTA_DM_REMOTE_NAME>(*msg));
888 break;
889 case BTA_DM_SEARCH_CMPL_EVT:
890 bta_dm_search_cmpl();
891 break;
892 case BTA_DM_API_SEARCH_CANCEL_EVT:
893 bta_dm_search_clear_queue();
894 bta_dm_search_set_state(BTA_DM_SEARCH_CANCELLING);
895 bta_dm_search_cancel();
896 break;
897 default:
898 log::info("Received unexpected event {}[0x{:x}] in state {}",
899 bta_dm_event_text(event), event,
900 bta_dm_state_text(bta_dm_search_get_state()));
901 }
902 break;
903 case BTA_DM_SEARCH_CANCELLING:
904 switch (event) {
905 case BTA_DM_API_SEARCH_EVT:
906 log::assert_that(std::holds_alternative<tBTA_DM_API_SEARCH>(*msg),
907 "bad message type: {}", msg->index());
908
909 bta_dm_queue_search(std::get<tBTA_DM_API_SEARCH>(*msg));
910 break;
911 case BTA_DM_API_SEARCH_CANCEL_EVT:
912 bta_dm_search_clear_queue();
913 bta_dm_search_cancel_notify();
914 break;
915 case BTA_DM_REMT_NAME_EVT:
916 case BTA_DM_SEARCH_CMPL_EVT:
917 bta_dm_search_set_state(BTA_DM_SEARCH_IDLE);
918 bta_dm_search_cancel_notify();
919 bta_dm_execute_queued_search_request();
920 break;
921 default:
922 log::info("Received unexpected event {}[0x{:x}] in state {}",
923 bta_dm_event_text(event), event,
924 bta_dm_state_text(bta_dm_search_get_state()));
925 }
926 break;
927 }
928 }
929
bta_dm_disable_search(void)930 static void bta_dm_disable_search(void) {
931 switch (bta_dm_search_get_state()) {
932 case BTA_DM_SEARCH_IDLE:
933 break;
934 case BTA_DM_SEARCH_ACTIVE:
935 case BTA_DM_SEARCH_CANCELLING:
936 default:
937 log::debug(
938 "Search state machine is not idle so issuing search cancel current "
939 "state:{}",
940 bta_dm_state_text(bta_dm_search_get_state()));
941 bta_dm_search_cancel();
942 }
943 }
944
bta_dm_disc_start_device_discovery(tBTA_DM_SEARCH_CBACK * p_cback)945 void bta_dm_disc_start_device_discovery(tBTA_DM_SEARCH_CBACK* p_cback) {
946 if (!com::android::bluetooth::flags::
947 separate_service_and_device_discovery()) {
948 bta_dm_disc_legacy::bta_dm_disc_start_device_discovery(p_cback);
949 return;
950 }
951 bta_dm_search_sm_execute(BTA_DM_API_SEARCH_EVT,
952 std::make_unique<tBTA_DM_SEARCH_MSG>(
953 tBTA_DM_API_SEARCH{.p_cback = p_cback}));
954 }
955
bta_dm_disc_stop_device_discovery()956 void bta_dm_disc_stop_device_discovery() {
957 if (!com::android::bluetooth::flags::
958 separate_service_and_device_discovery()) {
959 bta_dm_disc_legacy::bta_dm_disc_stop_device_discovery();
960 return;
961 }
962 bta_dm_search_sm_execute(BTA_DM_API_SEARCH_CANCEL_EVT, nullptr);
963 }
964
bta_dm_disc_init_search_cb(tBTA_DM_SEARCH_CB & bta_dm_search_cb)965 static void bta_dm_disc_init_search_cb(tBTA_DM_SEARCH_CB& bta_dm_search_cb) {
966 bta_dm_search_cb = {};
967 bta_dm_search_cb.search_state = BTA_DM_SEARCH_IDLE;
968 }
969
bta_dm_search_reset()970 static void bta_dm_search_reset() {
971 bta_dm_search_cb.p_pending_search.reset();
972 bta_dm_disc_init_search_cb(::bta_dm_search_cb);
973 }
974
bta_dm_search_stop()975 void bta_dm_search_stop() {
976 if (!com::android::bluetooth::flags::
977 separate_service_and_device_discovery()) {
978 log::info("no-op when flag is disabled");
979 return;
980 }
981 bta_dm_search_reset();
982 }
983
bta_dm_disc_discover_next_device()984 void bta_dm_disc_discover_next_device() {
985 if (!com::android::bluetooth::flags::
986 separate_service_and_device_discovery()) {
987 bta_dm_disc_legacy::bta_dm_disc_discover_next_device();
988 return;
989 }
990 bta_dm_discover_next_device();
991 }
992
993 #define DUMPSYS_TAG "shim::legacy::bta::dm"
DumpsysBtaDmSearch(int fd)994 void DumpsysBtaDmSearch(int fd) {
995 if (!com::android::bluetooth::flags::
996 separate_service_and_device_discovery()) {
997 log::info("no-op when flag is disabled");
998 return;
999 }
1000 auto copy = search_state_history_.Pull();
1001 LOG_DUMPSYS(fd, " last %zu search state transitions", copy.size());
1002 for (const auto& it : copy) {
1003 LOG_DUMPSYS(fd, " %s %s", EpochMillisToString(it.timestamp).c_str(),
1004 it.entry.ToString().c_str());
1005 }
1006 LOG_DUMPSYS(fd, " current bta_dm_search_state:%s",
1007 bta_dm_state_text(bta_dm_search_get_state()).c_str());
1008 }
1009 #undef DUMPSYS_TAG
1010
1011 namespace bluetooth {
1012 namespace legacy {
1013 namespace testing {
1014
bta_dm_disc_init_search_cb(tBTA_DM_SEARCH_CB & bta_dm_search_cb)1015 void bta_dm_disc_init_search_cb(tBTA_DM_SEARCH_CB& bta_dm_search_cb) {
1016 ::bta_dm_disc_init_search_cb(bta_dm_search_cb);
1017 }
bta_dm_discover_next_device()1018 void bta_dm_discover_next_device() { ::bta_dm_discover_next_device(); }
1019
bta_dm_disc_get_search_cb()1020 tBTA_DM_SEARCH_CB bta_dm_disc_get_search_cb() {
1021 tBTA_DM_SEARCH_CB search_cb = {};
1022 ::bta_dm_disc_init_search_cb(search_cb);
1023 return search_cb;
1024 }
bta_dm_disc_search_cb()1025 tBTA_DM_SEARCH_CB& bta_dm_disc_search_cb() { return ::bta_dm_search_cb; }
bta_dm_read_remote_device_name(const RawAddress & bd_addr,tBT_TRANSPORT transport)1026 bool bta_dm_read_remote_device_name(const RawAddress& bd_addr,
1027 tBT_TRANSPORT transport) {
1028 return ::bta_dm_read_remote_device_name(bd_addr, transport);
1029 }
1030
bta_dm_inq_cmpl()1031 void bta_dm_inq_cmpl() { ::bta_dm_inq_cmpl(); }
bta_dm_inq_cmpl_cb(void * p_result)1032 void bta_dm_inq_cmpl_cb(void* p_result) { ::bta_dm_inq_cmpl_cb(p_result); }
bta_dm_observe_cmpl_cb(void * p_result)1033 void bta_dm_observe_cmpl_cb(void* p_result) {
1034 ::bta_dm_observe_cmpl_cb(p_result);
1035 }
bta_dm_observe_results_cb(tBTM_INQ_RESULTS * p_inq,const uint8_t * p_eir,uint16_t eir_len)1036 void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq, const uint8_t* p_eir,
1037 uint16_t eir_len) {
1038 ::bta_dm_observe_results_cb(p_inq, p_eir, eir_len);
1039 }
bta_dm_opportunistic_observe_results_cb(tBTM_INQ_RESULTS * p_inq,const uint8_t * p_eir,uint16_t eir_len)1040 void bta_dm_opportunistic_observe_results_cb(tBTM_INQ_RESULTS* p_inq,
1041 const uint8_t* p_eir,
1042 uint16_t eir_len) {
1043 ::bta_dm_opportunistic_observe_results_cb(p_inq, p_eir, eir_len);
1044 }
bta_dm_queue_search(tBTA_DM_API_SEARCH & search)1045 void bta_dm_queue_search(tBTA_DM_API_SEARCH& search) {
1046 ::bta_dm_queue_search(search);
1047 }
1048
bta_dm_start_scan(uint8_t duration_sec,bool low_latency_scan=false)1049 void bta_dm_start_scan(uint8_t duration_sec, bool low_latency_scan = false) {
1050 ::bta_dm_start_scan(duration_sec, low_latency_scan);
1051 }
1052
1053 } // namespace testing
1054 } // namespace legacy
1055 } // namespace bluetooth
1056