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