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