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