OSDN Git Service

Do not send AT+CHLD=? if the 3-way call feature is not supported am: 79dc36d01a
[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     UINT16 index = 0;
3499     if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
3500          BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR))
3501     {
3502          APPL_TRACE_DEBUG("%s ACL is not down. Schedule for  Dev Removal when ACL closes",
3503                             __FUNCTION__);
3504         for (index = 0; index < bta_dm_cb.device_list.count; index ++)
3505         {
3506             if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, remote_bd_addr))
3507                 break;
3508         }
3509         if (index != bta_dm_cb.device_list.count)
3510         {
3511             bta_dm_cb.device_list.peer_device[index].remove_dev_pending = TRUE;
3512         }
3513         else
3514         {
3515             APPL_TRACE_ERROR(" %s Device does not exist in DB", __FUNCTION__);
3516         }
3517     }
3518     else
3519     {
3520         BTM_SecDeleteDevice (remote_bd_addr);
3521 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
3522         /* need to remove all pending background connection */
3523         BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
3524         /* remove all cached GATT information */
3525         BTA_GATTC_Refresh(remote_bd_addr);
3526 #endif
3527     }
3528 }
3529
3530
3531 /*******************************************************************************
3532 **
3533 ** Function         bta_dm_adjust_roles
3534 **
3535 ** Description      Adjust roles
3536 **
3537 **
3538 ** Returns          void
3539 **
3540 *******************************************************************************/
3541 static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
3542 {
3543
3544     UINT8 i;
3545     BOOLEAN set_master_role = FALSE;
3546 #if BLE_INCLUDED == TRUE
3547     UINT8 br_count = bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count;
3548 #else
3549     UINT8 br_count = bta_dm_cb.device_list.count;
3550 #endif
3551     if (br_count)
3552     {
3553
3554         /* the configuration is no scatternet
3555          * or AV connection exists and there are more than one ACL link */
3556         if ( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
3557              (bta_dm_cb.cur_av_count && br_count > 1) )
3558         {
3559
3560             L2CA_SetDesireRole (HCI_ROLE_MASTER);
3561             set_master_role = TRUE;
3562
3563         }
3564
3565         for(i=0; i<bta_dm_cb.device_list.count; i++)
3566         {
3567             if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED
3568 #if BLE_INCLUDED == TRUE
3569                 && bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_BR_EDR
3570 #endif
3571                 )
3572             {
3573                 if(!set_master_role && (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE)
3574                     && (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET))
3575                 {
3576                     L2CA_SetDesireRole (HCI_ROLE_MASTER);
3577                     set_master_role = TRUE;
3578                 }
3579
3580                 if((bta_dm_cb.device_list.peer_device[i].pref_role == BTA_MASTER_ROLE_ONLY)
3581                     || (br_count > 1))
3582                 {
3583
3584                 /* Initiating immediate role switch with certain remote devices
3585                   has caused issues due to role  switch colliding with link encryption setup and
3586                   causing encryption (and in turn the link) to fail .  These device . Firmware
3587                   versions are stored in a blacklist and role switch with these devices are
3588                   delayed to avoid the collision with link encryption setup */
3589
3590                     if (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_SLAVE_ROLE_ONLY &&
3591                             delay_role_switch == FALSE)
3592                     {
3593                         BTM_SwitchRole (bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
3594                                         HCI_ROLE_MASTER, NULL);
3595                     }
3596                     else
3597                     {
3598                         alarm_set_on_queue(bta_dm_cb.switch_delay_timer,
3599                                            BTA_DM_SWITCH_DELAY_TIMER_MS,
3600                                            bta_dm_delay_role_switch_cback,
3601                                            NULL, btu_bta_alarm_queue);
3602                     }
3603                 }
3604             }
3605         }
3606
3607
3608         if(!set_master_role)
3609         {
3610
3611             L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
3612
3613         }
3614
3615     }
3616     else
3617     {
3618         L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
3619     }
3620
3621
3622 }
3623
3624 /*******************************************************************************
3625 **
3626 ** Function         bta_dm_get_remname
3627 **
3628 ** Description      Returns a pointer to the remote name stored in the DM control
3629 **                  block if it exists, or from the BTM memory.
3630 **
3631 ** Returns          char * - Pointer to the remote device name
3632 *******************************************************************************/
3633 static char *bta_dm_get_remname(void)
3634 {
3635     char *p_name = (char *)bta_dm_search_cb.peer_name;
3636     char *p_temp;
3637
3638     /* If the name isn't already stored, try retrieving from BTM */
3639     if (*p_name == '\0')
3640         if ((p_temp = BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr)) != NULL)
3641             p_name = p_temp;
3642
3643     return p_name;
3644 }
3645
3646 /*******************************************************************************
3647 **
3648 ** Function         bta_dm_bond_cancel_complete_cback
3649 **
3650 ** Description      Authentication complete callback from BTM
3651 **
3652 ** Returns          void
3653 **
3654 *******************************************************************************/
3655 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result)
3656 {
3657
3658     tBTA_DM_SEC sec_event;
3659
3660     if (result == BTM_SUCCESS)
3661         sec_event.bond_cancel_cmpl.result = BTA_SUCCESS;
3662     else
3663         sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
3664
3665     if(bta_dm_cb.p_sec_cback)
3666     {
3667         bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
3668     }
3669 }
3670
3671 /*******************************************************************************
3672 **
3673 ** Function         find_utf8_char_boundary
3674 **
3675 ** Description      This function checks a UTF8 string |utf8str| starting at
3676 **                  |offset|, moving backwards and returns the offset of the
3677 **                  next valid UTF8 character boundary found.
3678 **
3679 ** Returns          Offset of UTF8 character boundary
3680 **
3681 *******************************************************************************/
3682 static size_t find_utf8_char_boundary(const char *utf8str, size_t offset)
3683 {
3684     assert(utf8str);
3685     assert(offset > 0);
3686
3687     while (--offset)
3688     {
3689         uint8_t ch = (uint8_t)utf8str[offset];
3690         if ((ch & 0x80) == 0x00) // ASCII
3691             return offset + 1;
3692         if ((ch & 0xC0) == 0xC0) // Multi-byte sequence start
3693             return offset;
3694     }
3695
3696     return 0;
3697 }
3698
3699 /*******************************************************************************
3700 **
3701 ** Function         bta_dm_set_eir
3702 **
3703 ** Description      This function creates EIR tagged data and writes it to controller.
3704 **
3705 ** Returns          None
3706 **
3707 *******************************************************************************/
3708 static void bta_dm_set_eir (char *local_name)
3709 {
3710     UINT8    *p;
3711     UINT8    *p_length;
3712 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3713     UINT8    *p_type;
3714     UINT8    max_num_uuid;
3715 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3716     UINT8    custom_uuid_idx;
3717 #endif  // BTA_EIR_SERVER_NUM_CUSTOM_UUID
3718 #endif  // BTA_EIR_CANNED_UUID_LIST
3719 #if (BTM_EIR_DEFAULT_FEC_REQUIRED == FALSE)
3720     UINT8    free_eir_length = HCI_EXT_INQ_RESPONSE_LEN;
3721 #else  // BTM_EIR_DEFAULT_FEC_REQUIRED
3722     UINT8    free_eir_length = HCI_DM5_PACKET_SIZE;
3723 #endif  // BTM_EIR_DEFAULT_FEC_REQUIRED
3724     UINT8    num_uuid;
3725     UINT8    data_type;
3726     UINT8    local_name_len;
3727
3728     /* wait until complete to disable */
3729     if (alarm_is_scheduled(bta_dm_cb.disable_timer))
3730         return;
3731
3732 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )
3733     /* if local name is not provided, get it from controller */
3734     if( local_name == NULL )
3735     {
3736         if( BTM_ReadLocalDeviceName( &local_name ) != BTM_SUCCESS )
3737         {
3738             APPL_TRACE_ERROR("Fail to read local device name for EIR");
3739         }
3740     }
3741 #endif  // BTA_EIR_CANNED_UUID_LIST
3742
3743     /* Allocate a buffer to hold HCI command */
3744     BT_HDR *p_buf = (BT_HDR *)osi_malloc(BTM_CMD_BUF_SIZE);
3745     p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET;
3746
3747     memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN );
3748
3749     APPL_TRACE_DEBUG("BTA is generating EIR");
3750
3751     if( local_name )
3752         local_name_len = strlen( local_name );
3753     else
3754         local_name_len = 0;
3755
3756     data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3757     /* if local name is longer than minimum length of shortened name */
3758     /* check whether it needs to be shortened or not */
3759     if( local_name_len > p_bta_dm_eir_cfg->bta_dm_eir_min_name_len )
3760     {
3761         /* get number of UUID 16-bit list */
3762 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3763         num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len/LEN_UUID_16;
3764 #else  // BTA_EIR_CANNED_UUID_LIST
3765         max_num_uuid = (free_eir_length - 2)/LEN_UUID_16;
3766         data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p,
3767                                                  max_num_uuid, &num_uuid );
3768         p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET; /* reset p */
3769 #endif  // BTA_EIR_CANNED_UUID_LIST
3770
3771         /* if UUID doesn't fit remaing space, shorten local name */
3772         if (local_name_len > (free_eir_length - 4 - num_uuid*LEN_UUID_16))
3773         {
3774             local_name_len = find_utf8_char_boundary(local_name,
3775                 p_bta_dm_eir_cfg->bta_dm_eir_min_name_len);
3776             APPL_TRACE_WARNING("%s local name is shortened (%d)", __func__, local_name_len);
3777             data_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE;
3778         } else {
3779             data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3780         }
3781     }
3782
3783     UINT8_TO_STREAM(p, local_name_len + 1);
3784     UINT8_TO_STREAM(p, data_type);
3785
3786     if (local_name != NULL)
3787     {
3788         memcpy(p, local_name, local_name_len);
3789         p += local_name_len;
3790     }
3791     free_eir_length -= local_name_len + 2;
3792
3793 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3794     /* if UUID list is provided as static data in configuration */
3795     if(( p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len > 0 )
3796         &&(p_bta_dm_eir_cfg->bta_dm_eir_uuid16))
3797     {
3798         if( free_eir_length > LEN_UUID_16 + 2)
3799         {
3800             free_eir_length -= 2;
3801
3802             if( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len)
3803             {
3804                 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / LEN_UUID_16;
3805                 data_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3806             }
3807             else /* not enough room for all UUIDs */
3808             {
3809                 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3810                 num_uuid = free_eir_length / LEN_UUID_16;
3811                 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3812             }
3813             UINT8_TO_STREAM(p, num_uuid * LEN_UUID_16 + 1);
3814             UINT8_TO_STREAM(p, data_type);
3815             memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_uuid16, num_uuid * LEN_UUID_16 );
3816             p += num_uuid * LEN_UUID_16;
3817             free_eir_length -= num_uuid * LEN_UUID_16;
3818         }
3819     }
3820 #else /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3821     /* if UUID list is dynamic */
3822     if ( free_eir_length >= 2)
3823     {
3824         p_length = p++;
3825         p_type   = p++;
3826         num_uuid = 0;
3827
3828         max_num_uuid = (free_eir_length - 2)/LEN_UUID_16;
3829         data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p, max_num_uuid, &num_uuid );
3830
3831         if( data_type == BTM_EIR_MORE_16BITS_UUID_TYPE )
3832         {
3833             APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3834         }
3835 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3836         else
3837         {
3838             for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++)
3839             {
3840                 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_16)
3841                 {
3842                     if ( num_uuid < max_num_uuid )
3843                     {
3844                         UINT16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid16);
3845                         num_uuid++;
3846                     }
3847                     else
3848                     {
3849                         data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3850                         APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3851                         break;
3852                     }
3853                 }
3854             }
3855         }
3856 #endif /* (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3857
3858         UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_16 + 1);
3859         UINT8_TO_STREAM(p_type, data_type);
3860         free_eir_length -= num_uuid * LEN_UUID_16 + 2;
3861     }
3862 #endif /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3863
3864 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3865     /* Adding 32-bit UUID list */
3866     if ( free_eir_length >= 2)
3867     {
3868         p_length = p++;
3869         p_type   = p++;
3870         num_uuid = 0;
3871         data_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE;
3872
3873         max_num_uuid = (free_eir_length - 2)/LEN_UUID_32;
3874
3875         for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++)
3876         {
3877             if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_32)
3878             {
3879                 if ( num_uuid < max_num_uuid )
3880                 {
3881                     UINT32_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid32);
3882                     num_uuid++;
3883                 }
3884                 else
3885                 {
3886                     data_type = BTM_EIR_MORE_32BITS_UUID_TYPE;
3887                     APPL_TRACE_WARNING("BTA EIR: UUID 32-bit list is truncated");
3888                     break;
3889                 }
3890             }
3891         }
3892
3893         UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_32 + 1);
3894         UINT8_TO_STREAM(p_type, data_type);
3895         free_eir_length -= num_uuid * LEN_UUID_32 + 2;
3896     }
3897
3898     /* Adding 128-bit UUID list */
3899     if ( free_eir_length >= 2)
3900     {
3901         p_length = p++;
3902         p_type   = p++;
3903         num_uuid = 0;
3904         data_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE;
3905
3906         max_num_uuid = (free_eir_length - 2)/LEN_UUID_128;
3907
3908         for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++)
3909         {
3910             if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_128)
3911             {
3912                 if ( num_uuid < max_num_uuid )
3913                 {
3914                     ARRAY16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid128);
3915                     num_uuid++;
3916                 }
3917                 else
3918                 {
3919                     data_type = BTM_EIR_MORE_128BITS_UUID_TYPE;
3920                     APPL_TRACE_WARNING("BTA EIR: UUID 128-bit list is truncated");
3921                     break;
3922                 }
3923             }
3924         }
3925
3926         UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_128 + 1);
3927         UINT8_TO_STREAM(p_type, data_type);
3928         free_eir_length -= num_uuid * LEN_UUID_128 + 2;
3929     }
3930 #endif /* ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3931
3932     /* if Flags are provided in configuration */
3933     if(( p_bta_dm_eir_cfg->bta_dm_eir_flag_len > 0 )
3934      &&( p_bta_dm_eir_cfg->bta_dm_eir_flags )
3935      &&( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2 ))
3936     {
3937         UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 1);
3938         UINT8_TO_STREAM(p, BTM_EIR_FLAGS_TYPE);
3939         memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_flags,
3940                p_bta_dm_eir_cfg->bta_dm_eir_flag_len);
3941         p += p_bta_dm_eir_cfg->bta_dm_eir_flag_len;
3942         free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2;
3943     }
3944
3945     /* if Manufacturer Specific are provided in configuration */
3946     if(( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len > 0 )
3947      &&( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec )
3948      &&( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2 ))
3949     {
3950         p_length = p;
3951
3952         UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 1);
3953         UINT8_TO_STREAM(p, BTM_EIR_MANUFACTURER_SPECIFIC_TYPE);
3954         memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec,
3955                p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len);
3956         p += p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len;
3957         free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2;
3958
3959     }
3960     else
3961     {
3962         p_length = NULL;
3963     }
3964
3965     /* if Inquiry Tx Resp Power compiled */
3966     if ((p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power) &&
3967         (free_eir_length >= 3))
3968     {
3969         UINT8_TO_STREAM(p, 2);      /* Length field */
3970         UINT8_TO_STREAM(p, BTM_EIR_TX_POWER_LEVEL_TYPE);
3971         UINT8_TO_STREAM(p, *(p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power));
3972         free_eir_length -= 3;
3973     }
3974
3975     if( free_eir_length )
3976         UINT8_TO_STREAM(p, 0); /* terminator of significant part */
3977
3978     BTM_WriteEIR( p_buf );
3979
3980 }
3981
3982 /*******************************************************************************
3983 **
3984 ** Function         bta_dm_eir_search_services
3985 **
3986 ** Description      This function searches services in received EIR
3987 **
3988 ** Returns          None
3989 **
3990 *******************************************************************************/
3991 static void bta_dm_eir_search_services( tBTM_INQ_RESULTS  *p_result,
3992                                         tBTA_SERVICE_MASK *p_services_to_search,
3993                                         tBTA_SERVICE_MASK *p_services_found)
3994 {
3995     tBTA_SERVICE_MASK       service_index = 0;
3996     tBTM_EIR_SEARCH_RESULT  result;
3997
3998     APPL_TRACE_DEBUG("BTA searching services in EIR of BDA:0x%02X%02X%02X%02X%02X%02X",
3999                         p_result->remote_bd_addr[0],p_result->remote_bd_addr[1],
4000                         p_result->remote_bd_addr[2],p_result->remote_bd_addr[3],
4001                         p_result->remote_bd_addr[4],p_result->remote_bd_addr[5]);
4002
4003     APPL_TRACE_DEBUG("    with services_to_search=0x%08X", *p_services_to_search);
4004
4005 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
4006     /* always do GATT based service discovery by SDP instead of from EIR    */
4007     /* if GATT based service is also to be put in EIR, need to modify this  */
4008     while (service_index < (BTA_MAX_SERVICE_ID - 1))
4009 #else
4010     while(service_index < BTA_MAX_SERVICE_ID)
4011 #endif
4012     {
4013         if( *p_services_to_search
4014            & (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)))
4015         {
4016             result = BTM_HasInquiryEirService( p_result,
4017                                                bta_service_id_to_uuid_lkup_tbl[service_index] );
4018
4019             /* Searching for HSP v1.2 only device */
4020             if ((result != BTM_EIR_FOUND) &&
4021                 (bta_service_id_to_uuid_lkup_tbl[service_index] == UUID_SERVCLASS_HEADSET))
4022             {
4023                 result = BTM_HasInquiryEirService (p_result, UUID_SERVCLASS_HEADSET_HS);
4024             }
4025
4026             if( result == BTM_EIR_FOUND )
4027             {
4028                 /* If Plug and Play service record, need to check to see if Broadcom stack */
4029                 /* However, EIR data doesn't have EXT_BRCM_VERSION so just skip it */
4030                 if( bta_service_id_to_uuid_lkup_tbl[service_index]
4031                     != UUID_SERVCLASS_PNP_INFORMATION )
4032                 {
4033
4034                     *p_services_found |=
4035                        (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index));
4036                     /* remove the service from services to be searched  */
4037                     *p_services_to_search &=
4038                        (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
4039                 }
4040             }
4041             else if( result == BTM_EIR_NOT_FOUND )
4042             {
4043                 /* remove the service from services to be searched  */
4044                 *p_services_to_search &=
4045                        (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
4046             }
4047         }
4048
4049         service_index++;
4050     }
4051
4052     APPL_TRACE_ERROR("BTA EIR search result, services_to_search=0x%08X, services_found=0x%08X",
4053                         *p_services_to_search, *p_services_found);
4054 }
4055
4056 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
4057 /*******************************************************************************
4058 **
4059 ** Function         bta_dm_eir_update_uuid
4060 **
4061 ** Description      This function adds or removes service UUID in EIR database.
4062 **
4063 ** Returns          None
4064 **
4065 *******************************************************************************/
4066 void bta_dm_eir_update_uuid(UINT16 uuid16, BOOLEAN adding)
4067 {
4068     /* if this UUID is not advertised in EIR */
4069     if( !BTM_HasEirService( p_bta_dm_eir_cfg->uuid_mask, uuid16 ))
4070         return;
4071
4072     if( adding )
4073     {
4074         APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid16);
4075
4076         BTM_AddEirService( bta_dm_cb.eir_uuid, uuid16 );
4077     }
4078     else
4079     {
4080         APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid16);
4081
4082         BTM_RemoveEirService( bta_dm_cb.eir_uuid, uuid16 );
4083     }
4084
4085     bta_dm_set_eir (NULL);
4086
4087     APPL_TRACE_EVENT("bta_dm_eir_update_uuid UUID bit mask=0x%08X %08X",
4088                        bta_dm_cb.eir_uuid[1], bta_dm_cb.eir_uuid[0] );
4089 }
4090 #endif
4091
4092 /*******************************************************************************
4093 **
4094 ** Function         bta_dm_enable_test_mode
4095 **
4096 ** Description      enable test mode
4097 **
4098 **
4099 ** Returns          void
4100 **
4101 *******************************************************************************/
4102 void bta_dm_enable_test_mode(tBTA_DM_MSG *p_data)
4103 {
4104     UNUSED(p_data);
4105     BTM_EnableTestMode();
4106 }
4107
4108 /*******************************************************************************
4109 **
4110 ** Function         bta_dm_disable_test_mode
4111 **
4112 ** Description      disable test mode
4113 **
4114 **
4115 ** Returns          void
4116 **
4117 *******************************************************************************/
4118 void bta_dm_disable_test_mode(tBTA_DM_MSG *p_data)
4119 {
4120     UNUSED(p_data);
4121     BTM_DeviceReset(NULL);
4122 }
4123
4124 /*******************************************************************************
4125 **
4126 ** Function         bta_dm_execute_callback
4127 **
4128 ** Description      Just execute a generic call back in the context of the BTU/BTA tack
4129 **
4130 **
4131 ** Returns          void
4132 **
4133 *******************************************************************************/
4134 void bta_dm_execute_callback(tBTA_DM_MSG *p_data)
4135 {
4136     /* sanity check */
4137     if(p_data->exec_cback.p_exec_cback == NULL)
4138     {
4139         return;
4140     }
4141
4142     p_data->exec_cback.p_exec_cback(p_data->exec_cback.p_param);
4143 }
4144
4145 /*******************************************************************************
4146 **
4147 ** Function         bta_dm_encrypt_cback
4148 **
4149 ** Description      link encryption complete callback.
4150 **
4151 ** Returns         None
4152 **
4153 *******************************************************************************/
4154 void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
4155 {
4156     tBTA_STATUS   bta_status = BTA_SUCCESS;
4157     tBTA_DM_ENCRYPT_CBACK *p_callback = NULL;
4158     UINT8   i ;
4159     UNUSED(p_ref_data);
4160
4161     for (i=0; i<bta_dm_cb.device_list.count; i++)
4162     {
4163         if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bd_addr) == 0 &&
4164             bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
4165             break;
4166     }
4167
4168     if (i < bta_dm_cb.device_list.count)
4169     {
4170         p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback;
4171         bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL;
4172     }
4173
4174     switch (result)
4175     {
4176         case BTM_SUCCESS:
4177             break;
4178         case BTM_WRONG_MODE:
4179             bta_status = BTA_WRONG_MODE;
4180             break;
4181         case BTM_NO_RESOURCES:
4182             bta_status = BTA_NO_RESOURCES;
4183             break;
4184         case BTM_BUSY:
4185             bta_status = BTA_BUSY;
4186             break;
4187         default:
4188             bta_status = BTA_FAILURE;
4189             break;
4190     }
4191
4192     APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=0x%x", bta_status, p_callback);
4193
4194     if (p_callback)
4195     {
4196         (*p_callback)(bd_addr, transport, bta_status);
4197     }
4198 }
4199
4200 /*******************************************************************************
4201 **
4202 ** Function         bta_dm_set_encryption
4203 **
4204 ** Description      This function to encrypt the link
4205 **
4206 ** Returns          None
4207 **
4208 *******************************************************************************/
4209 void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
4210 {
4211     UINT8 i ;
4212
4213     APPL_TRACE_DEBUG("bta_dm_set_encryption"); //todo
4214     if (!p_data->set_encryption.p_callback)
4215     {
4216         APPL_TRACE_ERROR("bta_dm_set_encryption callback is not provided");
4217         return;
4218     }
4219     for (i=0; i<bta_dm_cb.device_list.count; i++)
4220     {
4221         if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_data->set_encryption.bd_addr) == 0 &&
4222             bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
4223             break;
4224     }
4225     if (i < bta_dm_cb.device_list.count)
4226     {
4227         if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback)
4228         {
4229             APPL_TRACE_ERROR("earlier enc was not done for same device");
4230             (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr,
4231                                              p_data->set_encryption.transport,
4232                                              BTA_BUSY);
4233             return;
4234         }
4235
4236         if (BTM_SetEncryption(p_data->set_encryption.bd_addr, p_data->set_encryption.transport,
4237                               bta_dm_encrypt_cback, NULL, p_data->set_encryption.sec_act)
4238                               == BTM_CMD_STARTED)
4239         {
4240             bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_data->set_encryption.p_callback;
4241         }
4242     }
4243 }
4244
4245 #if (BLE_INCLUDED == TRUE)
4246 /*******************************************************************************
4247 **
4248 ** Function         bta_dm_observe_results_cb
4249 **
4250 ** Description      Callback for BLE Observe result
4251 **
4252 **
4253 ** Returns          void
4254 **
4255 *******************************************************************************/
4256 static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
4257 {
4258 ;
4259     tBTA_DM_SEARCH     result;
4260     tBTM_INQ_INFO      *p_inq_info;
4261     APPL_TRACE_DEBUG("bta_dm_observe_results_cb")
4262
4263     bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
4264     result.inq_res.rssi = p_inq->rssi;
4265     result.inq_res.ble_addr_type    = p_inq->ble_addr_type;
4266     result.inq_res.inq_result_type  = p_inq->inq_result_type;
4267     result.inq_res.device_type      = p_inq->device_type;
4268     result.inq_res.flag             = p_inq->flag;
4269
4270     /* application will parse EIR to find out remote device name */
4271     result.inq_res.p_eir = p_eir;
4272
4273     if((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL)
4274     {
4275         /* initialize remt_name_not_required to FALSE so that we get the name by default */
4276         result.inq_res.remt_name_not_required = FALSE;
4277     }
4278
4279     if(bta_dm_search_cb.p_scan_cback)
4280         bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result);
4281
4282     if(p_inq_info)
4283     {
4284         /* application indicates if it knows the remote name, inside the callback
4285          copy that to the inquiry data base*/
4286         if(result.inq_res.remt_name_not_required)
4287             p_inq_info->appl_knows_rem_name = TRUE;
4288     }
4289 }
4290
4291 /*******************************************************************************
4292 **
4293 ** Function         bta_dm_observe_cmpl_cb
4294 **
4295 ** Description      Callback for BLE Observe complete
4296 **
4297 **
4298 ** Returns          void
4299 **
4300 *******************************************************************************/
4301 static void bta_dm_observe_cmpl_cb (void * p_result)
4302 {
4303     tBTA_DM_SEARCH  data;
4304
4305     APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb");
4306
4307     data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
4308     if (bta_dm_search_cb.p_scan_cback)
4309     {
4310         bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
4311     }
4312 }
4313
4314 #if (SMP_INCLUDED == TRUE)
4315 /*******************************************************************************
4316 **
4317 ** Function         bta_dm_ble_smp_cback
4318 **
4319 ** Description      Callback for BLE SMP
4320 **
4321 **
4322 ** Returns          void
4323 **
4324 *******************************************************************************/
4325 static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data)
4326 {
4327     tBTM_STATUS status = BTM_SUCCESS;
4328     tBTA_DM_SEC sec_event;
4329     char *p_name = NULL;
4330
4331     if (!bta_dm_cb.p_sec_cback)
4332         return BTM_NOT_AUTHORIZED;
4333
4334     memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
4335     switch (event)
4336     {
4337         case BTM_LE_IO_REQ_EVT:
4338 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
4339
4340             bta_dm_co_ble_io_req(bda,
4341                                  &p_data->io_req.io_cap,
4342                                  &p_data->io_req.oob_data,
4343                                  &p_data->io_req.auth_req,
4344                                  &p_data->io_req.max_key_size,
4345                                  &p_data->io_req.init_keys,
4346                                  &p_data->io_req.resp_keys);
4347 #endif
4348             APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
4349
4350             break;
4351
4352         case BTM_LE_SEC_REQUEST_EVT:
4353             bdcpy(sec_event.ble_req.bd_addr, bda);
4354             p_name = BTM_SecReadDevName(bda);
4355             if (p_name != NULL)
4356                 strlcpy((char*)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN);
4357             else
4358                 sec_event.ble_req.bd_name[0] = 0;
4359             bta_dm_cb.p_sec_cback(BTA_DM_BLE_SEC_REQ_EVT, &sec_event);
4360             break;
4361
4362         case BTM_LE_KEY_NOTIF_EVT:
4363             bdcpy(sec_event.key_notif.bd_addr, bda);
4364             p_name = BTM_SecReadDevName(bda);
4365             if (p_name != NULL)
4366                 strlcpy((char*)sec_event.key_notif.bd_name, p_name, BD_NAME_LEN);
4367             else
4368                 sec_event.key_notif.bd_name[0] = 0;
4369             sec_event.key_notif.passkey = p_data->key_notif;
4370             bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_NOTIF_EVT, &sec_event);
4371             break;
4372
4373         case BTM_LE_KEY_REQ_EVT:
4374             bdcpy(sec_event.ble_req.bd_addr, bda);
4375             bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_REQ_EVT, &sec_event);
4376             break;
4377
4378         case BTM_LE_OOB_REQ_EVT:
4379             bdcpy(sec_event.ble_req.bd_addr, bda);
4380             bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event);
4381             break;
4382
4383         case BTM_LE_NC_REQ_EVT:
4384             bdcpy(sec_event.key_notif.bd_addr, bda);
4385             strlcpy((char*)sec_event.key_notif.bd_name, bta_dm_get_remname(), (BD_NAME_LEN));
4386             sec_event.key_notif.passkey = p_data->key_notif;
4387             bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
4388             break;
4389
4390         case BTM_LE_KEY_EVT:
4391             bdcpy(sec_event.ble_key.bd_addr, bda);
4392             sec_event.ble_key.key_type = p_data->key.key_type;
4393             sec_event.ble_key.p_key_value = p_data->key.p_key_value;
4394             bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event);
4395             break;
4396
4397         case BTM_LE_COMPLT_EVT:
4398             bdcpy(sec_event.auth_cmpl.bd_addr, bda);
4399 #if BLE_INCLUDED == TRUE
4400             BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
4401 #endif
4402             p_name = BTM_SecReadDevName(bda);
4403             if (p_name != NULL)
4404                 strlcpy((char*)sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN));
4405             else
4406                 sec_event.auth_cmpl.bd_name[0] = 0;
4407
4408             if (p_data->complt.reason != 0)
4409             {
4410                 sec_event.auth_cmpl.fail_reason = BTA_DM_AUTH_CONVERT_SMP_CODE(((UINT8)p_data->complt.reason));
4411                 /* delete this device entry from Sec Dev DB */
4412                 bta_dm_remove_sec_dev_entry (bda);
4413             }
4414             else
4415             {
4416                 sec_event.auth_cmpl.success = TRUE;
4417                 /* We also register for Service Changed right after connect. */
4418                 if (!p_data->complt.smp_over_br)
4419                     GATT_ConfigServiceChangeCCC(bda, TRUE, BT_TRANSPORT_LE);
4420             }
4421
4422             if (bta_dm_cb.p_sec_cback)
4423             {
4424                 //bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
4425                 bta_dm_cb.p_sec_cback(BTA_DM_BLE_AUTH_CMPL_EVT, &sec_event);
4426             }
4427             break;
4428
4429         default:
4430             status = BTM_NOT_AUTHORIZED;
4431             break;
4432     }
4433     return status;
4434 }
4435 #endif  /* SMP_INCLUDED == TRUE */
4436
4437 /*******************************************************************************
4438 **
4439 ** Function         bta_dm_ble_id_key_cback
4440 **
4441 ** Description      Callback for BLE local ID keys
4442 **
4443 **
4444 ** Returns          void
4445 **
4446 *******************************************************************************/
4447 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key)
4448 {
4449     UINT8   evt;
4450     tBTA_DM_SEC dm_key;
4451
4452     switch (key_type)
4453     {
4454         case BTM_BLE_KEY_TYPE_ID:
4455         case BTM_BLE_KEY_TYPE_ER:
4456             if (bta_dm_cb.p_sec_cback)
4457             {
4458                 memcpy(&dm_key.ble_id_keys, p_key, sizeof(tBTM_BLE_LOCAL_KEYS));
4459
4460                 evt = (key_type == BTM_BLE_KEY_TYPE_ID) ? BTA_DM_BLE_LOCAL_IR_EVT :\
4461                       BTA_DM_BLE_LOCAL_ER_EVT;
4462                 bta_dm_cb.p_sec_cback(evt, &dm_key);
4463             }
4464             break;
4465
4466         default:
4467             APPL_TRACE_DEBUG("Unknown key type %d", key_type);
4468             break;
4469     }
4470     return;
4471
4472 }
4473
4474 /*******************************************************************************
4475 **
4476 ** Function         bta_dm_add_blekey
4477 **
4478 ** Description      This function adds an BLE Key to an security database entry.
4479 **                  This function shall only be called AFTER BTA_DmAddBleDevice has been called.
4480 **                  It is normally called during host startup to restore all required information
4481 **                  stored in the NVRAM.
4482 **
4483 ** Parameters:
4484 **
4485 *******************************************************************************/
4486 void bta_dm_add_blekey (tBTA_DM_MSG *p_data)
4487 {
4488     if (!BTM_SecAddBleKey (p_data->add_ble_key.bd_addr,
4489                            (tBTM_LE_KEY_VALUE *)&p_data->add_ble_key.blekey,
4490                            p_data->add_ble_key.key_type))
4491     {
4492         APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Key for device %08x%04x",
4493                            (p_data->add_ble_key.bd_addr[0]<<24)+(p_data->add_ble_key.bd_addr[1]<<16)+\
4494                            (p_data->add_ble_key.bd_addr[2]<<8)+p_data->add_ble_key.bd_addr[3],
4495                            (p_data->add_ble_key.bd_addr[4]<<8)+p_data->add_ble_key.bd_addr[5]);
4496     }
4497 }
4498
4499 /*******************************************************************************
4500 **
4501 ** Function         bta_dm_add_ble_device
4502 **
4503 ** Description      This function adds an BLE device to an security database entry.
4504 **                  It is normally called during host startup to restore all required information
4505 **                  stored in the NVRAM.
4506 **
4507 ** Parameters:
4508 **
4509 *******************************************************************************/
4510 void bta_dm_add_ble_device (tBTA_DM_MSG *p_data)
4511 {
4512     if (!BTM_SecAddBleDevice (p_data->add_ble_device.bd_addr, NULL,
4513                               p_data->add_ble_device.dev_type  ,
4514                               p_data->add_ble_device.addr_type))
4515     {
4516         APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Device for device %08x%04x",
4517                            (p_data->add_ble_device.bd_addr[0]<<24)+(p_data->add_ble_device.bd_addr[1]<<16)+ \
4518                            (p_data->add_ble_device.bd_addr[2]<<8)+p_data->add_ble_device.bd_addr[3],
4519                            (p_data->add_ble_device.bd_addr[4]<<8)+p_data->add_ble_device.bd_addr[5]);
4520     }
4521 }
4522
4523 /*******************************************************************************
4524 **
4525 ** Function         bta_dm_add_ble_device
4526 **
4527 ** Description      This function adds an BLE device to an security database entry.
4528 **                  It is normally called during host startup to restore all required information
4529 **                  stored in the NVRAM.
4530 **
4531 ** Parameters:
4532 **
4533 *******************************************************************************/
4534 void bta_dm_ble_passkey_reply (tBTA_DM_MSG *p_data)
4535 {
4536     if (p_data->pin_reply.accept)
4537     {
4538         BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_SUCCESS, p_data->ble_passkey_reply.passkey);
4539     }
4540     else
4541     {
4542         BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED, p_data->ble_passkey_reply.passkey);
4543     }
4544
4545 }
4546
4547 /*******************************************************************************
4548 **
4549 ** Function         bta_dm_ble_confirm_reply
4550 **
4551 ** Description      This is response to SM numeric comparison request submitted
4552 **                  to application.
4553 **
4554 ** Parameters:
4555 **
4556 *******************************************************************************/
4557 void bta_dm_ble_confirm_reply (tBTA_DM_MSG *p_data)
4558 {
4559     if (p_data->confirm.accept)
4560     {
4561         BTM_BleConfirmReply(p_data->confirm.bd_addr, BTM_SUCCESS);
4562     }
4563     else
4564     {
4565         BTM_BleConfirmReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED);
4566     }
4567 }
4568
4569 /*******************************************************************************
4570 **
4571 ** Function         bta_dm_security_grant
4572 **
4573 ** Description      This function grant SMP security request access.
4574 **
4575 ** Parameters:
4576 **
4577 *******************************************************************************/
4578 void bta_dm_security_grant (tBTA_DM_MSG *p_data)
4579 {
4580     BTM_SecurityGrant(p_data->ble_sec_grant.bd_addr, p_data->ble_sec_grant.res);
4581 }
4582
4583 /*******************************************************************************
4584 **
4585 ** Function         bta_dm_ble_set_bg_conn_type
4586 **
4587 ** Description      This function set the BLE background connection type
4588 **
4589 ** Parameters:
4590 **
4591 *******************************************************************************/
4592 void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data)
4593 {
4594     BTM_BleSetBgConnType(p_data->ble_set_bd_conn_type.bg_conn_type,
4595                          p_data->ble_set_bd_conn_type.p_select_cback);
4596 }
4597
4598 /*******************************************************************************
4599 **
4600 ** Function         bta_dm_ble_set_conn_params
4601 **
4602 ** Description      This function set the preferred connection parameters.
4603 **
4604 ** Parameters:
4605 **
4606 *******************************************************************************/
4607 void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data)
4608 {
4609     BTM_BleSetPrefConnParams(p_data->ble_set_conn_params.peer_bda,
4610                              p_data->ble_set_conn_params.conn_int_min,
4611                              p_data->ble_set_conn_params.conn_int_max,
4612                              p_data->ble_set_conn_params.slave_latency,
4613                              p_data->ble_set_conn_params.supervision_tout);
4614 }
4615
4616 /*******************************************************************************
4617 **
4618 ** Function         bta_dm_ble_set_conn_scan_params
4619 **
4620 ** Description      This function sets BLE scan parameters.
4621 **
4622 ** Parameters:
4623 **
4624 *******************************************************************************/
4625 void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data)
4626 {
4627     BTM_BleSetScanParams(p_data->ble_set_scan_params.client_if,
4628                          p_data->ble_set_scan_params.scan_int,
4629                          p_data->ble_set_scan_params.scan_window,
4630                          p_data->ble_set_scan_params.scan_mode,
4631                          p_data->ble_set_scan_params.scan_param_setup_cback);
4632 }
4633
4634 /*******************************************************************************
4635 **
4636 ** Function         bta_dm_ble_set_conn_scan_params
4637 **
4638 ** Description      This function set the preferred connection scan parameters.
4639 **
4640 ** Parameters:
4641 **
4642 *******************************************************************************/
4643 void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data)
4644 {
4645     BTM_BleSetConnScanParams(p_data->ble_set_conn_scan_params.scan_int,
4646                              p_data->ble_set_conn_scan_params.scan_window);
4647 }
4648 /*******************************************************************************
4649 **
4650 ** Function         bta_dm_ble_update_conn_params
4651 **
4652 ** Description      This function update LE connection parameters.
4653 **
4654 ** Parameters:
4655 **
4656 *******************************************************************************/
4657 void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
4658 {
4659     if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr,
4660                                  p_data->ble_update_conn_params.min_int,
4661                                  p_data->ble_update_conn_params.max_int,
4662                                  p_data->ble_update_conn_params.latency,
4663                                  p_data->ble_update_conn_params.timeout))
4664     {
4665         APPL_TRACE_ERROR("Update connection parameters failed!");
4666     }
4667 }
4668
4669 #if BLE_PRIVACY_SPT == TRUE
4670 /*******************************************************************************
4671 **
4672 ** Function         bta_dm_ble_config_local_privacy
4673 **
4674 ** Description      This function set the local device LE privacy settings.
4675 **
4676 ** Parameters:
4677 **
4678 *******************************************************************************/
4679 void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data)
4680 {
4681     BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable);
4682 }
4683 #endif
4684
4685 /*******************************************************************************
4686 **
4687 ** Function         bta_dm_ble_observe
4688 **
4689 ** Description      This function set the preferred connection scan parameters.
4690 **
4691 ** Parameters:
4692 **
4693 *******************************************************************************/
4694 void bta_dm_ble_observe (tBTA_DM_MSG *p_data)
4695 {
4696     tBTM_STATUS status;
4697     if (p_data->ble_observe.start)
4698     {
4699         /*Save the  callback to be called when a scan results are available */
4700         bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback;
4701         if ((status = BTM_BleObserve(TRUE, p_data->ble_observe.duration,
4702                             bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb))!= BTM_CMD_STARTED)
4703         {
4704             tBTA_DM_SEARCH  data;
4705             APPL_TRACE_WARNING(" %s BTM_BleObserve  failed. status %d",__FUNCTION__,status);
4706             data.inq_cmpl.num_resps = 0;
4707             if (bta_dm_search_cb.p_scan_cback)
4708             {
4709                 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
4710             }
4711         }
4712     }
4713     else
4714     {
4715         bta_dm_search_cb.p_scan_cback = NULL;
4716         BTM_BleObserve(FALSE, 0, NULL,NULL );
4717     }
4718 }
4719 /*******************************************************************************
4720 **
4721 ** Function         bta_dm_ble_set_adv_params
4722 **
4723 ** Description      This function set the adv parameters.
4724 **
4725 ** Parameters:
4726 **
4727 *******************************************************************************/
4728 void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data)
4729 {
4730     BTM_BleSetAdvParams(p_data->ble_set_adv_params.adv_int_min,
4731                         p_data->ble_set_adv_params.adv_int_max,
4732                         p_data->ble_set_adv_params.p_dir_bda,
4733                         BTA_DM_BLE_ADV_CHNL_MAP);
4734 }
4735
4736 /*******************************************************************************
4737 **
4738 ** Function         bta_dm_ble_set_adv_config
4739 **
4740 ** Description      This function set the customized ADV data configuration
4741 **
4742 ** Parameters:
4743 **
4744 *******************************************************************************/
4745 void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data)
4746 {
4747     tBTA_STATUS status = BTA_FAILURE;
4748
4749     if (BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask,
4750                         (tBTM_BLE_ADV_DATA *)&p_data->ble_set_adv_data.adv_cfg) == BTM_SUCCESS)
4751     {
4752         status = BTA_SUCCESS;
4753     }
4754
4755     if (p_data->ble_set_adv_data.p_adv_data_cback)
4756         (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
4757 }
4758
4759 /*******************************************************************************
4760 **
4761 ** Function         bta_dm_ble_set_scan_rsp
4762 **
4763 ** Description      This function set the customized ADV scan resp. configuration
4764 **
4765 ** Parameters:
4766 **
4767 *******************************************************************************/
4768 void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data)
4769 {
4770     tBTA_STATUS status = BTA_FAILURE;
4771
4772     if(BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
4773                         (tBTM_BLE_ADV_DATA *)&p_data->ble_set_adv_data.adv_cfg) == BTM_SUCCESS)
4774     {
4775         status = BTA_SUCCESS;
4776     }
4777
4778     if (p_data->ble_set_adv_data.p_adv_data_cback)
4779         (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
4780 }
4781
4782 /*******************************************************************************
4783 **
4784 ** Function         bta_dm_ble_set_data_length
4785 **
4786 ** Description      This function set the maximum transmission packet size
4787 **
4788 ** Parameters
4789 **
4790 *******************************************************************************/
4791 void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data)
4792 {
4793     if (BTM_SetBleDataLength(p_data->ble_set_data_length.remote_bda,
4794                         p_data->ble_set_data_length.tx_data_length) != BTM_SUCCESS)
4795     {
4796         APPL_TRACE_ERROR("%s failed", __FUNCTION__);
4797     }
4798 }
4799
4800 /*******************************************************************************
4801 **
4802 ** Function         bta_dm_ble_broadcast
4803 **
4804 ** Description      Starts or stops LE broadcasts
4805 **
4806 ** Parameters:
4807 **
4808 *******************************************************************************/
4809 void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data)
4810 {
4811     BTM_BleBroadcast(p_data->ble_observe.start);
4812 }
4813
4814 /*******************************************************************************
4815 **
4816 ** Function         bta_dm_ble_multi_adv_enb
4817 **
4818 ** Description      This function enables a single advertising instance
4819 **
4820 ** Parameters:
4821 **
4822 *******************************************************************************/
4823 void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data)
4824 {
4825     tBTM_STATUS btm_status = 0;
4826
4827     bta_dm_cb.p_multi_adv_cback = p_data->ble_multi_adv_enb.p_cback;
4828     if(BTM_BleMaxMultiAdvInstanceCount() > 0 && NULL != p_data->ble_multi_adv_enb.p_ref)
4829     {
4830         btm_status = BTM_BleEnableAdvInstance((tBTM_BLE_ADV_PARAMS*)
4831                                             p_data->ble_multi_adv_enb.p_params,
4832                                             p_data->ble_multi_adv_enb.p_cback,
4833                                             p_data->ble_multi_adv_enb.p_ref);
4834     }
4835
4836     if(BTM_CMD_STARTED != btm_status)
4837     {
4838         bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_ENB_EVT, 0xFF,
4839                                     p_data->ble_multi_adv_enb.p_ref, BTA_FAILURE);
4840     }
4841 }
4842 /*******************************************************************************
4843 **
4844 ** Function         bta_dm_ble_multi_adv_param_upd
4845 **
4846 ** Description      This function updates multiple advertising instance parameters
4847 **
4848 ** Parameters:
4849 **
4850 *******************************************************************************/
4851 void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data)
4852 {
4853     tBTM_STATUS btm_status = 0;
4854     void *p_ref = NULL;
4855
4856     if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_param.inst_id > 0
4857         && p_data->ble_multi_adv_param.inst_id < BTM_BleMaxMultiAdvInstanceCount())
4858     {
4859         btm_status = BTM_BleUpdateAdvInstParam(p_data->ble_multi_adv_param.inst_id,
4860                          (tBTM_BLE_ADV_PARAMS*)p_data->ble_multi_adv_param.p_params);
4861     }
4862
4863     if(BTM_CMD_STARTED != btm_status)
4864     {
4865        p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_param.inst_id);
4866        bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_PARAM_EVT,
4867                                    p_data->ble_multi_adv_param.inst_id, p_ref, BTA_FAILURE);
4868     }
4869 }
4870 /*******************************************************************************
4871 **
4872 ** Function         bta_dm_ble_multi_adv_data
4873 **
4874 ** Description      This function write multiple advertising instance adv data
4875 **                  or scan response data
4876 **
4877 ** Parameters:
4878 **
4879 *******************************************************************************/
4880 void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data)
4881 {
4882     tBTM_STATUS btm_status = 0;
4883     void *p_ref = NULL;
4884
4885     if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_data.inst_id > 0
4886         && p_data->ble_multi_adv_data.inst_id < BTM_BleMaxMultiAdvInstanceCount())
4887     {
4888         btm_status = BTM_BleCfgAdvInstData(p_data->ble_multi_adv_data.inst_id,
4889                         p_data->ble_multi_adv_data.is_scan_rsp,
4890                         p_data->ble_multi_adv_data.data_mask,
4891                         (tBTM_BLE_ADV_DATA*)&p_data->ble_multi_adv_data.data);
4892     }
4893
4894     if(BTM_CMD_STARTED != btm_status)
4895     {
4896        p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_data.inst_id);
4897        bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DATA_EVT,
4898                                    p_data->ble_multi_adv_data.inst_id, p_ref, BTA_FAILURE);
4899     }
4900
4901 }
4902 /*******************************************************************************
4903 **
4904 ** Function         btm_dm_ble_multi_adv_disable
4905 **
4906 ** Description      This function disable a single adv instance
4907 **
4908 ** Parameters:
4909 **
4910 *******************************************************************************/
4911 void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data)
4912 {
4913     tBTM_STATUS btm_status = 0;
4914     void *p_ref = NULL;
4915
4916     if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_disable.inst_id > 0
4917         && p_data->ble_multi_adv_disable.inst_id < BTM_BleMaxMultiAdvInstanceCount())
4918     {
4919         btm_status = BTM_BleDisableAdvInstance(p_data->ble_multi_adv_disable.inst_id);
4920     }
4921
4922     if(BTM_CMD_STARTED != btm_status)
4923     {
4924        p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_disable.inst_id);
4925        bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DISABLE_EVT,
4926                                    p_data->ble_multi_adv_disable.inst_id, p_ref, BTA_FAILURE);
4927     }
4928 }
4929
4930 /*******************************************************************************
4931 **
4932 ** Function         bta_dm_ble_setup_storage
4933 **
4934 ** Description      This function configures up the storage parameters for ADV batch scanning
4935 **
4936 ** Parameters:
4937 **
4938 *******************************************************************************/
4939 void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data)
4940 {
4941     tBTM_STATUS btm_status = 0;
4942     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
4943
4944     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
4945
4946     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
4947     {
4948         btm_status = BTM_BleSetStorageConfig(p_data->ble_set_storage.batch_scan_full_max,
4949                                              p_data->ble_set_storage.batch_scan_trunc_max,
4950                                              p_data->ble_set_storage.batch_scan_notify_threshold,
4951                                              p_data->ble_set_storage.p_setup_cback,
4952                                              p_data->ble_set_storage.p_thres_cback,
4953                                              p_data->ble_set_storage.p_read_rep_cback,
4954                                              p_data->ble_set_storage.ref_value);
4955     }
4956
4957     if(BTM_CMD_STARTED != btm_status)
4958        bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, p_data->ble_set_storage.ref_value,
4959                              btm_status);
4960 }
4961
4962 /*******************************************************************************
4963 **
4964 ** Function         bta_dm_ble_enable_batch_scan
4965 **
4966 ** Description      This function sets up the parameters and enables batch scan
4967 **
4968 ** Parameters:
4969 **
4970 *******************************************************************************/
4971 void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data)
4972 {
4973     tBTM_STATUS btm_status = 0;
4974     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
4975
4976     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
4977
4978     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
4979     {
4980         btm_status = BTM_BleEnableBatchScan(p_data->ble_enable_scan.scan_mode,
4981                                             p_data->ble_enable_scan.scan_int,
4982                                             p_data->ble_enable_scan.scan_window,
4983                                             p_data->ble_enable_scan.discard_rule,
4984                                             p_data->ble_enable_scan.addr_type,
4985                                             p_data->ble_enable_scan.ref_value);
4986     }
4987
4988     if(BTM_CMD_STARTED != btm_status)
4989        bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_ENABLE_EVT, p_data->ble_enable_scan.ref_value,
4990                              btm_status);
4991 }
4992
4993 /*******************************************************************************
4994 **
4995 ** Function         bta_dm_ble_disable_batch_scan
4996 **
4997 ** Description      This function disables the batch scan
4998 **
4999 ** Parameters:
5000 **
5001 *******************************************************************************/
5002 void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data)
5003 {
5004     UNUSED(p_data);
5005     tBTM_STATUS btm_status = 0;
5006     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5007
5008     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5009
5010     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
5011     {
5012         btm_status = BTM_BleDisableBatchScan(p_data->ble_disable_scan.ref_value);
5013     }
5014
5015     if(BTM_CMD_STARTED != btm_status)
5016        bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_DISABLE_EVT, p_data->ble_enable_scan.ref_value,
5017                              btm_status);
5018 }
5019
5020 /*******************************************************************************
5021 **
5022 ** Function         bta_dm_ble_read_scan_reports
5023 **
5024 ** Description      This function reads the batch scan reports
5025 **
5026 ** Parameters:
5027 **
5028 *******************************************************************************/
5029 void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data)
5030 {
5031     tBTM_STATUS btm_status = 0;
5032     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5033
5034     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5035
5036     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
5037     {
5038         btm_status = BTM_BleReadScanReports(p_data->ble_read_reports.scan_type,
5039                                             p_data->ble_read_reports.ref_value);
5040     }
5041
5042     if(BTM_CMD_STARTED != btm_status)
5043        bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, p_data->ble_enable_scan.ref_value,
5044                              btm_status);
5045 }
5046
5047 /*******************************************************************************
5048 **
5049 ** Function         bta_dm_ble_track_advertiser
5050 **
5051 ** Description      This function tracks the specific advertiser
5052 **
5053 ** Parameters:
5054 **
5055 *******************************************************************************/
5056 void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data)
5057 {
5058     tBTM_STATUS btm_status = 0;
5059     BD_ADDR bda;
5060     memset(&bda, 0 , sizeof(BD_ADDR));
5061     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5062     tBTA_DM_BLE_TRACK_ADV_DATA track_adv_data;
5063
5064     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5065
5066     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
5067     {
5068         btm_status = BTM_BleTrackAdvertiser((tBTM_BLE_TRACK_ADV_CBACK *)
5069                                             p_data->ble_track_advert.p_track_adv_cback,
5070                                             p_data->ble_track_advert.ref_value);
5071     }
5072
5073     if(BTM_CMD_STARTED != btm_status)
5074     {
5075         memset(&track_adv_data, 0, sizeof(tBTA_DM_BLE_TRACK_ADV_DATA));
5076         track_adv_data.advertiser_info_present = NO_ADV_INFO_PRESENT; /* Indicates failure */
5077         track_adv_data.client_if = (UINT8)p_data->ble_track_advert.ref_value;
5078         p_data->ble_track_advert.p_track_adv_cback(&track_adv_data);
5079     }
5080 }
5081
5082 /*******************************************************************************
5083 **
5084 ** Function         bta_ble_scan_setup_cb
5085 **
5086 ** Description      Handle the setup callback from BTM layer and forward it to app layer
5087 **
5088 ** Parameters:
5089 **
5090 *******************************************************************************/
5091 void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_value,
5092                                   tBTM_STATUS status)
5093 {
5094     tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0;
5095
5096     APPL_TRACE_DEBUG("bta_ble_scan_setup_cb : evt: %d, ref_value: %d, status:%d", evt,
5097                       ref_value, status);
5098
5099     switch(evt)
5100     {
5101         case BTM_BLE_BATCH_SCAN_ENABLE_EVT:
5102            bta_evt = BTA_BLE_BATCH_SCAN_ENB_EVT;
5103            break;
5104         case BTM_BLE_BATCH_SCAN_CFG_STRG_EVT:
5105            bta_evt = BTA_BLE_BATCH_SCAN_CFG_STRG_EVT;
5106            break;
5107         case BTM_BLE_BATCH_SCAN_DISABLE_EVT:
5108             bta_evt = BTA_BLE_BATCH_SCAN_DIS_EVT;
5109             break;
5110         case BTM_BLE_BATCH_SCAN_PARAM_EVT:
5111             bta_evt = BTA_BLE_BATCH_SCAN_PARAM_EVT;
5112             break;
5113         default:
5114             break;
5115     }
5116
5117     if(NULL != bta_dm_cb.p_setup_cback)
5118        bta_dm_cb.p_setup_cback(bta_evt, ref_value, status);
5119 }
5120
5121
5122 #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
5123 /*******************************************************************************
5124 **
5125 ** Function         bta_ble_scan_pf_cmpl
5126 **
5127 ** Description      ADV payload filtering operation complete callback
5128 **
5129 **
5130 ** Returns         TRUE if handled, otherwise FALSE.
5131 **
5132 *******************************************************************************/
5133 static void bta_ble_scan_cfg_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op,
5134                                  tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status,
5135                                  tBTM_BLE_REF_VALUE ref_value)
5136 {
5137     tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE;
5138
5139     APPL_TRACE_DEBUG("bta_ble_scan_cfg_cmpl: %d, %d, %d, %d", action, cfg_op, avbl_space, status);
5140
5141     if(bta_dm_cb.p_scan_filt_cfg_cback)
5142        bta_dm_cb.p_scan_filt_cfg_cback(action, cfg_op, avbl_space, st, ref_value);
5143 }
5144
5145 /*******************************************************************************
5146 **
5147 ** Function         bta_dm_cfg_filter_cond
5148 **
5149 ** Description      This function configure adv payload filtering condition
5150 **
5151 ** Parameters:
5152 **
5153 *******************************************************************************/
5154 void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data)
5155 {
5156     tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5157     tBTA_STATUS status = BTA_FAILURE;
5158
5159     tBTM_BLE_VSC_CB cmn_vsc_cb;
5160
5161     APPL_TRACE_DEBUG("bta_dm_cfg_filter_cond");
5162     BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5163     if(0 != cmn_vsc_cb.filter_support)
5164     {
5165         if ((st = BTM_BleCfgFilterCondition(p_data->ble_cfg_filter_cond.action,
5166                             p_data->ble_cfg_filter_cond.cond_type,
5167                             (tBTM_BLE_PF_FILT_INDEX)p_data->ble_cfg_filter_cond.filt_index,
5168                             (tBTM_BLE_PF_COND_PARAM *)p_data->ble_cfg_filter_cond.p_cond_param,
5169                             bta_ble_scan_cfg_cmpl, p_data->ble_cfg_filter_cond.ref_value))
5170                 == BTM_CMD_STARTED)
5171         {
5172             bta_dm_cb.p_scan_filt_cfg_cback = p_data->ble_cfg_filter_cond.p_filt_cfg_cback;
5173             return;
5174         }
5175     }
5176
5177     if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback)
5178         p_data->ble_cfg_filter_cond.p_filt_cfg_cback(BTA_DM_BLE_PF_CONFIG_EVT,
5179                                             p_data->ble_cfg_filter_cond.cond_type, 0, status,
5180                                             p_data->ble_cfg_filter_cond.ref_value);
5181     return;
5182 }
5183
5184 /*******************************************************************************
5185 **
5186 ** Function         bta_dm_enable_scan_filter
5187 **
5188 ** Description      This function enable/disable adv payload filtering condition
5189 **
5190 ** Parameters:
5191 **
5192 *******************************************************************************/
5193 void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data)
5194 {
5195     tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5196     tBTA_STATUS status = BTA_FAILURE;
5197
5198     tBTM_BLE_VSC_CB cmn_vsc_cb;
5199     APPL_TRACE_DEBUG("bta_dm_enable_scan_filter");
5200     BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5201
5202     if(0 != cmn_vsc_cb.filter_support)
5203     {
5204         if((st = BTM_BleEnableDisableFilterFeature(p_data->ble_enable_scan_filt.action,
5205                    p_data->ble_enable_scan_filt.p_filt_status_cback,
5206                    (tBTM_BLE_REF_VALUE)p_data->ble_enable_scan_filt.ref_value)) == BTM_CMD_STARTED)
5207         bta_dm_cb.p_scan_filt_status_cback = p_data->ble_enable_scan_filt.p_filt_status_cback;
5208         return;
5209     }
5210
5211     if (p_data->ble_enable_scan_filt.p_filt_status_cback)
5212         p_data->ble_enable_scan_filt.p_filt_status_cback (BTA_DM_BLE_PF_ENABLE_EVT,
5213                                             p_data->ble_enable_scan_filt.ref_value, status);
5214
5215 }
5216
5217 /*******************************************************************************
5218 **
5219 ** Function         bta_dm_scan_filter_param_setup
5220 **
5221 ** Description      This function sets up scan filter params
5222 **
5223 ** Parameters:
5224 **
5225 *******************************************************************************/
5226 void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data)
5227 {
5228     tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5229     tBTA_STATUS status = BTA_FAILURE;
5230
5231     tBTM_BLE_VSC_CB cmn_vsc_cb;
5232
5233     APPL_TRACE_DEBUG("bta_dm_scan_filter_param_setup");
5234     BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5235     if(0 != cmn_vsc_cb.filter_support)
5236     {
5237         if ((st = BTM_BleAdvFilterParamSetup(p_data->ble_scan_filt_param_setup.action,
5238                    p_data->ble_scan_filt_param_setup.filt_index,
5239                   (tBTM_BLE_PF_FILT_PARAMS *)&p_data->ble_scan_filt_param_setup.filt_params,
5240                    p_data->ble_scan_filt_param_setup.p_target,
5241                    p_data->ble_scan_filt_param_setup.p_filt_param_cback,
5242                    p_data->ble_scan_filt_param_setup.ref_value)) == BTM_CMD_STARTED)
5243         {
5244             bta_dm_cb.p_scan_filt_param_cback = p_data->ble_scan_filt_param_setup.p_filt_param_cback;
5245             return;
5246         }
5247     }
5248
5249     if (p_data->ble_scan_filt_param_setup.p_filt_param_cback)
5250         p_data->ble_scan_filt_param_setup.p_filt_param_cback (BTA_DM_BLE_PF_ENABLE_EVT, 0,
5251                                         p_data->ble_scan_filt_param_setup.ref_value, status);
5252
5253     return;
5254 }
5255 #endif
5256
5257 /*******************************************************************************
5258 **
5259 ** Function         bta_ble_enable_scan_cmpl
5260 **
5261 ** Description      ADV payload filtering enable / disable complete callback
5262 **
5263 **
5264 ** Returns          None
5265 **
5266 *******************************************************************************/
5267 static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time,
5268                                         tBTM_BLE_RX_TIME_MS rx_time,
5269                                         tBTM_BLE_IDLE_TIME_MS idle_time,
5270                                         tBTM_BLE_ENERGY_USED  energy_used,
5271                                         tBTM_STATUS status)
5272 {
5273     tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE;
5274     tBTA_DM_CONTRL_STATE ctrl_state = 0;
5275
5276     if (BTA_SUCCESS == st)
5277        ctrl_state = bta_dm_pm_obtain_controller_state();
5278
5279     if (bta_dm_cb.p_energy_info_cback)
5280         bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, ctrl_state, st);
5281 }
5282
5283 /*******************************************************************************
5284 **
5285 ** Function         bta_dm_ble_get_energy_info
5286 **
5287 ** Description      This function obtains the energy info
5288 **
5289 ** Parameters:
5290 **
5291 *******************************************************************************/
5292 void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data)
5293 {
5294     tBTM_STATUS btm_status = 0;
5295
5296     bta_dm_cb.p_energy_info_cback = p_data->ble_energy_info.p_energy_info_cback;
5297     btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl);
5298     if (BTM_CMD_STARTED != btm_status)
5299         bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status);
5300 }
5301
5302 #if ((defined BTA_GATT_INCLUDED) &&  (BTA_GATT_INCLUDED == TRUE))
5303 #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
5304 #define BTA_DM_GATT_CLOSE_DELAY_TOUT    1000
5305 #endif
5306
5307 /*******************************************************************************
5308 **
5309 ** Function         bta_dm_gattc_register
5310 **
5311 ** Description      Register with GATTC in DM if BLE is needed.
5312 **
5313 **
5314 ** Returns          void
5315 **
5316 *******************************************************************************/
5317 static void bta_dm_gattc_register(void)
5318 {
5319     tBT_UUID                app_uuid = {LEN_UUID_128,{0}};
5320
5321     if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF)
5322     {
5323         memset (&app_uuid.uu.uuid128, 0x87, LEN_UUID_128);
5324         BTA_GATTC_AppRegister(&app_uuid, bta_dm_gattc_callback);
5325     }
5326 }
5327
5328 /*******************************************************************************
5329 **
5330 ** Function         btm_dm_start_disc_gatt_services
5331 **
5332 ** Description      This function starts a GATT service search request.
5333 **
5334 ** Parameters:
5335 **
5336 *******************************************************************************/
5337 static void btm_dm_start_disc_gatt_services (UINT16 conn_id)
5338 {
5339     tBT_UUID    *p_uuid = bta_dm_search_cb.p_srvc_uuid +
5340                           bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
5341
5342     p_uuid = bta_dm_search_cb.p_srvc_uuid +
5343              bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
5344
5345     /* always search for all services */
5346     BTA_GATTC_ServiceSearchRequest(conn_id, p_uuid);
5347 }
5348
5349 /*******************************************************************************
5350 **
5351 ** Function         bta_dm_gatt_disc_result
5352 **
5353 ** Description      This function process the GATT service search result.
5354 **
5355 ** Parameters:
5356 **
5357 *******************************************************************************/
5358 static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
5359 {
5360     tBTA_DM_SEARCH   result;
5361
5362     /*
5363         * This logic will not work for gatt case.  We are checking against the bluetooth profiles here
5364         * just copy the GATTID in raw data field and send it across.
5365         */
5366
5367
5368     if ( bta_dm_search_cb.ble_raw_used + sizeof(tBTA_GATT_ID) < bta_dm_search_cb.ble_raw_size )
5369     {
5370         APPL_TRACE_DEBUG("ADDING BLE SERVICE uuid=0x%x, ble_ptr = 0x%x, ble_raw_used = 0x%x",
5371             service_id.uuid.uu.uuid16,bta_dm_search_cb.p_ble_rawdata,bta_dm_search_cb.ble_raw_used);
5372
5373         if(bta_dm_search_cb.p_ble_rawdata)
5374         {
5375             memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used), &service_id,
5376                    sizeof(service_id) );
5377
5378             bta_dm_search_cb.ble_raw_used += sizeof(service_id);
5379         }
5380         else
5381         {
5382             APPL_TRACE_ERROR("p_ble_rawdata is NULL");
5383         }
5384
5385     }
5386     else
5387     {
5388         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 );
5389     }
5390
5391     LOG_INFO(LOG_TAG, "%s service_id_uuid_len=%d ", __func__, service_id.uuid.len);
5392     if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE)
5393     {
5394
5395         /* send result back to app now, one by one */
5396         bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
5397         strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN);
5398         memcpy(&result.disc_ble_res.service, &service_id.uuid, sizeof(tBT_UUID));
5399
5400         bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
5401     }
5402 }
5403
5404 /*******************************************************************************
5405 **
5406 ** Function         bta_dm_gatt_disc_complete
5407 **
5408 ** Description      This function process the GATT service search complete.
5409 **
5410 ** Parameters:
5411 **
5412 *******************************************************************************/
5413 static void bta_dm_gatt_disc_complete(UINT16 conn_id, tBTA_GATT_STATUS status)
5414 {
5415     APPL_TRACE_DEBUG("%s conn_id = %d", __func__, conn_id);
5416
5417     if (bta_dm_search_cb.uuid_to_search > 0)
5418         bta_dm_search_cb.uuid_to_search --;
5419
5420     if (status == BTA_GATT_OK && bta_dm_search_cb.uuid_to_search > 0) {
5421         btm_dm_start_disc_gatt_services(conn_id);
5422     } else {
5423         tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
5424
5425         bta_dm_search_cb.uuid_to_search = 0;
5426
5427         /* no more services to be discovered */
5428         p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
5429         p_msg->disc_result.result.disc_res.result = (status == BTA_GATT_OK) ? BTA_SUCCESS :BTA_FAILURE;
5430         APPL_TRACE_DEBUG("%s service found: 0x%08x", __func__,
5431                          bta_dm_search_cb.services_found);
5432         p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
5433         p_msg->disc_result.result.disc_res.num_uuids = 0;
5434         p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
5435         bdcpy(p_msg->disc_result.result.disc_res.bd_addr,
5436               bta_dm_search_cb.peer_bdaddr);
5437         strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
5438                 bta_dm_get_remname(), BD_NAME_LEN);
5439
5440         p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE;
5441         if (bta_dm_search_cb.ble_raw_used > 0) {
5442             p_msg->disc_result.result.disc_res.p_raw_data =
5443                 osi_malloc(bta_dm_search_cb.ble_raw_used);
5444
5445             memcpy(p_msg->disc_result.result.disc_res.p_raw_data,
5446                    bta_dm_search_cb.p_ble_rawdata,
5447                    bta_dm_search_cb.ble_raw_used);
5448
5449             p_msg->disc_result.result.disc_res.raw_data_size =
5450                 bta_dm_search_cb.ble_raw_used;
5451         } else {
5452             p_msg->disc_result.result.disc_res.p_raw_data = NULL;
5453             bta_dm_search_cb.p_ble_rawdata = 0;
5454         }
5455
5456         bta_sys_sendmsg(p_msg);
5457
5458         if (conn_id != BTA_GATT_INVALID_CONN_ID)
5459         {
5460             /* start a GATT channel close delay timer */
5461             bta_sys_start_timer(bta_dm_search_cb.gatt_close_timer,
5462                                 BTA_DM_GATT_CLOSE_DELAY_TOUT,
5463                                 BTA_DM_DISC_CLOSE_TOUT_EVT, 0);
5464             bdcpy(bta_dm_search_cb.pending_close_bda,
5465                   bta_dm_search_cb.peer_bdaddr);
5466         }
5467         bta_dm_search_cb.gatt_disc_active = FALSE;
5468     }
5469 }
5470
5471 /*******************************************************************************
5472 **
5473 ** Function         bta_dm_close_gatt_conn
5474 **
5475 ** Description      This function close the GATT connection after delay timeout.
5476 **
5477 ** Parameters:
5478 **
5479 *******************************************************************************/
5480 void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data)
5481 {
5482     UNUSED(p_data);
5483
5484     if (bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID)
5485         BTA_GATTC_Close(bta_dm_search_cb.conn_id);
5486
5487     memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
5488     bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
5489 }
5490 /*******************************************************************************
5491 **
5492 ** Function         btm_dm_start_gatt_discovery
5493 **
5494 ** Description      This is GATT initiate the service search by open a GATT connection
5495 **                  first.
5496 **
5497 ** Parameters:
5498 **
5499 *******************************************************************************/
5500 void btm_dm_start_gatt_discovery (BD_ADDR bd_addr)
5501 {
5502     bta_dm_search_cb.gatt_disc_active = TRUE;
5503
5504     /* connection is already open */
5505     if (bdcmp(bta_dm_search_cb.pending_close_bda, bd_addr) == 0 &&
5506         bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID)
5507     {
5508         memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
5509         alarm_cancel(bta_dm_search_cb.gatt_close_timer);
5510         btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
5511     }
5512     else
5513         BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE, BTA_GATT_TRANSPORT_LE);
5514 }
5515
5516 /*******************************************************************************
5517 **
5518 ** Function         bta_dm_cancel_gatt_discovery
5519 **
5520 ** Description      This is GATT cancel the GATT service search.
5521 **
5522 ** Parameters:
5523 **
5524 *******************************************************************************/
5525 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr)
5526 {
5527     if (bta_dm_search_cb.conn_id == BTA_GATT_INVALID_CONN_ID)
5528     {
5529         BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, TRUE);
5530     }
5531
5532     bta_dm_gatt_disc_complete(bta_dm_search_cb.conn_id, (tBTA_GATT_STATUS) BTA_GATT_ERROR);
5533 }
5534
5535 /*******************************************************************************
5536 **
5537 ** Function         bta_dm_proc_open_evt
5538 **
5539 ** Description      process BTA_GATTC_OPEN_EVT in DM.
5540 **
5541 ** Parameters:
5542 **
5543 *******************************************************************************/
5544 void bta_dm_proc_open_evt(tBTA_GATTC_OPEN *p_data)
5545 {
5546     UINT8           *p1;
5547     UINT8           *p2;
5548
5549     p1 = bta_dm_search_cb.peer_bdaddr;
5550     p2 = p_data->remote_bda;
5551
5552     APPL_TRACE_DEBUG("DM Search state= %d search_cb.peer_dbaddr: [%08x%04x] connected_bda= [%08x%04x] ",
5553                       bta_dm_search_cb.state,
5554                       ((p1[0])<<24)+((p1[1])<<16)+((p1[2])<<8)+(p1[3]),
5555                       ((p1[4])<<8)+ p1[5],
5556                       ((p2[0])<<24)+((p2[1])<<16)+((p2[2])<<8)+(p2[3]),
5557                       ((p2[4])<<8)+ p2[5]);
5558
5559     APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d" ,
5560                       p_data->conn_id,
5561                       p_data->client_if,
5562                       p_data->status);
5563
5564     bta_dm_search_cb.conn_id = p_data->conn_id;
5565
5566     if (p_data->status == BTA_GATT_OK)
5567     {
5568         btm_dm_start_disc_gatt_services(p_data->conn_id);
5569     }
5570     else
5571     {
5572         bta_dm_gatt_disc_complete(BTA_GATT_INVALID_CONN_ID, p_data->status);
5573     }
5574 }
5575
5576 /*******************************************************************************
5577 **
5578 ** Function         bta_dm_gattc_callback
5579 **
5580 ** Description      This is GATT client callback function used in DM.
5581 **
5582 ** Parameters:
5583 **
5584 *******************************************************************************/
5585 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
5586 {
5587     APPL_TRACE_DEBUG("bta_dm_gattc_callback event = %d", event);
5588
5589     switch (event)
5590     {
5591         case BTA_GATTC_REG_EVT:
5592             APPL_TRACE_DEBUG("BTA_GATTC_REG_EVT client_if = %d",  p_data->reg_oper.client_if);
5593             if (p_data->reg_oper.status == BTA_GATT_OK)
5594                 bta_dm_search_cb.client_if = p_data->reg_oper.client_if;
5595             else
5596                 bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF;
5597             break;
5598
5599         case BTA_GATTC_OPEN_EVT:
5600             bta_dm_proc_open_evt(&p_data->open);
5601             break;
5602
5603         case BTA_GATTC_SEARCH_RES_EVT:
5604             bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid);
5605             break;
5606
5607         case BTA_GATTC_SEARCH_CMPL_EVT:
5608             if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE)
5609                 bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
5610             break;
5611
5612         case BTA_GATTC_CLOSE_EVT:
5613             APPL_TRACE_DEBUG("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason);
5614             /* in case of disconnect before search is completed */
5615             if ( (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) &&
5616                  (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) &&
5617                  !memcmp(p_data->close.remote_bda, bta_dm_search_cb.peer_bdaddr, BD_ADDR_LEN))
5618             {
5619                 bta_dm_gatt_disc_complete((UINT16)BTA_GATT_INVALID_CONN_ID,  (tBTA_GATT_STATUS) BTA_GATT_ERROR);
5620             }
5621             break;
5622
5623         default:
5624             break;
5625     }
5626 }
5627
5628 #endif /* BTA_GATT_INCLUDED */
5629
5630 #if BLE_VND_INCLUDED == TRUE
5631 /*******************************************************************************
5632 **
5633 ** Function         bta_dm_ctrl_features_rd_cmpl_cback
5634 **
5635 ** Description      callback to handle controller feature read complete
5636 **
5637 ** Parameters:
5638 **
5639 *******************************************************************************/
5640 static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result)
5641 {
5642     APPL_TRACE_DEBUG("%s  status = %d ", __FUNCTION__, result);
5643     if (result == BTM_SUCCESS)
5644     {
5645         if(bta_dm_cb.p_sec_cback)
5646             bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
5647     }
5648     else
5649     {
5650         APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d",__FUNCTION__, result);
5651     }
5652
5653 }
5654 #endif /* BLE_VND_INCLUDED */
5655
5656 #endif  /* BLE_INCLUDED */