OSDN Git Service

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