1/******************************************************************************
2 *
3 *  Copyright 2003-2014 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 *  This file contains the action functions for device manager state
22 *  machine.
23 *
24 ******************************************************************************/
25
26#define LOG_TAG "bt_bta_dm"
27
28#include <base/bind.h>
29#include <base/callback.h>
30#include <base/logging.h>
31#include <string.h>
32
33#include "bt_common.h"
34#include "bt_target.h"
35#include "bt_types.h"
36#include "bta_api.h"
37#include "bta_dm_api.h"
38#include "bta_dm_co.h"
39#include "bta_dm_int.h"
40#include "bta_sys.h"
41#include "btm_api.h"
42#include "btm_int.h"
43#include "btu.h"
44#include "gap_api.h" /* For GAP_BleReadPeerPrefConnParams */
45#include "l2c_api.h"
46#include "osi/include/log.h"
47#include "osi/include/osi.h"
48#include "sdp_api.h"
49#include "utl.h"
50
51#if (GAP_INCLUDED == TRUE)
52#include "gap_api.h"
53#endif
54
55using bluetooth::Uuid;
56
57static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, uint8_t* p_eir,
58                                  uint16_t eir_len);
59static void bta_dm_inq_cmpl_cb(void* p_result);
60static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr,
61                                                DEV_CLASS dc, BD_NAME bd_name);
62static void bta_dm_remname_cback(void* p);
63static void bta_dm_find_services(const RawAddress& bd_addr);
64static void bta_dm_discover_next_device(void);
65static void bta_dm_sdp_callback(uint16_t sdp_status);
66static uint8_t bta_dm_authorize_cback(const RawAddress& bd_addr,
67                                      DEV_CLASS dev_class, BD_NAME bd_name,
68                                      uint8_t* service_name, uint8_t service_id,
69                                      bool is_originator);
70static uint8_t bta_dm_pin_cback(const RawAddress& bd_addr, DEV_CLASS dev_class,
71                                BD_NAME bd_name, bool min_16_digit);
72static uint8_t bta_dm_new_link_key_cback(const RawAddress& bd_addr,
73                                         DEV_CLASS dev_class, BD_NAME bd_name,
74                                         LINK_KEY key, uint8_t key_type);
75static uint8_t bta_dm_authentication_complete_cback(const RawAddress& bd_addr,
76                                                    DEV_CLASS dev_class,
77                                                    BD_NAME bd_name,
78                                                    int result);
79static void bta_dm_local_name_cback(void* p_name);
80static bool bta_dm_check_av(uint16_t event);
81static void bta_dm_bl_change_cback(tBTM_BL_EVENT_DATA* p_data);
82
83static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
84                                uint8_t app_id, const RawAddress& peer_addr);
85
86/* Extended Inquiry Response */
87static uint8_t bta_dm_sp_cback(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data);
88
89static void bta_dm_set_eir(char* local_name);
90
91static void bta_dm_eir_search_services(tBTM_INQ_RESULTS* p_result,
92                                       tBTA_SERVICE_MASK* p_services_to_search,
93                                       tBTA_SERVICE_MASK* p_services_found);
94
95static void bta_dm_search_timer_cback(void* data);
96static void bta_dm_disable_conn_down_timer_cback(void* data);
97static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
98                            uint8_t app_id, const RawAddress& peer_addr);
99static void bta_dm_adjust_roles(bool delay_role_switch);
100static char* bta_dm_get_remname(void);
101static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result);
102
103static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr,
104                                           tBT_TRANSPORT transport);
105static void bta_dm_discover_device(const RawAddress& remote_bd_addr);
106
107static void bta_dm_sys_hw_cback(tBTA_SYS_HW_EVT status);
108static void bta_dm_disable_search_and_disc(void);
109
110static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda,
111                                    tBTM_LE_EVT_DATA* p_data);
112static void bta_dm_ble_id_key_cback(uint8_t key_type,
113                                    tBTM_BLE_LOCAL_KEYS* p_key);
114static void bta_dm_gattc_register(void);
115static void btm_dm_start_gatt_discovery(const RawAddress& bd_addr);
116static void bta_dm_cancel_gatt_discovery(const RawAddress& bd_addr);
117static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
118extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void);
119
120#if (BLE_VND_INCLUDED == TRUE)
121static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result);
122#endif
123
124#ifndef BTA_DM_BLE_ADV_CHNL_MAP
125#define BTA_DM_BLE_ADV_CHNL_MAP \
126  (BTM_BLE_ADV_CHNL_37 | BTM_BLE_ADV_CHNL_38 | BTM_BLE_ADV_CHNL_39)
127#endif
128
129/* Disable timer interval (in milliseconds) */
130#ifndef BTA_DM_DISABLE_TIMER_MS
131#define BTA_DM_DISABLE_TIMER_MS 5000
132#endif
133
134/* Disable timer retrial interval (in milliseconds) */
135#ifndef BTA_DM_DISABLE_TIMER_RETRIAL_MS
136#define BTA_DM_DISABLE_TIMER_RETRIAL_MS 1500
137#endif
138
139/* Disable connection down timer (in milliseconds) */
140#ifndef BTA_DM_DISABLE_CONN_DOWN_TIMER_MS
141#define BTA_DM_DISABLE_CONN_DOWN_TIMER_MS 1000
142#endif
143
144/* Switch delay timer (in milliseconds) */
145#ifndef BTA_DM_SWITCH_DELAY_TIMER_MS
146#define BTA_DM_SWITCH_DELAY_TIMER_MS 500
147#endif
148
149static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr);
150static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr);
151static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq, uint8_t* p_eir,
152                                      uint16_t eir_len);
153static void bta_dm_observe_cmpl_cb(void* p_result);
154static void bta_dm_delay_role_switch_cback(void* data);
155static void bta_dm_disable_timer_cback(void* data);
156
157const uint16_t bta_service_id_to_uuid_lkup_tbl[BTA_MAX_SERVICE_ID] = {
158    UUID_SERVCLASS_PNP_INFORMATION,       /* Reserved */
159    UUID_SERVCLASS_SERIAL_PORT,           /* BTA_SPP_SERVICE_ID */
160    UUID_SERVCLASS_DIALUP_NETWORKING,     /* BTA_DUN_SERVICE_ID */
161    UUID_SERVCLASS_AUDIO_SOURCE,          /* BTA_A2DP_SOURCE_SERVICE_ID */
162    UUID_SERVCLASS_LAN_ACCESS_USING_PPP,  /* BTA_LAP_SERVICE_ID */
163    UUID_SERVCLASS_HEADSET,               /* BTA_HSP_HS_SERVICE_ID */
164    UUID_SERVCLASS_HF_HANDSFREE,          /* BTA_HFP_HS_SERVICE_ID */
165    UUID_SERVCLASS_OBEX_OBJECT_PUSH,      /* BTA_OPP_SERVICE_ID */
166    UUID_SERVCLASS_OBEX_FILE_TRANSFER,    /* BTA_FTP_SERVICE_ID */
167    UUID_SERVCLASS_CORDLESS_TELEPHONY,    /* BTA_CTP_SERVICE_ID */
168    UUID_SERVCLASS_INTERCOM,              /* BTA_ICP_SERVICE_ID */
169    UUID_SERVCLASS_IRMC_SYNC,             /* BTA_SYNC_SERVICE_ID */
170    UUID_SERVCLASS_DIRECT_PRINTING,       /* BTA_BPP_SERVICE_ID */
171    UUID_SERVCLASS_IMAGING_RESPONDER,     /* BTA_BIP_SERVICE_ID */
172    UUID_SERVCLASS_PANU,                  /* BTA_PANU_SERVICE_ID */
173    UUID_SERVCLASS_NAP,                   /* BTA_NAP_SERVICE_ID */
174    UUID_SERVCLASS_GN,                    /* BTA_GN_SERVICE_ID */
175    UUID_SERVCLASS_SAP,                   /* BTA_SAP_SERVICE_ID */
176    UUID_SERVCLASS_AUDIO_SINK,            /* BTA_A2DP_SERVICE_ID */
177    UUID_SERVCLASS_AV_REMOTE_CONTROL,     /* BTA_AVRCP_SERVICE_ID */
178    UUID_SERVCLASS_HUMAN_INTERFACE,       /* BTA_HID_SERVICE_ID */
179    UUID_SERVCLASS_VIDEO_SINK,            /* BTA_VDP_SERVICE_ID */
180    UUID_SERVCLASS_PBAP_PSE,              /* BTA_PBAP_SERVICE_ID */
181    UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, /* BTA_HSP_SERVICE_ID */
182    UUID_SERVCLASS_AG_HANDSFREE,          /* BTA_HFP_SERVICE_ID */
183    UUID_SERVCLASS_MESSAGE_ACCESS,        /* BTA_MAP_SERVICE_ID */
184    UUID_SERVCLASS_MESSAGE_NOTIFICATION,  /* BTA_MN_SERVICE_ID */
185    UUID_SERVCLASS_HDP_PROFILE,           /* BTA_HDP_SERVICE_ID */
186    UUID_SERVCLASS_PBAP_PCE,              /* BTA_PCE_SERVICE_ID */
187    UUID_PROTOCOL_ATT                     /* BTA_GATT_SERVICE_ID */
188};
189
190/*
191 * NOTE : The number of element in bta_service_id_to_btm_srv_id_lkup_tbl should
192 * be matching with
193 *        the value BTA_MAX_SERVICE_ID in bta_api.h
194 *
195 *        i.e., If you add new Service ID for BTA, the correct security ID of
196 * the new service
197 *              from Security service definitions (btm_api.h) should be added to
198 * this lookup table.
199 */
200const uint32_t bta_service_id_to_btm_srv_id_lkup_tbl[BTA_MAX_SERVICE_ID] = {
201    0,                             /* Reserved */
202    BTM_SEC_SERVICE_SERIAL_PORT,   /* BTA_SPP_SERVICE_ID */
203    BTM_SEC_SERVICE_DUN,           /* BTA_DUN_SERVICE_ID */
204    BTM_SEC_SERVICE_AVDTP,         /* BTA_AUDIO_SOURCE_SERVICE_ID */
205    BTM_SEC_SERVICE_LAN_ACCESS,    /* BTA_LAP_SERVICE_ID */
206    BTM_SEC_SERVICE_HEADSET_AG,    /* BTA_HSP_SERVICE_ID */
207    BTM_SEC_SERVICE_AG_HANDSFREE,  /* BTA_HFP_SERVICE_ID */
208    BTM_SEC_SERVICE_OBEX,          /* BTA_OPP_SERVICE_ID */
209    BTM_SEC_SERVICE_OBEX_FTP,      /* BTA_FTP_SERVICE_ID */
210    BTM_SEC_SERVICE_CORDLESS,      /* BTA_CTP_SERVICE_ID */
211    BTM_SEC_SERVICE_INTERCOM,      /* BTA_ICP_SERVICE_ID */
212    BTM_SEC_SERVICE_IRMC_SYNC,     /* BTA_SYNC_SERVICE_ID */
213    BTM_SEC_SERVICE_BPP_JOB,       /* BTA_BPP_SERVICE_ID */
214    BTM_SEC_SERVICE_BIP,           /* BTA_BIP_SERVICE_ID */
215    BTM_SEC_SERVICE_BNEP_PANU,     /* BTA_PANU_SERVICE_ID */
216    BTM_SEC_SERVICE_BNEP_NAP,      /* BTA_NAP_SERVICE_ID */
217    BTM_SEC_SERVICE_BNEP_GN,       /* BTA_GN_SERVICE_ID */
218    BTM_SEC_SERVICE_SAP,           /* BTA_SAP_SERVICE_ID */
219    BTM_SEC_SERVICE_AVDTP,         /* BTA_A2DP_SERVICE_ID */
220    BTM_SEC_SERVICE_AVCTP,         /* BTA_AVRCP_SERVICE_ID */
221    BTM_SEC_SERVICE_HIDH_SEC_CTRL, /* BTA_HID_SERVICE_ID */
222    BTM_SEC_SERVICE_AVDTP,         /* BTA_VDP_SERVICE_ID */
223    BTM_SEC_SERVICE_PBAP,          /* BTA_PBAP_SERVICE_ID */
224    BTM_SEC_SERVICE_HEADSET,       /* BTA_HSP_HS_SERVICE_ID */
225    BTM_SEC_SERVICE_HF_HANDSFREE,  /* BTA_HFP_HS_SERVICE_ID */
226    BTM_SEC_SERVICE_MAP,           /* BTA_MAP_SERVICE_ID */
227    BTM_SEC_SERVICE_MAP,           /* BTA_MN_SERVICE_ID */
228    BTM_SEC_SERVICE_HDP_SNK,       /* BTA_HDP_SERVICE_ID */
229    BTM_SEC_SERVICE_PBAP,          /* BTA_PCE_SERVICE_ID */
230    BTM_SEC_SERVICE_ATT            /* BTA_GATT_SERVICE_ID */
231};
232
233/* bta security callback */
234const tBTM_APPL_INFO bta_security = {&bta_dm_authorize_cback,
235                                     &bta_dm_pin_cback,
236                                     &bta_dm_new_link_key_cback,
237                                     &bta_dm_authentication_complete_cback,
238                                     &bta_dm_bond_cancel_complete_cback,
239                                     &bta_dm_sp_cback,
240                                     &bta_dm_ble_smp_cback,
241                                     &bta_dm_ble_id_key_cback};
242
243#define MAX_DISC_RAW_DATA_BUF (4096)
244uint8_t g_disc_raw_data_buf[MAX_DISC_RAW_DATA_BUF];
245
246extern DEV_CLASS local_device_default_class;
247
248/** Initialises the BT device manager */
249void bta_dm_enable(tBTA_DM_SEC_CBACK* p_sec_cback) {
250  /* if already in use, return an error */
251  if (bta_dm_cb.is_bta_dm_active) {
252    tBTA_DM_SEC enable_event;
253    APPL_TRACE_WARNING("%s Device already started by another application",
254                       __func__);
255    memset(&enable_event, 0, sizeof(tBTA_DM_SEC));
256    enable_event.enable.status = BTA_FAILURE;
257    if (p_sec_cback != NULL) p_sec_cback(BTA_DM_ENABLE_EVT, &enable_event);
258    return;
259  }
260
261  /* first, register our callback to SYS HW manager */
262  bta_sys_hw_register(BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback);
263
264  /* make sure security callback is saved - if no callback, do not erase the
265  previous one,
266  it could be an error recovery mechanism */
267  if (p_sec_cback != NULL) bta_dm_cb.p_sec_cback = p_sec_cback;
268  /* notify BTA DM is now active */
269  bta_dm_cb.is_bta_dm_active = true;
270
271  /* send a message to BTA SYS */
272  tBTA_SYS_HW_MSG* sys_enable_event =
273      (tBTA_SYS_HW_MSG*)osi_malloc(sizeof(tBTA_SYS_HW_MSG));
274  sys_enable_event->hdr.event = BTA_SYS_API_ENABLE_EVT;
275  sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;
276
277  bta_sys_sendmsg(sys_enable_event);
278}
279
280/*******************************************************************************
281 *
282 * Function         bta_dm_init_cb
283 *
284 * Description      Initializes the bta_dm_cb control block
285 *
286 *
287 * Returns          void
288 *
289 ******************************************************************************/
290void bta_dm_init_cb(void) {
291  memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
292  bta_dm_cb.disable_timer = alarm_new("bta_dm.disable_timer");
293  bta_dm_cb.switch_delay_timer = alarm_new("bta_dm.switch_delay_timer");
294  for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
295    for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
296      bta_dm_cb.pm_timer[i].timer[j] = alarm_new("bta_dm.pm_timer");
297    }
298  }
299}
300
301/*******************************************************************************
302 *
303 * Function         bta_dm_deinit_cb
304 *
305 * Description      De-initializes the bta_dm_cb control block
306 *
307 *
308 * Returns          void
309 *
310 ******************************************************************************/
311void bta_dm_deinit_cb(void) {
312  /*
313   * TODO: Should alarm_free() the bta_dm_cb timers during graceful
314   * shutdown.
315   */
316  alarm_free(bta_dm_cb.disable_timer);
317  alarm_free(bta_dm_cb.switch_delay_timer);
318  for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
319    for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
320      alarm_free(bta_dm_cb.pm_timer[i].timer[j]);
321    }
322  }
323  memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
324}
325
326/*******************************************************************************
327 *
328 * Function         bta_dm_sys_hw_cback
329 *
330 * Description     callback register to SYS to get HW status updates
331 *
332 *
333 * Returns          void
334 *
335 ******************************************************************************/
336static void bta_dm_sys_hw_cback(tBTA_SYS_HW_EVT status) {
337  DEV_CLASS dev_class;
338  tBTA_DM_SEC_CBACK* temp_cback;
339  uint8_t key_mask = 0;
340  BT_OCTET16 er;
341  tBTA_BLE_LOCAL_ID_KEYS id_key;
342
343  APPL_TRACE_DEBUG("%s with event: %i", __func__, status);
344
345  /* On H/W error evt, report to the registered DM application callback */
346  if (status == BTA_SYS_HW_ERROR_EVT) {
347    if (bta_dm_cb.p_sec_cback != NULL)
348      bta_dm_cb.p_sec_cback(BTA_DM_HW_ERROR_EVT, NULL);
349    return;
350  }
351
352  if (status == BTA_SYS_HW_OFF_EVT) {
353    if (bta_dm_cb.p_sec_cback != NULL)
354      bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL);
355
356    /* reinitialize the control block */
357    bta_dm_deinit_cb();
358
359    /* hw is ready, go on with BTA DM initialization */
360    alarm_free(bta_dm_search_cb.search_timer);
361    alarm_free(bta_dm_search_cb.gatt_close_timer);
362    memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb));
363
364    /* unregister from SYS */
365    bta_sys_hw_unregister(BTA_SYS_HW_BLUETOOTH);
366    /* notify BTA DM is now unactive */
367    bta_dm_cb.is_bta_dm_active = false;
368  } else if (status == BTA_SYS_HW_ON_EVT) {
369    /* FIXME: We should not unregister as the SYS shall invoke this callback on
370     * a H/W error.
371     * We need to revisit when this platform has more than one BLuetooth H/W
372     * chip
373     */
374    // bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH);
375
376    /* save security callback */
377    temp_cback = bta_dm_cb.p_sec_cback;
378    /* make sure the control block is properly initialized */
379    bta_dm_init_cb();
380    /* and retrieve the callback */
381    bta_dm_cb.p_sec_cback = temp_cback;
382    bta_dm_cb.is_bta_dm_active = true;
383
384    /* hw is ready, go on with BTA DM initialization */
385    alarm_free(bta_dm_search_cb.search_timer);
386    alarm_free(bta_dm_search_cb.gatt_close_timer);
387    memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb));
388    /*
389     * TODO: Should alarm_free() the bta_dm_search_cb timers during
390     * graceful shutdown.
391     */
392    bta_dm_search_cb.search_timer = alarm_new("bta_dm_search.search_timer");
393    bta_dm_search_cb.gatt_close_timer =
394        alarm_new("bta_dm_search.gatt_close_timer");
395
396    memset(&bta_dm_conn_srvcs, 0, sizeof(bta_dm_conn_srvcs));
397    memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB));
398
399    memcpy(dev_class, p_bta_dm_cfg->dev_class, sizeof(dev_class));
400    BTM_SetDeviceClass(dev_class);
401
402    /* load BLE local information: ID keys, ER if available */
403    bta_dm_co_ble_load_local_keys(&key_mask, er, &id_key);
404
405    if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ER) {
406      BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ER,
407                           (tBTM_BLE_LOCAL_KEYS*)&er);
408    }
409    if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ID) {
410      BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ID,
411                           (tBTM_BLE_LOCAL_KEYS*)&id_key);
412    }
413    bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID;
414
415    BTM_SecRegister(&bta_security);
416    BTM_SetDefaultLinkSuperTout(p_bta_dm_cfg->link_timeout);
417    BTM_WritePageTimeout(p_bta_dm_cfg->page_timeout);
418    bta_dm_cb.cur_policy = p_bta_dm_cfg->policy_settings;
419    BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
420    BTM_RegBusyLevelNotif(bta_dm_bl_change_cback, NULL,
421                          BTM_BL_UPDATE_MASK | BTM_BL_ROLE_CHG_MASK);
422
423#if (BLE_VND_INCLUDED == TRUE)
424    BTM_BleReadControllerFeatures(bta_dm_ctrl_features_rd_cmpl_cback);
425#else
426    /* If VSC multi adv commands are available, advertising will be initialized
427     * when capabilities are read. If they are not avaliable, initialize
428     * advertising here */
429    btm_ble_adv_init();
430#endif
431
432    /* Earlier, we used to invoke BTM_ReadLocalAddr which was just copying the
433       bd_addr
434       from the control block and invoking the callback which was sending the
435       DM_ENABLE_EVT.
436       But then we have a few HCI commands being invoked above which were still
437       in progress
438       when the ENABLE_EVT was sent. So modified this to fetch the local name
439       which forces
440       the DM_ENABLE_EVT to be sent only after all the init steps are complete
441       */
442    BTM_ReadLocalDeviceNameFromController(bta_dm_local_name_cback);
443
444    bta_sys_rm_register(bta_dm_rm_cback);
445
446    /* initialize bluetooth low power manager */
447    bta_dm_init_pm();
448
449    bta_sys_policy_register(bta_dm_policy_cback);
450
451    bta_dm_gattc_register();
452
453  } else
454    APPL_TRACE_DEBUG(" --- ignored event");
455}
456
457/** Disables the BT device manager */
458void bta_dm_disable() {
459  /* Set l2cap idle timeout to 0 (so BTE immediately disconnects ACL link after
460   * last channel is closed) */
461  L2CA_SetIdleTimeoutByBdAddr(RawAddress::kAny, 0, BT_TRANSPORT_BR_EDR);
462  L2CA_SetIdleTimeoutByBdAddr(RawAddress::kAny, 0, BT_TRANSPORT_LE);
463
464  /* disable all active subsystems */
465  bta_sys_disable(BTA_SYS_HW_BLUETOOTH);
466
467  BTM_SetDiscoverability(BTM_NON_DISCOVERABLE, 0, 0);
468  BTM_SetConnectability(BTM_NON_CONNECTABLE, 0, 0);
469
470  bta_dm_disable_pm();
471  bta_dm_disable_search_and_disc();
472  bta_dm_cb.disabling = true;
473
474  BTM_BleClearBgConnDev();
475
476  if (BTM_GetNumAclLinks() == 0) {
477#if (BTA_DISABLE_DELAY > 0)
478    /* If BTA_DISABLE_DELAY is defined and greater than zero, then delay the
479     * shutdown by
480     * BTA_DISABLE_DELAY milliseconds
481     */
482    APPL_TRACE_WARNING("%s BTA_DISABLE_DELAY set to %d ms", __func__,
483                       BTA_DISABLE_DELAY);
484    alarm_set_on_mloop(bta_dm_cb.disable_timer, BTA_DISABLE_DELAY,
485                       bta_dm_disable_conn_down_timer_cback, NULL);
486#else
487    bta_dm_disable_conn_down_timer_cback(NULL);
488#endif
489  } else {
490    alarm_set_on_mloop(bta_dm_cb.disable_timer, BTA_DM_DISABLE_TIMER_MS,
491                       bta_dm_disable_timer_cback, UINT_TO_PTR(0));
492  }
493}
494
495/*******************************************************************************
496 *
497 * Function         bta_dm_disable_timer_cback
498 *
499 * Description      Called if the disable timer expires
500 *                  Used to close ACL connections which are still active
501 *
502 *
503 *
504 * Returns          void
505 *
506 ******************************************************************************/
507static void bta_dm_disable_timer_cback(void* data) {
508  uint8_t i;
509  tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
510  bool trigger_disc = false;
511  uint32_t param = PTR_TO_UINT(data);
512
513  APPL_TRACE_EVENT("%s trial %u", __func__, param);
514
515  if (BTM_GetNumAclLinks() && (param == 0)) {
516    for (i = 0; i < bta_dm_cb.device_list.count; i++) {
517      transport = bta_dm_cb.device_list.peer_device[i].transport;
518      btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
519                     transport);
520      trigger_disc = true;
521    }
522
523    /* Retrigger disable timer in case ACL disconnect failed, DISABLE_EVT still
524       need
525        to be sent out to avoid jave layer disable timeout */
526    if (trigger_disc) {
527      alarm_set_on_mloop(bta_dm_cb.disable_timer,
528                         BTA_DM_DISABLE_TIMER_RETRIAL_MS,
529                         bta_dm_disable_timer_cback, UINT_TO_PTR(1));
530    }
531  } else {
532    bta_dm_cb.disabling = false;
533
534    bta_sys_remove_uuid(UUID_SERVCLASS_PNP_INFORMATION);
535    bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL);
536  }
537}
538
539/** Sets local device name */
540void bta_dm_set_dev_name(const std::vector<uint8_t>& name) {
541  BTM_SetLocalDeviceName((char*)name.data());
542  bta_dm_set_eir((char*)name.data());
543}
544
545/** Sets discoverability, connectability and pairability */
546void bta_dm_set_visibility(tBTA_DM_DISC disc_mode_param,
547                           tBTA_DM_CONN conn_mode_param, uint8_t pairable_mode,
548                           uint8_t conn_paired_only) {
549  uint16_t window, interval;
550  uint16_t le_disc_mode = BTM_BleReadDiscoverability();
551  uint16_t le_conn_mode = BTM_BleReadConnectability();
552  uint16_t disc_mode = BTM_ReadDiscoverability(&window, &interval);
553  uint16_t conn_mode = BTM_ReadConnectability(&window, &interval);
554
555  /* set modes for Discoverability and connectability if not ignore */
556  if (disc_mode_param != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE)) {
557    if ((disc_mode_param & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE)
558      disc_mode_param = ((disc_mode_param & ~BTA_DM_LE_IGNORE) | le_disc_mode);
559    if ((disc_mode_param & BTA_DM_IGNORE) == BTA_DM_IGNORE)
560      disc_mode_param = ((disc_mode_param & ~BTA_DM_IGNORE) | disc_mode);
561
562    BTM_SetDiscoverability(disc_mode_param, bta_dm_cb.inquiry_scan_window,
563                           bta_dm_cb.inquiry_scan_interval);
564  }
565
566  if (conn_mode_param != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE)) {
567    if ((conn_mode_param & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE)
568      conn_mode_param = ((conn_mode_param & ~BTA_DM_LE_IGNORE) | le_conn_mode);
569    if ((conn_mode_param & BTA_DM_IGNORE) == BTA_DM_IGNORE)
570      conn_mode_param = ((conn_mode_param & ~BTA_DM_IGNORE) | conn_mode);
571
572    BTM_SetConnectability(conn_mode_param, bta_dm_cb.page_scan_window,
573                          bta_dm_cb.page_scan_interval);
574  }
575
576  /* Send False or True if not ignore */
577  if (pairable_mode != BTA_DM_IGNORE) {
578    if (pairable_mode == BTA_DM_NON_PAIRABLE)
579      bta_dm_cb.disable_pair_mode = true;
580    else
581      bta_dm_cb.disable_pair_mode = false;
582  }
583
584  /* Send False or True if not ignore */
585  if (conn_paired_only != BTA_DM_IGNORE) {
586    if (conn_paired_only == BTA_DM_CONN_ALL)
587      bta_dm_cb.conn_paired_only = false;
588    else
589      bta_dm_cb.conn_paired_only = true;
590  }
591
592  /* Change mode if either mode is not ignore */
593  if (pairable_mode != BTA_DM_IGNORE || conn_paired_only != BTA_DM_IGNORE)
594    BTM_SetPairableMode((bool)(!(bta_dm_cb.disable_pair_mode)),
595                        bta_dm_cb.conn_paired_only);
596}
597
598/*******************************************************************************
599 *
600 * Function         bta_dm_process_remove_device
601 *
602 * Description      Removes device, Disconnects ACL link if required.
603 ***
604 ******************************************************************************/
605void bta_dm_process_remove_device(const RawAddress& bd_addr) {
606  /* need to remove all pending background connection before unpair */
607  BTA_GATTC_CancelOpen(0, bd_addr, false);
608
609  BTM_SecDeleteDevice(bd_addr);
610
611  /* remove all cached GATT information */
612  BTA_GATTC_Refresh(bd_addr);
613
614  if (bta_dm_cb.p_sec_cback) {
615    tBTA_DM_SEC sec_event;
616    sec_event.link_down.bd_addr = bd_addr;
617    ;
618    /* No connection, set status to success (acl disc code not valid) */
619    sec_event.link_down.status = HCI_SUCCESS;
620    bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event);
621  }
622}
623
624/** Removes device, disconnects ACL link if required */
625void bta_dm_remove_device(const RawAddress& bd_addr) {
626  /* If ACL exists for the device in the remove_bond message*/
627  bool is_bd_addr_connected =
628      BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) ||
629      BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR);
630
631  uint8_t other_transport = BT_TRANSPORT_INVALID;
632  if (is_bd_addr_connected) {
633    APPL_TRACE_DEBUG("%s: ACL Up count: %d", __func__,
634                     bta_dm_cb.device_list.count);
635
636    /* Take the link down first, and mark the device for removal when
637     * disconnected */
638    for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
639      auto& peer_device = bta_dm_cb.device_list.peer_device[i];
640      if (peer_device.peer_bdaddr == bd_addr) {
641        peer_device.conn_state = BTA_DM_UNPAIRING;
642        btm_remove_acl(bd_addr, peer_device.transport);
643        APPL_TRACE_DEBUG("%s: transport: %d", __func__, peer_device.transport);
644
645        /* save the other transport to check if device is connected on
646         * other_transport */
647        if (peer_device.transport == BT_TRANSPORT_LE)
648          other_transport = BT_TRANSPORT_BR_EDR;
649        else
650          other_transport = BT_TRANSPORT_LE;
651
652        break;
653      }
654    }
655  }
656
657  RawAddress other_address = bd_addr;
658  RawAddress other_address2 = bd_addr;
659
660  // If it is DUMO device and device is paired as different address, unpair that
661  // device
662  bool other_address_connected =
663      (other_transport)
664          ? BTM_ReadConnectedTransportAddress(&other_address, other_transport)
665          : (BTM_ReadConnectedTransportAddress(&other_address,
666                                               BT_TRANSPORT_BR_EDR) ||
667             BTM_ReadConnectedTransportAddress(&other_address2,
668                                               BT_TRANSPORT_LE));
669  if (other_address == bd_addr) other_address = other_address2;
670
671  if (other_address_connected) {
672    /* Take the link down first, and mark the device for removal when
673     * disconnected */
674    for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
675      auto& peer_device = bta_dm_cb.device_list.peer_device[i];
676      if (peer_device.peer_bdaddr == other_address) {
677        peer_device.conn_state = BTA_DM_UNPAIRING;
678        btm_remove_acl(other_address, peer_device.transport);
679        break;
680      }
681    }
682  }
683
684  /* Delete the device mentioned in the msg */
685  if (!is_bd_addr_connected) {
686    bta_dm_process_remove_device(bd_addr);
687  }
688
689  /* Delete the other paired device too */
690  if (!other_address_connected && !other_address.IsEmpty()) {
691    bta_dm_process_remove_device(other_address);
692  }
693}
694
695/*******************************************************************************
696 *
697 * Function         bta_dm_add_device
698 *
699 * Description      This function adds a Link Key to an security database entry.
700 *                  It is normally called during host startup to restore all
701 *                  required information stored in the NVRAM.
702 ***
703 ******************************************************************************/
704void bta_dm_add_device(std::unique_ptr<tBTA_DM_API_ADD_DEVICE> msg) {
705  uint8_t* p_dc = NULL;
706  uint8_t* p_lc = NULL;
707  uint32_t trusted_services_mask[BTM_SEC_SERVICE_ARRAY_SIZE];
708  uint8_t index = 0;
709  uint8_t btm_mask_index = 0;
710
711  memset(trusted_services_mask, 0, sizeof(trusted_services_mask));
712
713  /* If not all zeros, the device class has been specified */
714  if (msg->dc_known) p_dc = (uint8_t*)msg->dc;
715
716  if (msg->link_key_known) p_lc = (uint8_t*)msg->link_key;
717
718  if (msg->is_trusted) {
719    /* covert BTA service mask to BTM mask */
720    while (msg->tm && (index < BTA_MAX_SERVICE_ID)) {
721      if (msg->tm & (uint32_t)(1 << index)) {
722        btm_mask_index =
723            bta_service_id_to_btm_srv_id_lkup_tbl[index] / BTM_SEC_ARRAY_BITS;
724        trusted_services_mask[btm_mask_index] |=
725            (uint32_t)(1 << (bta_service_id_to_btm_srv_id_lkup_tbl[index] -
726                             (uint32_t)(btm_mask_index * 32)));
727
728        msg->tm &= (uint32_t)(~(1 << index));
729      }
730      index++;
731    }
732  }
733
734  if (!BTM_SecAddDevice(msg->bd_addr, p_dc, msg->bd_name, msg->features,
735                        trusted_services_mask, p_lc, msg->key_type, msg->io_cap,
736                        msg->pin_length)) {
737    LOG(ERROR) << "BTA_DM: Error adding device " << msg->bd_addr;
738  }
739}
740
741/** This function forces to close the connection to a remote device and
742 * optionaly remove the device from security database if required. */
743void bta_dm_close_acl(const RawAddress& bd_addr, bool remove_dev,
744                      tBTA_TRANSPORT transport) {
745  uint8_t index;
746
747  APPL_TRACE_DEBUG("bta_dm_close_acl");
748
749  if (BTM_IsAclConnectionUp(bd_addr, transport)) {
750    for (index = 0; index < bta_dm_cb.device_list.count; index++) {
751      if (bta_dm_cb.device_list.peer_device[index].peer_bdaddr == bd_addr)
752        break;
753    }
754    if (index != bta_dm_cb.device_list.count) {
755      if (remove_dev)
756        bta_dm_cb.device_list.peer_device[index].remove_dev_pending = true;
757    } else {
758      APPL_TRACE_ERROR("unknown device, remove ACL failed");
759    }
760    /* Disconnect the ACL link */
761    btm_remove_acl(bd_addr, transport);
762  }
763  /* if to remove the device from security database ? do it now */
764  else if (remove_dev) {
765    if (!BTM_SecDeleteDevice(bd_addr)) {
766      APPL_TRACE_ERROR("delete device from security database failed.");
767    }
768    /* need to remove all pending background connection if any */
769    BTA_GATTC_CancelOpen(0, bd_addr, false);
770    /* remove all cached GATT information */
771    BTA_GATTC_Refresh(bd_addr);
772  }
773  /* otherwise, no action needed */
774}
775
776// TODO: this is unused. remove?
777/** This function forces to close all the ACL links specified by link type */
778void bta_dm_remove_all_acl(const tBTA_DM_LINK_TYPE link_type) {
779  tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
780
781  APPL_TRACE_DEBUG("%s link type = %d", __func__, link_type);
782
783  for (uint8_t i = 0; i < bta_dm_cb.device_list.count; i++) {
784    transport = bta_dm_cb.device_list.peer_device[i].transport;
785    if ((link_type == BTA_DM_LINK_TYPE_ALL) ||
786        ((link_type == BTA_DM_LINK_TYPE_LE) &&
787         (transport == BT_TRANSPORT_LE)) ||
788        ((link_type == BTA_DM_LINK_TYPE_BR_EDR) &&
789         (transport == BT_TRANSPORT_BR_EDR))) {
790      /* Disconnect the ACL link */
791      btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
792                     transport);
793    }
794  }
795}
796
797/** Bonds with peer device */
798void bta_dm_bond(const RawAddress& bd_addr, tBTA_TRANSPORT transport) {
799  tBTM_STATUS status;
800  tBTA_DM_SEC sec_event;
801  char* p_name;
802
803  if (transport == BTA_TRANSPORT_UNKNOWN)
804    status = BTM_SecBond(bd_addr, 0, NULL, 0);
805  else
806    status = BTM_SecBondByTransport(bd_addr, transport, 0, NULL, 0);
807
808  if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED)) {
809    memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
810    sec_event.auth_cmpl.bd_addr = bd_addr;
811    p_name = BTM_SecReadDevName(bd_addr);
812    if (p_name != NULL) {
813      memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN - 1));
814      sec_event.auth_cmpl.bd_name[BD_NAME_LEN - 1] = 0;
815    }
816
817    /*      taken care of by memset [above]
818            sec_event.auth_cmpl.key_present = false;
819            sec_event.auth_cmpl.success = false;
820    */
821    sec_event.auth_cmpl.fail_reason = HCI_ERR_ILLEGAL_COMMAND;
822    if (status == BTM_SUCCESS) {
823      sec_event.auth_cmpl.success = true;
824    } else {
825      /* delete this device entry from Sec Dev DB */
826      bta_dm_remove_sec_dev_entry(bd_addr);
827    }
828    bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
829  }
830}
831
832/** Cancels bonding with a peer device */
833void bta_dm_bond_cancel(const RawAddress& bd_addr) {
834  tBTM_STATUS status;
835  tBTA_DM_SEC sec_event;
836
837  APPL_TRACE_EVENT(" bta_dm_bond_cancel ");
838  status = BTM_SecBondCancel(bd_addr);
839
840  if (bta_dm_cb.p_sec_cback &&
841      (status != BTM_CMD_STARTED && status != BTM_SUCCESS)) {
842    sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
843
844    bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
845  }
846}
847
848/** Send the pin_reply to a request from BTM */
849void bta_dm_pin_reply(std::unique_ptr<tBTA_DM_API_PIN_REPLY> msg) {
850  uint32_t trusted_mask[BTM_SEC_SERVICE_ARRAY_SIZE];
851
852  uint32_t* current_trusted_mask = BTM_ReadTrustedMask(msg->bd_addr);
853  if (current_trusted_mask) {
854    memcpy(trusted_mask, current_trusted_mask, sizeof(trusted_mask));
855  } else {
856    memset(trusted_mask, 0, sizeof(trusted_mask));
857  }
858
859  if (msg->accept) {
860    BTM_PINCodeReply(msg->bd_addr, BTM_SUCCESS, msg->pin_len, msg->p_pin,
861                     trusted_mask);
862  } else {
863    BTM_PINCodeReply(msg->bd_addr, BTM_NOT_AUTHORIZED, 0, NULL, trusted_mask);
864  }
865}
866
867/*******************************************************************************
868 *
869 * Function         bta_dm_policy_cback
870 *
871 * Description      process the link policy changes
872 *
873 * Returns          void
874 *
875 ******************************************************************************/
876static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
877                                uint8_t app_id, const RawAddress& peer_addr) {
878  tBTA_DM_PEER_DEVICE* p_dev = NULL;
879  uint16_t policy = app_id;
880  uint32_t mask = (uint32_t)(1 << id);
881
882  if (peer_addr != RawAddress::kEmpty) {
883    p_dev = bta_dm_find_peer_device(peer_addr);
884  }
885
886  APPL_TRACE_DEBUG(" bta_dm_policy_cback cmd:%d, policy:0x%x", status, policy);
887  switch (status) {
888    case BTA_SYS_PLCY_SET:
889      if (!p_dev) return;
890      /* restore the default link policy */
891      p_dev->link_policy |= policy;
892      BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy));
893      break;
894
895    case BTA_SYS_PLCY_CLR:
896      if (!p_dev) return;
897      /* clear the policy from the default link policy */
898      p_dev->link_policy &= (~policy);
899      BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy));
900
901      if (policy & (HCI_ENABLE_SNIFF_MODE | HCI_ENABLE_PARK_MODE)) {
902        /* if clearing sniff/park, wake the link */
903        bta_dm_pm_active(p_dev->peer_bdaddr);
904      }
905      break;
906
907    case BTA_SYS_PLCY_DEF_SET:
908      /* want to restore/set the role switch policy */
909      bta_dm_cb.role_policy_mask &= ~mask;
910      if (0 == bta_dm_cb.role_policy_mask) {
911        /* if nobody wants to insist on the role */
912        bta_dm_cb.cur_policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
913        BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
914      }
915      break;
916
917    case BTA_SYS_PLCY_DEF_CLR:
918      /* want to remove the role switch policy */
919      bta_dm_cb.role_policy_mask |= mask;
920      bta_dm_cb.cur_policy &= ~HCI_ENABLE_MASTER_SLAVE_SWITCH;
921      BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
922      break;
923  }
924}
925
926/** Send the user confirm request reply in response to a request from BTM */
927void bta_dm_confirm(const RawAddress& bd_addr, bool accept) {
928  BTM_ConfirmReqReply(accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED, bd_addr);
929}
930
931/** respond to the IO capabilities request from BTM */
932void bta_dm_ci_io_req_act(const RawAddress& bd_addr, tBTA_IO_CAP io_cap,
933                          tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req) {
934  BTM_IoCapRsp(bd_addr, io_cap, oob_data,
935               auth_req ? BTM_AUTH_AP_YES : BTM_AUTH_AP_NO);
936}
937
938/** respond to the OOB data request for the remote device from BTM */
939void bta_dm_ci_rmt_oob_act(std::unique_ptr<tBTA_DM_CI_RMT_OOB> msg) {
940  BTM_RemoteOobDataReply(msg->accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED,
941                         msg->bd_addr, msg->c, msg->r);
942}
943
944/*******************************************************************************
945 *
946 * Function         bta_dm_search_start
947 *
948 * Description      Starts an inquiry
949 *
950 *
951 * Returns          void
952 *
953 ******************************************************************************/
954void bta_dm_search_start(tBTA_DM_MSG* p_data) {
955  tBTM_INQUIRY_CMPL result = {};
956
957  size_t len = sizeof(Uuid) * p_data->search.num_uuid;
958  bta_dm_gattc_register();
959
960  APPL_TRACE_DEBUG("%s avoid_scatter=%d", __func__,
961                   p_bta_dm_cfg->avoid_scatter);
962
963  if (p_bta_dm_cfg->avoid_scatter &&
964      (p_data->search.rs_res == BTA_DM_RS_NONE) &&
965      bta_dm_check_av(BTA_DM_API_SEARCH_EVT)) {
966    LOG(INFO) << __func__ << ": delay search to avoid scatter";
967    memcpy(&bta_dm_cb.search_msg, &p_data->search, sizeof(tBTA_DM_API_SEARCH));
968    return;
969  }
970
971  BTM_ClearInqDb(nullptr);
972  /* save search params */
973  bta_dm_search_cb.p_search_cback = p_data->search.p_cback;
974  bta_dm_search_cb.services = p_data->search.services;
975
976  osi_free_and_reset((void**)&bta_dm_search_cb.p_srvc_uuid);
977
978  if ((bta_dm_search_cb.num_uuid = p_data->search.num_uuid) != 0 &&
979      p_data->search.p_uuid != nullptr) {
980    bta_dm_search_cb.p_srvc_uuid = (Uuid*)osi_malloc(len);
981    *bta_dm_search_cb.p_srvc_uuid = *p_data->search.p_uuid;
982  }
983  result.status = BTM_StartInquiry((tBTM_INQ_PARMS*)&p_data->search.inq_params,
984                                   bta_dm_inq_results_cb, bta_dm_inq_cmpl_cb);
985
986  APPL_TRACE_EVENT("%s status=%d", __func__, result.status);
987  if (result.status != BTM_CMD_STARTED) {
988    LOG(ERROR) << __func__ << ": BTM_StartInquiry returned "
989               << std::to_string(result.status);
990    result.num_resp = 0;
991    bta_dm_inq_cmpl_cb((void*)&result);
992  }
993}
994
995/*******************************************************************************
996 *
997 * Function         bta_dm_search_cancel
998 *
999 * Description      Cancels an ongoing search for devices
1000 *
1001 *
1002 * Returns          void
1003 *
1004 ******************************************************************************/
1005void bta_dm_search_cancel(UNUSED_ATTR tBTA_DM_MSG* p_data) {
1006  tBTA_DM_MSG* p_msg;
1007
1008  if (BTM_IsInquiryActive()) {
1009    if (BTM_CancelInquiry() == BTM_SUCCESS) {
1010      bta_dm_search_cancel_notify(NULL);
1011      p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
1012      p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1013      p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1014      bta_sys_sendmsg(p_msg);
1015    } else {
1016      /* flag a search cancel is pending */
1017      bta_dm_search_cb.cancel_pending = true;
1018    }
1019  }
1020  /* If no Service Search going on then issue cancel remote name in case it is
1021     active */
1022  else if (!bta_dm_search_cb.name_discover_done) {
1023    BTM_CancelRemoteDeviceName();
1024
1025    p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
1026    p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1027    p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1028    bta_sys_sendmsg(p_msg);
1029  } else {
1030    p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
1031    p_msg->hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
1032    p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1033    bta_sys_sendmsg(p_msg);
1034  }
1035
1036  if (bta_dm_search_cb.gatt_disc_active) {
1037    bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
1038  }
1039}
1040
1041/*******************************************************************************
1042 *
1043 * Function         bta_dm_discover
1044 *
1045 * Description      Discovers services on a remote device
1046 *
1047 *
1048 * Returns          void
1049 *
1050 ******************************************************************************/
1051void bta_dm_discover(tBTA_DM_MSG* p_data) {
1052  size_t len = sizeof(Uuid) * p_data->discover.num_uuid;
1053  APPL_TRACE_EVENT("%s services_to_search=0x%04X, sdp_search=%d", __func__,
1054                   p_data->discover.services, p_data->discover.sdp_search);
1055
1056  /* save the search condition */
1057  bta_dm_search_cb.services = p_data->discover.services;
1058
1059  bta_dm_gattc_register();
1060  osi_free_and_reset((void**)&bta_dm_search_cb.p_srvc_uuid);
1061  if ((bta_dm_search_cb.num_uuid = p_data->discover.num_uuid) != 0 &&
1062      p_data->discover.p_uuid != NULL) {
1063    bta_dm_search_cb.p_srvc_uuid = (Uuid*)osi_malloc(len);
1064    *bta_dm_search_cb.p_srvc_uuid = *p_data->discover.p_uuid;
1065  }
1066  bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid;
1067
1068  bta_dm_search_cb.p_search_cback = p_data->discover.p_cback;
1069  bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
1070  bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
1071  bta_dm_search_cb.service_index = 0;
1072  bta_dm_search_cb.services_found = 0;
1073  bta_dm_search_cb.peer_name[0] = 0;
1074  bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
1075  bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead(p_data->discover.bd_addr);
1076  bta_dm_search_cb.transport = p_data->discover.transport;
1077
1078  bta_dm_search_cb.name_discover_done = false;
1079  bta_dm_search_cb.uuid = p_data->discover.uuid;
1080  bta_dm_discover_device(p_data->discover.bd_addr);
1081}
1082
1083/*******************************************************************************
1084 *
1085 * Function         bta_dm_di_disc_cmpl
1086 *
1087 * Description      Sends event to application when DI discovery complete
1088 *
1089 * Returns          void
1090 *
1091 ******************************************************************************/
1092void bta_dm_di_disc_cmpl(tBTA_DM_MSG* p_data) {
1093  tBTA_DM_DI_DISC_CMPL di_disc;
1094
1095  memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL));
1096  di_disc.bd_addr = bta_dm_search_cb.peer_bdaddr;
1097
1098  if ((p_data->hdr.offset == SDP_SUCCESS) ||
1099      (p_data->hdr.offset == SDP_DB_FULL)) {
1100    di_disc.num_record = SDP_GetNumDiRecords(bta_dm_di_cb.p_di_db);
1101  } else
1102    di_disc.result = BTA_FAILURE;
1103
1104  bta_dm_di_cb.p_di_db = NULL;
1105  bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT,
1106                                  (tBTA_DM_SEARCH*)&di_disc);
1107}
1108
1109/*******************************************************************************
1110 *
1111 * Function         bta_dm_di_disc_callback
1112 *
1113 * Description      This function queries a remote device for DI information.
1114 *
1115 *
1116 * Returns          void
1117 *
1118 ******************************************************************************/
1119static void bta_dm_di_disc_callback(uint16_t result) {
1120  tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
1121
1122  p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1123  p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT;
1124  p_msg->hdr.offset = result;
1125
1126  bta_sys_sendmsg(p_msg);
1127}
1128
1129/*******************************************************************************
1130 *
1131 * Function         bta_dm_disable_search_and_disc
1132 *
1133 * Description      Cancels an ongoing search or discovery for devices in case
1134 *                  of a Bluetooth disable
1135 *
1136 *
1137 * Returns          void
1138 *
1139 ******************************************************************************/
1140static void bta_dm_disable_search_and_disc(void) {
1141  tBTA_DM_DI_DISC_CMPL di_disc;
1142
1143  if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) bta_dm_search_cancel(NULL);
1144
1145  if (bta_dm_di_cb.p_di_db != NULL) {
1146    memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL));
1147    di_disc.bd_addr = bta_dm_search_cb.peer_bdaddr;
1148    di_disc.result = BTA_FAILURE;
1149
1150    bta_dm_di_cb.p_di_db = NULL;
1151    bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT, NULL);
1152  }
1153}
1154
1155/*******************************************************************************
1156 *
1157 * Function         bta_dm_di_disc
1158 *
1159 * Description      This function queries a remote device for DI information.
1160 *
1161 *
1162 * Returns          void
1163 *
1164 ******************************************************************************/
1165void bta_dm_di_disc(tBTA_DM_MSG* p_data) {
1166  uint16_t result = BTA_FAILURE;
1167
1168  bta_dm_search_cb.p_search_cback = p_data->di_disc.p_cback;
1169  bta_dm_search_cb.peer_bdaddr = p_data->di_disc.bd_addr;
1170  bta_dm_di_cb.p_di_db = p_data->di_disc.p_sdp_db;
1171
1172  bta_dm_search_cb.p_sdp_db =
1173      (tSDP_DISCOVERY_DB*)osi_malloc(BTA_DM_SDP_DB_SIZE);
1174  if (SDP_DiDiscover(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.p_sdp_db,
1175                     p_data->di_disc.len,
1176                     bta_dm_di_disc_callback) == SDP_SUCCESS) {
1177    result = BTA_SUCCESS;
1178  }
1179
1180  if (result == BTA_FAILURE) {
1181    tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
1182
1183    p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1184    p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT;
1185    p_data->hdr.offset = result;
1186    bta_sys_sendmsg(p_msg);
1187  }
1188}
1189
1190/*******************************************************************************
1191 *
1192 * Function         bta_dm_read_remote_device_name
1193 *
1194 * Description      Initiate to get remote device name
1195 *
1196 * Returns          true if started to get remote name
1197 *
1198 ******************************************************************************/
1199static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr,
1200                                           tBT_TRANSPORT transport) {
1201  tBTM_STATUS btm_status;
1202
1203  APPL_TRACE_DEBUG("%s", __func__);
1204
1205  bta_dm_search_cb.peer_bdaddr = bd_addr;
1206  bta_dm_search_cb.peer_name[0] = 0;
1207
1208  btm_status = BTM_ReadRemoteDeviceName(bta_dm_search_cb.peer_bdaddr,
1209                                        bta_dm_remname_cback, transport);
1210
1211  if (btm_status == BTM_CMD_STARTED) {
1212    APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is started", __func__);
1213
1214    return (true);
1215  } else if (btm_status == BTM_BUSY) {
1216    APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is busy", __func__);
1217
1218    /* Remote name discovery is on going now so BTM cannot notify through
1219     * "bta_dm_remname_cback" */
1220    /* adding callback to get notified that current reading remore name done */
1221    BTM_SecAddRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1222
1223    return (true);
1224  } else {
1225    APPL_TRACE_WARNING("%s: BTM_ReadRemoteDeviceName returns 0x%02X", __func__,
1226                       btm_status);
1227
1228    return (false);
1229  }
1230}
1231
1232/*******************************************************************************
1233 *
1234 * Function         bta_dm_inq_cmpl
1235 *
1236 * Description      Process the inquiry complete event from BTM
1237 *
1238 * Returns          void
1239 *
1240 ******************************************************************************/
1241void bta_dm_inq_cmpl(tBTA_DM_MSG* p_data) {
1242  tBTA_DM_SEARCH data;
1243
1244  APPL_TRACE_DEBUG("bta_dm_inq_cmpl");
1245
1246  data.inq_cmpl.num_resps = p_data->inq_cmpl.num;
1247  bta_dm_search_cb.p_search_cback(BTA_DM_INQ_CMPL_EVT, &data);
1248
1249  bta_dm_search_cb.p_btm_inq_info = BTM_InqDbFirst();
1250  if (bta_dm_search_cb.p_btm_inq_info != NULL) {
1251    /* start name and service discovery from the first device on inquiry result
1252     */
1253    bta_dm_search_cb.name_discover_done = false;
1254    bta_dm_search_cb.peer_name[0] = 0;
1255    bta_dm_discover_device(
1256        bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
1257  } else {
1258    tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
1259
1260    /* no devices, search complete */
1261    bta_dm_search_cb.services = 0;
1262
1263    p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1264    p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1265    bta_sys_sendmsg(p_msg);
1266  }
1267}
1268
1269/*******************************************************************************
1270 *
1271 * Function         bta_dm_rmt_name
1272 *
1273 * Description      Process the remote name result from BTM
1274 *
1275 * Returns          void
1276 *
1277 ******************************************************************************/
1278void bta_dm_rmt_name(tBTA_DM_MSG* p_data) {
1279  APPL_TRACE_DEBUG("bta_dm_rmt_name");
1280
1281  if (p_data->rem_name.result.disc_res.bd_name[0] &&
1282      bta_dm_search_cb.p_btm_inq_info) {
1283    bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name = true;
1284  }
1285
1286  bta_dm_discover_device(bta_dm_search_cb.peer_bdaddr);
1287}
1288
1289/*******************************************************************************
1290 *
1291 * Function         bta_dm_disc_rmt_name
1292 *
1293 * Description      Process the remote name result from BTM when application
1294 *                  wants to find the name for a bdaddr
1295 *
1296 * Returns          void
1297 *
1298 ******************************************************************************/
1299void bta_dm_disc_rmt_name(tBTA_DM_MSG* p_data) {
1300  tBTM_INQ_INFO* p_btm_inq_info;
1301
1302  APPL_TRACE_DEBUG("bta_dm_disc_rmt_name");
1303
1304  p_btm_inq_info = BTM_InqDbRead(p_data->rem_name.result.disc_res.bd_addr);
1305  if (p_btm_inq_info) {
1306    if (p_data->rem_name.result.disc_res.bd_name[0]) {
1307      p_btm_inq_info->appl_knows_rem_name = true;
1308    }
1309  }
1310
1311  bta_dm_discover_device(p_data->rem_name.result.disc_res.bd_addr);
1312}
1313
1314/*******************************************************************************
1315 *
1316 * Function         bta_dm_sdp_result
1317 *
1318 * Description      Process the discovery result from sdp
1319 *
1320 * Returns          void
1321 *
1322 ******************************************************************************/
1323void bta_dm_sdp_result(tBTA_DM_MSG* p_data) {
1324  tSDP_DISC_REC* p_sdp_rec = NULL;
1325  tBTA_DM_MSG* p_msg;
1326  bool scn_found = false;
1327  uint16_t service = 0xFFFF;
1328  tSDP_PROTOCOL_ELEM pe;
1329
1330  Uuid* p_uuid = bta_dm_search_cb.p_srvc_uuid;
1331  tBTA_DM_SEARCH result;
1332
1333  std::vector<Uuid> uuid_list;
1334
1335  if ((p_data->sdp_event.sdp_result == SDP_SUCCESS) ||
1336      (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH) ||
1337      (p_data->sdp_event.sdp_result == SDP_DB_FULL)) {
1338    APPL_TRACE_DEBUG("sdp_result::0x%x", p_data->sdp_event.sdp_result);
1339    do {
1340      p_sdp_rec = NULL;
1341      if (bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID + 1)) {
1342        p_sdp_rec = SDP_FindServiceUUIDInDb(bta_dm_search_cb.p_sdp_db,
1343                                            bta_dm_search_cb.uuid, p_sdp_rec);
1344
1345        if (p_sdp_rec && SDP_FindProtocolListElemInRec(
1346                             p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
1347          bta_dm_search_cb.peer_scn = (uint8_t)pe.params[0];
1348          scn_found = true;
1349        }
1350      } else {
1351        service =
1352            bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1];
1353        p_sdp_rec =
1354            SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, service, p_sdp_rec);
1355      }
1356      /* finished with BR/EDR services, now we check the result for GATT based
1357       * service UUID */
1358      if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID) {
1359        if (bta_dm_search_cb.uuid_to_search != 0 && p_uuid != NULL) {
1360          p_uuid +=
1361              (bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search);
1362          /* only support 16 bits UUID for now */
1363          service = p_uuid->As16Bit();
1364        }
1365        /* all GATT based services */
1366        do {
1367          /* find a service record, report it */
1368          p_sdp_rec =
1369              SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, 0, p_sdp_rec);
1370          if (p_sdp_rec) {
1371            Uuid service_uuid;
1372            if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) {
1373              /* send result back to app now, one by one */
1374              result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
1375              strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(),
1376                      BD_NAME_LEN);
1377
1378              result.disc_ble_res.service = service_uuid;
1379              bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
1380            }
1381          }
1382
1383          if (bta_dm_search_cb.uuid_to_search > 0) break;
1384
1385        } while (p_sdp_rec);
1386      } else {
1387        /* SDP_DB_FULL means some records with the
1388           required attributes were received */
1389        if (((p_data->sdp_event.sdp_result == SDP_DB_FULL) &&
1390             bta_dm_search_cb.services != BTA_ALL_SERVICE_MASK) ||
1391            (p_sdp_rec != NULL)) {
1392          if (service != UUID_SERVCLASS_PNP_INFORMATION) {
1393            bta_dm_search_cb.services_found |=
1394                (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(
1395                    bta_dm_search_cb.service_index - 1));
1396            uint16_t tmp_svc =
1397                bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index -
1398                                                1];
1399            /* Add to the list of UUIDs */
1400            uuid_list.push_back(Uuid::From16Bit(tmp_svc));
1401          }
1402        }
1403      }
1404
1405      if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK &&
1406          bta_dm_search_cb.services_to_search == 0) {
1407        if (bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID &&
1408            bta_dm_search_cb.uuid_to_search > 0)
1409          bta_dm_search_cb.uuid_to_search--;
1410
1411        if (bta_dm_search_cb.uuid_to_search == 0 ||
1412            bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID)
1413          bta_dm_search_cb.service_index++;
1414      } else /* regular one service per search or PNP search */
1415        break;
1416
1417    } while (bta_dm_search_cb.service_index <= BTA_MAX_SERVICE_ID);
1418
1419    APPL_TRACE_DEBUG("%s services_found = %04x", __func__,
1420                     bta_dm_search_cb.services_found);
1421
1422    /* Collect the 128-bit services here and put them into the list */
1423    if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) {
1424      p_sdp_rec = NULL;
1425      do {
1426        /* find a service record, report it */
1427        p_sdp_rec =
1428            SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec);
1429        if (p_sdp_rec) {
1430          // SDP_FindServiceUUIDInRec_128bit is used only once, refactor?
1431          Uuid temp_uuid;
1432          if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid)) {
1433            uuid_list.push_back(temp_uuid);
1434          }
1435        }
1436      } while (p_sdp_rec);
1437    }
1438    /* if there are more services to search for */
1439    if (bta_dm_search_cb.services_to_search) {
1440      /* Free up the p_sdp_db before checking the next one */
1441      bta_dm_free_sdp_db(NULL);
1442      bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
1443    } else {
1444      /* callbacks */
1445      /* start next bd_addr if necessary */
1446
1447      BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1448
1449      p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
1450      p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1451      p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
1452      p_msg->disc_result.result.disc_res.p_raw_data = NULL;
1453      p_msg->disc_result.result.disc_res.raw_data_size = 0;
1454      p_msg->disc_result.result.disc_res.num_uuids = uuid_list.size();
1455      p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
1456      if (uuid_list.size() > 0) {
1457        // TODO(jpawlowski): make p_uuid_list into vector, and just copy
1458        // vectors, but first get rid of bta_sys_sendmsg below.
1459        p_msg->disc_result.result.disc_res.p_uuid_list =
1460            (Uuid*)osi_malloc(uuid_list.size() * sizeof(Uuid));
1461        memcpy(p_msg->disc_result.result.disc_res.p_uuid_list, uuid_list.data(),
1462               uuid_list.size() * sizeof(Uuid));
1463      }
1464      // Copy the raw_data to the discovery result structure
1465      if (bta_dm_search_cb.p_sdp_db != NULL &&
1466          bta_dm_search_cb.p_sdp_db->raw_used != 0 &&
1467          bta_dm_search_cb.p_sdp_db->raw_data != NULL) {
1468        APPL_TRACE_DEBUG("%s raw_data used = 0x%x raw_data_ptr = 0x%x",
1469                         __func__, bta_dm_search_cb.p_sdp_db->raw_used,
1470                         bta_dm_search_cb.p_sdp_db->raw_data);
1471
1472        p_msg->disc_result.result.disc_res.p_raw_data =
1473            (uint8_t*)osi_malloc(bta_dm_search_cb.p_sdp_db->raw_used);
1474        memcpy(p_msg->disc_result.result.disc_res.p_raw_data,
1475               bta_dm_search_cb.p_sdp_db->raw_data,
1476               bta_dm_search_cb.p_sdp_db->raw_used);
1477
1478        p_msg->disc_result.result.disc_res.raw_data_size =
1479            bta_dm_search_cb.p_sdp_db->raw_used;
1480
1481        bta_dm_search_cb.p_sdp_db->raw_data =
1482            NULL;  // no need to free this - it is a global assigned.
1483        bta_dm_search_cb.p_sdp_db->raw_used = 0;
1484        bta_dm_search_cb.p_sdp_db->raw_size = 0;
1485      } else {
1486        APPL_TRACE_DEBUG("%s raw data size is 0 or raw_data is null!!",
1487                         __func__);
1488      }
1489      /* Done with p_sdp_db. Free it */
1490      bta_dm_free_sdp_db(NULL);
1491      p_msg->disc_result.result.disc_res.services =
1492          bta_dm_search_cb.services_found;
1493
1494      // Piggy back the SCN over result field
1495      if (scn_found) {
1496        p_msg->disc_result.result.disc_res.result =
1497            (3 + bta_dm_search_cb.peer_scn);
1498        p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK;
1499
1500        APPL_TRACE_EVENT(" Piggy back the SCN over result field  SCN=%d",
1501                         bta_dm_search_cb.peer_scn);
1502      }
1503      p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
1504      strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
1505              bta_dm_get_remname(), BD_NAME_LEN);
1506
1507      bta_sys_sendmsg(p_msg);
1508    }
1509  } else {
1510    /* conn failed. No need for timer */
1511    if (p_data->sdp_event.sdp_result == SDP_CONN_FAILED ||
1512        p_data->sdp_event.sdp_result == SDP_CONN_REJECTED ||
1513        p_data->sdp_event.sdp_result == SDP_SECURITY_ERR)
1514      bta_dm_search_cb.wait_disc = false;
1515
1516    /* not able to connect go to next device */
1517    if (bta_dm_search_cb.p_sdp_db)
1518      osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db);
1519
1520    BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1521
1522    p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
1523    p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1524    p_msg->disc_result.result.disc_res.result = BTA_FAILURE;
1525    p_msg->disc_result.result.disc_res.services =
1526        bta_dm_search_cb.services_found;
1527    p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
1528    strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
1529            bta_dm_get_remname(), BD_NAME_LEN);
1530
1531    bta_sys_sendmsg(p_msg);
1532  }
1533}
1534
1535/*******************************************************************************
1536 *
1537 * Function         bta_dm_search_cmpl
1538 *
1539 * Description      Sends event to application
1540 *
1541 * Returns          void
1542 *
1543 ******************************************************************************/
1544void bta_dm_search_cmpl(tBTA_DM_MSG* p_data) {
1545  APPL_TRACE_EVENT("%s", __func__);
1546
1547  osi_free_and_reset((void**)&bta_dm_search_cb.p_srvc_uuid);
1548
1549  if (p_data->hdr.layer_specific == BTA_DM_API_DI_DISCOVER_EVT)
1550    bta_dm_di_disc_cmpl(p_data);
1551  else
1552    bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, NULL);
1553}
1554
1555/*******************************************************************************
1556 *
1557 * Function         bta_dm_disc_result
1558 *
1559 * Description      Service discovery result when discovering services on a
1560 *                  device
1561 *
1562 * Returns          void
1563 *
1564 ******************************************************************************/
1565void bta_dm_disc_result(tBTA_DM_MSG* p_data) {
1566  APPL_TRACE_EVENT("%s", __func__);
1567
1568  /* if any BR/EDR service discovery has been done, report the event */
1569  if ((bta_dm_search_cb.services &
1570       ((BTA_ALL_SERVICE_MASK | BTA_USER_SERVICE_MASK) &
1571        ~BTA_BLE_SERVICE_MASK)))
1572    bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT,
1573                                    &p_data->disc_result.result);
1574
1575  tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
1576
1577  /* send a message to change state */
1578  p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1579  p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1580  bta_sys_sendmsg(p_msg);
1581}
1582
1583/*******************************************************************************
1584 *
1585 * Function         bta_dm_search_result
1586 *
1587 * Description      Service discovery result while searching for devices
1588 *
1589 * Returns          void
1590 *
1591 ******************************************************************************/
1592void bta_dm_search_result(tBTA_DM_MSG* p_data) {
1593  APPL_TRACE_DEBUG("%s searching:0x%04x, result:0x%04x", __func__,
1594                   bta_dm_search_cb.services,
1595                   p_data->disc_result.result.disc_res.services);
1596
1597  /* call back if application wants name discovery or found services that
1598   * application is searching */
1599  if ((!bta_dm_search_cb.services) ||
1600      ((bta_dm_search_cb.services) &&
1601       (p_data->disc_result.result.disc_res.services))) {
1602    bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT,
1603                                    &p_data->disc_result.result);
1604  }
1605
1606  /* if searching did not initiate to create link */
1607  if (!bta_dm_search_cb.wait_disc) {
1608    /* if service searching is done with EIR, don't search next device */
1609    if (bta_dm_search_cb.p_btm_inq_info) bta_dm_discover_next_device();
1610  } else {
1611    /* wait until link is disconnected or timeout */
1612    bta_dm_search_cb.sdp_results = true;
1613    alarm_set_on_mloop(bta_dm_search_cb.search_timer,
1614                       1000 * (L2CAP_LINK_INACTIVITY_TOUT + 1),
1615                       bta_dm_search_timer_cback, NULL);
1616  }
1617}
1618
1619/*******************************************************************************
1620 *
1621 * Function         bta_dm_search_timer_cback
1622 *
1623 * Description      Called when ACL disconnect time is over
1624 *
1625 *
1626 * Returns          void
1627 *
1628 ******************************************************************************/
1629static void bta_dm_search_timer_cback(UNUSED_ATTR void* data) {
1630  APPL_TRACE_EVENT("%s", __func__);
1631  bta_dm_search_cb.wait_disc = false;
1632
1633  /* proceed with next device */
1634  bta_dm_discover_next_device();
1635}
1636
1637/*******************************************************************************
1638 *
1639 * Function         bta_dm_free_sdp_db
1640 *
1641 * Description      Frees SDP data base
1642 *
1643 * Returns          void
1644 *
1645 ******************************************************************************/
1646void bta_dm_free_sdp_db(UNUSED_ATTR tBTA_DM_MSG* p_data) {
1647  osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db);
1648}
1649
1650/*******************************************************************************
1651 *
1652 * Function         bta_dm_queue_search
1653 *
1654 * Description      Queues search command while search is being cancelled
1655 *
1656 * Returns          void
1657 *
1658 ******************************************************************************/
1659void bta_dm_queue_search(tBTA_DM_MSG* p_data) {
1660  osi_free(bta_dm_search_cb.p_search_queue);
1661  bta_dm_search_cb.p_search_queue =
1662      (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_SEARCH));
1663  memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_SEARCH));
1664}
1665
1666/*******************************************************************************
1667 *
1668 * Function         bta_dm_queue_disc
1669 *
1670 * Description      Queues discovery command while search is being cancelled
1671 *
1672 * Returns          void
1673 *
1674 ******************************************************************************/
1675void bta_dm_queue_disc(tBTA_DM_MSG* p_data) {
1676  osi_free(bta_dm_search_cb.p_search_queue);
1677  bta_dm_search_cb.p_search_queue =
1678      (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_DISCOVER));
1679  memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_DISCOVER));
1680}
1681
1682/*******************************************************************************
1683 *
1684 * Function         bta_dm_search_clear_queue
1685 *
1686 * Description      Clears the queue if API search cancel is called
1687 *
1688 * Returns          void
1689 *
1690 ******************************************************************************/
1691void bta_dm_search_clear_queue(UNUSED_ATTR tBTA_DM_MSG* p_data) {
1692  osi_free_and_reset((void**)&bta_dm_search_cb.p_search_queue);
1693}
1694
1695/*******************************************************************************
1696 *
1697 * Function         bta_dm_search_cancel_cmpl
1698 *
1699 * Description      Search cancel is complete
1700 *
1701 * Returns          void
1702 *
1703 ******************************************************************************/
1704void bta_dm_search_cancel_cmpl(UNUSED_ATTR tBTA_DM_MSG* p_data) {
1705  if (bta_dm_search_cb.p_search_queue) {
1706    bta_sys_sendmsg(bta_dm_search_cb.p_search_queue);
1707    bta_dm_search_cb.p_search_queue = NULL;
1708  }
1709}
1710
1711/*******************************************************************************
1712 *
1713 * Function         bta_dm_search_cancel_transac_cmpl
1714 *
1715 * Description      Current Service Discovery or remote name procedure is
1716 *                  completed after search cancellation
1717 *
1718 * Returns          void
1719 *
1720 ******************************************************************************/
1721void bta_dm_search_cancel_transac_cmpl(UNUSED_ATTR tBTA_DM_MSG* p_data) {
1722  osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db);
1723  bta_dm_search_cancel_notify(NULL);
1724}
1725
1726/*******************************************************************************
1727 *
1728 * Function         bta_dm_search_cancel_notify
1729 *
1730 * Description      Notify application that search has been cancelled
1731 *
1732 * Returns          void
1733 *
1734 ******************************************************************************/
1735void bta_dm_search_cancel_notify(UNUSED_ATTR tBTA_DM_MSG* p_data) {
1736  if (bta_dm_search_cb.p_search_cback) {
1737    bta_dm_search_cb.p_search_cback(BTA_DM_SEARCH_CANCEL_CMPL_EVT, NULL);
1738  }
1739  if (!bta_dm_search_cb.name_discover_done) {
1740    BTM_CancelRemoteDeviceName();
1741  }
1742  if (bta_dm_search_cb.gatt_disc_active) {
1743    bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
1744  }
1745}
1746
1747/*******************************************************************************
1748 *
1749 * Function         bta_dm_find_services
1750 *
1751 * Description      Starts discovery on a device
1752 *
1753 * Returns          void
1754 *
1755 ******************************************************************************/
1756static void bta_dm_find_services(const RawAddress& bd_addr) {
1757
1758  while (bta_dm_search_cb.service_index < BTA_MAX_SERVICE_ID) {
1759    Uuid uuid = Uuid::kEmpty;
1760    if (bta_dm_search_cb.services_to_search &
1761        (tBTA_SERVICE_MASK)(
1762            BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index))) {
1763      bta_dm_search_cb.p_sdp_db =
1764          (tSDP_DISCOVERY_DB*)osi_malloc(BTA_DM_SDP_DB_SIZE);
1765      APPL_TRACE_DEBUG("bta_dm_search_cb.services = %04x***********",
1766                       bta_dm_search_cb.services);
1767      /* try to search all services by search based on L2CAP UUID */
1768      if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) {
1769        LOG_INFO(LOG_TAG, "%s services_to_search=%08x", __func__,
1770                 bta_dm_search_cb.services_to_search);
1771        if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK) {
1772          uuid = Uuid::From16Bit(bta_service_id_to_uuid_lkup_tbl[0]);
1773          bta_dm_search_cb.services_to_search &= ~BTA_RES_SERVICE_MASK;
1774        } else {
1775          uuid = Uuid::From16Bit(UUID_PROTOCOL_L2CAP);
1776          bta_dm_search_cb.services_to_search = 0;
1777        }
1778      } else {
1779        /* for LE only profile */
1780        if (bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID) {
1781          if (bta_dm_search_cb.uuid_to_search > 0 &&
1782              bta_dm_search_cb.p_srvc_uuid) {
1783            uuid = *(bta_dm_search_cb.p_srvc_uuid + bta_dm_search_cb.num_uuid -
1784                     bta_dm_search_cb.uuid_to_search);
1785
1786            bta_dm_search_cb.uuid_to_search--;
1787          } else {
1788            uuid = Uuid::From16Bit(
1789                bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb
1790                                                    .service_index]);
1791          }
1792
1793          /* last one? clear the BLE service bit if all discovery has been done
1794           */
1795          if (bta_dm_search_cb.uuid_to_search == 0)
1796            bta_dm_search_cb.services_to_search &=
1797                (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(
1798                    bta_dm_search_cb.service_index)));
1799
1800        } else {
1801          /* remove the service from services to be searched  */
1802          bta_dm_search_cb.services_to_search &= (tBTA_SERVICE_MASK)(~(
1803              BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
1804          uuid = Uuid::From16Bit(
1805              bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index]);
1806        }
1807      }
1808
1809      if (bta_dm_search_cb.service_index == BTA_USER_SERVICE_ID) {
1810        uuid = bta_dm_search_cb.uuid;
1811      }
1812
1813      LOG_INFO(LOG_TAG, "%s search UUID = %s", __func__,
1814               uuid.ToString().c_str());
1815      SDP_InitDiscoveryDb(bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1,
1816                          &uuid, 0, NULL);
1817
1818      memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
1819      bta_dm_search_cb.p_sdp_db->raw_data = g_disc_raw_data_buf;
1820
1821      bta_dm_search_cb.p_sdp_db->raw_size = MAX_DISC_RAW_DATA_BUF;
1822
1823      if (!SDP_ServiceSearchAttributeRequest(bd_addr, bta_dm_search_cb.p_sdp_db,
1824                                             &bta_dm_sdp_callback)) {
1825        /*
1826         * If discovery is not successful with this device, then
1827         * proceed with the next one.
1828         */
1829        osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db);
1830        bta_dm_search_cb.service_index = BTA_MAX_SERVICE_ID;
1831
1832      } else {
1833        if ((bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID &&
1834             bta_dm_search_cb.uuid_to_search == 0) ||
1835            bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID)
1836          bta_dm_search_cb.service_index++;
1837        return;
1838      }
1839    }
1840
1841    bta_dm_search_cb.service_index++;
1842  }
1843
1844  /* no more services to be discovered */
1845  if (bta_dm_search_cb.service_index >= BTA_MAX_SERVICE_ID) {
1846    tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
1847    /* initialize the data structure - includes p_raw_data and raw_data_size */
1848    memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES));
1849    p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1850    p_msg->disc_result.result.disc_res.services =
1851        bta_dm_search_cb.services_found;
1852    p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
1853    strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
1854            bta_dm_get_remname(), BD_NAME_LEN);
1855
1856    bta_sys_sendmsg(p_msg);
1857  }
1858}
1859
1860/*******************************************************************************
1861 *
1862 * Function         bta_dm_discover_next_device
1863 *
1864 * Description      Starts discovery on the next device in Inquiry data base
1865 *
1866 * Returns          void
1867 *
1868 ******************************************************************************/
1869static void bta_dm_discover_next_device(void) {
1870  APPL_TRACE_DEBUG("bta_dm_discover_next_device");
1871
1872  /* searching next device on inquiry result */
1873  bta_dm_search_cb.p_btm_inq_info =
1874      BTM_InqDbNext(bta_dm_search_cb.p_btm_inq_info);
1875  if (bta_dm_search_cb.p_btm_inq_info != NULL) {
1876    bta_dm_search_cb.name_discover_done = false;
1877    bta_dm_search_cb.peer_name[0] = 0;
1878    bta_dm_discover_device(
1879        bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
1880  } else {
1881    tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
1882
1883    /* no devices, search complete */
1884    bta_dm_search_cb.services = 0;
1885
1886    p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1887    p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1888
1889    bta_sys_sendmsg(p_msg);
1890  }
1891}
1892
1893/*******************************************************************************
1894 *
1895 * Function         bta_dm_discover_device
1896 *
1897 * Description      Starts name and service discovery on the device
1898 *
1899 * Returns          void
1900 *
1901 ******************************************************************************/
1902static void bta_dm_discover_device(const RawAddress& remote_bd_addr) {
1903  tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
1904  if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN) {
1905    tBT_DEVICE_TYPE dev_type;
1906    tBLE_ADDR_TYPE addr_type;
1907
1908    BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
1909    if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM)
1910      transport = BT_TRANSPORT_LE;
1911  } else {
1912    transport = bta_dm_search_cb.transport;
1913  }
1914
1915  /* Reset transport state for next discovery */
1916  bta_dm_search_cb.transport = BTA_TRANSPORT_UNKNOWN;
1917
1918  VLOG(1) << __func__ << " BDA: " << remote_bd_addr;
1919
1920  bta_dm_search_cb.peer_bdaddr = remote_bd_addr;
1921
1922  APPL_TRACE_DEBUG(
1923      "%s name_discover_done = %d p_btm_inq_info 0x%x state = %d, transport=%d",
1924      __func__, bta_dm_search_cb.name_discover_done,
1925      bta_dm_search_cb.p_btm_inq_info, bta_dm_search_cb.state, transport);
1926
1927  if (bta_dm_search_cb.p_btm_inq_info) {
1928    APPL_TRACE_DEBUG("%s appl_knows_rem_name %d", __func__,
1929                     bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name);
1930  }
1931  if ((bta_dm_search_cb.p_btm_inq_info) &&
1932      (bta_dm_search_cb.p_btm_inq_info->results.device_type ==
1933       BT_DEVICE_TYPE_BLE) &&
1934      (bta_dm_search_cb.state == BTA_DM_SEARCH_ACTIVE)) {
1935    /* Do not perform RNR for LE devices at inquiry complete*/
1936    bta_dm_search_cb.name_discover_done = true;
1937  }
1938  /* if name discovery is not done and application needs remote name */
1939  if ((!bta_dm_search_cb.name_discover_done) &&
1940      ((bta_dm_search_cb.p_btm_inq_info == NULL) ||
1941       (bta_dm_search_cb.p_btm_inq_info &&
1942        (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name)))) {
1943    if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport))
1944      return;
1945
1946    /* starting name discovery failed */
1947    bta_dm_search_cb.name_discover_done = true;
1948  }
1949
1950  /* if application wants to discover service */
1951  if (bta_dm_search_cb.services) {
1952    /* initialize variables */
1953    bta_dm_search_cb.service_index = 0;
1954    bta_dm_search_cb.services_found = 0;
1955    bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
1956    bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid;
1957    if ((bta_dm_search_cb.p_btm_inq_info != NULL) &&
1958        bta_dm_search_cb.services != BTA_USER_SERVICE_MASK &&
1959        (!bta_dm_search_cb.sdp_search)) {
1960      /* check if EIR provides the information of supported services */
1961      bta_dm_eir_search_services(&bta_dm_search_cb.p_btm_inq_info->results,
1962                                 &bta_dm_search_cb.services_to_search,
1963                                 &bta_dm_search_cb.services_found);
1964    }
1965
1966    /* if seaching with EIR is not completed */
1967    if (bta_dm_search_cb.services_to_search) {
1968      /* check whether connection already exists to the device
1969         if connection exists, we don't have to wait for ACL
1970         link to go down to start search on next device */
1971      if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr,
1972                                BT_TRANSPORT_BR_EDR))
1973        bta_dm_search_cb.wait_disc = false;
1974      else
1975        bta_dm_search_cb.wait_disc = true;
1976
1977      if (bta_dm_search_cb.p_btm_inq_info) {
1978        APPL_TRACE_DEBUG(
1979            "%s p_btm_inq_info 0x%x results.device_type 0x%x "
1980            "services_to_search 0x%x",
1981            __func__, bta_dm_search_cb.p_btm_inq_info,
1982            bta_dm_search_cb.p_btm_inq_info->results.device_type,
1983            bta_dm_search_cb.services_to_search);
1984      }
1985
1986      if (transport == BT_TRANSPORT_LE) {
1987        if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK) {
1988          // set the raw data buffer here
1989          memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
1990          bta_dm_search_cb.p_ble_rawdata = g_disc_raw_data_buf;
1991
1992          bta_dm_search_cb.ble_raw_size = MAX_DISC_RAW_DATA_BUF;
1993          bta_dm_search_cb.ble_raw_used = 0;
1994
1995          /* start GATT for service discovery */
1996          btm_dm_start_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
1997          return;
1998        }
1999      } else {
2000        bta_dm_search_cb.sdp_results = false;
2001        bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
2002        return;
2003      }
2004    }
2005  }
2006
2007  /* name discovery and service discovery are done for this device */
2008  tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
2009  p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
2010  /* initialize the data structure - includes p_raw_data and raw_data_size */
2011  memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES));
2012  p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
2013  p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
2014  p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
2015  strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
2016          (char*)bta_dm_search_cb.peer_name, BD_NAME_LEN);
2017
2018  bta_sys_sendmsg(p_msg);
2019}
2020
2021/*******************************************************************************
2022 *
2023 * Function         bta_dm_sdp_callback
2024 *
2025 * Description      Callback from sdp with discovery status
2026 *
2027 * Returns          void
2028 *
2029 ******************************************************************************/
2030static void bta_dm_sdp_callback(uint16_t sdp_status) {
2031  tBTA_DM_SDP_RESULT* p_msg =
2032      (tBTA_DM_SDP_RESULT*)osi_malloc(sizeof(tBTA_DM_SDP_RESULT));
2033
2034  p_msg->hdr.event = BTA_DM_SDP_RESULT_EVT;
2035  p_msg->sdp_result = sdp_status;
2036
2037  bta_sys_sendmsg(p_msg);
2038}
2039
2040/*******************************************************************************
2041 *
2042 * Function         bta_dm_inq_results_cb
2043 *
2044 * Description      Inquiry results callback from BTM
2045 *
2046 * Returns          void
2047 *
2048 ******************************************************************************/
2049static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, uint8_t* p_eir,
2050                                  uint16_t eir_len) {
2051  tBTA_DM_SEARCH result;
2052  tBTM_INQ_INFO* p_inq_info;
2053  uint16_t service_class;
2054
2055  result.inq_res.bd_addr = p_inq->remote_bd_addr;
2056  memcpy(result.inq_res.dev_class, p_inq->dev_class, DEV_CLASS_LEN);
2057  BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class);
2058  result.inq_res.is_limited =
2059      (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? true : false;
2060  result.inq_res.rssi = p_inq->rssi;
2061
2062  result.inq_res.ble_addr_type = p_inq->ble_addr_type;
2063  result.inq_res.inq_result_type = p_inq->inq_result_type;
2064  result.inq_res.device_type = p_inq->device_type;
2065  result.inq_res.flag = p_inq->flag;
2066
2067  /* application will parse EIR to find out remote device name */
2068  result.inq_res.p_eir = p_eir;
2069  result.inq_res.eir_len = eir_len;
2070
2071  p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr);
2072  if (p_inq_info != NULL) {
2073    /* initialize remt_name_not_required to false so that we get the name by
2074     * default */
2075    result.inq_res.remt_name_not_required = false;
2076  }
2077
2078  if (bta_dm_search_cb.p_search_cback)
2079    bta_dm_search_cb.p_search_cback(BTA_DM_INQ_RES_EVT, &result);
2080
2081  if (p_inq_info) {
2082    /* application indicates if it knows the remote name, inside the callback
2083     copy that to the inquiry data base*/
2084    if (result.inq_res.remt_name_not_required)
2085      p_inq_info->appl_knows_rem_name = true;
2086  }
2087}
2088
2089/*******************************************************************************
2090 *
2091 * Function         bta_dm_inq_cmpl_cb
2092 *
2093 * Description      Inquiry complete callback from BTM
2094 *
2095 * Returns          void
2096 *
2097 ******************************************************************************/
2098static void bta_dm_inq_cmpl_cb(void* p_result) {
2099  tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
2100
2101  APPL_TRACE_DEBUG("%s", __func__);
2102
2103  if (!bta_dm_search_cb.cancel_pending) {
2104    p_msg->inq_cmpl.hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
2105    p_msg->inq_cmpl.num = ((tBTM_INQUIRY_CMPL*)p_result)->num_resp;
2106  } else {
2107    bta_dm_search_cb.cancel_pending = false;
2108    bta_dm_search_cancel_notify(NULL);
2109    p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
2110    p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
2111  }
2112
2113  bta_sys_sendmsg(p_msg);
2114}
2115
2116/*******************************************************************************
2117 *
2118 * Function         bta_dm_service_search_remname_cback
2119 *
2120 * Description      Remote name call back from BTM during service discovery
2121 *
2122 * Returns          void
2123 *
2124 ******************************************************************************/
2125static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr,
2126                                                UNUSED_ATTR DEV_CLASS dc,
2127                                                BD_NAME bd_name) {
2128  tBTM_REMOTE_DEV_NAME rem_name;
2129  tBTM_STATUS btm_status;
2130
2131  APPL_TRACE_DEBUG("%s name=<%s>", __func__, bd_name);
2132
2133  /* if this is what we are looking for */
2134  if (bta_dm_search_cb.peer_bdaddr == bd_addr) {
2135    rem_name.length = strlen((char*)bd_name);
2136    if (rem_name.length > (BD_NAME_LEN - 1)) {
2137      rem_name.length = (BD_NAME_LEN - 1);
2138      rem_name.remote_bd_name[(BD_NAME_LEN - 1)] = 0;
2139    }
2140    strlcpy((char*)rem_name.remote_bd_name, (char*)bd_name, BD_NAME_LEN);
2141    rem_name.status = BTM_SUCCESS;
2142
2143    bta_dm_remname_cback(&rem_name);
2144  } else {
2145    /* get name of device */
2146    btm_status =
2147        BTM_ReadRemoteDeviceName(bta_dm_search_cb.peer_bdaddr,
2148                                 bta_dm_remname_cback, BT_TRANSPORT_BR_EDR);
2149    if (btm_status == BTM_BUSY) {
2150      /* wait for next chance(notification of remote name discovery done) */
2151      APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is busy", __func__);
2152    } else if (btm_status != BTM_CMD_STARTED) {
2153      /* if failed to start getting remote name then continue */
2154      APPL_TRACE_WARNING("%s: BTM_ReadRemoteDeviceName returns 0x%02X",
2155                         __func__, btm_status);
2156
2157      rem_name.length = 0;
2158      rem_name.remote_bd_name[0] = 0;
2159      rem_name.status = btm_status;
2160      bta_dm_remname_cback(&rem_name);
2161    }
2162  }
2163}
2164
2165/*******************************************************************************
2166 *
2167 * Function         bta_dm_remname_cback
2168 *
2169 * Description      Remote name complete call back from BTM
2170 *
2171 * Returns          void
2172 *
2173 ******************************************************************************/
2174static void bta_dm_remname_cback(void* p) {
2175  tBTM_REMOTE_DEV_NAME* p_remote_name = (tBTM_REMOTE_DEV_NAME*)p;
2176  APPL_TRACE_DEBUG("bta_dm_remname_cback len = %d name=<%s>",
2177                   p_remote_name->length, p_remote_name->remote_bd_name);
2178
2179  /* remote name discovery is done but it could be failed */
2180  bta_dm_search_cb.name_discover_done = true;
2181  strlcpy((char*)bta_dm_search_cb.peer_name,
2182          (char*)p_remote_name->remote_bd_name, BD_NAME_LEN);
2183
2184  BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
2185
2186  if (bta_dm_search_cb.transport == BT_TRANSPORT_LE) {
2187    GAP_BleReadPeerPrefConnParams(bta_dm_search_cb.peer_bdaddr);
2188  }
2189
2190  tBTA_DM_REM_NAME* p_msg =
2191      (tBTA_DM_REM_NAME*)osi_malloc(sizeof(tBTA_DM_REM_NAME));
2192  p_msg->result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
2193  strlcpy((char*)p_msg->result.disc_res.bd_name,
2194          (char*)p_remote_name->remote_bd_name, BD_NAME_LEN);
2195  p_msg->hdr.event = BTA_DM_REMT_NAME_EVT;
2196
2197  bta_sys_sendmsg(p_msg);
2198}
2199
2200/*******************************************************************************
2201 *
2202 * Function         bta_dm_authorize_cback
2203 *
2204 * Description      cback requesting authorization
2205 *
2206 * Returns          void
2207 *
2208 ******************************************************************************/
2209static uint8_t bta_dm_authorize_cback(const RawAddress& bd_addr,
2210                                      DEV_CLASS dev_class, BD_NAME bd_name,
2211                                      UNUSED_ATTR uint8_t* service_name,
2212                                      uint8_t service_id,
2213                                      UNUSED_ATTR bool is_originator) {
2214  tBTA_DM_SEC sec_event;
2215  uint8_t index = 1;
2216
2217  sec_event.authorize.bd_addr = bd_addr;
2218  memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN);
2219  strlcpy((char*)sec_event.authorize.bd_name, (char*)bd_name, BD_NAME_LEN);
2220
2221#if (BTA_JV_INCLUDED == TRUE)
2222  sec_event.authorize.service = service_id;
2223#endif
2224
2225  while (index < BTA_MAX_SERVICE_ID) {
2226    /* get the BTA service id corresponding to BTM id */
2227    if (bta_service_id_to_btm_srv_id_lkup_tbl[index] == service_id) {
2228      sec_event.authorize.service = index;
2229      break;
2230    }
2231    index++;
2232  }
2233
2234  /* if supported service callback otherwise not authorized */
2235  if (bta_dm_cb.p_sec_cback && (index < BTA_MAX_SERVICE_ID
2236#if (BTA_JV_INCLUDED == TRUE)
2237                                /* pass through JV service ID */
2238                                || (service_id >= BTA_FIRST_JV_SERVICE_ID &&
2239                                    service_id <= BTA_LAST_JV_SERVICE_ID)
2240#endif
2241                                    )) {
2242    bta_dm_cb.p_sec_cback(BTA_DM_AUTHORIZE_EVT, &sec_event);
2243    return BTM_CMD_STARTED;
2244  } else {
2245    return BTM_NOT_AUTHORIZED;
2246  }
2247}
2248
2249/*******************************************************************************
2250 *
2251 * Function         bta_dm_pinname_cback
2252 *
2253 * Description      Callback requesting pin_key
2254 *
2255 * Returns          void
2256 *
2257 ******************************************************************************/
2258static void bta_dm_pinname_cback(void* p_data) {
2259  tBTM_REMOTE_DEV_NAME* p_result = (tBTM_REMOTE_DEV_NAME*)p_data;
2260  tBTA_DM_SEC sec_event;
2261  uint32_t bytes_to_copy;
2262  tBTA_DM_SEC_EVT event = bta_dm_cb.pin_evt;
2263
2264  if (BTA_DM_SP_CFM_REQ_EVT == event) {
2265    /* Retrieved saved device class and bd_addr */
2266    sec_event.cfm_req.bd_addr = bta_dm_cb.pin_bd_addr;
2267    BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_cb.pin_dev_class);
2268
2269    if (p_result && p_result->status == BTM_SUCCESS) {
2270      bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1))
2271                          ? p_result->length
2272                          : (BD_NAME_LEN - 1);
2273      memcpy(sec_event.cfm_req.bd_name, p_result->remote_bd_name,
2274             bytes_to_copy);
2275      sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2276    } else /* No name found */
2277      sec_event.cfm_req.bd_name[0] = 0;
2278
2279    sec_event.key_notif.passkey =
2280        bta_dm_cb.num_val; /* get PIN code numeric number */
2281
2282    /* 1 additional event data fields for this event */
2283    sec_event.cfm_req.just_works = bta_dm_cb.just_works;
2284    /* retrieve the loc and rmt caps */
2285    sec_event.cfm_req.loc_io_caps = bta_dm_cb.loc_io_caps;
2286    sec_event.cfm_req.rmt_io_caps = bta_dm_cb.rmt_io_caps;
2287    sec_event.cfm_req.loc_auth_req = bta_dm_cb.loc_auth_req;
2288    sec_event.cfm_req.rmt_auth_req = bta_dm_cb.rmt_auth_req;
2289
2290  } else {
2291    /* Retrieved saved device class and bd_addr */
2292    sec_event.pin_req.bd_addr = bta_dm_cb.pin_bd_addr;
2293    BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_cb.pin_dev_class);
2294
2295    if (p_result && p_result->status == BTM_SUCCESS) {
2296      bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1))
2297                          ? p_result->length
2298                          : (BD_NAME_LEN - 1);
2299      memcpy(sec_event.pin_req.bd_name, p_result->remote_bd_name,
2300             bytes_to_copy);
2301      sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2302    } else /* No name found */
2303      sec_event.pin_req.bd_name[0] = 0;
2304
2305    event = bta_dm_cb.pin_evt;
2306    sec_event.key_notif.passkey =
2307        bta_dm_cb.num_val; /* get PIN code numeric number */
2308  }
2309
2310  if (bta_dm_cb.p_sec_cback) bta_dm_cb.p_sec_cback(event, &sec_event);
2311}
2312
2313/*******************************************************************************
2314 *
2315 * Function         bta_dm_pin_cback
2316 *
2317 * Description      Callback requesting pin_key
2318 *
2319 * Returns          void
2320 *
2321 ******************************************************************************/
2322static uint8_t bta_dm_pin_cback(const RawAddress& bd_addr, DEV_CLASS dev_class,
2323                                BD_NAME bd_name, bool min_16_digit) {
2324  tBTA_DM_SEC sec_event;
2325
2326  if (!bta_dm_cb.p_sec_cback) return BTM_NOT_AUTHORIZED;
2327
2328  /* If the device name is not known, save bdaddr and devclass and initiate a
2329   * name request */
2330  if (bd_name[0] == 0) {
2331    bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
2332    bta_dm_cb.pin_bd_addr = bd_addr;
2333    BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
2334    if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback,
2335                                  BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
2336      return BTM_CMD_STARTED;
2337
2338    APPL_TRACE_WARNING(
2339        " bta_dm_pin_cback() -> Failed to start Remote Name Request  ");
2340  }
2341
2342  sec_event.pin_req.bd_addr = bd_addr;
2343  BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
2344  strlcpy((char*)sec_event.pin_req.bd_name, (char*)bd_name, BD_NAME_LEN);
2345  sec_event.pin_req.min_16_digit = min_16_digit;
2346
2347  bta_dm_cb.p_sec_cback(BTA_DM_PIN_REQ_EVT, &sec_event);
2348  return BTM_CMD_STARTED;
2349}
2350
2351/*******************************************************************************
2352 *
2353 * Function         bta_dm_new_link_key_cback
2354 *
2355 * Description      Callback from BTM to notify new link key
2356 *
2357 * Returns          void
2358 *
2359 ******************************************************************************/
2360static uint8_t bta_dm_new_link_key_cback(const RawAddress& bd_addr,
2361                                         UNUSED_ATTR DEV_CLASS dev_class,
2362                                         BD_NAME bd_name, LINK_KEY key,
2363                                         uint8_t key_type) {
2364  tBTA_DM_SEC sec_event;
2365  tBTA_DM_AUTH_CMPL* p_auth_cmpl;
2366  uint8_t event;
2367
2368  memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
2369
2370  /* Not AMP Key type */
2371  if (key_type != HCI_LKEY_TYPE_AMP_WIFI && key_type != HCI_LKEY_TYPE_AMP_UWB) {
2372    event = BTA_DM_AUTH_CMPL_EVT;
2373    p_auth_cmpl = &sec_event.auth_cmpl;
2374
2375    p_auth_cmpl->bd_addr = bd_addr;
2376
2377    memcpy(p_auth_cmpl->bd_name, bd_name, (BD_NAME_LEN - 1));
2378    p_auth_cmpl->bd_name[BD_NAME_LEN - 1] = 0;
2379
2380    p_auth_cmpl->key_present = true;
2381    p_auth_cmpl->key_type = key_type;
2382    p_auth_cmpl->success = true;
2383
2384    memcpy(p_auth_cmpl->key, key, LINK_KEY_LEN);
2385    sec_event.auth_cmpl.fail_reason = HCI_SUCCESS;
2386
2387    // Report the BR link key based on the BR/EDR address and type
2388    BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type,
2389                    &sec_event.auth_cmpl.addr_type);
2390    if (bta_dm_cb.p_sec_cback) bta_dm_cb.p_sec_cback(event, &sec_event);
2391
2392    // Setting remove_dev_pending flag to false, where it will avoid deleting
2393    // the
2394    // security device record when the ACL connection link goes down in case of
2395    // reconnection.
2396    if (bta_dm_cb.device_list.count)
2397      bta_dm_reset_sec_dev_pending(p_auth_cmpl->bd_addr);
2398  } else {
2399    APPL_TRACE_WARNING("%s() Received AMP Key", __func__);
2400  }
2401
2402  return BTM_CMD_STARTED;
2403}
2404
2405/*******************************************************************************
2406 *
2407 * Function         bta_dm_authentication_complete_cback
2408 *
2409 * Description      Authentication complete callback from BTM
2410 *
2411 * Returns          void
2412 *
2413 ******************************************************************************/
2414static uint8_t bta_dm_authentication_complete_cback(
2415    const RawAddress& bd_addr, UNUSED_ATTR DEV_CLASS dev_class, BD_NAME bd_name,
2416    int result) {
2417  tBTA_DM_SEC sec_event;
2418
2419  if (result != BTM_SUCCESS) {
2420    memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
2421    sec_event.auth_cmpl.bd_addr = bd_addr;
2422
2423    memcpy(sec_event.auth_cmpl.bd_name, bd_name, (BD_NAME_LEN - 1));
2424    sec_event.auth_cmpl.bd_name[BD_NAME_LEN - 1] = 0;
2425
2426    // Report the BR link key based on the BR/EDR address and type
2427    BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type,
2428                    &sec_event.auth_cmpl.addr_type);
2429    sec_event.auth_cmpl.fail_reason = (uint8_t)result;
2430
2431    if (bta_dm_cb.p_sec_cback)
2432      bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
2433
2434    if (result == HCI_ERR_AUTH_FAILURE || result == HCI_ERR_KEY_MISSING ||
2435        result == HCI_ERR_HOST_REJECT_SECURITY ||
2436        result == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE) {
2437      APPL_TRACE_WARNING("%s deleting %s - result: 0x%02x", __func__,
2438                         bd_addr.ToString().c_str(), result);
2439      bta_dm_remove_sec_dev_entry(bd_addr);
2440    }
2441  }
2442
2443  return BTM_SUCCESS;
2444}
2445
2446/*******************************************************************************
2447 *
2448 * Function         bta_dm_sp_cback
2449 *
2450 * Description      simple pairing callback from BTM
2451 *
2452 * Returns          void
2453 *
2454 ******************************************************************************/
2455static uint8_t bta_dm_sp_cback(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data) {
2456  tBTM_STATUS status = BTM_CMD_STARTED;
2457  tBTA_DM_SEC sec_event;
2458  tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT;
2459
2460  APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event);
2461  if (!bta_dm_cb.p_sec_cback) return BTM_NOT_AUTHORIZED;
2462
2463  /* TODO_SP */
2464  switch (event) {
2465    case BTM_SP_IO_REQ_EVT:
2466#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2467      /* translate auth_req */
2468      bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap,
2469                       &p_data->io_req.oob_data, &p_data->io_req.auth_req,
2470                       p_data->io_req.is_orig);
2471#endif
2472      APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req,
2473                       p_data->io_req.oob_data);
2474      break;
2475    case BTM_SP_IO_RSP_EVT:
2476#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2477      bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap,
2478                       p_data->io_rsp.oob_data, p_data->io_rsp.auth_req);
2479#endif
2480      break;
2481
2482    case BTM_SP_CFM_REQ_EVT:
2483      pin_evt = BTA_DM_SP_CFM_REQ_EVT;
2484      bta_dm_cb.just_works = sec_event.cfm_req.just_works =
2485          p_data->cfm_req.just_works;
2486      sec_event.cfm_req.loc_auth_req = p_data->cfm_req.loc_auth_req;
2487      sec_event.cfm_req.rmt_auth_req = p_data->cfm_req.rmt_auth_req;
2488      sec_event.cfm_req.loc_io_caps = p_data->cfm_req.loc_io_caps;
2489      sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps;
2490
2491    /* continue to next case */
2492#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2493    /* Passkey entry mode, mobile device with output capability is very
2494        unlikely to receive key request, so skip this event */
2495    /*case BTM_SP_KEY_REQ_EVT: */
2496    case BTM_SP_KEY_NOTIF_EVT:
2497#endif
2498      bta_dm_cb.num_val = sec_event.key_notif.passkey =
2499          p_data->key_notif.passkey;
2500
2501      if (BTM_SP_CFM_REQ_EVT == event) {
2502        /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
2503           call remote name request using values from cfm_req */
2504        if (p_data->cfm_req.bd_name[0] == 0) {
2505          bta_dm_cb.pin_evt = pin_evt;
2506          bta_dm_cb.pin_bd_addr = p_data->cfm_req.bd_addr;
2507          bta_dm_cb.rmt_io_caps = sec_event.cfm_req.rmt_io_caps;
2508          bta_dm_cb.loc_io_caps = sec_event.cfm_req.loc_io_caps;
2509          bta_dm_cb.rmt_auth_req = sec_event.cfm_req.rmt_auth_req;
2510          bta_dm_cb.loc_auth_req = sec_event.cfm_req.loc_auth_req;
2511
2512          BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class,
2513                                p_data->cfm_req.dev_class);
2514          if ((BTM_ReadRemoteDeviceName(
2515                  p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
2516                  BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
2517            return BTM_CMD_STARTED;
2518          APPL_TRACE_WARNING(
2519              " bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
2520        } else {
2521          /* Due to the switch case falling through below to
2522             BTM_SP_KEY_NOTIF_EVT,
2523             copy these values into key_notif from cfm_req */
2524          sec_event.key_notif.bd_addr = p_data->cfm_req.bd_addr;
2525          BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class,
2526                                p_data->cfm_req.dev_class);
2527          strlcpy((char*)sec_event.key_notif.bd_name,
2528                  (char*)p_data->cfm_req.bd_name, BD_NAME_LEN);
2529        }
2530      }
2531
2532      if (BTM_SP_KEY_NOTIF_EVT == event) {
2533        /* If the device name is not known, save bdaddr and devclass
2534           and initiate a name request with values from key_notif */
2535        if (p_data->key_notif.bd_name[0] == 0) {
2536          bta_dm_cb.pin_evt = pin_evt;
2537          bta_dm_cb.pin_bd_addr = p_data->key_notif.bd_addr;
2538          BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class,
2539                                p_data->key_notif.dev_class);
2540          if ((BTM_ReadRemoteDeviceName(
2541                  p_data->key_notif.bd_addr, bta_dm_pinname_cback,
2542                  BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
2543            return BTM_CMD_STARTED;
2544          APPL_TRACE_WARNING(
2545              " bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
2546        } else {
2547          sec_event.key_notif.bd_addr = p_data->key_notif.bd_addr;
2548          BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class,
2549                                p_data->key_notif.dev_class);
2550          strlcpy((char*)sec_event.key_notif.bd_name,
2551                  (char*)p_data->key_notif.bd_name, BD_NAME_LEN);
2552          sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
2553        }
2554      }
2555
2556      bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
2557
2558      break;
2559
2560    case BTM_SP_LOC_OOB_EVT:
2561      bta_dm_co_loc_oob((bool)(p_data->loc_oob.status == BTM_SUCCESS),
2562                        p_data->loc_oob.c, p_data->loc_oob.r);
2563      break;
2564
2565    case BTM_SP_RMT_OOB_EVT:
2566      /* If the device name is not known, save bdaddr and devclass and initiate
2567       * a name request */
2568      if (p_data->rmt_oob.bd_name[0] == 0) {
2569        bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
2570        bta_dm_cb.pin_bd_addr = p_data->rmt_oob.bd_addr;
2571        BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class,
2572                              p_data->rmt_oob.dev_class);
2573        if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr,
2574                                      bta_dm_pinname_cback,
2575                                      BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
2576          return BTM_CMD_STARTED;
2577        APPL_TRACE_WARNING(
2578            " bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
2579      }
2580
2581      sec_event.rmt_oob.bd_addr = p_data->rmt_oob.bd_addr;
2582      BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class,
2583                            p_data->rmt_oob.dev_class);
2584      strlcpy((char*)sec_event.rmt_oob.bd_name, (char*)p_data->rmt_oob.bd_name,
2585              BD_NAME_LEN);
2586
2587      bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
2588
2589      bta_dm_co_rmt_oob(p_data->rmt_oob.bd_addr);
2590      break;
2591
2592    case BTM_SP_COMPLT_EVT:
2593      /* do not report this event - handled by link_key_callback or
2594       * auth_complete_callback */
2595      break;
2596
2597    case BTM_SP_KEYPRESS_EVT:
2598      memcpy(&sec_event.key_press, &p_data->key_press,
2599             sizeof(tBTM_SP_KEYPRESS));
2600      bta_dm_cb.p_sec_cback(BTA_DM_SP_KEYPRESS_EVT, &sec_event);
2601      break;
2602
2603    case BTM_SP_UPGRADE_EVT:
2604      bta_dm_co_lk_upgrade(p_data->upgrade.bd_addr, &p_data->upgrade.upgrade);
2605      break;
2606
2607    default:
2608      status = BTM_NOT_AUTHORIZED;
2609      break;
2610  }
2611  APPL_TRACE_EVENT("dm status: %d", status);
2612  return status;
2613}
2614
2615/*******************************************************************************
2616 *
2617 * Function         bta_dm_local_name_cback
2618 *
2619 * Description      Callback from btm after local name is read
2620 *
2621 *
2622 * Returns          void
2623 *
2624 ******************************************************************************/
2625static void bta_dm_local_name_cback(UNUSED_ATTR void* p_name) {
2626  tBTA_DM_SEC sec_event;
2627
2628  sec_event.enable.status = BTA_SUCCESS;
2629
2630  if (bta_dm_cb.p_sec_cback)
2631    bta_dm_cb.p_sec_cback(BTA_DM_ENABLE_EVT, &sec_event);
2632}
2633
2634static void send_busy_level_update(uint8_t busy_level,
2635                                   uint8_t busy_level_flags) {
2636  if (!bta_dm_cb.p_sec_cback) return;
2637
2638  tBTA_DM_SEC conn;
2639  memset(&conn, 0, sizeof(tBTA_DM_SEC));
2640  conn.busy_level.level = busy_level;
2641  conn.busy_level.level_flags = busy_level_flags;
2642  bta_dm_cb.p_sec_cback(BTA_DM_BUSY_LEVEL_EVT, &conn);
2643}
2644
2645static void handle_role_change(const RawAddress& bd_addr, uint8_t new_role,
2646                               uint8_t hci_status) {
2647  tBTA_DM_SEC conn;
2648  memset(&conn, 0, sizeof(tBTA_DM_SEC));
2649
2650  tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr);
2651  if (!p_dev) return;
2652  LOG_INFO(LOG_TAG,
2653           "%s: peer %s info:0x%x new_role:0x%x dev count:%d hci_status=%d",
2654           __func__, bd_addr.ToString().c_str(), p_dev->info, new_role,
2655           bta_dm_cb.device_list.count, hci_status);
2656  if (p_dev->info & BTA_DM_DI_AV_ACTIVE) {
2657    bool need_policy_change = false;
2658
2659    /* there's AV activity on this link */
2660    if (new_role == HCI_ROLE_SLAVE && bta_dm_cb.device_list.count > 1 &&
2661        hci_status == HCI_SUCCESS) {
2662      /* more than one connections and the AV connection is role switched
2663       * to slave
2664       * switch it back to master and remove the switch policy */
2665      BTM_SwitchRole(bd_addr, BTM_ROLE_MASTER, NULL);
2666      need_policy_change = true;
2667    } else if (p_bta_dm_cfg->avoid_scatter && (new_role == HCI_ROLE_MASTER)) {
2668      /* if the link updated to be master include AV activities, remove
2669       * the switch policy */
2670      need_policy_change = true;
2671    }
2672
2673    if (need_policy_change) {
2674      bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH,
2675                          p_dev->peer_bdaddr);
2676    }
2677  } else {
2678    /* there's AV no activity on this link and role switch happened
2679     * check if AV is active
2680     * if so, make sure the AV link is master */
2681    bta_dm_check_av(0);
2682  }
2683  bta_sys_notify_role_chg(bd_addr, new_role, hci_status);
2684  conn.role_chg.bd_addr = bd_addr;
2685  conn.role_chg.new_role = (uint8_t)new_role;
2686  if (bta_dm_cb.p_sec_cback) bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, &conn);
2687}
2688
2689static void bta_dm_acl_change(bool is_new, const RawAddress& bd_addr,
2690                              tBT_TRANSPORT transport, uint16_t handle) {
2691  bool issue_unpair_cb = false;
2692
2693  tBTA_DM_SEC conn;
2694  memset(&conn, 0, sizeof(tBTA_DM_SEC));
2695
2696  if (is_new) {
2697    uint8_t i;
2698    for (i = 0; i < bta_dm_cb.device_list.count; i++) {
2699      if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == bd_addr &&
2700          bta_dm_cb.device_list.peer_device[i].conn_handle == handle)
2701        break;
2702    }
2703
2704    if (i == bta_dm_cb.device_list.count) {
2705      if (bta_dm_cb.device_list.count < BTA_DM_NUM_PEER_DEVICE) {
2706        bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count]
2707            .peer_bdaddr = bd_addr;
2708        bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count]
2709            .link_policy = bta_dm_cb.cur_policy;
2710        bta_dm_cb.device_list.count++;
2711        bta_dm_cb.device_list.peer_device[i].conn_handle = handle;
2712        if (transport == BT_TRANSPORT_LE) bta_dm_cb.device_list.le_count++;
2713      } else {
2714        APPL_TRACE_ERROR("%s max active connection reached, no resources",
2715                         __func__);
2716        return;
2717      }
2718    }
2719
2720    bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED;
2721    bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE;
2722    conn.link_up.bd_addr = bd_addr;
2723    bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE;
2724    conn.link_up.link_type = transport;
2725    bta_dm_cb.device_list.peer_device[i].transport = transport;
2726
2727    uint8_t* p;
2728    if (((NULL != (p = BTM_ReadLocalFeatures())) &&
2729         HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
2730        ((NULL != (p = BTM_ReadRemoteFeatures(bd_addr))) &&
2731         HCI_SNIFF_SUB_RATE_SUPPORTED(p))) {
2732      /* both local and remote devices support SSR */
2733      bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR;
2734    }
2735    APPL_TRACE_WARNING("%s info: 0x%x", __func__,
2736                       bta_dm_cb.device_list.peer_device[i].info);
2737
2738    if (bta_dm_cb.p_sec_cback) bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, &conn);
2739  } else {
2740    for (uint8_t i = 0; i < bta_dm_cb.device_list.count; i++) {
2741      if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr != bd_addr ||
2742          bta_dm_cb.device_list.peer_device[i].transport != transport)
2743        continue;
2744
2745      if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING) {
2746        if (BTM_SecDeleteDevice(
2747                bta_dm_cb.device_list.peer_device[i].peer_bdaddr))
2748          issue_unpair_cb = true;
2749
2750        APPL_TRACE_DEBUG("%s: Unpairing: issue unpair CB = %d ", __func__,
2751                         issue_unpair_cb);
2752      }
2753
2754      conn.link_down.is_removed =
2755          bta_dm_cb.device_list.peer_device[i].remove_dev_pending;
2756
2757      // Iterate to the one before the last when shrinking the list,
2758      // otherwise we memcpy garbage data into the record.
2759      // Then clear out the last item in the list since we are shrinking.
2760      for (; i < bta_dm_cb.device_list.count - 1; i++) {
2761        memcpy(&bta_dm_cb.device_list.peer_device[i],
2762               &bta_dm_cb.device_list.peer_device[i + 1],
2763               sizeof(bta_dm_cb.device_list.peer_device[i]));
2764      }
2765      if (bta_dm_cb.device_list.count > 0) {
2766        int clear_index = bta_dm_cb.device_list.count - 1;
2767        memset(&bta_dm_cb.device_list.peer_device[clear_index], 0,
2768               sizeof(bta_dm_cb.device_list.peer_device[clear_index]));
2769      }
2770      break;
2771    }
2772    if (bta_dm_cb.device_list.count) bta_dm_cb.device_list.count--;
2773    if ((transport == BT_TRANSPORT_LE) && (bta_dm_cb.device_list.le_count))
2774      bta_dm_cb.device_list.le_count--;
2775    conn.link_down.link_type = transport;
2776
2777    if (bta_dm_search_cb.wait_disc && bta_dm_search_cb.peer_bdaddr == bd_addr) {
2778      bta_dm_search_cb.wait_disc = false;
2779
2780      if (bta_dm_search_cb.sdp_results) {
2781        APPL_TRACE_EVENT(" timer stopped  ");
2782        alarm_cancel(bta_dm_search_cb.search_timer);
2783        bta_dm_discover_next_device();
2784      }
2785    }
2786
2787    if (bta_dm_cb.disabling) {
2788      if (!BTM_GetNumAclLinks()) {
2789        /*
2790         * Start a timer to make sure that the profiles
2791         * get the disconnect event.
2792         */
2793        alarm_set_on_mloop(bta_dm_cb.disable_timer,
2794                           BTA_DM_DISABLE_CONN_DOWN_TIMER_MS,
2795                           bta_dm_disable_conn_down_timer_cback, NULL);
2796      }
2797    }
2798    if (conn.link_down.is_removed) {
2799      BTM_SecDeleteDevice(bd_addr);
2800      /* need to remove all pending background connection */
2801      BTA_GATTC_CancelOpen(0, bd_addr, false);
2802      /* remove all cached GATT information */
2803      BTA_GATTC_Refresh(bd_addr);
2804    }
2805
2806    conn.link_down.bd_addr = bd_addr;
2807    conn.link_down.status = (uint8_t)btm_get_acl_disc_reason_code();
2808    if (bta_dm_cb.p_sec_cback) {
2809      bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn);
2810      if (issue_unpair_cb)
2811        bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn);
2812    }
2813  }
2814
2815  bta_dm_adjust_roles(true);
2816}
2817
2818/** Callback from btm when acl connection goes up or down */
2819static void bta_dm_bl_change_cback(tBTM_BL_EVENT_DATA* p_data) {
2820  switch (p_data->event) {
2821    case BTM_BL_CONN_EVT:
2822      /* connection up */
2823      do_in_bta_thread(FROM_HERE,
2824                       base::Bind(bta_dm_acl_change, true, *p_data->conn.p_bda,
2825                                  p_data->conn.transport, p_data->conn.handle));
2826      break;
2827    case BTM_BL_DISCN_EVT:
2828      /* connection down */
2829      do_in_bta_thread(
2830          FROM_HERE, base::Bind(bta_dm_acl_change, false, *p_data->discn.p_bda,
2831                                p_data->discn.transport, p_data->discn.handle));
2832      break;
2833
2834    case BTM_BL_UPDATE_EVT: {
2835      /* busy level update */
2836      do_in_bta_thread(FROM_HERE, base::Bind(send_busy_level_update,
2837                                             p_data->update.busy_level,
2838                                             p_data->update.busy_level_flags));
2839      return;
2840    }
2841    case BTM_BL_ROLE_CHG_EVT: {
2842      const auto& tmp = p_data->role_chg;
2843      do_in_bta_thread(FROM_HERE, base::Bind(handle_role_change, *tmp.p_bda,
2844                                             tmp.new_role, tmp.hci_status));
2845      return;
2846    }
2847
2848    case BTM_BL_COLLISION_EVT:
2849      /* Collision report from Stack: Notify profiles */
2850      do_in_bta_thread(
2851          FROM_HERE, base::Bind(bta_sys_notify_collision, *p_data->conn.p_bda));
2852      return;
2853  }
2854}
2855
2856/*******************************************************************************
2857 *
2858 * Function         bta_dm_rs_cback
2859 *
2860 * Description      Receives the role switch complete event
2861 *
2862 * Returns
2863 *
2864 ******************************************************************************/
2865static void bta_dm_rs_cback(UNUSED_ATTR void* p1) {
2866  APPL_TRACE_WARNING("bta_dm_rs_cback:%d", bta_dm_cb.rs_event);
2867  if (bta_dm_cb.rs_event == BTA_DM_API_SEARCH_EVT) {
2868    bta_dm_cb.search_msg.rs_res =
2869        BTA_DM_RS_OK; /* do not care about the result for now */
2870    bta_dm_cb.rs_event = 0;
2871    bta_dm_search_start((tBTA_DM_MSG*)&bta_dm_cb.search_msg);
2872  }
2873}
2874
2875/*******************************************************************************
2876 *
2877 * Function         bta_dm_check_av
2878 *
2879 * Description      This function checks if AV is active
2880 *                  if yes, make sure the AV link is master
2881 *
2882 * Returns          bool - true, if switch is in progress
2883 *
2884 ******************************************************************************/
2885static bool bta_dm_check_av(uint16_t event) {
2886  bool avoid_roleswitch = false;
2887  bool switching = false;
2888  uint8_t i;
2889  tBTA_DM_PEER_DEVICE* p_dev;
2890
2891#if (BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY == TRUE)
2892
2893  /* avoid role switch upon inquiry if a2dp is actively streaming as it
2894     introduces an audioglitch due to FW scheduling delays (unavoidable) */
2895  if (event == BTA_DM_API_SEARCH_EVT) {
2896    avoid_roleswitch = true;
2897  }
2898#endif
2899
2900  APPL_TRACE_WARNING("bta_dm_check_av:%d", bta_dm_cb.cur_av_count);
2901  if (bta_dm_cb.cur_av_count) {
2902    for (i = 0; i < bta_dm_cb.device_list.count; i++) {
2903      p_dev = &bta_dm_cb.device_list.peer_device[i];
2904      APPL_TRACE_WARNING("[%d]: state:%d, info:x%x, avoid_rs %d", i,
2905                         p_dev->conn_state, p_dev->info, avoid_roleswitch);
2906      if ((p_dev->conn_state == BTA_DM_CONNECTED) &&
2907          (p_dev->info & BTA_DM_DI_AV_ACTIVE) && (!avoid_roleswitch)) {
2908        /* make master and take away the role switch policy */
2909        if (BTM_CMD_STARTED == BTM_SwitchRole(p_dev->peer_bdaddr,
2910                                              HCI_ROLE_MASTER,
2911                                              bta_dm_rs_cback)) {
2912          /* the role switch command is actually sent */
2913          bta_dm_cb.rs_event = event;
2914          switching = true;
2915        }
2916        /* else either already master or can not switch for some reasons */
2917        bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH,
2918                            p_dev->peer_bdaddr);
2919        break;
2920      }
2921    }
2922  }
2923  return switching;
2924}
2925
2926/*******************************************************************************
2927 *
2928 * Function         bta_dm_disable_conn_down_timer_cback
2929 *
2930 * Description      Sends disable event to application
2931 *
2932 *
2933 * Returns          void
2934 *
2935 ******************************************************************************/
2936static void bta_dm_disable_conn_down_timer_cback(UNUSED_ATTR void* data) {
2937  tBTA_SYS_HW_MSG* sys_enable_event =
2938      (tBTA_SYS_HW_MSG*)osi_malloc(sizeof(tBTA_SYS_HW_MSG));
2939
2940  /* disable the power managment module */
2941  bta_dm_disable_pm();
2942
2943  /* register our callback to SYS HW manager */
2944  bta_sys_hw_register(BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback);
2945
2946  /* send a message to BTA SYS */
2947  sys_enable_event->hdr.event = BTA_SYS_API_DISABLE_EVT;
2948  sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;
2949  bta_sys_sendmsg(sys_enable_event);
2950
2951  bta_dm_cb.disabling = false;
2952}
2953
2954/*******************************************************************************
2955 *
2956 * Function         bta_dm_rm_cback
2957 *
2958 * Description      Role management callback from sys
2959 *
2960 *
2961 * Returns          void
2962 *
2963 ******************************************************************************/
2964static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id,
2965                            uint8_t app_id, const RawAddress& peer_addr) {
2966  uint8_t j;
2967  tBTA_PREF_ROLES role;
2968  tBTA_DM_PEER_DEVICE* p_dev;
2969
2970  p_dev = bta_dm_find_peer_device(peer_addr);
2971  if (status == BTA_SYS_CONN_OPEN) {
2972    if (p_dev) {
2973      /* Do not set to connected if we are in the middle of unpairing. When AV
2974       * stream is
2975       * started it fakes out a SYS_CONN_OPEN to potentially trigger a role
2976       * switch command.
2977       * But this should not be done if we are in the middle of unpairing.
2978       */
2979      if (p_dev->conn_state != BTA_DM_UNPAIRING)
2980        p_dev->conn_state = BTA_DM_CONNECTED;
2981
2982      for (j = 1; j <= p_bta_dm_rm_cfg[0].app_id; j++) {
2983        if (((p_bta_dm_rm_cfg[j].app_id == app_id) ||
2984             (p_bta_dm_rm_cfg[j].app_id == BTA_ALL_APP_ID)) &&
2985            (p_bta_dm_rm_cfg[j].id == id)) {
2986          role = p_bta_dm_rm_cfg[j].cfg;
2987
2988          if (role > p_dev->pref_role) p_dev->pref_role = role;
2989          break;
2990        }
2991      }
2992    }
2993  }
2994
2995  if ((BTA_ID_AV == id) || (BTA_ID_AVK == id)) {
2996    if (status == BTA_SYS_CONN_BUSY) {
2997      if (p_dev) p_dev->info |= BTA_DM_DI_AV_ACTIVE;
2998      /* AV calls bta_sys_conn_open with the A2DP stream count as app_id */
2999      if (BTA_ID_AV == id) bta_dm_cb.cur_av_count = bta_dm_get_av_count();
3000    } else if (status == BTA_SYS_CONN_IDLE) {
3001      if (p_dev) p_dev->info &= ~BTA_DM_DI_AV_ACTIVE;
3002
3003      /* get cur_av_count from connected services */
3004      if (BTA_ID_AV == id) bta_dm_cb.cur_av_count = bta_dm_get_av_count();
3005    }
3006    APPL_TRACE_WARNING("bta_dm_rm_cback:%d, status:%d", bta_dm_cb.cur_av_count,
3007                       status);
3008  }
3009
3010  /* Don't adjust roles for each busy/idle state transition to avoid
3011     excessive switch requests when individual profile busy/idle status
3012     changes */
3013  if ((status != BTA_SYS_CONN_BUSY) && (status != BTA_SYS_CONN_IDLE))
3014    bta_dm_adjust_roles(false);
3015}
3016
3017/*******************************************************************************
3018 *
3019 * Function         bta_dm_delay_role_switch_cback
3020 *
3021 * Description      Callback from btm to delay a role switch
3022 *
3023 * Returns          void
3024 *
3025 ******************************************************************************/
3026static void bta_dm_delay_role_switch_cback(UNUSED_ATTR void* data) {
3027  APPL_TRACE_EVENT("%s: initiating Delayed RS", __func__);
3028  bta_dm_adjust_roles(false);
3029}
3030
3031/*******************************************************************************
3032 *
3033 * Function         bta_dm_reset_sec_dev_pending
3034 *
3035 * Description      Setting the remove device pending status to false from
3036 *                  security device DB, when the link key notification
3037 *                  event comes.
3038 *
3039 * Returns          void
3040 *
3041 ******************************************************************************/
3042static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr) {
3043  for (size_t i = 0; i < bta_dm_cb.device_list.count; i++) {
3044    if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == remote_bd_addr) {
3045      bta_dm_cb.device_list.peer_device[i].remove_dev_pending = false;
3046      return;
3047    }
3048  }
3049}
3050
3051/*******************************************************************************
3052 *
3053 * Function         bta_dm_remove_sec_dev_entry
3054 *
3055 * Description      Removes device entry from Security device DB if ACL
3056 connection with
3057 *                  remtoe device does not exist, else schedule for dev entry
3058 removal upon
3059                     ACL close
3060 *
3061 * Returns          void
3062 *
3063 ******************************************************************************/
3064static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr) {
3065  if (BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
3066      BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR)) {
3067    APPL_TRACE_DEBUG(
3068        "%s ACL is not down. Schedule for  Dev Removal when ACL closes",
3069        __func__);
3070    BTM_SecClearSecurityFlags(remote_bd_addr);
3071    for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
3072      if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == remote_bd_addr) {
3073        bta_dm_cb.device_list.peer_device[i].remove_dev_pending = TRUE;
3074        break;
3075      }
3076    }
3077  } else {
3078    BTM_SecDeleteDevice(remote_bd_addr);
3079    /* need to remove all pending background connection */
3080    BTA_GATTC_CancelOpen(0, remote_bd_addr, false);
3081    /* remove all cached GATT information */
3082    BTA_GATTC_Refresh(remote_bd_addr);
3083  }
3084}
3085
3086/*******************************************************************************
3087 *
3088 * Function         bta_dm_adjust_roles
3089 *
3090 * Description      Adjust roles
3091 *
3092 *
3093 * Returns          void
3094 *
3095 ******************************************************************************/
3096static void bta_dm_adjust_roles(bool delay_role_switch) {
3097  uint8_t i;
3098  bool set_master_role = false;
3099  uint8_t br_count =
3100      bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count;
3101  if (br_count) {
3102    /* the configuration is no scatternet
3103     * or AV connection exists and there are more than one ACL link */
3104    if ((p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
3105        (bta_dm_cb.cur_av_count && br_count > 1)) {
3106      L2CA_SetDesireRole(HCI_ROLE_MASTER);
3107      set_master_role = true;
3108    }
3109
3110    for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3111      if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED &&
3112          bta_dm_cb.device_list.peer_device[i].transport ==
3113              BT_TRANSPORT_BR_EDR) {
3114        if (!set_master_role &&
3115            (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE) &&
3116            (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET)) {
3117          L2CA_SetDesireRole(HCI_ROLE_MASTER);
3118          set_master_role = true;
3119        }
3120
3121        if ((bta_dm_cb.device_list.peer_device[i].pref_role ==
3122             BTA_MASTER_ROLE_ONLY) ||
3123            (br_count > 1)) {
3124          /* Initiating immediate role switch with certain remote devices
3125            has caused issues due to role  switch colliding with link encryption
3126            setup and
3127            causing encryption (and in turn the link) to fail .  These device .
3128            Firmware
3129            versions are stored in a blacklist and role switch with these
3130            devices are
3131            delayed to avoid the collision with link encryption setup */
3132
3133          if (bta_dm_cb.device_list.peer_device[i].pref_role !=
3134                  BTA_SLAVE_ROLE_ONLY &&
3135              !delay_role_switch) {
3136            BTM_SwitchRole(bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
3137                           HCI_ROLE_MASTER, NULL);
3138          } else {
3139            alarm_set_on_mloop(bta_dm_cb.switch_delay_timer,
3140                               BTA_DM_SWITCH_DELAY_TIMER_MS,
3141                               bta_dm_delay_role_switch_cback, NULL);
3142          }
3143        }
3144      }
3145    }
3146
3147    if (!set_master_role) {
3148      L2CA_SetDesireRole(L2CAP_DESIRED_LINK_ROLE);
3149    }
3150
3151  } else {
3152    L2CA_SetDesireRole(L2CAP_DESIRED_LINK_ROLE);
3153  }
3154}
3155
3156/*******************************************************************************
3157 *
3158 * Function         bta_dm_get_remname
3159 *
3160 * Description      Returns a pointer to the remote name stored in the DM
3161 *                  control block if it exists, or from the BTM memory.
3162 *
3163 * Returns          char * - Pointer to the remote device name
3164 ******************************************************************************/
3165static char* bta_dm_get_remname(void) {
3166  char* p_name = (char*)bta_dm_search_cb.peer_name;
3167  char* p_temp;
3168
3169  /* If the name isn't already stored, try retrieving from BTM */
3170  if (*p_name == '\0') {
3171    p_temp = BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr);
3172    if (p_temp != NULL) p_name = p_temp;
3173  }
3174
3175  return p_name;
3176}
3177
3178/*******************************************************************************
3179 *
3180 * Function         bta_dm_bond_cancel_complete_cback
3181 *
3182 * Description      Authentication complete callback from BTM
3183 *
3184 * Returns          void
3185 *
3186 ******************************************************************************/
3187static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result) {
3188  tBTA_DM_SEC sec_event;
3189
3190  if (result == BTM_SUCCESS)
3191    sec_event.bond_cancel_cmpl.result = BTA_SUCCESS;
3192  else
3193    sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
3194
3195  if (bta_dm_cb.p_sec_cback) {
3196    bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
3197  }
3198}
3199
3200/*******************************************************************************
3201 *
3202 * Function         find_utf8_char_boundary
3203 *
3204 * Description      This function checks a UTF8 string |utf8str| starting at
3205 *                  |offset|, moving backwards and returns the offset of the
3206 *                  next valid UTF8 character boundary found.
3207 *
3208 * Returns          Offset of UTF8 character boundary
3209 *
3210 ******************************************************************************/
3211static size_t find_utf8_char_boundary(const char* utf8str, size_t offset) {
3212  CHECK(utf8str);
3213  CHECK(offset > 0);
3214
3215  while (--offset) {
3216    uint8_t ch = (uint8_t)utf8str[offset];
3217    if ((ch & 0x80) == 0x00)  // ASCII
3218      return offset + 1;
3219    if ((ch & 0xC0) == 0xC0)  // Multi-byte sequence start
3220      return offset;
3221  }
3222
3223  return 0;
3224}
3225
3226/*******************************************************************************
3227 *
3228 * Function         bta_dm_set_eir
3229 *
3230 * Description      This function creates EIR tagged data and writes it to
3231 *                  controller.
3232 *
3233 * Returns          None
3234 *
3235 ******************************************************************************/
3236static void bta_dm_set_eir(char* local_name) {
3237  uint8_t* p;
3238  uint8_t* p_length;
3239#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3240  uint8_t* p_type;
3241  uint8_t max_num_uuid;
3242#if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3243  uint8_t custom_uuid_idx;
3244#endif  // BTA_EIR_SERVER_NUM_CUSTOM_UUID
3245#endif  // BTA_EIR_CANNED_UUID_LIST
3246#if (BTM_EIR_DEFAULT_FEC_REQUIRED == FALSE)
3247  uint8_t free_eir_length = HCI_EXT_INQ_RESPONSE_LEN;
3248#else  // BTM_EIR_DEFAULT_FEC_REQUIRED
3249  uint8_t free_eir_length = HCI_DM5_PACKET_SIZE;
3250#endif  // BTM_EIR_DEFAULT_FEC_REQUIRED
3251  uint8_t num_uuid;
3252  uint8_t data_type;
3253  uint8_t local_name_len;
3254
3255  /* wait until complete to disable */
3256  if (alarm_is_scheduled(bta_dm_cb.disable_timer)) return;
3257
3258#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3259  /* if local name is not provided, get it from controller */
3260  if (local_name == NULL) {
3261    if (BTM_ReadLocalDeviceName(&local_name) != BTM_SUCCESS) {
3262      APPL_TRACE_ERROR("Fail to read local device name for EIR");
3263    }
3264  }
3265#endif  // BTA_EIR_CANNED_UUID_LIST
3266
3267  /* Allocate a buffer to hold HCI command */
3268  BT_HDR* p_buf = (BT_HDR*)osi_malloc(BTM_CMD_BUF_SIZE);
3269  p = (uint8_t*)p_buf + BTM_HCI_EIR_OFFSET;
3270
3271  memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN);
3272
3273  APPL_TRACE_DEBUG("BTA is generating EIR");
3274
3275  if (local_name)
3276    local_name_len = strlen(local_name);
3277  else
3278    local_name_len = 0;
3279
3280  data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3281  /* if local name is longer than minimum length of shortened name */
3282  /* check whether it needs to be shortened or not */
3283  if (local_name_len > p_bta_dm_eir_cfg->bta_dm_eir_min_name_len) {
3284/* get number of UUID 16-bit list */
3285#if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3286    num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / Uuid::kNumBytes16;
3287#else   // BTA_EIR_CANNED_UUID_LIST
3288    max_num_uuid = (free_eir_length - 2) / Uuid::kNumBytes16;
3289    data_type = BTM_GetEirSupportedServices(bta_dm_cb.eir_uuid, &p,
3290                                            max_num_uuid, &num_uuid);
3291    p = (uint8_t*)p_buf + BTM_HCI_EIR_OFFSET; /* reset p */
3292#endif  // BTA_EIR_CANNED_UUID_LIST
3293
3294    /* if UUID doesn't fit remaing space, shorten local name */
3295    if (local_name_len > (free_eir_length - 4 - num_uuid * Uuid::kNumBytes16)) {
3296      local_name_len = find_utf8_char_boundary(
3297          local_name, p_bta_dm_eir_cfg->bta_dm_eir_min_name_len);
3298      APPL_TRACE_WARNING("%s local name is shortened (%d)", __func__,
3299                         local_name_len);
3300      data_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE;
3301    } else {
3302      data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3303    }
3304  }
3305
3306  UINT8_TO_STREAM(p, local_name_len + 1);
3307  UINT8_TO_STREAM(p, data_type);
3308
3309  if (local_name != NULL) {
3310    memcpy(p, local_name, local_name_len);
3311    p += local_name_len;
3312  }
3313  free_eir_length -= local_name_len + 2;
3314
3315#if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3316  /* if UUID list is provided as static data in configuration */
3317  if ((p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len > 0) &&
3318      (p_bta_dm_eir_cfg->bta_dm_eir_uuid16)) {
3319    if (free_eir_length > Uuid::kNumBytes16 + 2) {
3320      free_eir_length -= 2;
3321
3322      if (free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len) {
3323        num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / Uuid::kNumBytes16;
3324        data_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3325      } else /* not enough room for all UUIDs */
3326      {
3327        APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3328        num_uuid = free_eir_length / Uuid::kNumBytes16;
3329        data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3330      }
3331      UINT8_TO_STREAM(p, num_uuid * Uuid::kNumBytes16 + 1);
3332      UINT8_TO_STREAM(p, data_type);
3333      memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_uuid16,
3334             num_uuid * Uuid::kNumBytes16);
3335      p += num_uuid * Uuid::kNumBytes16;
3336      free_eir_length -= num_uuid * Uuid::kNumBytes16;
3337    }
3338  }
3339#else /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3340  /* if UUID list is dynamic */
3341  if (free_eir_length >= 2) {
3342    p_length = p++;
3343    p_type = p++;
3344    num_uuid = 0;
3345
3346    max_num_uuid = (free_eir_length - 2) / Uuid::kNumBytes16;
3347    data_type = BTM_GetEirSupportedServices(bta_dm_cb.eir_uuid, &p,
3348                                            max_num_uuid, &num_uuid);
3349
3350    if (data_type == BTM_EIR_MORE_16BITS_UUID_TYPE) {
3351      APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3352    }
3353#if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3354    else {
3355      for (custom_uuid_idx = 0;
3356           custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID;
3357           custom_uuid_idx++) {
3358        const Uuid& curr = bta_dm_cb.custom_uuid[custom_uuid_idx];
3359        if (curr.GetShortestRepresentationSize() == Uuid::kNumBytes16) {
3360          if (num_uuid < max_num_uuid) {
3361            UINT16_TO_STREAM(p, curr.As16Bit());
3362            num_uuid++;
3363          } else {
3364            data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3365            APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3366            break;
3367          }
3368        }
3369      }
3370    }
3371#endif /* (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3372
3373    UINT8_TO_STREAM(p_length, num_uuid * Uuid::kNumBytes16 + 1);
3374    UINT8_TO_STREAM(p_type, data_type);
3375    free_eir_length -= num_uuid * Uuid::kNumBytes16 + 2;
3376  }
3377#endif /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3378
3379#if (BTA_EIR_CANNED_UUID_LIST != TRUE && BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3380  /* Adding 32-bit UUID list */
3381  if (free_eir_length >= 2) {
3382    p_length = p++;
3383    p_type = p++;
3384    num_uuid = 0;
3385    data_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE;
3386
3387    max_num_uuid = (free_eir_length - 2) / Uuid::kNumBytes32;
3388
3389    for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID;
3390         custom_uuid_idx++) {
3391      const Uuid& curr = bta_dm_cb.custom_uuid[custom_uuid_idx];
3392      if (curr.GetShortestRepresentationSize() == Uuid::kNumBytes32) {
3393        if (num_uuid < max_num_uuid) {
3394          UINT32_TO_STREAM(p, curr.As32Bit());
3395          num_uuid++;
3396        } else {
3397          data_type = BTM_EIR_MORE_32BITS_UUID_TYPE;
3398          APPL_TRACE_WARNING("BTA EIR: UUID 32-bit list is truncated");
3399          break;
3400        }
3401      }
3402    }
3403
3404    UINT8_TO_STREAM(p_length, num_uuid * Uuid::kNumBytes32 + 1);
3405    UINT8_TO_STREAM(p_type, data_type);
3406    free_eir_length -= num_uuid * Uuid::kNumBytes32 + 2;
3407  }
3408
3409  /* Adding 128-bit UUID list */
3410  if (free_eir_length >= 2) {
3411    p_length = p++;
3412    p_type = p++;
3413    num_uuid = 0;
3414    data_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE;
3415
3416    max_num_uuid = (free_eir_length - 2) / Uuid::kNumBytes128;
3417
3418    for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID;
3419         custom_uuid_idx++) {
3420      const Uuid& curr = bta_dm_cb.custom_uuid[custom_uuid_idx];
3421      if (curr.GetShortestRepresentationSize() == Uuid::kNumBytes128) {
3422        if (num_uuid < max_num_uuid) {
3423          ARRAY16_TO_STREAM(p, curr.To128BitBE().data());
3424          num_uuid++;
3425        } else {
3426          data_type = BTM_EIR_MORE_128BITS_UUID_TYPE;
3427          APPL_TRACE_WARNING("BTA EIR: UUID 128-bit list is truncated");
3428          break;
3429        }
3430      }
3431    }
3432
3433    UINT8_TO_STREAM(p_length, num_uuid * Uuid::kNumBytes128 + 1);
3434    UINT8_TO_STREAM(p_type, data_type);
3435    free_eir_length -= num_uuid * Uuid::kNumBytes128 + 2;
3436  }
3437#endif /* ( BTA_EIR_CANNED_UUID_LIST != TRUE \
3438          )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3439
3440  /* if Flags are provided in configuration */
3441  if ((p_bta_dm_eir_cfg->bta_dm_eir_flag_len > 0) &&
3442      (p_bta_dm_eir_cfg->bta_dm_eir_flags) &&
3443      (free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2)) {
3444    UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 1);
3445    UINT8_TO_STREAM(p, BTM_EIR_FLAGS_TYPE);
3446    memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_flags,
3447           p_bta_dm_eir_cfg->bta_dm_eir_flag_len);
3448    p += p_bta_dm_eir_cfg->bta_dm_eir_flag_len;
3449    free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2;
3450  }
3451
3452  /* if Manufacturer Specific are provided in configuration */
3453  if ((p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len > 0) &&
3454      (p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec) &&
3455      (free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2)) {
3456    p_length = p;
3457
3458    UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 1);
3459    UINT8_TO_STREAM(p, BTM_EIR_MANUFACTURER_SPECIFIC_TYPE);
3460    memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec,
3461           p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len);
3462    p += p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len;
3463    free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2;
3464
3465  } else {
3466    p_length = NULL;
3467  }
3468
3469  /* if Inquiry Tx Resp Power compiled */
3470  if ((p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power) && (free_eir_length >= 3)) {
3471    UINT8_TO_STREAM(p, 2); /* Length field */
3472    UINT8_TO_STREAM(p, BTM_EIR_TX_POWER_LEVEL_TYPE);
3473    UINT8_TO_STREAM(p, *(p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power));
3474    free_eir_length -= 3;
3475  }
3476
3477  if (free_eir_length)
3478    UINT8_TO_STREAM(p, 0); /* terminator of significant part */
3479
3480  BTM_WriteEIR(p_buf);
3481}
3482
3483/*******************************************************************************
3484 *
3485 * Function         bta_dm_eir_search_services
3486 *
3487 * Description      This function searches services in received EIR
3488 *
3489 * Returns          None
3490 *
3491 ******************************************************************************/
3492static void bta_dm_eir_search_services(tBTM_INQ_RESULTS* p_result,
3493                                       tBTA_SERVICE_MASK* p_services_to_search,
3494                                       tBTA_SERVICE_MASK* p_services_found) {
3495  tBTA_SERVICE_MASK service_index = 0;
3496  tBTM_EIR_SEARCH_RESULT result;
3497
3498  VLOG(1) << "BTA searching services in EIR of BDA:"
3499          << p_result->remote_bd_addr;
3500
3501  APPL_TRACE_DEBUG("    with services_to_search=0x%08X", *p_services_to_search);
3502
3503  /* always do GATT based service discovery by SDP instead of from EIR    */
3504  /* if GATT based service is also to be put in EIR, need to modify this  */
3505  while (service_index < (BTA_MAX_SERVICE_ID - 1)) {
3506    if (*p_services_to_search &
3507        (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index))) {
3508      result = BTM_HasInquiryEirService(
3509          p_result, bta_service_id_to_uuid_lkup_tbl[service_index]);
3510
3511      /* Searching for HSP v1.2 only device */
3512      if ((result != BTM_EIR_FOUND) &&
3513          (bta_service_id_to_uuid_lkup_tbl[service_index] ==
3514           UUID_SERVCLASS_HEADSET)) {
3515        result = BTM_HasInquiryEirService(p_result, UUID_SERVCLASS_HEADSET_HS);
3516      }
3517
3518      if (result == BTM_EIR_FOUND) {
3519        /* If Plug and Play service record, need to check to see if Broadcom
3520         * stack */
3521        /* However, EIR data doesn't have EXT_BRCM_VERSION so just skip it */
3522        if (bta_service_id_to_uuid_lkup_tbl[service_index] !=
3523            UUID_SERVCLASS_PNP_INFORMATION) {
3524          *p_services_found |= (tBTA_SERVICE_MASK)(
3525              BTA_SERVICE_ID_TO_SERVICE_MASK(service_index));
3526          /* remove the service from services to be searched  */
3527          *p_services_to_search &= (tBTA_SERVICE_MASK)(
3528              ~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
3529        }
3530      } else if (result == BTM_EIR_NOT_FOUND) {
3531        /* remove the service from services to be searched  */
3532        *p_services_to_search &= (tBTA_SERVICE_MASK)(
3533            ~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
3534      }
3535    }
3536
3537    service_index++;
3538  }
3539
3540  APPL_TRACE_ERROR(
3541      "BTA EIR search result, services_to_search=0x%08X, services_found=0x%08X",
3542      *p_services_to_search, *p_services_found);
3543}
3544
3545#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3546/*******************************************************************************
3547 *
3548 * Function         bta_dm_eir_update_uuid
3549 *
3550 * Description      This function adds or removes service UUID in EIR database.
3551 *
3552 * Returns          None
3553 *
3554 ******************************************************************************/
3555void bta_dm_eir_update_uuid(uint16_t uuid16, bool adding) {
3556  /* if this UUID is not advertised in EIR */
3557  if (!BTM_HasEirService(p_bta_dm_eir_cfg->uuid_mask, uuid16)) return;
3558
3559  if (adding) {
3560    APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid16);
3561
3562    BTM_AddEirService(bta_dm_cb.eir_uuid, uuid16);
3563  } else {
3564    APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid16);
3565
3566    BTM_RemoveEirService(bta_dm_cb.eir_uuid, uuid16);
3567  }
3568
3569  bta_dm_set_eir(NULL);
3570
3571  APPL_TRACE_EVENT("bta_dm_eir_update_uuid UUID bit mask=0x%08X %08X",
3572                   bta_dm_cb.eir_uuid[1], bta_dm_cb.eir_uuid[0]);
3573}
3574#endif
3575
3576/*******************************************************************************
3577 *
3578 * Function         bta_dm_encrypt_cback
3579 *
3580 * Description      link encryption complete callback.
3581 *
3582 * Returns         None
3583 *
3584 ******************************************************************************/
3585void bta_dm_encrypt_cback(const RawAddress* bd_addr, tBT_TRANSPORT transport,
3586                          UNUSED_ATTR void* p_ref_data, tBTM_STATUS result) {
3587  tBTA_STATUS bta_status = BTA_SUCCESS;
3588  tBTA_DM_ENCRYPT_CBACK* p_callback = NULL;
3589  uint8_t i;
3590
3591  for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3592    if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == *bd_addr &&
3593        bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
3594      break;
3595  }
3596
3597  if (i < bta_dm_cb.device_list.count) {
3598    p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback;
3599    bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL;
3600  }
3601
3602  switch (result) {
3603    case BTM_SUCCESS:
3604      break;
3605    case BTM_WRONG_MODE:
3606      bta_status = BTA_WRONG_MODE;
3607      break;
3608    case BTM_NO_RESOURCES:
3609      bta_status = BTA_NO_RESOURCES;
3610      break;
3611    case BTM_BUSY:
3612      bta_status = BTA_BUSY;
3613      break;
3614    default:
3615      bta_status = BTA_FAILURE;
3616      break;
3617  }
3618
3619  APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=0x%x",
3620                   bta_status, p_callback);
3621
3622  if (p_callback) {
3623    (*p_callback)(*bd_addr, transport, bta_status);
3624  }
3625}
3626
3627/**This function to encrypt the link */
3628void bta_dm_set_encryption(const RawAddress& bd_addr, tBTA_TRANSPORT transport,
3629                           tBTA_DM_ENCRYPT_CBACK* p_callback,
3630                           tBTA_DM_BLE_SEC_ACT sec_act) {
3631  uint8_t i;
3632
3633  APPL_TRACE_DEBUG("bta_dm_set_encryption");  // todo
3634  if (!p_callback) {
3635    APPL_TRACE_ERROR("bta_dm_set_encryption callback is not provided");
3636    return;
3637  }
3638  for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3639    if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == bd_addr &&
3640        bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
3641      break;
3642  }
3643  if (i < bta_dm_cb.device_list.count) {
3644    if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback) {
3645      APPL_TRACE_ERROR("earlier enc was not done for same device");
3646      (*p_callback)(bd_addr, transport, BTA_BUSY);
3647      return;
3648    }
3649
3650    if (BTM_SetEncryption(bd_addr, transport, bta_dm_encrypt_cback, NULL,
3651                          sec_act) == BTM_CMD_STARTED) {
3652      bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_callback;
3653    }
3654  }
3655}
3656
3657bool bta_dm_check_if_only_hd_connected(const RawAddress& peer_addr) {
3658  APPL_TRACE_DEBUG("%s: count(%d)", __func__, bta_dm_conn_srvcs.count);
3659
3660  for (uint8_t j = 0; j < bta_dm_conn_srvcs.count; j++) {
3661    // Check if profiles other than hid are connected
3662    if ((bta_dm_conn_srvcs.conn_srvc[j].id != BTA_ID_HD) &&
3663        bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr == peer_addr) {
3664      APPL_TRACE_DEBUG("%s: Another profile (id=%d) is connected", __func__,
3665                       bta_dm_conn_srvcs.conn_srvc[j].id);
3666      return false;
3667    }
3668  }
3669
3670  return true;
3671}
3672
3673/*******************************************************************************
3674 *
3675 * Function         bta_dm_observe_results_cb
3676 *
3677 * Description      Callback for BLE Observe result
3678 *
3679 *
3680 * Returns          void
3681 *
3682 ******************************************************************************/
3683static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq, uint8_t* p_eir,
3684                                      uint16_t eir_len) {
3685  tBTA_DM_SEARCH result;
3686  tBTM_INQ_INFO* p_inq_info;
3687  APPL_TRACE_DEBUG("bta_dm_observe_results_cb");
3688
3689  result.inq_res.bd_addr = p_inq->remote_bd_addr;
3690  result.inq_res.rssi = p_inq->rssi;
3691  result.inq_res.ble_addr_type = p_inq->ble_addr_type;
3692  result.inq_res.inq_result_type = p_inq->inq_result_type;
3693  result.inq_res.device_type = p_inq->device_type;
3694  result.inq_res.flag = p_inq->flag;
3695  result.inq_res.ble_evt_type = p_inq->ble_evt_type;
3696  result.inq_res.ble_primary_phy = p_inq->ble_primary_phy;
3697  result.inq_res.ble_secondary_phy = p_inq->ble_secondary_phy;
3698  result.inq_res.ble_advertising_sid = p_inq->ble_advertising_sid;
3699  result.inq_res.ble_tx_power = p_inq->ble_tx_power;
3700  result.inq_res.ble_periodic_adv_int = p_inq->ble_periodic_adv_int;
3701
3702  /* application will parse EIR to find out remote device name */
3703  result.inq_res.p_eir = p_eir;
3704  result.inq_res.eir_len = eir_len;
3705
3706  p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr);
3707  if (p_inq_info != NULL) {
3708    /* initialize remt_name_not_required to false so that we get the name by
3709     * default */
3710    result.inq_res.remt_name_not_required = false;
3711  }
3712
3713  if (bta_dm_search_cb.p_scan_cback)
3714    bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result);
3715
3716  if (p_inq_info) {
3717    /* application indicates if it knows the remote name, inside the callback
3718     copy that to the inquiry data base*/
3719    if (result.inq_res.remt_name_not_required)
3720      p_inq_info->appl_knows_rem_name = true;
3721  }
3722}
3723
3724/*******************************************************************************
3725 *
3726 * Function         bta_dm_observe_cmpl_cb
3727 *
3728 * Description      Callback for BLE Observe complete
3729 *
3730 *
3731 * Returns          void
3732 *
3733 ******************************************************************************/
3734static void bta_dm_observe_cmpl_cb(void* p_result) {
3735  tBTA_DM_SEARCH data;
3736
3737  APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb");
3738
3739  data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL*)p_result)->num_resp;
3740  if (bta_dm_search_cb.p_scan_cback) {
3741    bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
3742  }
3743}
3744
3745/*******************************************************************************
3746 *
3747 * Function         bta_dm_ble_smp_cback
3748 *
3749 * Description      Callback for BLE SMP
3750 *
3751 *
3752 * Returns          void
3753 *
3754 ******************************************************************************/
3755static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda,
3756                                    tBTM_LE_EVT_DATA* p_data) {
3757  tBTM_STATUS status = BTM_SUCCESS;
3758  tBTA_DM_SEC sec_event;
3759  char* p_name = NULL;
3760
3761  if (!bta_dm_cb.p_sec_cback) return BTM_NOT_AUTHORIZED;
3762
3763  memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
3764  switch (event) {
3765    case BTM_LE_IO_REQ_EVT:
3766#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
3767
3768      bta_dm_co_ble_io_req(
3769          bda, &p_data->io_req.io_cap, &p_data->io_req.oob_data,
3770          &p_data->io_req.auth_req, &p_data->io_req.max_key_size,
3771          &p_data->io_req.init_keys, &p_data->io_req.resp_keys);
3772#endif
3773      APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req,
3774                       p_data->io_req.oob_data);
3775
3776      break;
3777
3778    case BTM_LE_SEC_REQUEST_EVT:
3779      sec_event.ble_req.bd_addr = bda;
3780      p_name = BTM_SecReadDevName(bda);
3781      if (p_name != NULL)
3782        strlcpy((char*)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN);
3783      else
3784        sec_event.ble_req.bd_name[0] = 0;
3785      bta_dm_cb.p_sec_cback(BTA_DM_BLE_SEC_REQ_EVT, &sec_event);
3786      break;
3787
3788    case BTM_LE_KEY_NOTIF_EVT:
3789      sec_event.key_notif.bd_addr = bda;
3790      p_name = BTM_SecReadDevName(bda);
3791      if (p_name != NULL)
3792        strlcpy((char*)sec_event.key_notif.bd_name, p_name, BD_NAME_LEN);
3793      else
3794        sec_event.key_notif.bd_name[0] = 0;
3795      sec_event.key_notif.passkey = p_data->key_notif;
3796      bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_NOTIF_EVT, &sec_event);
3797      break;
3798
3799    case BTM_LE_KEY_REQ_EVT:
3800      sec_event.ble_req.bd_addr = bda;
3801      bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_REQ_EVT, &sec_event);
3802      break;
3803
3804    case BTM_LE_OOB_REQ_EVT:
3805      sec_event.ble_req.bd_addr = bda;
3806      bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event);
3807      break;
3808
3809    case BTM_LE_NC_REQ_EVT:
3810      sec_event.key_notif.bd_addr = bda;
3811      strlcpy((char*)sec_event.key_notif.bd_name, bta_dm_get_remname(),
3812              (BD_NAME_LEN));
3813      sec_event.key_notif.passkey = p_data->key_notif;
3814      bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
3815      break;
3816
3817    case BTM_LE_SC_OOB_REQ_EVT:
3818      sec_event.ble_req.bd_addr = bda;
3819      bta_dm_cb.p_sec_cback(BTA_DM_BLE_SC_OOB_REQ_EVT, &sec_event);
3820      break;
3821
3822    case BTM_LE_KEY_EVT:
3823      sec_event.ble_key.bd_addr = bda;
3824      sec_event.ble_key.key_type = p_data->key.key_type;
3825      sec_event.ble_key.p_key_value = p_data->key.p_key_value;
3826      bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event);
3827      break;
3828
3829    case BTM_LE_COMPLT_EVT:
3830      sec_event.auth_cmpl.bd_addr = bda;
3831      BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type,
3832                      &sec_event.auth_cmpl.addr_type);
3833      p_name = BTM_SecReadDevName(bda);
3834      if (p_name != NULL)
3835        strlcpy((char*)sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN));
3836      else
3837        sec_event.auth_cmpl.bd_name[0] = 0;
3838
3839      if (p_data->complt.reason != 0) {
3840        sec_event.auth_cmpl.fail_reason =
3841            BTA_DM_AUTH_CONVERT_SMP_CODE(((uint8_t)p_data->complt.reason));
3842        /* delete this device entry from Sec Dev DB */
3843        bta_dm_remove_sec_dev_entry(bda);
3844      } else {
3845        sec_event.auth_cmpl.success = true;
3846      }
3847
3848      if (bta_dm_cb.p_sec_cback) {
3849        // bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
3850        bta_dm_cb.p_sec_cback(BTA_DM_BLE_AUTH_CMPL_EVT, &sec_event);
3851      }
3852      break;
3853
3854    default:
3855      status = BTM_NOT_AUTHORIZED;
3856      break;
3857  }
3858  return status;
3859}
3860
3861/*******************************************************************************
3862 *
3863 * Function         bta_dm_ble_id_key_cback
3864 *
3865 * Description      Callback for BLE local ID keys
3866 *
3867 *
3868 * Returns          void
3869 *
3870 ******************************************************************************/
3871static void bta_dm_ble_id_key_cback(uint8_t key_type,
3872                                    tBTM_BLE_LOCAL_KEYS* p_key) {
3873  uint8_t evt;
3874  tBTA_DM_SEC dm_key;
3875
3876  switch (key_type) {
3877    case BTM_BLE_KEY_TYPE_ID:
3878    case BTM_BLE_KEY_TYPE_ER:
3879      if (bta_dm_cb.p_sec_cback) {
3880        memcpy(&dm_key.ble_id_keys, p_key, sizeof(tBTM_BLE_LOCAL_KEYS));
3881
3882        evt = (key_type == BTM_BLE_KEY_TYPE_ID) ? BTA_DM_BLE_LOCAL_IR_EVT
3883                                                : BTA_DM_BLE_LOCAL_ER_EVT;
3884        bta_dm_cb.p_sec_cback(evt, &dm_key);
3885      }
3886      break;
3887
3888    default:
3889      APPL_TRACE_DEBUG("Unknown key type %d", key_type);
3890      break;
3891  }
3892  return;
3893}
3894
3895/*******************************************************************************
3896 *
3897 * Function         bta_dm_add_blekey
3898 *
3899 * Description      This function adds an BLE Key to an security database entry.
3900 *                  This function shall only be called AFTER BTA_DmAddBleDevice
3901 *                  has been called.
3902 *                  It is normally called during host startup to restore all
3903 *                  required information stored in the NVRAM.
3904 *
3905 * Parameters:
3906 *
3907 ******************************************************************************/
3908void bta_dm_add_blekey(const RawAddress& bd_addr, tBTA_LE_KEY_VALUE blekey,
3909                       tBTA_LE_KEY_TYPE key_type) {
3910  if (!BTM_SecAddBleKey(bd_addr, (tBTM_LE_KEY_VALUE*)&blekey, key_type)) {
3911    LOG(ERROR) << "BTA_DM: Error adding BLE Key for device " << bd_addr;
3912  }
3913}
3914
3915/*******************************************************************************
3916 *
3917 * Function         bta_dm_add_ble_device
3918 *
3919 * Description      This function adds an BLE device to an security database
3920 *                  entry.
3921 *                  It is normally called during host startup to restore all
3922 *                  required information stored in the NVRAM.
3923 *
3924 * Parameters:
3925 *
3926 ******************************************************************************/
3927void bta_dm_add_ble_device(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type,
3928                           tBT_DEVICE_TYPE dev_type) {
3929  if (!BTM_SecAddBleDevice(bd_addr, NULL, dev_type, addr_type)) {
3930    LOG(ERROR) << "BTA_DM: Error adding BLE Device for device " << bd_addr;
3931  }
3932}
3933
3934/*******************************************************************************
3935 *
3936 * Function         bta_dm_add_ble_device
3937 *
3938 * Description      This function adds an BLE device to an security database
3939 *                  entry.
3940 *                  It is normally called during host startup to restore all
3941 *                  required information stored in the NVRAM.
3942 *
3943 * Parameters:
3944 *
3945 ******************************************************************************/
3946void bta_dm_ble_passkey_reply(const RawAddress& bd_addr, bool accept,
3947                              uint32_t passkey) {
3948  BTM_BlePasskeyReply(bd_addr, accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED,
3949                      passkey);
3950}
3951
3952/** This is response to SM numeric comparison request submitted to application.
3953 */
3954void bta_dm_ble_confirm_reply(const RawAddress& bd_addr, bool accept) {
3955  BTM_BleConfirmReply(bd_addr, accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED);
3956}
3957
3958/** This function set the preferred connection parameters */
3959void bta_dm_ble_set_conn_params(const RawAddress& bd_addr,
3960                                uint16_t conn_int_min, uint16_t conn_int_max,
3961                                uint16_t slave_latency,
3962                                uint16_t supervision_tout) {
3963  L2CA_AdjustConnectionIntervals(&conn_int_min, &conn_int_max,
3964                                 BTM_BLE_CONN_INT_MIN);
3965
3966  BTM_BleSetPrefConnParams(bd_addr, conn_int_min, conn_int_max, slave_latency,
3967                           supervision_tout);
3968}
3969
3970/** This function set the preferred connection scan parameters */
3971void bta_dm_ble_set_conn_scan_params(uint32_t scan_interval,
3972                                     uint32_t scan_window) {
3973  BTM_BleSetConnScanParams(scan_interval, scan_window);
3974}
3975
3976/** This function update LE connection parameters */
3977void bta_dm_ble_update_conn_params(const RawAddress& bd_addr, uint16_t min_int,
3978                                   uint16_t max_int, uint16_t latency,
3979                                   uint16_t timeout, uint16_t min_ce_len,
3980                                   uint16_t max_ce_len) {
3981  L2CA_AdjustConnectionIntervals(&min_int, &max_int, BTM_BLE_CONN_INT_MIN);
3982
3983  if (!L2CA_UpdateBleConnParams(bd_addr, min_int, max_int, latency, timeout,
3984                                min_ce_len, max_ce_len)) {
3985    APPL_TRACE_ERROR("Update connection parameters failed!");
3986  }
3987}
3988
3989#if (BLE_PRIVACY_SPT == TRUE)
3990/** This function set the local device LE privacy settings. */
3991void bta_dm_ble_config_local_privacy(bool privacy_enable) {
3992  BTM_BleConfigPrivacy(privacy_enable);
3993}
3994#endif
3995
3996void bta_dm_ble_observe(bool start, uint8_t duration,
3997                        tBTA_DM_SEARCH_CBACK* p_cback) {
3998  if (!start) {
3999    bta_dm_search_cb.p_scan_cback = NULL;
4000    BTM_BleObserve(false, 0, NULL, NULL);
4001    return;
4002  }
4003
4004  /*Save the  callback to be called when a scan results are available */
4005  bta_dm_search_cb.p_scan_cback = p_cback;
4006  tBTM_STATUS status = BTM_BleObserve(true, duration, bta_dm_observe_results_cb,
4007                                      bta_dm_observe_cmpl_cb);
4008  if (status != BTM_CMD_STARTED) {
4009    tBTA_DM_SEARCH data;
4010    APPL_TRACE_WARNING(" %s BTM_BleObserve  failed. status %d", __func__,
4011                       status);
4012    data.inq_cmpl.num_resps = 0;
4013    if (bta_dm_search_cb.p_scan_cback) {
4014      bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
4015    }
4016  }
4017}
4018/*******************************************************************************
4019 *
4020 * Function         bta_dm_ble_set_adv_params
4021 *
4022 * Description      This function set the adv parameters.
4023 *
4024 * Parameters:
4025 *
4026 ******************************************************************************/
4027void bta_dm_ble_set_adv_params(uint16_t adv_int_min, uint16_t adv_int_max,
4028                               tBLE_BD_ADDR* p_dir_bda) {
4029  BTM_BleSetAdvParams(adv_int_min, adv_int_max, p_dir_bda,
4030                      BTA_DM_BLE_ADV_CHNL_MAP);
4031}
4032
4033/** This function set the maximum transmission packet size */
4034void bta_dm_ble_set_data_length(const RawAddress& bd_addr,
4035                                uint16_t tx_data_length) {
4036  if (BTM_SetBleDataLength(bd_addr, tx_data_length) != BTM_SUCCESS) {
4037    APPL_TRACE_ERROR("%s failed", __func__);
4038  }
4039}
4040
4041/*******************************************************************************
4042 *
4043 * Function         bta_ble_enable_scan_cmpl
4044 *
4045 * Description      ADV payload filtering enable / disable complete callback
4046 *
4047 *
4048 * Returns          None
4049 *
4050 ******************************************************************************/
4051static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time,
4052                                     tBTM_BLE_RX_TIME_MS rx_time,
4053                                     tBTM_BLE_IDLE_TIME_MS idle_time,
4054                                     tBTM_BLE_ENERGY_USED energy_used,
4055                                     tBTM_STATUS status) {
4056  tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
4057  tBTA_DM_CONTRL_STATE ctrl_state = 0;
4058
4059  if (BTA_SUCCESS == st) ctrl_state = bta_dm_pm_obtain_controller_state();
4060
4061  if (bta_dm_cb.p_energy_info_cback)
4062    bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used,
4063                                  ctrl_state, st);
4064}
4065
4066/** This function obtains the energy info */
4067void bta_dm_ble_get_energy_info(
4068    tBTA_BLE_ENERGY_INFO_CBACK* p_energy_info_cback) {
4069  bta_dm_cb.p_energy_info_cback = p_energy_info_cback;
4070  tBTM_STATUS btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl);
4071  if (BTM_CMD_STARTED != btm_status)
4072    bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status);
4073}
4074
4075#ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
4076#define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000
4077#endif
4078
4079/*******************************************************************************
4080 *
4081 * Function         bta_dm_gattc_register
4082 *
4083 * Description      Register with GATTC in DM if BLE is needed.
4084 *
4085 *
4086 * Returns          void
4087 *
4088 ******************************************************************************/
4089static void bta_dm_gattc_register(void) {
4090  if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF) {
4091    BTA_GATTC_AppRegister(bta_dm_gattc_callback,
4092                          base::Bind([](uint8_t client_id, uint8_t status) {
4093                            if (status == GATT_SUCCESS)
4094                              bta_dm_search_cb.client_if = client_id;
4095                            else
4096                              bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF;
4097
4098                          }));
4099  }
4100}
4101
4102/*******************************************************************************
4103 *
4104 * Function         btm_dm_start_disc_gatt_services
4105 *
4106 * Description      This function starts a GATT service search request.
4107 *
4108 * Parameters:
4109 *
4110 ******************************************************************************/
4111static void btm_dm_start_disc_gatt_services(uint16_t conn_id) {
4112  Uuid* p_uuid = bta_dm_search_cb.p_srvc_uuid + bta_dm_search_cb.num_uuid -
4113                 bta_dm_search_cb.uuid_to_search;
4114
4115  /* always search for all services */
4116  BTA_GATTC_ServiceSearchRequest(conn_id, p_uuid);
4117}
4118
4119/*******************************************************************************
4120 *
4121 * Function         bta_dm_gatt_disc_result
4122 *
4123 * Description      This function process the GATT service search result.
4124 *
4125 * Parameters:
4126 *
4127 ******************************************************************************/
4128static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id) {
4129  tBTA_DM_SEARCH result;
4130
4131  /*
4132   * This logic will not work for gatt case.  We are checking against the
4133   * bluetooth profiles here
4134   * just copy the GATTID in raw data field and send it across.
4135   */
4136
4137  if (bta_dm_search_cb.ble_raw_used + sizeof(tBTA_GATT_ID) <
4138      bta_dm_search_cb.ble_raw_size) {
4139    APPL_TRACE_DEBUG(
4140        "ADDING BLE SERVICE uuid=%s, ble_ptr = 0x%x, ble_raw_used = 0x%x",
4141        service_id.uuid.ToString().c_str(), bta_dm_search_cb.p_ble_rawdata,
4142        bta_dm_search_cb.ble_raw_used);
4143
4144    if (bta_dm_search_cb.p_ble_rawdata) {
4145      // TODO(jpawlowski): the p_ble_raw data is only sent to btif_dm.cc, but is
4146      // never used there. Get rid of this code completly, or implement the
4147      // TODOs from btif_dm.cc
4148      memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used),
4149             &service_id, sizeof(service_id));
4150
4151      bta_dm_search_cb.ble_raw_used += sizeof(service_id);
4152    } else {
4153      APPL_TRACE_ERROR("p_ble_rawdata is NULL");
4154    }
4155
4156  } else {
4157    APPL_TRACE_ERROR(
4158        "%s out of room to accomodate more service ids ble_raw_size = %d "
4159        "ble_raw_used = %d",
4160        __func__, bta_dm_search_cb.ble_raw_size, bta_dm_search_cb.ble_raw_used);
4161  }
4162
4163  LOG_INFO(LOG_TAG, "%s service_id_uuid_len=%zu", __func__,
4164           service_id.uuid.GetShortestRepresentationSize());
4165  if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
4166    /* send result back to app now, one by one */
4167    result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
4168    strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(),
4169            BD_NAME_LEN);
4170    result.disc_ble_res.service = service_id.uuid;
4171
4172    bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
4173  }
4174}
4175
4176/*******************************************************************************
4177 *
4178 * Function         bta_dm_gatt_disc_complete
4179 *
4180 * Description      This function process the GATT service search complete.
4181 *
4182 * Parameters:
4183 *
4184 ******************************************************************************/
4185static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) {
4186  APPL_TRACE_DEBUG("%s conn_id = %d", __func__, conn_id);
4187
4188  if (bta_dm_search_cb.uuid_to_search > 0) bta_dm_search_cb.uuid_to_search--;
4189
4190  if (status == GATT_SUCCESS && bta_dm_search_cb.uuid_to_search > 0) {
4191    btm_dm_start_disc_gatt_services(conn_id);
4192  } else {
4193    tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG));
4194
4195    bta_dm_search_cb.uuid_to_search = 0;
4196
4197    /* no more services to be discovered */
4198    p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
4199    p_msg->disc_result.result.disc_res.result =
4200        (status == GATT_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
4201    APPL_TRACE_DEBUG("%s service found: 0x%08x", __func__,
4202                     bta_dm_search_cb.services_found);
4203    p_msg->disc_result.result.disc_res.services =
4204        bta_dm_search_cb.services_found;
4205    p_msg->disc_result.result.disc_res.num_uuids = 0;
4206    p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
4207    p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr;
4208    strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
4209            bta_dm_get_remname(), BD_NAME_LEN);
4210
4211    p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE;
4212    if (bta_dm_search_cb.ble_raw_used > 0) {
4213      p_msg->disc_result.result.disc_res.p_raw_data =
4214          (uint8_t*)osi_malloc(bta_dm_search_cb.ble_raw_used);
4215
4216      memcpy(p_msg->disc_result.result.disc_res.p_raw_data,
4217             bta_dm_search_cb.p_ble_rawdata, bta_dm_search_cb.ble_raw_used);
4218
4219      p_msg->disc_result.result.disc_res.raw_data_size =
4220          bta_dm_search_cb.ble_raw_used;
4221    } else {
4222      p_msg->disc_result.result.disc_res.p_raw_data = NULL;
4223      bta_dm_search_cb.p_ble_rawdata = 0;
4224    }
4225
4226    bta_sys_sendmsg(p_msg);
4227
4228    if (conn_id != GATT_INVALID_CONN_ID) {
4229      /* start a GATT channel close delay timer */
4230      bta_sys_start_timer(bta_dm_search_cb.gatt_close_timer,
4231                          BTA_DM_GATT_CLOSE_DELAY_TOUT,
4232                          BTA_DM_DISC_CLOSE_TOUT_EVT, 0);
4233      bta_dm_search_cb.pending_close_bda = bta_dm_search_cb.peer_bdaddr;
4234    }
4235    bta_dm_search_cb.gatt_disc_active = false;
4236  }
4237}
4238
4239/*******************************************************************************
4240 *
4241 * Function         bta_dm_close_gatt_conn
4242 *
4243 * Description      This function close the GATT connection after delay
4244 *timeout.
4245 *
4246 * Parameters:
4247 *
4248 ******************************************************************************/
4249void bta_dm_close_gatt_conn(UNUSED_ATTR tBTA_DM_MSG* p_data) {
4250  if (bta_dm_search_cb.conn_id != GATT_INVALID_CONN_ID)
4251    BTA_GATTC_Close(bta_dm_search_cb.conn_id);
4252
4253  bta_dm_search_cb.pending_close_bda = RawAddress::kEmpty;
4254  bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID;
4255}
4256/*******************************************************************************
4257 *
4258 * Function         btm_dm_start_gatt_discovery
4259 *
4260 * Description      This is GATT initiate the service search by open a GATT
4261 *                  connection first.
4262 *
4263 * Parameters:
4264 *
4265 ******************************************************************************/
4266void btm_dm_start_gatt_discovery(const RawAddress& bd_addr) {
4267  bta_dm_search_cb.gatt_disc_active = true;
4268
4269  /* connection is already open */
4270  if (bta_dm_search_cb.pending_close_bda == bd_addr &&
4271      bta_dm_search_cb.conn_id != GATT_INVALID_CONN_ID) {
4272    bta_dm_search_cb.pending_close_bda = RawAddress::kEmpty;
4273    alarm_cancel(bta_dm_search_cb.gatt_close_timer);
4274    btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
4275  } else {
4276    if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) {
4277      BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, true,
4278                     GATT_TRANSPORT_LE, true);
4279    } else {
4280      BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, true,
4281                     GATT_TRANSPORT_LE, false);
4282    }
4283  }
4284}
4285
4286/*******************************************************************************
4287 *
4288 * Function         bta_dm_cancel_gatt_discovery
4289 *
4290 * Description      This is GATT cancel the GATT service search.
4291 *
4292 * Parameters:
4293 *
4294 ******************************************************************************/
4295static void bta_dm_cancel_gatt_discovery(const RawAddress& bd_addr) {
4296  if (bta_dm_search_cb.conn_id == GATT_INVALID_CONN_ID) {
4297    BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, true);
4298  }
4299
4300  bta_dm_gatt_disc_complete(bta_dm_search_cb.conn_id, (tGATT_STATUS)GATT_ERROR);
4301}
4302
4303/*******************************************************************************
4304 *
4305 * Function         bta_dm_proc_open_evt
4306 *
4307 * Description      process BTA_GATTC_OPEN_EVT in DM.
4308 *
4309 * Parameters:
4310 *
4311 ******************************************************************************/
4312void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) {
4313  VLOG(1) << "DM Search state= " << bta_dm_search_cb.state
4314          << " search_cb.peer_dbaddr:" << bta_dm_search_cb.peer_bdaddr
4315          << " connected_bda=" << p_data->remote_bda.address;
4316
4317  APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d",
4318                   p_data->conn_id, p_data->client_if, p_data->status);
4319
4320  bta_dm_search_cb.conn_id = p_data->conn_id;
4321
4322  if (p_data->status == GATT_SUCCESS) {
4323    btm_dm_start_disc_gatt_services(p_data->conn_id);
4324  } else {
4325    bta_dm_gatt_disc_complete(GATT_INVALID_CONN_ID, p_data->status);
4326  }
4327}
4328
4329/*******************************************************************************
4330 *
4331 * Function         bta_dm_gattc_callback
4332 *
4333 * Description      This is GATT client callback function used in DM.
4334 *
4335 * Parameters:
4336 *
4337 ******************************************************************************/
4338static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
4339  APPL_TRACE_DEBUG("bta_dm_gattc_callback event = %d", event);
4340
4341  switch (event) {
4342    case BTA_GATTC_OPEN_EVT:
4343      bta_dm_proc_open_evt(&p_data->open);
4344      break;
4345
4346    case BTA_GATTC_SEARCH_RES_EVT:
4347      bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid);
4348      break;
4349
4350    case BTA_GATTC_SEARCH_CMPL_EVT:
4351      if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE)
4352        bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id,
4353                                  p_data->search_cmpl.status);
4354      break;
4355
4356    case BTA_GATTC_CLOSE_EVT:
4357      APPL_TRACE_DEBUG("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason);
4358      /* in case of disconnect before search is completed */
4359      if ((bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) &&
4360          (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) &&
4361          p_data->close.remote_bda == bta_dm_search_cb.peer_bdaddr) {
4362        bta_dm_gatt_disc_complete((uint16_t)GATT_INVALID_CONN_ID,
4363                                  (tGATT_STATUS)GATT_ERROR);
4364      }
4365      break;
4366
4367    default:
4368      break;
4369  }
4370}
4371
4372#if (BLE_VND_INCLUDED == TRUE)
4373/*******************************************************************************
4374 *
4375 * Function         bta_dm_ctrl_features_rd_cmpl_cback
4376 *
4377 * Description      callback to handle controller feature read complete
4378 *
4379 * Parameters:
4380 *
4381 ******************************************************************************/
4382static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result) {
4383  APPL_TRACE_DEBUG("%s  status = %d ", __func__, result);
4384  if (result == BTM_SUCCESS) {
4385    if (bta_dm_cb.p_sec_cback)
4386      bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
4387  } else {
4388    APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d", __func__,
4389                     result);
4390  }
4391}
4392#endif /* BLE_VND_INCLUDED */
4393