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