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