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