OSDN Git Service

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