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