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