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