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