]> granicus.if.org Git - esp-idf/blob - components/bt/bluedroid/bta/dm/bta_dm_act.c
e0b1595a9e06e0497bb598dfb9b6bb85ca7cd69d
[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             p_sdp_rec = NULL;
1564             if ( bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID + 1) ) {
1565                 p_sdp_rec = SDP_FindServiceUUIDInDb(bta_dm_search_cb.p_sdp_db, &bta_dm_search_cb.uuid, p_sdp_rec);
1566                 if (p_sdp_rec && SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
1567                     bta_dm_search_cb.peer_scn = (UINT8) pe.params[0];
1568                     scn_found = TRUE;
1569                 }
1570             } else {
1571                 service = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1];
1572                 p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, service, p_sdp_rec);
1573             }
1574 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1575             /* finished with BR/EDR services, now we check the result for GATT based service UUID */
1576             if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID) {
1577                 if (bta_dm_search_cb.uuid_to_search != 0 && p_uuid != NULL) {
1578                     p_uuid +=  (bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search);
1579                     /* only support 16 bits UUID for now */
1580                     service = p_uuid->uu.uuid16;
1581                 }
1582                 /* all GATT based services */
1583                 do {
1584                     /* find a service record, report it */
1585                     p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db,
1586                                                     0, p_sdp_rec);
1587                     if (p_sdp_rec) {
1588                         if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) {
1589                             /* send result back to app now, one by one */
1590                             bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1591                             BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN));
1592                             result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
1593                             result.disc_ble_res.service.len = service_uuid.len;
1594                             result.disc_ble_res.service.uu.uuid16 = service_uuid.uu.uuid16;
1595
1596                             bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
1597                         }
1598                     }
1599
1600                     if (bta_dm_search_cb.uuid_to_search > 0) {
1601                         break;
1602                     }
1603
1604                 } while (p_sdp_rec);
1605             } else
1606 #endif
1607             {
1608                 /* SDP_DB_FULL means some records with the
1609                    required attributes were received */
1610                 if (((p_data->sdp_event.sdp_result == SDP_DB_FULL) &&
1611                         bta_dm_search_cb.services != BTA_ALL_SERVICE_MASK) ||
1612                         (p_sdp_rec != NULL)) {
1613                     if (service != UUID_SERVCLASS_PNP_INFORMATION && service != 0) {
1614                         UINT16 tmp_svc = 0xFFFF;
1615                         bta_dm_search_cb.services_found |=
1616                             (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index - 1));
1617                         tmp_svc = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1];
1618                         /* Add to the list of UUIDs */
1619                         sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]);
1620                         num_uuids++;
1621                     }
1622                 }
1623             }
1624
1625             if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK &&
1626                     bta_dm_search_cb.services_to_search == 0) {
1627 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1628                 if ( bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID &&
1629                         bta_dm_search_cb.uuid_to_search > 0) {
1630                     bta_dm_search_cb.uuid_to_search --;
1631                 }
1632
1633                 if (bta_dm_search_cb.uuid_to_search == 0 ||
1634                         bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID)
1635 #endif
1636                     bta_dm_search_cb.service_index++;
1637             } else { /* regular one service per search or PNP search */
1638                 break;
1639             }
1640         } while (bta_dm_search_cb.service_index <= BTA_MAX_SERVICE_ID);
1641
1642         APPL_TRACE_DEBUG("%s services_found = %04x", __FUNCTION__,
1643                          bta_dm_search_cb.services_found);
1644
1645         /* Collect the 128-bit services here and put them into the list */
1646         if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) {
1647             p_sdp_rec = NULL;
1648             do {
1649                 tBT_UUID temp_uuid;
1650                 /* find a service record, report it */
1651                 p_sdp_rec = SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec);
1652                 if (p_sdp_rec) {
1653                     if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid)) {
1654                         memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE);
1655                         num_uuids++;
1656                     }
1657                 }
1658             } while (p_sdp_rec);
1659         }
1660         /* if there are more services to search for */
1661         if (bta_dm_search_cb.services_to_search) {
1662             /* Free up the p_sdp_db before checking the next one */
1663             bta_dm_free_sdp_db(NULL);
1664             bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
1665         } else {
1666             /* callbacks */
1667             /* start next bd_addr if necessary */
1668
1669             BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1670
1671
1672             if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1673                 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1674                 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
1675                 p_msg->disc_result.result.disc_res.p_raw_data = NULL;
1676                 p_msg->disc_result.result.disc_res.raw_data_size = 0;
1677                 p_msg->disc_result.result.disc_res.num_uuids = num_uuids;
1678                 p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
1679                 if (num_uuids > 0) {
1680                     p_msg->disc_result.result.disc_res.p_uuid_list = (UINT8 *)osi_malloc(num_uuids * MAX_UUID_SIZE);
1681                     if (p_msg->disc_result.result.disc_res.p_uuid_list) {
1682                         memcpy(p_msg->disc_result.result.disc_res.p_uuid_list, uuid_list,
1683                                num_uuids * MAX_UUID_SIZE);
1684                     } else {
1685                         p_msg->disc_result.result.disc_res.num_uuids = 0;
1686                         APPL_TRACE_ERROR("%s: Unable to allocate memory for uuid_list", __func__);
1687                     }
1688                 }
1689                 //copy the raw_data to the discovery result  structure
1690                 //
1691
1692                 if (  bta_dm_search_cb.p_sdp_db != NULL && bta_dm_search_cb.p_sdp_db->raw_used != 0   &&
1693                         bta_dm_search_cb.p_sdp_db->raw_data != NULL) {
1694                     APPL_TRACE_DEBUG(
1695                         "%s raw_data used = 0x%x raw_data_ptr = %p", __func__,
1696                         bta_dm_search_cb.p_sdp_db->raw_used,
1697                         bta_dm_search_cb.p_sdp_db->raw_data);
1698
1699                     p_msg->disc_result.result.disc_res.p_raw_data = osi_malloc(bta_dm_search_cb.p_sdp_db->raw_used);
1700                     if ( NULL != p_msg->disc_result.result.disc_res.p_raw_data  ) {
1701                         memcpy(     p_msg->disc_result.result.disc_res.p_raw_data,
1702                                     bta_dm_search_cb.p_sdp_db->raw_data,
1703                                     bta_dm_search_cb.p_sdp_db->raw_used );
1704
1705                         p_msg->disc_result.result.disc_res.raw_data_size =
1706                             bta_dm_search_cb.p_sdp_db->raw_used;
1707
1708                     } else {
1709                         APPL_TRACE_DEBUG("%s Alloc failed to allocate %d bytes !!", __func__,
1710                                          bta_dm_search_cb.p_sdp_db->raw_used);
1711                     }
1712
1713                     bta_dm_search_cb.p_sdp_db->raw_data = NULL;     //no need to free this - it is a global assigned.
1714                     bta_dm_search_cb.p_sdp_db->raw_used = 0;
1715                     bta_dm_search_cb.p_sdp_db->raw_size = 0;
1716                 } else {
1717                     APPL_TRACE_DEBUG("%s raw data size is 0 or raw_data is null!!", __func__);
1718                 }
1719                 /* Done with p_sdp_db. Free it */
1720                 bta_dm_free_sdp_db(NULL);
1721                 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
1722
1723                 //Piggy back the SCN over result field
1724                 if ( scn_found ) {
1725                     p_msg->disc_result.result.disc_res.result = (3 + bta_dm_search_cb.peer_scn);
1726                     p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK;
1727
1728                     APPL_TRACE_EVENT(" Piggy back the SCN over result field  SCN=%d", bta_dm_search_cb.peer_scn);
1729
1730                 }
1731                 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1732                 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
1733                               bta_dm_get_remname(), (BD_NAME_LEN - 1));
1734
1735                 /* make sure the string is null terminated */
1736                 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
1737
1738                 bta_sys_sendmsg(p_msg);
1739             }
1740         }
1741     } else {
1742         /* conn failed. No need for timer */
1743         if (p_data->sdp_event.sdp_result == SDP_CONN_FAILED || p_data->sdp_event.sdp_result == SDP_CONN_REJECTED
1744                 || p_data->sdp_event.sdp_result == SDP_SECURITY_ERR) {
1745             bta_dm_search_cb.wait_disc = FALSE;
1746         }
1747
1748         /* not able to connect go to next device */
1749         osi_free(bta_dm_search_cb.p_sdp_db);
1750         bta_dm_search_cb.p_sdp_db = NULL;
1751
1752         BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1753
1754         if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1755             p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1756             p_msg->disc_result.result.disc_res.result = BTA_FAILURE;
1757             p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
1758             bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1759             BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
1760                           bta_dm_get_remname(), (BD_NAME_LEN - 1));
1761
1762             /* make sure the string is null terminated */
1763             p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
1764
1765             bta_sys_sendmsg(p_msg);
1766         }
1767     }
1768 }
1769 #endif  ///SDP_INCLUDE == TRUE
1770
1771 /*******************************************************************************
1772 **
1773 ** Function         bta_dm_search_cmpl
1774 **
1775 ** Description      Sends event to application
1776 **
1777 ** Returns          void
1778 **
1779 *******************************************************************************/
1780 void bta_dm_search_cmpl (tBTA_DM_MSG *p_data)
1781 {
1782     APPL_TRACE_EVENT("%s", __func__);
1783
1784 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE)
1785     utl_freebuf((void **)&bta_dm_search_cb.p_srvc_uuid);
1786 #endif
1787
1788     if (p_data->hdr.layer_specific == BTA_DM_API_DI_DISCOVER_EVT) {
1789  #if (SDP_INCLUDED == TRUE)
1790         bta_dm_di_disc_cmpl(p_data);
1791  #endif ///SDP_INCLUDED == TRUE
1792     } else {
1793         bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, NULL);
1794     }
1795 }
1796
1797 /*******************************************************************************
1798 **
1799 ** Function         bta_dm_disc_result
1800 **
1801 ** Description      Service discovery result when discovering services on a device
1802 **
1803 ** Returns          void
1804 **
1805 *******************************************************************************/
1806 void bta_dm_disc_result (tBTA_DM_MSG *p_data)
1807 {
1808     APPL_TRACE_EVENT("%s", __func__);
1809
1810 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1811     /* if any BR/EDR service discovery has been done, report the event */
1812     if ((bta_dm_search_cb.services & ((BTA_ALL_SERVICE_MASK | BTA_USER_SERVICE_MASK ) & ~BTA_BLE_SERVICE_MASK)))
1813 #endif
1814         bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
1815
1816     tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
1817
1818     /* send a message to change state */
1819     if (p_msg != NULL) {
1820         p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1821         p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1822         bta_sys_sendmsg(p_msg);
1823     }
1824 }
1825
1826 /*******************************************************************************
1827 **
1828 ** Function         bta_dm_search_result
1829 **
1830 ** Description      Service discovery result while searching for devices
1831 **
1832 ** Returns          void
1833 **
1834 *******************************************************************************/
1835 void bta_dm_search_result (tBTA_DM_MSG *p_data)
1836 {
1837     APPL_TRACE_DEBUG("%s searching:0x%04x, result:0x%04x", __func__,
1838                      bta_dm_search_cb.services,
1839                      p_data->disc_result.result.disc_res.services);
1840
1841     /* call back if application wants name discovery or found services that application is searching */
1842     if (( !bta_dm_search_cb.services )
1843             || (( bta_dm_search_cb.services ) && ( p_data->disc_result.result.disc_res.services ))) {
1844         bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
1845     }
1846
1847     /* if searching did not initiate to create link */
1848     if (!bta_dm_search_cb.wait_disc ) {
1849         /* if service searching is done with EIR, don't search next device */
1850         if ( bta_dm_search_cb.p_btm_inq_info ) {
1851             bta_dm_discover_next_device();
1852         }
1853     } else {
1854         /* wait until link is disconnected or timeout */
1855         bta_dm_search_cb.sdp_results = TRUE;
1856         bta_dm_search_cb.search_timer.p_cback = (TIMER_CBACK *)&bta_dm_search_timer_cback;
1857         bta_sys_start_timer(&bta_dm_search_cb.search_timer, 0, 1000 * (L2CAP_LINK_INACTIVITY_TOUT + 1) );
1858     }
1859
1860 }
1861
1862 /*******************************************************************************
1863 **
1864 ** Function         bta_dm_search_timer_cback
1865 **
1866 ** Description      Called when ACL disconnect time is over
1867 **
1868 **
1869 ** Returns          void
1870 **
1871 *******************************************************************************/
1872 static void bta_dm_search_timer_cback (TIMER_LIST_ENT *p_tle)
1873 {
1874     UNUSED(p_tle);
1875
1876     APPL_TRACE_EVENT("%s", __func__);
1877     bta_dm_search_cb.wait_disc = FALSE;
1878
1879     /* proceed with next device */
1880     bta_dm_discover_next_device();
1881
1882 }
1883
1884
1885 /*******************************************************************************
1886 **
1887 ** Function         bta_dm_free_sdp_db
1888 **
1889 ** Description      Frees SDP data base
1890 **
1891 ** Returns          void
1892 **
1893 *******************************************************************************/
1894 #if (SDP_INCLUDED == TRUE)
1895 void bta_dm_free_sdp_db (tBTA_DM_MSG *p_data)
1896 {
1897     UNUSED(p_data);
1898     if (bta_dm_search_cb.p_sdp_db) {
1899         osi_free(bta_dm_search_cb.p_sdp_db);
1900         bta_dm_search_cb.p_sdp_db = NULL;
1901     }
1902 }
1903 #endif  ///SDP_INCLUDED == TRUE
1904
1905 /*******************************************************************************
1906 **
1907 ** Function         bta_dm_queue_search
1908 **
1909 ** Description      Queues search command while search is being cancelled
1910 **
1911 ** Returns          void
1912 **
1913 *******************************************************************************/
1914 void bta_dm_queue_search (tBTA_DM_MSG *p_data)
1915 {
1916     if (bta_dm_search_cb.p_search_queue) {
1917         osi_free(bta_dm_search_cb.p_search_queue);
1918     }
1919
1920     bta_dm_search_cb.p_search_queue = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_SEARCH));
1921     memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_SEARCH));
1922
1923 }
1924
1925 /*******************************************************************************
1926 **
1927 ** Function         bta_dm_queue_disc
1928 **
1929 ** Description      Queues discovery command while search is being cancelled
1930 **
1931 ** Returns          void
1932 **
1933 *******************************************************************************/
1934 #if (SDP_INCLUDED == TRUE)
1935 void bta_dm_queue_disc (tBTA_DM_MSG *p_data)
1936 {
1937     if (bta_dm_search_cb.p_search_queue) {
1938         osi_free(bta_dm_search_cb.p_search_queue);
1939     }
1940
1941     bta_dm_search_cb.p_search_queue = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_DISCOVER));
1942     memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_DISCOVER));
1943 }
1944 #endif  ///SDP_INCLUDED == TRUE
1945
1946 /*******************************************************************************
1947 **
1948 ** Function         bta_dm_search_clear_queue
1949 **
1950 ** Description      Clears the queue if API search cancel is called
1951 **
1952 ** Returns          void
1953 **
1954 *******************************************************************************/
1955 void bta_dm_search_clear_queue (tBTA_DM_MSG *p_data)
1956 {
1957     UNUSED(p_data);
1958     if (bta_dm_search_cb.p_search_queue) {
1959         osi_free(bta_dm_search_cb.p_search_queue);
1960         bta_dm_search_cb.p_search_queue = NULL;
1961     }
1962 }
1963
1964 /*******************************************************************************
1965 **
1966 ** Function         bta_dm_search_cancel_cmpl
1967 **
1968 ** Description      Search cancel is complete
1969 **
1970 ** Returns          void
1971 **
1972 *******************************************************************************/
1973 void bta_dm_search_cancel_cmpl (tBTA_DM_MSG *p_data)
1974 {
1975     UNUSED(p_data);
1976     if (bta_dm_search_cb.p_search_queue) {
1977         bta_sys_sendmsg(bta_dm_search_cb.p_search_queue);
1978         bta_dm_search_cb.p_search_queue = NULL;
1979     }
1980
1981 }
1982
1983 /*******************************************************************************
1984 **
1985 ** Function         bta_dm_search_cancel_transac_cmpl
1986 **
1987 ** Description      Current Service Discovery or remote name procedure is
1988 **                  completed after search cancellation
1989 **
1990 ** Returns          void
1991 **
1992 *******************************************************************************/
1993 #if (SDP_INCLUDED == TRUE)
1994 void bta_dm_search_cancel_transac_cmpl(tBTA_DM_MSG *p_data)
1995 {
1996     UNUSED(p_data);
1997     if (bta_dm_search_cb.p_sdp_db) {
1998         osi_free(bta_dm_search_cb.p_sdp_db);
1999         bta_dm_search_cb.p_sdp_db = NULL;
2000     }
2001
2002     bta_dm_search_cancel_notify(NULL);
2003 }
2004 #endif  ///SDP_INCLUDED == TRUE
2005
2006
2007 /*******************************************************************************
2008 **
2009 ** Function         bta_dm_search_cancel_notify
2010 **
2011 ** Description      Notify application that search has been cancelled
2012 **
2013 ** Returns          void
2014 **
2015 *******************************************************************************/
2016 void bta_dm_search_cancel_notify (tBTA_DM_MSG *p_data)
2017 {
2018     UNUSED(p_data);
2019     if (bta_dm_search_cb.p_search_cback) {
2020         bta_dm_search_cb.p_search_cback(BTA_DM_SEARCH_CANCEL_CMPL_EVT, NULL);
2021     }
2022     if (!bta_dm_search_cb.name_discover_done) {
2023         BTM_CancelRemoteDeviceName();
2024     }
2025 #if (BLE_INCLUDED == TRUE) && (BTA_GATT_INCLUDED == TRUE) && (SDP_INCLUDED == TRUE) && (GATTC_INCLUDED) == TRUE
2026     if (bta_dm_search_cb.gatt_disc_active) {
2027         bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
2028     }
2029 #endif
2030
2031 }
2032
2033 /*******************************************************************************
2034 **
2035 ** Function         bta_dm_find_services
2036 **
2037 ** Description      Starts discovery on a device
2038 **
2039 ** Returns          void
2040 **
2041 *******************************************************************************/
2042 #if (SDP_INCLUDED == TRUE)
2043 static void bta_dm_find_services ( BD_ADDR bd_addr)
2044 {
2045     tSDP_UUID    uuid;
2046     tBTA_DM_MSG *p_msg;
2047
2048     memset (&uuid, 0, sizeof(tSDP_UUID));
2049
2050     while (bta_dm_search_cb.service_index < BTA_MAX_SERVICE_ID) {
2051         tBTA_SERVICE_MASK this_service_mask = (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index));
2052         if ( bta_dm_search_cb.services_to_search & this_service_mask) {
2053             if ((bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(BTA_DM_SDP_DB_SIZE)) != NULL) {
2054                 APPL_TRACE_DEBUG("bta_dm_search_cb.services = %04x***********", bta_dm_search_cb.services);
2055                 /* try to search all services by search based on L2CAP UUID */
2056                 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK ) {
2057                     APPL_TRACE_DEBUG("%s services_to_search=%08x", __func__, bta_dm_search_cb.services_to_search);
2058                     if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK) {
2059                         uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[0];
2060                         bta_dm_search_cb.services_to_search &= ~BTA_RES_SERVICE_MASK;
2061                     } else {
2062                         uuid.uu.uuid16 = UUID_PROTOCOL_L2CAP;
2063                         bta_dm_search_cb.services_to_search = 0;
2064                     }
2065                 } else {
2066 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
2067                     /* for LE only profile */
2068                     if (this_service_mask == BTA_BLE_SERVICE_MASK) {
2069                         if (bta_dm_search_cb.uuid_to_search > 0 && bta_dm_search_cb.p_srvc_uuid) {
2070                             memcpy(&uuid,
2071                                    (const void *)(bta_dm_search_cb.p_srvc_uuid + \
2072                                                   bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search),
2073                                    sizeof(tBT_UUID));
2074
2075                             bta_dm_search_cb.uuid_to_search -- ;
2076                         } else {
2077                             uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index];
2078                         }
2079
2080                         /* last one? clear the BLE service bit if all discovery has been done */
2081                         if (bta_dm_search_cb.uuid_to_search == 0)
2082                             bta_dm_search_cb.services_to_search &=
2083                                 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
2084
2085                     } else
2086 #endif
2087                     {
2088                         /* remove the service from services to be searched  */
2089                         bta_dm_search_cb.services_to_search &=
2090                             (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
2091                         uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index];
2092                     }
2093                 }
2094
2095                 if (uuid.len == 0) {
2096                     uuid.len = LEN_UUID_16;
2097                 }
2098
2099                 if (this_service_mask == BTA_USER_SERVICE_MASK) {
2100                     memcpy(&uuid, &bta_dm_search_cb.uuid, sizeof(tSDP_UUID));
2101                 }
2102
2103                 APPL_TRACE_DEBUG("%s search UUID = %04x", __func__, uuid.uu.uuid16);
2104                 SDP_InitDiscoveryDb (bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1, &uuid, 0, NULL);
2105
2106                 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
2107                 bta_dm_search_cb.p_sdp_db->raw_data = g_disc_raw_data_buf;
2108
2109                 bta_dm_search_cb.p_sdp_db->raw_size = MAX_DISC_RAW_DATA_BUF;
2110
2111                 if (!SDP_ServiceSearchAttributeRequest (bd_addr, bta_dm_search_cb.p_sdp_db, &bta_dm_sdp_callback)) {
2112                     /* if discovery not successful with this device
2113                     proceed to next one */
2114                     osi_free(bta_dm_search_cb.p_sdp_db);
2115                     bta_dm_search_cb.p_sdp_db = NULL;
2116                     bta_dm_search_cb.service_index = BTA_MAX_SERVICE_ID;
2117
2118                 } else {
2119 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
2120                     if ((this_service_mask == BTA_BLE_SERVICE_MASK &&
2121                             bta_dm_search_cb.uuid_to_search == 0) ||
2122                             this_service_mask != BTA_BLE_SERVICE_MASK)
2123 #endif
2124                         bta_dm_search_cb.service_index++;
2125                     return;
2126                 }
2127             } else {
2128                 APPL_TRACE_ERROR("#### Failed to allocate SDP DB buffer! ####");
2129             }
2130         }
2131
2132         bta_dm_search_cb.service_index++;
2133     }
2134
2135     /* no more services to be discovered */
2136     if (bta_dm_search_cb.service_index >= BTA_MAX_SERVICE_ID) {
2137         if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
2138             p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
2139             p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
2140             bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2141             BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
2142                           bta_dm_get_remname(), (BD_NAME_LEN - 1));
2143
2144             /* make sure the string is terminated */
2145             p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
2146
2147             bta_sys_sendmsg(p_msg);
2148         }
2149     }
2150 }
2151 #endif  ///SDP_INCLUDED == TRUE
2152
2153 /*******************************************************************************
2154 **
2155 ** Function         bta_dm_discover_next_device
2156 **
2157 ** Description      Starts discovery on the next device in Inquiry data base
2158 **
2159 ** Returns          void
2160 **
2161 *******************************************************************************/
2162 static void bta_dm_discover_next_device(void)
2163 {
2164
2165     tBTA_DM_MSG *p_msg;
2166
2167     APPL_TRACE_DEBUG("bta_dm_discover_next_device");
2168
2169     /* searching next device on inquiry result */
2170     if ((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbNext(bta_dm_search_cb.p_btm_inq_info)) != NULL) {
2171         bta_dm_search_cb.name_discover_done = FALSE;
2172         bta_dm_search_cb.peer_name[0]       = 0;
2173 #if (SDP_INCLUDED == TRUE)
2174         bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
2175 #endif  ///SDP_INCLUDED == TRUE
2176     } else {
2177         /* no devices, search complete */
2178         bta_dm_search_cb.services = 0;
2179
2180         if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
2181             p_msg->hdr.event          = BTA_DM_SEARCH_CMPL_EVT;
2182             p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
2183             bta_sys_sendmsg(p_msg);
2184         }
2185     }
2186 }
2187
2188 /*******************************************************************************
2189 **
2190 ** Function         bta_dm_discover_device
2191 **
2192 ** Description      Starts name and service discovery on the device
2193 **
2194 ** Returns          void
2195 **
2196 *******************************************************************************/
2197 #if (SDP_INCLUDED == TRUE)
2198 static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
2199 {
2200     tBTA_DM_MSG *p_msg;
2201     tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
2202
2203 #if BLE_INCLUDED == TRUE
2204     if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN) {
2205         tBT_DEVICE_TYPE dev_type;
2206         tBLE_ADDR_TYPE  addr_type;
2207
2208         BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
2209         if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM) {
2210             transport = BT_TRANSPORT_LE;
2211         }
2212     } else {
2213         transport = bta_dm_search_cb.transport;
2214     }
2215 #endif
2216
2217     /* Reset transport state for next discovery */
2218     bta_dm_search_cb.transport = BTA_TRANSPORT_UNKNOWN;
2219
2220     APPL_TRACE_DEBUG("%s BDA:0x%02X%02X%02X%02X%02X%02X", __func__,
2221                      remote_bd_addr[0], remote_bd_addr[1],
2222                      remote_bd_addr[2], remote_bd_addr[3],
2223                      remote_bd_addr[4], remote_bd_addr[5]);
2224
2225     bdcpy(bta_dm_search_cb.peer_bdaddr, remote_bd_addr);
2226
2227     APPL_TRACE_DEBUG("%s name_discover_done = %d p_btm_inq_info %p state = %d, transport=%d",
2228                      __func__,
2229                      bta_dm_search_cb.name_discover_done,
2230                      bta_dm_search_cb.p_btm_inq_info,
2231                      bta_dm_search_cb.state,
2232                      transport);
2233
2234     if (bta_dm_search_cb.p_btm_inq_info) {
2235         APPL_TRACE_DEBUG("%s appl_knows_rem_name %d", __func__,
2236                          bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name);
2237     }
2238
2239     if ((bta_dm_search_cb.p_btm_inq_info)
2240             && (bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE)
2241             && (bta_dm_search_cb.state == BTA_DM_SEARCH_ACTIVE)) {
2242         /* Do not perform RNR for LE devices at inquiry complete*/
2243         bta_dm_search_cb.name_discover_done = TRUE;
2244     }
2245
2246     /* if name discovery is not done and application needs remote name */
2247     if ((!bta_dm_search_cb.name_discover_done)
2248             && (( bta_dm_search_cb.p_btm_inq_info == NULL )
2249                 || (bta_dm_search_cb.p_btm_inq_info && (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name)))) {
2250         if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport) == TRUE) {
2251             return;
2252         }
2253
2254         /* starting name discovery failed */
2255         bta_dm_search_cb.name_discover_done = TRUE;
2256     }
2257
2258     /* if application wants to discover service */
2259     if ( bta_dm_search_cb.services ) {
2260         /* initialize variables */
2261         bta_dm_search_cb.service_index      = 0;
2262         bta_dm_search_cb.services_found     = 0;
2263         bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
2264 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE
2265         bta_dm_search_cb.uuid_to_search     = bta_dm_search_cb.num_uuid;
2266 #endif
2267         if ((bta_dm_search_cb.p_btm_inq_info != NULL) &&
2268                 bta_dm_search_cb.services != BTA_USER_SERVICE_MASK
2269                 && (bta_dm_search_cb.sdp_search == FALSE)) {
2270             /* check if EIR provides the information of supported services */
2271             bta_dm_eir_search_services( &bta_dm_search_cb.p_btm_inq_info->results,
2272                                         &bta_dm_search_cb.services_to_search,
2273                                         &bta_dm_search_cb.services_found );
2274         }
2275
2276         /* if seaching with EIR is not completed */
2277         if (bta_dm_search_cb.services_to_search) {
2278             /* check whether connection already exists to the device
2279                if connection exists, we don't have to wait for ACL
2280                link to go down to start search on next device */
2281             if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR)) {
2282                 bta_dm_search_cb.wait_disc = FALSE;
2283             } else {
2284                 bta_dm_search_cb.wait_disc = TRUE;
2285             }
2286
2287 #if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE)
2288             if ( bta_dm_search_cb.p_btm_inq_info ) {
2289                 APPL_TRACE_DEBUG("%s p_btm_inq_info %p results.device_type 0x%x services_to_search 0x%x",
2290                                  __func__,
2291                                  bta_dm_search_cb.p_btm_inq_info,
2292                                  bta_dm_search_cb.p_btm_inq_info->results.device_type,
2293                                  bta_dm_search_cb.services_to_search);
2294             }
2295
2296             if (transport == BT_TRANSPORT_LE) {
2297                 if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK) {
2298                     //set the raw data buffer here
2299                     memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
2300                     bta_dm_search_cb.p_ble_rawdata = g_disc_raw_data_buf;
2301
2302                     bta_dm_search_cb.ble_raw_size = MAX_DISC_RAW_DATA_BUF;
2303                     bta_dm_search_cb.ble_raw_used = 0;
2304
2305                     /* start GATT for service discovery */
2306                     btm_dm_start_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
2307                     return;
2308                 }
2309             } else
2310 #endif
2311             {
2312                 bta_dm_search_cb.sdp_results = FALSE;
2313                 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
2314                 return;
2315             }
2316         }
2317     }
2318
2319     /* name discovery and service discovery are done for this device */
2320     if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
2321         p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
2322         /* initialize the data structure - includes p_raw_data and raw_data_size */
2323         memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES));
2324         p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
2325         p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
2326         bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2327         BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name,  sizeof(BD_NAME),
2328                       (char *)bta_dm_search_cb.peer_name, (BD_NAME_LEN - 1));
2329
2330         /* make sure the string is terminated */
2331         p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
2332
2333         bta_sys_sendmsg(p_msg);
2334     }
2335 }
2336
2337 /*******************************************************************************
2338 **
2339 ** Function         bta_dm_sdp_callback
2340 **
2341 ** Description      Callback from sdp with discovery status
2342 **
2343 ** Returns          void
2344 **
2345 *******************************************************************************/
2346 static void bta_dm_sdp_callback (UINT16 sdp_status)
2347 {
2348
2349     tBTA_DM_SDP_RESULT *p_msg;
2350
2351     if ((p_msg = (tBTA_DM_SDP_RESULT *) osi_malloc(sizeof(tBTA_DM_SDP_RESULT))) != NULL) {
2352         p_msg->hdr.event = BTA_DM_SDP_RESULT_EVT;
2353         p_msg->sdp_result = sdp_status;
2354         bta_sys_sendmsg(p_msg);
2355
2356     }
2357 }
2358 #endif  ///SDP_INCLUDED == TRUE
2359 /*******************************************************************************
2360 **
2361 ** Function         bta_dm_inq_results_cb
2362 **
2363 ** Description      Inquiry results callback from BTM
2364 **
2365 ** Returns          void
2366 **
2367 *******************************************************************************/
2368 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
2369 {
2370
2371     tBTA_DM_SEARCH     result;
2372     tBTM_INQ_INFO      *p_inq_info;
2373     UINT16             service_class;
2374
2375     bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
2376     memcpy(result.inq_res.dev_class, p_inq->dev_class, DEV_CLASS_LEN);
2377     BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class);
2378     result.inq_res.is_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? TRUE : FALSE;
2379     result.inq_res.rssi = p_inq->rssi;
2380
2381 #if (BLE_INCLUDED == TRUE)
2382     result.inq_res.ble_addr_type    = p_inq->ble_addr_type;
2383     result.inq_res.inq_result_type  = p_inq->inq_result_type;
2384     result.inq_res.device_type      = p_inq->device_type;
2385     result.inq_res.flag             = p_inq->flag;
2386 #endif
2387
2388     /* application will parse EIR to find out remote device name */
2389     result.inq_res.p_eir = p_eir;
2390
2391     if ((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL) {
2392         /* initialize remt_name_not_required to FALSE so that we get the name by default */
2393         result.inq_res.remt_name_not_required = FALSE;
2394
2395     }
2396
2397     if (bta_dm_search_cb.p_search_cback) {
2398         bta_dm_search_cb.p_search_cback(BTA_DM_INQ_RES_EVT, &result);
2399     }
2400
2401     if (p_inq_info) {
2402         /* application indicates if it knows the remote name, inside the callback
2403          copy that to the inquiry data base*/
2404         if (result.inq_res.remt_name_not_required) {
2405             p_inq_info->appl_knows_rem_name = TRUE;
2406         }
2407
2408     }
2409
2410
2411 }
2412
2413
2414 /*******************************************************************************
2415 **
2416 ** Function         bta_dm_inq_cmpl_cb
2417 **
2418 ** Description      Inquiry complete callback from BTM
2419 **
2420 ** Returns          void
2421 **
2422 *******************************************************************************/
2423 static void bta_dm_inq_cmpl_cb (void *p_result)
2424 {
2425     tBTA_DM_MSG *p_msg;
2426
2427     if (bta_dm_search_cb.cancel_pending == FALSE) {
2428         APPL_TRACE_DEBUG("%s", __FUNCTION__);
2429         p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
2430         if (p_msg != NULL) {
2431             p_msg->inq_cmpl.hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
2432             p_msg->inq_cmpl.num = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
2433             bta_sys_sendmsg(p_msg);
2434         }
2435     } else {
2436         bta_dm_search_cb.cancel_pending = FALSE;
2437         bta_dm_search_cancel_notify(NULL);
2438
2439         p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
2440         if (p_msg != NULL) {
2441             p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
2442             p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
2443             bta_sys_sendmsg(p_msg);
2444         }
2445     }
2446 }
2447
2448 /*******************************************************************************
2449 **
2450 ** Function         bta_dm_service_search_remname_cback
2451 **
2452 ** Description      Remote name call back from BTM during service discovery
2453 **
2454 ** Returns          void
2455 **
2456 *******************************************************************************/
2457 static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, BD_NAME bd_name)
2458 {
2459     tBTM_REMOTE_DEV_NAME    rem_name;
2460     tBTM_STATUS             btm_status;
2461     UNUSED(dc);
2462
2463     APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback name=<%s>", bd_name);
2464
2465     /* if this is what we are looking for */
2466     if (!bdcmp( bta_dm_search_cb.peer_bdaddr, bd_addr)) {
2467         rem_name.length = strlen((char *)bd_name);
2468         if (rem_name.length > (BD_NAME_LEN - 1)) {
2469             rem_name.length = (BD_NAME_LEN - 1);
2470             rem_name.remote_bd_name[(BD_NAME_LEN - 1)] = 0;
2471         }
2472         BCM_STRNCPY_S((char *)rem_name.remote_bd_name,  sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
2473         rem_name.status = BTM_SUCCESS;
2474
2475         bta_dm_remname_cback(&rem_name);
2476     } else {
2477         /* get name of device */
2478         btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
2479                                                (tBTM_CMPL_CB *) bta_dm_remname_cback,
2480                                                BT_TRANSPORT_BR_EDR);
2481         if ( btm_status == BTM_BUSY ) {
2482             /* wait for next chance(notification of remote name discovery done) */
2483             APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName is busy");
2484         } else if ( btm_status != BTM_CMD_STARTED ) {
2485             /* if failed to start getting remote name then continue */
2486             APPL_TRACE_WARNING("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
2487
2488             rem_name.length = 0;
2489             rem_name.remote_bd_name[0] = 0;
2490             rem_name.status = btm_status;
2491             bta_dm_remname_cback(&rem_name);
2492         }
2493     }
2494 }
2495
2496
2497 /*******************************************************************************
2498 **
2499 ** Function         bta_dm_remname_cback
2500 **
2501 ** Description      Remote name complete call back from BTM
2502 **
2503 ** Returns          void
2504 **
2505 *******************************************************************************/
2506 static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
2507 {
2508     tBTA_DM_REM_NAME *p_msg;
2509
2510     APPL_TRACE_DEBUG("bta_dm_remname_cback len = %d name=<%s>", p_remote_name->length,
2511                      p_remote_name->remote_bd_name);
2512
2513     /* remote name discovery is done but it could be failed */
2514     bta_dm_search_cb.name_discover_done = TRUE;
2515     BCM_STRNCPY_S((char *)bta_dm_search_cb.peer_name, sizeof(BD_NAME), (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
2516     bta_dm_search_cb.peer_name[BD_NAME_LEN] = 0;
2517
2518     BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
2519
2520 #if BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE
2521     if (bta_dm_search_cb.transport == BT_TRANSPORT_LE ) {
2522         GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
2523     }
2524 #endif
2525
2526     if ((p_msg = (tBTA_DM_REM_NAME *) osi_malloc(sizeof(tBTA_DM_REM_NAME))) != NULL) {
2527         bdcpy (p_msg->result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2528         BCM_STRNCPY_S((char *)p_msg->result.disc_res.bd_name, sizeof(BD_NAME), (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
2529
2530         /* make sure the string is null terminated */
2531         p_msg->result.disc_res.bd_name[BD_NAME_LEN] = 0;
2532
2533         p_msg->hdr.event = BTA_DM_REMT_NAME_EVT;
2534         bta_sys_sendmsg(p_msg);
2535
2536     }
2537 }
2538
2539 /*******************************************************************************
2540 **
2541 ** Function         bta_dm_authorize_cback
2542 **
2543 ** Description      cback requesting authorization
2544 **
2545 ** Returns          void
2546 **
2547 *******************************************************************************/
2548 #if (SMP_INCLUDED == TRUE)
2549 static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
2550                                      UINT8 *service_name, UINT8 service_id, BOOLEAN is_originator)
2551 {
2552     tBTA_DM_SEC sec_event;
2553     UINT8       index = 1;
2554     UNUSED(service_name);
2555     UNUSED(is_originator);
2556
2557     bdcpy(sec_event.authorize.bd_addr, bd_addr);
2558     memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN);
2559
2560     BCM_STRNCPY_S((char *)sec_event.authorize.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
2561
2562     /* make sure the string is null terminated */
2563     sec_event.authorize.bd_name[BD_NAME_LEN - 1] = 0;
2564
2565 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
2566     sec_event.authorize.service = service_id;
2567 #endif
2568
2569     while (index < BTA_MAX_SERVICE_ID) {
2570         /* get the BTA service id corresponding to BTM id */
2571         if (bta_service_id_to_btm_srv_id_lkup_tbl[index] == service_id) {
2572             sec_event.authorize.service = index;
2573             break;
2574         }
2575         index++;
2576     }
2577
2578
2579     /* if supported service callback otherwise not authorized */
2580     if (bta_dm_cb.p_sec_cback && (index < BTA_MAX_SERVICE_ID
2581 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
2582                                   /* pass through JV service ID */
2583                                   || (service_id >= BTA_FIRST_JV_SERVICE_ID && service_id <= BTA_LAST_JV_SERVICE_ID)
2584 #endif
2585                                  )) {
2586         bta_dm_cb.p_sec_cback(BTA_DM_AUTHORIZE_EVT, &sec_event);
2587         return BTM_CMD_STARTED;
2588     } else {
2589         return BTM_NOT_AUTHORIZED;
2590     }
2591 }
2592  
2593
2594
2595
2596 /*******************************************************************************
2597 **
2598 ** Function         bta_dm_pinname_cback
2599 **
2600 ** Description      Callback requesting pin_key
2601 **
2602 ** Returns          void
2603 **
2604 *******************************************************************************/
2605  static void bta_dm_pinname_cback (void *p_data)
2606 {
2607     tBTM_REMOTE_DEV_NAME *p_result = (tBTM_REMOTE_DEV_NAME *)p_data;
2608     tBTA_DM_SEC           sec_event;
2609     UINT32                bytes_to_copy;
2610     tBTA_DM_SEC_EVT       event = bta_dm_cb.pin_evt;
2611
2612     if (BTA_DM_SP_CFM_REQ_EVT == event) {
2613         /* Retrieved saved device class and bd_addr */
2614         bdcpy(sec_event.cfm_req.bd_addr, bta_dm_cb.pin_bd_addr);
2615         BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_cb.pin_dev_class);
2616
2617         if (p_result && p_result->status == BTM_SUCCESS) {
2618             bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1))
2619                             ? p_result->length : (BD_NAME_LEN - 1);
2620             memcpy(sec_event.cfm_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
2621             sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2622         } else { /* No name found */
2623             sec_event.cfm_req.bd_name[0] = 0;
2624         }
2625
2626         sec_event.key_notif.passkey    = bta_dm_cb.num_val; /* get PIN code numeric number */
2627
2628         /* 1 additional event data fields for this event */
2629         sec_event.cfm_req.just_works = bta_dm_cb.just_works;
2630     } else {
2631         /* Retrieved saved device class and bd_addr */
2632         bdcpy(sec_event.pin_req.bd_addr, bta_dm_cb.pin_bd_addr);
2633         BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_cb.pin_dev_class);
2634
2635         if (p_result && p_result->status == BTM_SUCCESS) {
2636             bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1))
2637                             ? p_result->length : (BD_NAME_LEN - 1);
2638             memcpy(sec_event.pin_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
2639             sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2640         } else { /* No name found */
2641             sec_event.pin_req.bd_name[0] = 0;
2642         }
2643
2644         event = bta_dm_cb.pin_evt;
2645         sec_event.key_notif.passkey    = bta_dm_cb.num_val; /* get PIN code numeric number */
2646     }
2647
2648     if ( bta_dm_cb.p_sec_cback ) {
2649         bta_dm_cb.p_sec_cback(event, &sec_event);
2650     }
2651 }
2652
2653 /*******************************************************************************
2654 **
2655 ** Function         bta_dm_pin_cback
2656 **
2657 ** Description      Callback requesting pin_key
2658 **
2659 ** Returns          void
2660 **
2661 *******************************************************************************/
2662 static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
2663                                BOOLEAN min_16_digit)
2664 {
2665     tBTA_DM_SEC sec_event;
2666
2667     if (!bta_dm_cb.p_sec_cback) {
2668         return BTM_NOT_AUTHORIZED;
2669     }
2670
2671     /* If the device name is not known, save bdaddr and devclass and initiate a name request */
2672     if (bd_name[0] == 0) {
2673         bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
2674         bdcpy(bta_dm_cb.pin_bd_addr, bd_addr);
2675         BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
2676         if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2677             return BTM_CMD_STARTED;
2678         }
2679
2680         APPL_TRACE_WARNING(" bta_dm_pin_cback() -> Failed to start Remote Name Request  ");
2681     }
2682
2683     bdcpy(sec_event.pin_req.bd_addr, bd_addr);
2684     BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
2685     BCM_STRNCPY_S((char *)sec_event.pin_req.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
2686     sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2687     sec_event.pin_req.min_16_digit = min_16_digit;
2688
2689     bta_dm_cb.p_sec_cback(BTA_DM_PIN_REQ_EVT, &sec_event);
2690     return BTM_CMD_STARTED;
2691 }
2692
2693 /*******************************************************************************
2694 **
2695 ** Function         bta_dm_new_link_key_cback
2696 **
2697 ** Description      Callback from BTM to notify new link key
2698 **
2699 ** Returns          void
2700 **
2701 *******************************************************************************/
2702 static UINT8  bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
2703                                         BD_NAME bd_name, LINK_KEY key, UINT8 key_type)
2704 {
2705     tBTA_DM_SEC sec_event;
2706     tBTA_DM_AUTH_CMPL *p_auth_cmpl;
2707     UINT8             event;
2708     UNUSED(dev_class);
2709
2710     memset (&sec_event, 0, sizeof(tBTA_DM_SEC));
2711
2712     /* Not AMP Key type */
2713     if (key_type != HCI_LKEY_TYPE_AMP_WIFI && key_type != HCI_LKEY_TYPE_AMP_UWB) {
2714         event = BTA_DM_AUTH_CMPL_EVT;
2715         p_auth_cmpl = &sec_event.auth_cmpl;
2716
2717         bdcpy(p_auth_cmpl->bd_addr, bd_addr);
2718
2719         memcpy(p_auth_cmpl->bd_name, bd_name, (BD_NAME_LEN - 1));
2720         p_auth_cmpl->bd_name[BD_NAME_LEN - 1] = 0;
2721
2722         p_auth_cmpl->key_present = TRUE;
2723         p_auth_cmpl->key_type = key_type;
2724         p_auth_cmpl->success = TRUE;
2725
2726         memcpy(p_auth_cmpl->key, key, LINK_KEY_LEN);
2727         sec_event.auth_cmpl.fail_reason = HCI_SUCCESS;
2728
2729 #if BLE_INCLUDED == TRUE
2730         // Report the BR link key based on the BR/EDR address and type
2731         BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
2732 #endif
2733         if (bta_dm_cb.p_sec_cback) {
2734             bta_dm_cb.p_sec_cback(event, &sec_event);
2735         }
2736     } else {
2737         APPL_TRACE_WARNING("%s() Received AMP Key", __func__);
2738     }
2739
2740     return BTM_CMD_STARTED;
2741 }
2742
2743
2744 /*******************************************************************************
2745 **
2746 ** Function         bta_dm_authentication_complete_cback
2747 **
2748 ** Description      Authentication complete callback from BTM
2749 **
2750 ** Returns          void
2751 **
2752 *******************************************************************************/
2753 static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, int result)
2754 {
2755     tBTA_DM_SEC sec_event;
2756     UNUSED(dev_class);
2757
2758     if (result != BTM_SUCCESS) {
2759         memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
2760         bdcpy(sec_event.auth_cmpl.bd_addr, bd_addr);
2761
2762         memcpy(sec_event.auth_cmpl.bd_name, bd_name, (BD_NAME_LEN - 1));
2763         sec_event.auth_cmpl.bd_name[BD_NAME_LEN - 1] = 0;
2764
2765 #if BLE_INCLUDED == TRUE
2766         // Report the BR link key based on the BR/EDR address and type
2767         BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
2768 #endif
2769         sec_event.auth_cmpl.fail_reason = (UINT8)result;
2770
2771         if (bta_dm_cb.p_sec_cback) {
2772             bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
2773         }
2774
2775         bta_dm_remove_sec_dev_entry(bd_addr);
2776     }
2777
2778     return BTM_SUCCESS;
2779 }
2780
2781 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2782 /*******************************************************************************
2783 **
2784 ** Function         bta_dm_sp_cback
2785 **
2786 ** Description      simple pairing callback from BTM
2787 **
2788 ** Returns          void
2789 **
2790 *******************************************************************************/
2791 static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
2792 {
2793     tBTM_STATUS status = BTM_CMD_STARTED;
2794     tBTA_DM_SEC sec_event;
2795     tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT;
2796
2797     APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event);
2798     if (!bta_dm_cb.p_sec_cback) {
2799         return BTM_NOT_AUTHORIZED;
2800     }
2801
2802     /* TODO_SP */
2803     switch (event) {
2804     case BTM_SP_IO_REQ_EVT:
2805 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2806         /* translate auth_req */
2807         bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap,
2808                          &p_data->io_req.oob_data, &p_data->io_req.auth_req, p_data->io_req.is_orig);
2809 #endif
2810 #if BTM_OOB_INCLUDED == FALSE
2811         status = BTM_SUCCESS;
2812 #endif
2813
2814         APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
2815         break;
2816     case BTM_SP_IO_RSP_EVT:
2817 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2818         bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap,
2819                          p_data->io_rsp.oob_data, p_data->io_rsp.auth_req );
2820 #endif
2821         break;
2822
2823     case BTM_SP_CFM_REQ_EVT:
2824         pin_evt = BTA_DM_SP_CFM_REQ_EVT;
2825         bta_dm_cb.just_works = sec_event.cfm_req.just_works = p_data->cfm_req.just_works;
2826         sec_event.cfm_req.loc_auth_req = p_data->cfm_req.loc_auth_req;
2827         sec_event.cfm_req.rmt_auth_req = p_data->cfm_req.rmt_auth_req;
2828         sec_event.cfm_req.loc_io_caps = p_data->cfm_req.loc_io_caps;
2829         sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps;
2830
2831         /* continue to next case */
2832 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2833     /* Passkey entry mode, mobile device with output capability is very
2834         unlikely to receive key request, so skip this event */
2835     /*case BTM_SP_KEY_REQ_EVT: */
2836     case BTM_SP_KEY_NOTIF_EVT:
2837 #endif
2838         if (BTM_SP_CFM_REQ_EVT == event) {
2839             /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
2840                call remote name request using values from cfm_req */
2841             if (p_data->cfm_req.bd_name[0] == 0) {
2842                 bta_dm_cb.pin_evt = pin_evt;
2843                 bdcpy(bta_dm_cb.pin_bd_addr, p_data->cfm_req.bd_addr);
2844                 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class);
2845                 if ((BTM_ReadRemoteDeviceName(p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
2846                                               BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2847                     return BTM_CMD_STARTED;
2848                 }
2849                 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
2850             } else {
2851                 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
2852                    copy these values into key_notif from cfm_req */
2853                 bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
2854                 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class);
2855                 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
2856                               (char *)p_data->cfm_req.bd_name, (BD_NAME_LEN - 1));
2857                 sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
2858             }
2859         }
2860
2861         bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
2862         if (BTM_SP_KEY_NOTIF_EVT == event) {
2863             /* If the device name is not known, save bdaddr and devclass
2864                and initiate a name request with values from key_notif */
2865             if (p_data->key_notif.bd_name[0] == 0) {
2866                 bta_dm_cb.pin_evt = pin_evt;
2867                 bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
2868                 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
2869                 if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback,
2870                                               BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2871                     return BTM_CMD_STARTED;
2872                 }
2873                 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
2874             } else {
2875                 bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
2876                 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
2877                 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
2878                               (char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
2879                 sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
2880             }
2881         }
2882
2883         bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
2884
2885         break;
2886
2887 #if BTM_OOB_INCLUDED == TRUE
2888     case BTM_SP_LOC_OOB_EVT:
2889         bta_dm_co_loc_oob((BOOLEAN)(p_data->loc_oob.status == BTM_SUCCESS),
2890                           p_data->loc_oob.c, p_data->loc_oob.r);
2891         break;
2892
2893     case BTM_SP_RMT_OOB_EVT:
2894         /* If the device name is not known, save bdaddr and devclass and initiate a name request */
2895         if (p_data->rmt_oob.bd_name[0] == 0) {
2896             bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
2897             bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
2898             BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class);
2899             if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback,
2900                                           BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2901                 return BTM_CMD_STARTED;
2902             }
2903             APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request  ");
2904         }
2905
2906         bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
2907         BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
2908         BCM_STRNCPY_S((char *)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char *)p_data->rmt_oob.bd_name, (BD_NAME_LEN - 1));
2909         sec_event.rmt_oob.bd_name[BD_NAME_LEN - 1] = 0;
2910
2911         bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
2912
2913         bta_dm_co_rmt_oob(p_data->rmt_oob.bd_addr);
2914         break;
2915 #endif
2916     case BTM_SP_COMPLT_EVT:
2917         /* do not report this event - handled by link_key_callback or auth_complete_callback */
2918         break;
2919
2920     case BTM_SP_KEYPRESS_EVT:
2921         memcpy(&sec_event.key_press, &p_data->key_press, sizeof(tBTM_SP_KEYPRESS));
2922         bta_dm_cb.p_sec_cback(BTA_DM_SP_KEYPRESS_EVT, &sec_event);
2923         break;
2924
2925     case BTM_SP_UPGRADE_EVT:
2926         bta_dm_co_lk_upgrade(p_data->upgrade.bd_addr, &p_data->upgrade.upgrade );
2927         break;
2928
2929     default:
2930         status = BTM_NOT_AUTHORIZED;
2931         break;
2932     }
2933     APPL_TRACE_EVENT("dm status: %d", status);
2934     return status;
2935 }
2936 #endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */
2937
2938 #endif  ///SMP_INCLUDED == TRUE
2939
2940
2941 /*******************************************************************************
2942 **
2943 ** Function         bta_dm_local_name_cback
2944 **
2945 ** Description      Callback from btm after local name is read
2946 **
2947 **
2948 ** Returns          void
2949 **
2950 *******************************************************************************/
2951 static void bta_dm_local_name_cback(UINT8 *p_name)
2952 {
2953     tBTA_DM_SEC sec_event;
2954     UNUSED(p_name);
2955
2956     sec_event.enable.status = BTA_SUCCESS;
2957
2958     if (bta_dm_cb.p_sec_cback) {
2959         bta_dm_cb.p_sec_cback(BTA_DM_ENABLE_EVT, &sec_event);
2960     }
2961
2962 }
2963
2964 /*******************************************************************************
2965 **
2966 ** Function         bta_dm_bl_change_cback
2967 **
2968 ** Description      Callback from btm when acl connection goes up or down
2969 **
2970 **
2971 ** Returns          void
2972 **
2973 *******************************************************************************/
2974 static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
2975 {
2976     tBTA_DM_ACL_CHANGE *p_msg;
2977
2978     if ((p_msg = (tBTA_DM_ACL_CHANGE *) osi_malloc(sizeof(tBTA_DM_ACL_CHANGE))) != NULL) {
2979         p_msg->event = p_data->event;
2980         p_msg->is_new = FALSE;
2981
2982         switch (p_msg->event) {
2983         case BTM_BL_CONN_EVT:
2984             p_msg->is_new = TRUE;
2985             bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
2986 #if BLE_INCLUDED == TRUE
2987             p_msg->transport = p_data->conn.transport;
2988             p_msg->handle = p_data->conn.handle;
2989 #endif
2990             break;
2991         case BTM_BL_DISCN_EVT:
2992             bdcpy(p_msg->bd_addr, p_data->discn.p_bda);
2993 #if BLE_INCLUDED == TRUE
2994             p_msg->transport = p_data->discn.transport;
2995             p_msg->handle = p_data->discn.handle;
2996 #endif
2997             break;
2998         case BTM_BL_UPDATE_EVT:
2999             p_msg->busy_level = p_data->update.busy_level;
3000             p_msg->busy_level_flags = p_data->update.busy_level_flags;
3001             break;
3002         case BTM_BL_ROLE_CHG_EVT:
3003             p_msg->new_role = p_data->role_chg.new_role;
3004             p_msg->hci_status = p_data->role_chg.hci_status;
3005             bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda);
3006             break;
3007         case BTM_BL_COLLISION_EVT:
3008             bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
3009             break;
3010         }
3011
3012         p_msg->hdr.event = BTA_DM_ACL_CHANGE_EVT;
3013         bta_sys_sendmsg(p_msg);
3014
3015     }
3016
3017 }
3018
3019 /*******************************************************************************
3020 **
3021 ** Function         bta_dm_rs_cback
3022 **
3023 ** Description      Receives the role switch complete event
3024 **
3025 ** Returns
3026 **
3027 *******************************************************************************/
3028 static void bta_dm_rs_cback (tBTM_ROLE_SWITCH_CMPL *p1)
3029 {
3030     UNUSED(p1);
3031     APPL_TRACE_WARNING("bta_dm_rs_cback:%d", bta_dm_cb.rs_event);
3032     if (bta_dm_cb.rs_event == BTA_DM_API_SEARCH_EVT) {
3033         bta_dm_cb.search_msg.rs_res = BTA_DM_RS_OK; /* do not care about the result for now */
3034         bta_dm_cb.rs_event = 0;
3035         bta_dm_search_start((tBTA_DM_MSG *)&bta_dm_cb.search_msg);
3036     }
3037 }
3038
3039 /*******************************************************************************
3040 **
3041 ** Function         bta_dm_check_av
3042 **
3043 ** Description      This function checks if AV is active
3044 **                  if yes, make sure the AV link is master
3045 **
3046 ** Returns          BOOLEAN - TRUE, if switch is in progress
3047 **
3048 *******************************************************************************/
3049 static BOOLEAN bta_dm_check_av(UINT16 event)
3050 {
3051     BOOLEAN avoid_roleswitch = FALSE;
3052     BOOLEAN switching = FALSE;
3053     UINT8 i;
3054     tBTA_DM_PEER_DEVICE *p_dev;
3055
3056 #if defined(BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY) && (BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY == TRUE)
3057
3058     /* avoid role switch upon inquiry if a2dp is actively streaming as it
3059        introduces an audioglitch due to FW scheduling delays (unavoidable) */
3060     if (event == BTA_DM_API_SEARCH_EVT) {
3061         avoid_roleswitch = TRUE;
3062     }
3063 #endif
3064
3065     APPL_TRACE_WARNING("bta_dm_check_av:%d", bta_dm_cb.cur_av_count);
3066     if (bta_dm_cb.cur_av_count) {
3067         for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3068             p_dev = &bta_dm_cb.device_list.peer_device[i];
3069             APPL_TRACE_WARNING("[%d]: state:%d, info:x%x, avoid_rs %d",
3070                                i, p_dev->conn_state, p_dev->info, avoid_roleswitch);
3071             if ((p_dev->conn_state == BTA_DM_CONNECTED) && (p_dev->info & BTA_DM_DI_AV_ACTIVE) &&
3072                     (avoid_roleswitch == FALSE)) {
3073                 /* make master and take away the role switch policy */
3074                 if (BTM_CMD_STARTED == BTM_SwitchRole (p_dev->peer_bdaddr, HCI_ROLE_MASTER, (tBTM_CMPL_CB *)bta_dm_rs_cback)) {
3075                     /* the role switch command is actually sent */
3076                     bta_dm_cb.rs_event = event;
3077                     switching = TRUE;
3078                 }
3079                 /* else either already master or can not switch for some reasons */
3080                 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr);
3081                 break;
3082             }
3083         }
3084     }
3085     return switching;
3086 }
3087
3088 /*******************************************************************************
3089 **
3090 ** Function         bta_dm_acl_change
3091 **
3092 ** Description      Process BTA_DM_ACL_CHANGE_EVT
3093 **
3094 **
3095 ** Returns          void
3096 **
3097 *******************************************************************************/
3098 void bta_dm_acl_change(tBTA_DM_MSG *p_data)
3099 {
3100
3101     UINT8 i;
3102     UINT8 *p;
3103     tBTA_DM_SEC conn;
3104     BOOLEAN is_new = p_data->acl_change.is_new;
3105     BD_ADDR_PTR     p_bda = p_data->acl_change.bd_addr;
3106     BOOLEAN         need_policy_change = FALSE;
3107     BOOLEAN         issue_unpair_cb = FALSE;
3108
3109     tBTA_DM_PEER_DEVICE *p_dev;
3110     memset(&conn, 0, sizeof(tBTA_DM_SEC));
3111
3112     switch (p_data->acl_change.event) {
3113     case BTM_BL_UPDATE_EVT:     /* busy level update */
3114         if ( bta_dm_cb.p_sec_cback ) {
3115             conn.busy_level.level = p_data->acl_change.busy_level;
3116             conn.busy_level.level_flags = p_data->acl_change.busy_level_flags;
3117             bta_dm_cb.p_sec_cback(BTA_DM_BUSY_LEVEL_EVT, &conn);
3118         }
3119         return;
3120
3121     case BTM_BL_ROLE_CHG_EVT:   /* role change event */
3122         p_dev = bta_dm_find_peer_device(p_bda);
3123         if (p_dev) {
3124             APPL_TRACE_DEBUG("bta_dm_acl_change role chg info:x%x new_role:%d dev count:%d",
3125                              p_dev->info, p_data->acl_change.new_role, bta_dm_cb.device_list.count);
3126             if (p_dev->info & BTA_DM_DI_AV_ACTIVE) {
3127                 /* there's AV activity on this link */
3128                 if (p_data->acl_change.new_role == HCI_ROLE_SLAVE && bta_dm_cb.device_list.count > 1
3129                         && p_data->acl_change.hci_status == HCI_SUCCESS) {
3130                     /* more than one connections and the AV connection is role switched to slave
3131                      * switch it back to master and remove the switch policy */
3132                     BTM_SwitchRole(p_bda, BTM_ROLE_MASTER, NULL);
3133                     need_policy_change = TRUE;
3134                 } else if (p_bta_dm_cfg->avoid_scatter && (p_data->acl_change.new_role == HCI_ROLE_MASTER)) {
3135                     /* if the link updated to be master include AV activities, remove the switch policy */
3136                     need_policy_change = TRUE;
3137                 }
3138
3139                 if (need_policy_change) {
3140                     bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr);
3141                 }
3142             } else {
3143                 /* there's AV no activity on this link and role switch happened
3144                  * check if AV is active
3145                  * if so, make sure the AV link is master */
3146                 bta_dm_check_av(0);
3147             }
3148             bta_sys_notify_role_chg(p_data->acl_change.bd_addr, p_data->acl_change.new_role, p_data->acl_change.hci_status);
3149             bdcpy(conn.role_chg.bd_addr, p_bda);
3150             conn.role_chg.new_role = (UINT8) p_data->acl_change.new_role;
3151             if ( bta_dm_cb.p_sec_cback ) {
3152                 bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, (tBTA_DM_SEC *)&conn);
3153             }
3154         }
3155         return;
3156     }
3157
3158     /* Collision report from Stack: Notify profiles */
3159     if (p_data->acl_change.event == BTM_BL_COLLISION_EVT) {
3160         bta_sys_notify_collision (p_bda);
3161         return;
3162     }
3163
3164     if (is_new) {
3165         for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3166             if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
3167 #if BLE_INCLUDED == TRUE
3168                     && bta_dm_cb.device_list.peer_device[i].conn_handle == p_data->acl_change.handle
3169 #endif
3170                ) {
3171                 break;
3172             }
3173
3174         }
3175
3176         if (i == bta_dm_cb.device_list.count) {
3177             if (bta_dm_cb.device_list.count < BTA_DM_NUM_PEER_DEVICE) {
3178                 bdcpy(bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].peer_bdaddr, p_bda);
3179                 bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].link_policy = bta_dm_cb.cur_policy;
3180                 bta_dm_cb.device_list.count++;
3181 #if BLE_INCLUDED == TRUE
3182                 bta_dm_cb.device_list.peer_device[i].conn_handle = p_data->acl_change.handle;
3183                 if (p_data->acl_change.transport == BT_TRANSPORT_LE) {
3184                     bta_dm_cb.device_list.le_count++;
3185                 }
3186 #endif
3187             } else {
3188                 APPL_TRACE_ERROR("%s max active connection reached, no resources", __func__);
3189                 return;
3190             }
3191         }
3192
3193         bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED;
3194         bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE;
3195         bdcpy(conn.link_up.bd_addr, p_bda);
3196         bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE;
3197 #if BLE_INCLUDED == TRUE
3198         conn.link_up.link_type = p_data->acl_change.transport;
3199         bta_dm_cb.device_list.peer_device[i].transport = p_data->acl_change.transport;
3200 #endif
3201
3202         if (((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
3203                 ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p))) {
3204             /* both local and remote devices support SSR */
3205             bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR;
3206         }
3207         APPL_TRACE_DEBUG("%s info: 0x%x", __func__, bta_dm_cb.device_list.peer_device[i].info);
3208
3209         if (bta_dm_cb.p_sec_cback) {
3210             bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, (tBTA_DM_SEC *)&conn);
3211         }
3212     } else {
3213         for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3214             if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
3215 #if BLE_INCLUDED == TRUE
3216                     || bta_dm_cb.device_list.peer_device[i].transport != p_data->acl_change.transport
3217 #endif
3218                ) {
3219                 continue;
3220             }
3221
3222             if ( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING ) {
3223                 if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr)) {
3224                     issue_unpair_cb = TRUE;
3225                 }
3226
3227                 APPL_TRACE_DEBUG("%s: Unpairing: issue unpair CB = %d ", __FUNCTION__, issue_unpair_cb);
3228             }
3229
3230             conn.link_down.is_removed = bta_dm_cb.device_list.peer_device[i].remove_dev_pending;
3231
3232             for (; i < bta_dm_cb.device_list.count ; i++) {
3233                 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]));
3234             }
3235             break;
3236         }
3237         if (bta_dm_cb.device_list.count) {
3238             bta_dm_cb.device_list.count--;
3239         }
3240 #if BLE_INCLUDED == TRUE
3241         if ((p_data->acl_change.transport == BT_TRANSPORT_LE) &&
3242                 (bta_dm_cb.device_list.le_count)) {
3243             bta_dm_cb.device_list.le_count--;
3244         }
3245         conn.link_down.link_type = p_data->acl_change.transport;
3246 #endif
3247
3248         if (bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda)) {
3249             bta_dm_search_cb.wait_disc = FALSE;
3250
3251             if (bta_dm_search_cb.sdp_results) {
3252                 APPL_TRACE_EVENT(" timer stopped  ");
3253                 bta_sys_stop_timer(&bta_dm_search_cb.search_timer);
3254                 bta_dm_discover_next_device();
3255             }
3256
3257         }
3258
3259         if (bta_dm_cb.disabling) {
3260             if (!BTM_GetNumAclLinks()) {
3261                 bta_sys_stop_timer(&bta_dm_cb.disable_timer);
3262                 bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK *)&bta_dm_disable_conn_down_timer_cback;
3263                 /*
3264                  * Start a timer to make sure that the profiles
3265                  * get the disconnect event.
3266                  */
3267                 bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 1000);
3268             }
3269         }
3270         if (conn.link_down.is_removed) {
3271             BTM_SecDeleteDevice(p_bda);
3272 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
3273             /* need to remove all pending background connection */
3274             BTA_GATTC_CancelOpen(0, p_bda, FALSE);
3275             /* remove all cached GATT information */
3276             BTA_GATTC_Refresh(p_bda);
3277 #endif
3278         }
3279
3280         bdcpy(conn.link_down.bd_addr, p_bda);
3281         conn.link_down.reason = (UINT8) btm_get_acl_disc_reason_code();
3282         if ( bta_dm_cb.p_sec_cback ) {
3283             bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn);
3284             if ( issue_unpair_cb ) {
3285                 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn);
3286             }
3287         }
3288     }
3289
3290     bta_dm_adjust_roles(TRUE);
3291 }
3292
3293 /*******************************************************************************
3294 **
3295 ** Function         bta_dm_disable_conn_down_timer_cback
3296 **
3297 ** Description      Sends disable event to application
3298 **
3299 **
3300 ** Returns          void
3301 **
3302 *******************************************************************************/
3303 static void bta_dm_disable_conn_down_timer_cback (TIMER_LIST_ENT *p_tle)
3304 {
3305     UNUSED(p_tle);
3306     tBTA_SYS_HW_MSG *sys_enable_event;
3307 #if (BTM_SSR_INCLUDED == TRUE)
3308     /* disable the power managment module */
3309     bta_dm_disable_pm();
3310 #endif  ///BTM_SSR_INCLUDED == TRUE
3311     /* register our callback to SYS HW manager */
3312     bta_sys_hw_register( BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback );
3313
3314     /* send a message to BTA SYS */
3315     if ((sys_enable_event = (tBTA_SYS_HW_MSG *) osi_malloc(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
3316         sys_enable_event->hdr.event = BTA_SYS_API_DISABLE_EVT;
3317         sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;
3318         bta_sys_sendmsg(sys_enable_event);
3319     }
3320
3321     bta_dm_cb.disabling = FALSE;
3322
3323 }
3324
3325 /*******************************************************************************
3326 **
3327 ** Function         bta_dm_rm_cback
3328 **
3329 ** Description      Role management callback from sys
3330 **
3331 **
3332 ** Returns          void
3333 **
3334 *******************************************************************************/
3335 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
3336 {
3337     UINT8 j;
3338     tBTA_PREF_ROLES role;
3339     tBTA_DM_PEER_DEVICE *p_dev;
3340
3341     p_dev = bta_dm_find_peer_device(peer_addr);
3342     if ( status == BTA_SYS_CONN_OPEN) {
3343         if (p_dev) {
3344             /* Do not set to connected if we are in the middle of unpairing. When AV stream is
3345              * started it fakes out a SYS_CONN_OPEN to potentially trigger a role switch command.
3346              * But this should not be done if we are in the middle of unpairing.
3347              */
3348             if (p_dev->conn_state != BTA_DM_UNPAIRING) {
3349                 p_dev->conn_state = BTA_DM_CONNECTED;
3350             }
3351
3352             for (j = 1; j <= p_bta_dm_rm_cfg[0].app_id; j++) {
3353                 if (((p_bta_dm_rm_cfg[j].app_id == app_id) || (p_bta_dm_rm_cfg[j].app_id == BTA_ALL_APP_ID))
3354                         && (p_bta_dm_rm_cfg[j].id == id)) {
3355                     role = p_bta_dm_rm_cfg[j].cfg;
3356
3357                     if (role > p_dev->pref_role ) {
3358                         p_dev->pref_role = role;
3359                     }
3360                     break;
3361                 }
3362             }
3363         }
3364     }
3365
3366     if ((BTA_ID_AV == id) || (BTA_ID_AVK == id)) {
3367         if ( status == BTA_SYS_CONN_BUSY) {
3368             if (p_dev) {
3369                 p_dev->info |= BTA_DM_DI_AV_ACTIVE;
3370             }
3371             /* AV calls bta_sys_conn_open with the A2DP stream count as app_id */
3372             if (BTA_ID_AV == id) {
3373 #if (BTM_SSR_INCLUDED == TRUE)
3374                 bta_dm_cb.cur_av_count = bta_dm_get_av_count();
3375 #endif  ///BTM_SSR_INCLUDED == TRUE
3376             }
3377         } else if ( status == BTA_SYS_CONN_IDLE) {
3378             if (p_dev) {
3379                 p_dev->info &= ~BTA_DM_DI_AV_ACTIVE;
3380             }
3381
3382             /* get cur_av_count from connected services */
3383             if (BTA_ID_AV == id) {
3384 #if (BTM_SSR_INCLUDED == TRUE)
3385                 bta_dm_cb.cur_av_count = bta_dm_get_av_count();
3386 #endif  ///BTM_SSR_INCLUDED == TRUE
3387             }
3388         }
3389         APPL_TRACE_WARNING("bta_dm_rm_cback:%d, status:%d", bta_dm_cb.cur_av_count, status);
3390     }
3391
3392     /* Don't adjust roles for each busy/idle state transition to avoid
3393        excessive switch requests when individual profile busy/idle status
3394        changes */
3395     if ((status != BTA_SYS_CONN_BUSY) && (status != BTA_SYS_CONN_IDLE)) {
3396         bta_dm_adjust_roles(FALSE);
3397     }
3398 }
3399
3400 /*******************************************************************************
3401 **
3402 ** Function         bta_dm_delay_role_switch_cback
3403 **
3404 ** Description      Callback from btm to delay a role switch
3405 **
3406 ** Returns          void
3407 **
3408 *******************************************************************************/
3409 static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle)
3410 {
3411     UNUSED(p_tle);
3412     APPL_TRACE_EVENT("bta_dm_delay_role_switch_cback: initiating Delayed RS");
3413     bta_dm_adjust_roles (FALSE);
3414 }
3415
3416 /*******************************************************************************
3417 **
3418 ** Function         bta_dm_remove_sec_dev_entry
3419 **
3420 ** Description      Removes device entry from Security device DB if ACL connection with
3421 **                  remtoe device does not exist, else schedule for dev entry removal upon
3422                      ACL close
3423 **
3424 ** Returns          void
3425 **
3426 *******************************************************************************/
3427 #if (SMP_INCLUDED == TRUE)
3428 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
3429 {
3430     UINT16 index = 0;
3431     if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
3432             BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR)) {
3433         APPL_TRACE_DEBUG("%s ACL is not down. Schedule for  Dev Removal when ACL closes",
3434                          __FUNCTION__);
3435         BTM_SecClearSecurityFlags (remote_bd_addr);
3436         for (index = 0; index < bta_dm_cb.device_list.count; index ++) {
3437             if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, remote_bd_addr)) {
3438                 break;
3439             }
3440         }
3441         if (index != bta_dm_cb.device_list.count) {
3442             bta_dm_cb.device_list.peer_device[index].remove_dev_pending = TRUE;
3443         } else {
3444             APPL_TRACE_ERROR(" %s Device does not exist in DB", __FUNCTION__);
3445         }
3446     } else {
3447         BTM_SecDeleteDevice (remote_bd_addr);
3448 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
3449         /* need to remove all pending background connection */
3450         BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
3451         /* remove all cached GATT information */
3452         BTA_GATTC_Refresh(remote_bd_addr);
3453 #endif
3454     }
3455 }
3456 #endif  ///SMP_INCLUDED == TRUE
3457
3458
3459 /*******************************************************************************
3460 **
3461 ** Function         bta_dm_adjust_roles
3462 **
3463 ** Description      Adjust roles
3464 **
3465 **
3466 ** Returns          void
3467 **
3468 *******************************************************************************/
3469 static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
3470 {
3471
3472     UINT8 i;
3473     BOOLEAN set_master_role = FALSE;
3474 #if BLE_INCLUDED == TRUE
3475     UINT8 br_count = bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count;
3476 #else
3477     UINT8 br_count = bta_dm_cb.device_list.count;
3478 #endif
3479     if (br_count) {
3480
3481         /* the configuration is no scatternet
3482          * or AV connection exists and there are more than one ACL link */
3483         if ( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
3484                 (bta_dm_cb.cur_av_count && br_count > 1) ) {
3485
3486             L2CA_SetDesireRole (HCI_ROLE_MASTER);
3487             set_master_role = TRUE;
3488
3489         }
3490
3491         for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3492             if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED
3493 #if BLE_INCLUDED == TRUE
3494                     && bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_BR_EDR
3495 #endif
3496                ) {
3497                 if (!set_master_role && (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE)
3498                         && (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET)) {
3499                     L2CA_SetDesireRole (HCI_ROLE_MASTER);
3500                     set_master_role = TRUE;
3501                 }
3502
3503                 if ((bta_dm_cb.device_list.peer_device[i].pref_role == BTA_MASTER_ROLE_ONLY)
3504                         || (br_count > 1)) {
3505
3506                     /* Initiating immediate role switch with certain remote devices
3507                       has caused issues due to role  switch colliding with link encryption setup and
3508                       causing encryption (and in turn the link) to fail .  These device . Firmware
3509                       versions are stored in a blacklist and role switch with these devices are
3510                       delayed to avoid the collision with link encryption setup */
3511
3512                     if (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_SLAVE_ROLE_ONLY &&
3513                             delay_role_switch == FALSE) {
3514                         BTM_SwitchRole (bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
3515                                         HCI_ROLE_MASTER, NULL);
3516                     } else {
3517                         bta_dm_cb.switch_delay_timer.p_cback =
3518                             (TIMER_CBACK *)&bta_dm_delay_role_switch_cback;
3519                         bta_sys_start_timer(&bta_dm_cb.switch_delay_timer, 0, 500);
3520                     }
3521                 }
3522
3523             }
3524         }
3525
3526
3527         if (!set_master_role) {
3528
3529             L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
3530
3531         }
3532
3533     } else {
3534         L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
3535     }
3536
3537
3538 }
3539
3540 /*******************************************************************************
3541 **
3542 ** Function         bta_dm_get_remname
3543 **
3544 ** Description      Returns a pointer to the remote name stored in the DM control
3545 **                  block if it exists, or from the BTM memory.
3546 **
3547 ** Returns          char * - Pointer to the remote device name
3548 *******************************************************************************/
3549 #if (SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE)
3550 static char *bta_dm_get_remname(void)
3551 {
3552     char *p_name = (char *)bta_dm_search_cb.peer_name;
3553     char *p_temp;
3554
3555     /* If the name isn't already stored, try retrieving from BTM */
3556     if (*p_name == '\0')
3557         if ((p_temp = BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr)) != NULL) {
3558             p_name = p_temp;
3559         }
3560
3561     return p_name;
3562 }
3563 #endif  ///SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE
3564
3565 /*******************************************************************************
3566 **
3567 ** Function         bta_dm_bond_cancel_complete_cback
3568 **
3569 ** Description      Authentication complete callback from BTM
3570 **
3571 ** Returns          void
3572 **
3573 *******************************************************************************/
3574 #if (SMP_INCLUDED == TRUE)
3575 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result)
3576 {
3577
3578     tBTA_DM_SEC sec_event;
3579
3580     if (result == BTM_SUCCESS) {
3581         sec_event.bond_cancel_cmpl.result = BTA_SUCCESS;
3582     } else {
3583         sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
3584     }
3585
3586     if (bta_dm_cb.p_sec_cback) {
3587         bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
3588     }
3589 }
3590 #endif  ///SMP_INCLUDED == TRUE
3591
3592 /*******************************************************************************
3593 **
3594 ** Function         bta_dm_set_eir
3595 **
3596 ** Description      This function creates EIR tagged data and writes it to controller.
3597 **
3598 ** Returns          None
3599 **
3600 *******************************************************************************/
3601 static void bta_dm_set_eir (char *local_name)
3602 {
3603     BT_HDR   *p_buf;
3604     UINT8    *p;
3605     UINT8    *p_length;
3606 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3607     UINT8    *p_type;
3608     UINT8    max_num_uuid;
3609 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3610     UINT8    custom_uuid_idx;
3611 #endif  // BTA_EIR_SERVER_NUM_CUSTOM_UUID
3612 #endif  // BTA_EIR_CANNED_UUID_LIST
3613 #if (BTM_EIR_DEFAULT_FEC_REQUIRED == FALSE)
3614     UINT8    free_eir_length = HCI_EXT_INQ_RESPONSE_LEN;
3615 #else  // BTM_EIR_DEFAULT_FEC_REQUIRED
3616     UINT8    free_eir_length = HCI_DM5_PACKET_SIZE;
3617 #endif  // BTM_EIR_DEFAULT_FEC_REQUIRED
3618     UINT8    num_uuid;
3619     UINT8    data_type;
3620     UINT8    local_name_len;
3621
3622     /* wait until complete to disable */
3623     if (bta_dm_cb.disable_timer.in_use) {
3624         return;
3625     }
3626
3627 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )
3628     /* wait until App is ready */
3629     if (bta_dm_cb.app_ready_timer.in_use) {
3630         return;
3631     }
3632
3633     /* if local name is not provided, get it from controller */
3634     if ( local_name == NULL ) {
3635         if ( BTM_ReadLocalDeviceName( &local_name ) != BTM_SUCCESS ) {
3636             APPL_TRACE_ERROR("Fail to read local device name for EIR");
3637         }
3638     }
3639 #endif  // BTA_EIR_CANNED_UUID_LIST
3640
3641     /* Allocate a buffer to hold HCI command */
3642     if ((p_buf = (BT_HDR *)osi_malloc(BTM_CMD_BUF_SIZE)) == NULL) {
3643         APPL_TRACE_ERROR("bta_dm_set_eir couldn't allocate buffer");
3644         return;
3645     }
3646     p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET;
3647
3648     memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN );
3649
3650     APPL_TRACE_DEBUG("BTA is generating EIR");
3651
3652     if ( local_name ) {
3653         local_name_len = strlen( local_name );
3654     } else {
3655         local_name_len = 0;
3656     }
3657
3658     data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3659     /* if local name is longer than minimum length of shortened name */
3660     /* check whether it needs to be shortened or not */
3661     if ( local_name_len > p_bta_dm_eir_cfg->bta_dm_eir_min_name_len ) {
3662         /* get number of UUID 16-bit list */
3663 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3664         num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / LEN_UUID_16;
3665 #else  // BTA_EIR_CANNED_UUID_LIST
3666         max_num_uuid = (free_eir_length - 2) / LEN_UUID_16;
3667         data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p,
3668                     max_num_uuid, &num_uuid );
3669         p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET; /* reset p */
3670 #endif  // BTA_EIR_CANNED_UUID_LIST
3671
3672         /* if UUID doesn't fit remaing space, shorten local name */
3673         if ( local_name_len > (free_eir_length - 4 - num_uuid * LEN_UUID_16)) {
3674             APPL_TRACE_WARNING("BTA EIR: local name is shortened");
3675             local_name_len = p_bta_dm_eir_cfg->bta_dm_eir_min_name_len;
3676             data_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE;
3677         } else {
3678             data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3679         }
3680     }
3681
3682     UINT8_TO_STREAM(p, local_name_len + 1);
3683     UINT8_TO_STREAM(p, data_type);
3684
3685     if (local_name != NULL) {
3686         memcpy(p, local_name, local_name_len);
3687         p += local_name_len;
3688     }
3689     free_eir_length -= local_name_len + 2;
3690
3691 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3692     /* if UUID list is provided as static data in configuration */
3693     if (( p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len > 0 )
3694             && (p_bta_dm_eir_cfg->bta_dm_eir_uuid16)) {
3695         if ( free_eir_length > LEN_UUID_16 + 2) {
3696             free_eir_length -= 2;
3697
3698             if ( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len) {
3699                 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / LEN_UUID_16;
3700                 data_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3701             } else { /* not enough room for all UUIDs */
3702                 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3703                 num_uuid = free_eir_length / LEN_UUID_16;
3704                 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3705             }
3706             UINT8_TO_STREAM(p, num_uuid * LEN_UUID_16 + 1);
3707             UINT8_TO_STREAM(p, data_type);
3708             memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_uuid16, num_uuid * LEN_UUID_16 );
3709             p += num_uuid * LEN_UUID_16;
3710             free_eir_length -= num_uuid * LEN_UUID_16;
3711         }
3712     }
3713 #else /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3714     /* if UUID list is dynamic */
3715     if ( free_eir_length >= 2) {
3716         p_length = p++;
3717         p_type   = p++;
3718         num_uuid = 0;
3719
3720         max_num_uuid = (free_eir_length - 2) / LEN_UUID_16;
3721         data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p, max_num_uuid, &num_uuid );
3722
3723         if ( data_type == BTM_EIR_MORE_16BITS_UUID_TYPE ) {
3724             APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3725         }
3726 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3727         else {
3728             for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) {
3729                 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_16) {
3730                     if ( num_uuid < max_num_uuid ) {
3731                         UINT16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid16);
3732                         num_uuid++;
3733                     } else {
3734                         data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3735                         APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3736                         break;
3737                     }
3738                 }
3739             }
3740         }
3741 #endif /* (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3742
3743         UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_16 + 1);
3744         UINT8_TO_STREAM(p_type, data_type);
3745         free_eir_length -= num_uuid * LEN_UUID_16 + 2;
3746     }
3747 #endif /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3748
3749 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3750     /* Adding 32-bit UUID list */
3751     if ( free_eir_length >= 2) {
3752         p_length = p++;
3753         p_type   = p++;
3754         num_uuid = 0;
3755         data_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE;
3756
3757         max_num_uuid = (free_eir_length - 2) / LEN_UUID_32;
3758
3759         for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) {
3760             if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_32) {
3761                 if ( num_uuid < max_num_uuid ) {
3762                     UINT32_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid32);
3763                     num_uuid++;
3764                 } else {
3765                     data_type = BTM_EIR_MORE_32BITS_UUID_TYPE;
3766                     APPL_TRACE_WARNING("BTA EIR: UUID 32-bit list is truncated");
3767                     break;
3768                 }
3769             }
3770         }
3771
3772         UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_32 + 1);
3773         UINT8_TO_STREAM(p_type, data_type);
3774         free_eir_length -= num_uuid * LEN_UUID_32 + 2;
3775     }
3776
3777     /* Adding 128-bit UUID list */
3778     if ( free_eir_length >= 2) {
3779         p_length = p++;
3780         p_type   = p++;
3781         num_uuid = 0;
3782         data_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE;
3783
3784         max_num_uuid = (free_eir_length - 2) / LEN_UUID_128;
3785
3786         for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) {
3787             if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_128) {
3788                 if ( num_uuid < max_num_uuid ) {
3789                     ARRAY16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid128);
3790                     num_uuid++;
3791                 } else {
3792                     data_type = BTM_EIR_MORE_128BITS_UUID_TYPE;
3793                     APPL_TRACE_WARNING("BTA EIR: UUID 128-bit list is truncated");
3794                     break;
3795                 }
3796             }
3797         }
3798
3799         UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_128 + 1);
3800         UINT8_TO_STREAM(p_type, data_type);
3801         free_eir_length -= num_uuid * LEN_UUID_128 + 2;
3802     }
3803 #endif /* ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3804
3805     /* if Flags are provided in configuration */
3806     if (( p_bta_dm_eir_cfg->bta_dm_eir_flag_len > 0 )
3807             && ( p_bta_dm_eir_cfg->bta_dm_eir_flags )
3808             && ( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2 )) {
3809         UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 1);
3810         UINT8_TO_STREAM(p, BTM_EIR_FLAGS_TYPE);
3811         memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_flags,
3812                p_bta_dm_eir_cfg->bta_dm_eir_flag_len);
3813         p += p_bta_dm_eir_cfg->bta_dm_eir_flag_len;
3814         free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2;
3815     }
3816
3817     /* if Manufacturer Specific are provided in configuration */
3818     if (( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len > 0 )
3819             && ( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec )
3820             && ( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2 )) {
3821         p_length = p;
3822
3823         UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 1);
3824         UINT8_TO_STREAM(p, BTM_EIR_MANUFACTURER_SPECIFIC_TYPE);
3825         memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec,
3826                p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len);
3827         p += p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len;
3828         free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2;
3829
3830     } else {
3831         p_length = NULL;
3832     }
3833
3834     /* if Inquiry Tx Resp Power compiled */
3835     if ((p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power) &&
3836             (free_eir_length >= 3)) {
3837         UINT8_TO_STREAM(p, 2);      /* Length field */
3838         UINT8_TO_STREAM(p, BTM_EIR_TX_POWER_LEVEL_TYPE);
3839         UINT8_TO_STREAM(p, *(p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power));
3840         free_eir_length -= 3;
3841     }
3842
3843     if ( free_eir_length ) {
3844         UINT8_TO_STREAM(p, 0);    /* terminator of significant part */
3845     }
3846
3847     BTM_WriteEIR( p_buf );
3848
3849 }
3850
3851 /*******************************************************************************
3852 **
3853 ** Function         bta_dm_eir_search_services
3854 **
3855 ** Description      This function searches services in received EIR
3856 **
3857 ** Returns          None
3858 **
3859 *******************************************************************************/
3860 #if (SDP_INCLUDED == TRUE)
3861 static void bta_dm_eir_search_services( tBTM_INQ_RESULTS  *p_result,
3862                                         tBTA_SERVICE_MASK *p_services_to_search,
3863                                         tBTA_SERVICE_MASK *p_services_found)
3864 {
3865     tBTA_SERVICE_MASK       service_index = 0;
3866     tBTM_EIR_SEARCH_RESULT  result;
3867
3868     APPL_TRACE_DEBUG("BTA searching services in EIR of BDA:0x%02X%02X%02X%02X%02X%02X",
3869                      p_result->remote_bd_addr[0], p_result->remote_bd_addr[1],
3870                      p_result->remote_bd_addr[2], p_result->remote_bd_addr[3],
3871                      p_result->remote_bd_addr[4], p_result->remote_bd_addr[5]);
3872
3873     APPL_TRACE_DEBUG("    with services_to_search=0x%08X", *p_services_to_search);
3874
3875 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
3876     /* always do GATT based service discovery by SDP instead of from EIR    */
3877     /* if GATT based service is also to be put in EIR, need to modify this  */
3878     while (service_index < (BTA_MAX_SERVICE_ID - 1))
3879 #else
3880     while (service_index < BTA_MAX_SERVICE_ID)
3881 #endif
3882     {
3883         if ( *p_services_to_search
3884                 & (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index))) {
3885             result = BTM_HasInquiryEirService( p_result,
3886                                                bta_service_id_to_uuid_lkup_tbl[service_index] );
3887
3888             /* Searching for HSP v1.2 only device */
3889             if ((result != BTM_EIR_FOUND) &&
3890                     (bta_service_id_to_uuid_lkup_tbl[service_index] == UUID_SERVCLASS_HEADSET)) {
3891                 result = BTM_HasInquiryEirService (p_result, UUID_SERVCLASS_HEADSET_HS);
3892             }
3893
3894             if ( result == BTM_EIR_FOUND ) {
3895                 /* If Plug and Play service record, need to check to see if Broadcom stack */
3896                 /* However, EIR data doesn't have EXT_BRCM_VERSION so just skip it */
3897                 if ( bta_service_id_to_uuid_lkup_tbl[service_index]
3898                         != UUID_SERVCLASS_PNP_INFORMATION ) {
3899
3900                     *p_services_found |=
3901                         (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index));
3902                     /* remove the service from services to be searched  */
3903                     *p_services_to_search &=
3904                         (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
3905                 }
3906             } else if ( result == BTM_EIR_NOT_FOUND ) {
3907                 /* remove the service from services to be searched  */
3908                 *p_services_to_search &=
3909                     (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
3910             }
3911         }
3912
3913         service_index++;
3914     }
3915
3916     APPL_TRACE_ERROR("BTA EIR search result, services_to_search=0x%08X, services_found=0x%08X",
3917                      *p_services_to_search, *p_services_found);
3918 }
3919 #endif  ///SDP_INCLUDED == TRUE
3920
3921 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3922 /*******************************************************************************
3923 **
3924 ** Function         bta_dm_eir_update_uuid
3925 **
3926 ** Description      This function adds or removes service UUID in EIR database.
3927 **
3928 ** Returns          None
3929 **
3930 *******************************************************************************/
3931 void bta_dm_eir_update_uuid(UINT16 uuid16, BOOLEAN adding)
3932 {
3933     /* if this UUID is not advertised in EIR */
3934     if ( !BTM_HasEirService( p_bta_dm_eir_cfg->uuid_mask, uuid16 )) {
3935         return;
3936     }
3937
3938     if ( adding ) {
3939         APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid16);
3940
3941         BTM_AddEirService( bta_dm_cb.eir_uuid, uuid16 );
3942     } else {
3943         APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid16);
3944
3945         BTM_RemoveEirService( bta_dm_cb.eir_uuid, uuid16 );
3946     }
3947
3948     bta_dm_set_eir (NULL);
3949
3950     APPL_TRACE_EVENT("bta_dm_eir_update_uuid UUID bit mask=0x%08X %08X",
3951                      bta_dm_cb.eir_uuid[1], bta_dm_cb.eir_uuid[0] );
3952 }
3953 #endif
3954
3955 /*******************************************************************************
3956 **
3957 ** Function         bta_dm_enable_test_mode
3958 **
3959 ** Description      enable test mode
3960 **
3961 **
3962 ** Returns          void
3963 **
3964 *******************************************************************************/
3965 void bta_dm_enable_test_mode(tBTA_DM_MSG *p_data)
3966 {
3967     UNUSED(p_data);
3968     BTM_EnableTestMode();
3969 }
3970
3971 /*******************************************************************************
3972 **
3973 ** Function         bta_dm_disable_test_mode
3974 **
3975 ** Description      disable test mode
3976 **
3977 **
3978 ** Returns          void
3979 **
3980 *******************************************************************************/
3981 void bta_dm_disable_test_mode(tBTA_DM_MSG *p_data)
3982 {
3983     UNUSED(p_data);
3984     BTM_DeviceReset(NULL);
3985 }
3986
3987 /*******************************************************************************
3988 **
3989 ** Function         bta_dm_execute_callback
3990 **
3991 ** Description      Just execute a generic call back in the context of the BTU/BTA tack
3992 **
3993 **
3994 ** Returns          void
3995 **
3996 *******************************************************************************/
3997 void bta_dm_execute_callback(tBTA_DM_MSG *p_data)
3998 {
3999     /* sanity check */
4000     if (p_data->exec_cback.p_exec_cback == NULL) {
4001         return;
4002     }
4003
4004     p_data->exec_cback.p_exec_cback(p_data->exec_cback.p_param);
4005 }
4006
4007 /*******************************************************************************
4008 **
4009 ** Function         bta_dm_encrypt_cback
4010 **
4011 ** Description      link encryption complete callback.
4012 **
4013 ** Returns         None
4014 **
4015 *******************************************************************************/
4016 void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
4017 {
4018     tBTA_STATUS   bta_status = BTA_SUCCESS;
4019     tBTA_DM_ENCRYPT_CBACK *p_callback = NULL;
4020     UINT8   i ;
4021     UNUSED(p_ref_data);
4022
4023     for (i = 0; i < bta_dm_cb.device_list.count; i++) {
4024         if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bd_addr) == 0 &&
4025                 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) {
4026             break;
4027         }
4028     }
4029
4030     if (i < bta_dm_cb.device_list.count) {
4031         p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback;
4032         bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL;
4033     }
4034
4035     switch (result) {
4036     case BTM_SUCCESS:
4037         break;
4038     case BTM_WRONG_MODE:
4039         bta_status = BTA_WRONG_MODE;
4040         break;
4041     case BTM_NO_RESOURCES:
4042         bta_status = BTA_NO_RESOURCES;
4043         break;
4044     case BTM_BUSY:
4045         bta_status = BTA_BUSY;
4046         break;
4047     default:
4048         bta_status = BTA_FAILURE;
4049         break;
4050     }
4051
4052     APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=%p", bta_status, p_callback);
4053
4054     if (p_callback) {
4055         (*p_callback)(bd_addr, transport, bta_status);
4056     }
4057 }
4058
4059 /*******************************************************************************
4060 **
4061 ** Function         bta_dm_set_encryption
4062 **
4063 ** Description      This function to encrypt the link
4064 **
4065 ** Returns          None
4066 **
4067 *******************************************************************************/
4068 #if (SMP_INCLUDED == TRUE)
4069 void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
4070 {
4071     UINT8 i ;
4072
4073     APPL_TRACE_DEBUG("bta_dm_set_encryption\n"); //todo
4074     if (!p_data->set_encryption.p_callback) {
4075         APPL_TRACE_ERROR("bta_dm_set_encryption callback is not provided\n");
4076         return;
4077     }
4078     for (i = 0; i < bta_dm_cb.device_list.count; i++) {
4079         if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_data->set_encryption.bd_addr) == 0 &&
4080                 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) {
4081             break;
4082         }
4083     }
4084     if (i < bta_dm_cb.device_list.count) {
4085         if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback) {
4086             APPL_TRACE_ERROR("earlier enc was not done for same device\n");
4087             (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr,
4088                                                  p_data->set_encryption.transport,
4089                                                  BTA_BUSY);
4090             return;
4091         }
4092
4093         if (BTM_SetEncryption(p_data->set_encryption.bd_addr, p_data->set_encryption.transport,
4094                               bta_dm_encrypt_cback, &p_data->set_encryption.sec_act)
4095                 == BTM_CMD_STARTED) {
4096             bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_data->set_encryption.p_callback;
4097         }
4098     }else{
4099         APPL_TRACE_ERROR("%s, not find peer_bdaddr or peer_bdaddr connection state error", __func__);
4100     }
4101 }
4102 #endif  ///SMP_INCLUDED == TRUE
4103
4104 #if (BLE_INCLUDED == TRUE)
4105 /*******************************************************************************
4106 **
4107 ** Function         bta_dm_observe_results_cb
4108 **
4109 ** Description      Callback for BLE Observe result
4110 **
4111 **
4112 ** Returns          void
4113 **
4114 *******************************************************************************/
4115 static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
4116 {
4117     tBTA_DM_SEARCH     result;
4118     tBTM_INQ_INFO      *p_inq_info;
4119     APPL_TRACE_DEBUG("bta_dm_observe_results_cb")
4120
4121     bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
4122     result.inq_res.rssi = p_inq->rssi;
4123     result.inq_res.ble_addr_type    = p_inq->ble_addr_type;
4124     result.inq_res.inq_result_type  = p_inq->inq_result_type;
4125     result.inq_res.device_type      = p_inq->device_type;
4126     result.inq_res.flag             = p_inq->flag;
4127     result.inq_res.adv_data_len     = p_inq->adv_data_len;
4128     result.inq_res.scan_rsp_len     = p_inq->scan_rsp_len;
4129
4130     /* application will parse EIR to find out remote device name */
4131     result.inq_res.p_eir = p_eir;
4132
4133     if ((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL) {
4134         /* initialize remt_name_not_required to FALSE so that we get the name by default */
4135         result.inq_res.remt_name_not_required = FALSE;
4136     }
4137
4138     if (bta_dm_search_cb.p_scan_cback) {
4139         bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result);
4140     }
4141
4142     if (p_inq_info) {
4143         /* application indicates if it knows the remote name, inside the callback
4144          copy that to the inquiry data base*/
4145         if (result.inq_res.remt_name_not_required) {
4146             p_inq_info->appl_knows_rem_name = TRUE;
4147         }
4148     }
4149 }
4150
4151 /*******************************************************************************
4152 **
4153 ** Function         bta_dm_observe_cmpl_cb
4154 **
4155 ** Description      Callback for BLE Observe complete
4156 **
4157 **
4158 ** Returns          void
4159 **
4160 *******************************************************************************/
4161 static void bta_dm_observe_cmpl_cb (void *p_result)
4162 {
4163     tBTA_DM_SEARCH  data;
4164
4165     APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb");
4166
4167     data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
4168     if (bta_dm_search_cb.p_scan_cback) {
4169         bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
4170     }
4171 }
4172
4173 #if (SMP_INCLUDED == TRUE)
4174 /*******************************************************************************
4175 **
4176 ** Function         bta_dm_ble_smp_cback
4177 **
4178 ** Description      Callback for BLE SMP
4179 **
4180 **
4181 ** Returns          void
4182 **
4183 *******************************************************************************/
4184 static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data)
4185 {
4186     tBTM_STATUS status = BTM_SUCCESS;
4187     tBTA_DM_SEC sec_event;
4188     char *p_name = NULL;
4189
4190     if (!bta_dm_cb.p_sec_cback) {
4191         return BTM_NOT_AUTHORIZED;
4192     }
4193
4194     memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
4195     switch (event) {
4196     case BTM_LE_IO_REQ_EVT:
4197         // #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
4198
4199         bta_dm_co_ble_io_req(bda,
4200                              &p_data->io_req.io_cap,
4201                              &p_data->io_req.oob_data,
4202                              &p_data->io_req.auth_req,
4203                              &p_data->io_req.max_key_size,
4204                              &p_data->io_req.init_keys,
4205                              &p_data->io_req.resp_keys);
4206         // #endif
4207 #if BTM_OOB_INCLUDED == FALSE
4208         status = BTM_SUCCESS;
4209 #endif
4210         APPL_TRACE_EVENT("io mitm: %d oob_data:%d\n", p_data->io_req.auth_req, p_data->io_req.oob_data);
4211
4212         break;
4213
4214     case BTM_LE_SEC_REQUEST_EVT:
4215         bdcpy(sec_event.ble_req.bd_addr, bda);
4216         p_name = BTM_SecReadDevName(bda);
4217         if (p_name != NULL) {
4218             BCM_STRNCPY_S((char *)sec_event.ble_req.bd_name,
4219                           sizeof(BD_NAME), p_name, (BD_NAME_LEN));
4220         } else {
4221             sec_event.ble_req.bd_name[0] = 0;
4222         }
4223         sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
4224         bta_dm_cb.p_sec_cback(BTA_DM_BLE_SEC_REQ_EVT, &sec_event);
4225         break;
4226
4227     case BTM_LE_KEY_NOTIF_EVT:
4228         bdcpy(sec_event.key_notif.bd_addr, bda);
4229         p_name = BTM_SecReadDevName(bda);
4230         if (p_name != NULL) {
4231             BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,
4232                           sizeof(BD_NAME), p_name, (BD_NAME_LEN));
4233         } else {
4234             sec_event.key_notif.bd_name[0] = 0;
4235         }
4236         sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
4237         sec_event.key_notif.passkey = p_data->key_notif;
4238         bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_NOTIF_EVT, &sec_event);
4239         break;
4240
4241     case BTM_LE_KEY_REQ_EVT:
4242         bdcpy(sec_event.ble_req.bd_addr, bda);
4243         bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_REQ_EVT, &sec_event);
4244         break;
4245
4246     case BTM_LE_OOB_REQ_EVT:
4247         bdcpy(sec_event.ble_req.bd_addr, bda);
4248         bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event);
4249         break;
4250
4251     case BTM_LE_NC_REQ_EVT:
4252         bdcpy(sec_event.key_notif.bd_addr, bda);
4253         BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN));
4254         sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
4255         sec_event.key_notif.passkey = p_data->key_notif;
4256         bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
4257         break;
4258
4259     case BTM_LE_KEY_EVT:
4260         bdcpy(sec_event.ble_key.bd_addr, bda);
4261         sec_event.ble_key.key_type = p_data->key.key_type;
4262         sec_event.ble_key.p_key_value = p_data->key.p_key_value;
4263         bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event);
4264         break;
4265
4266     case BTM_LE_COMPLT_EVT:
4267         bdcpy(sec_event.auth_cmpl.bd_addr, bda);
4268 #if BLE_INCLUDED == TRUE
4269         BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
4270 #endif
4271         p_name = BTM_SecReadDevName(bda);
4272         if (p_name != NULL) {
4273             BCM_STRNCPY_S((char *)sec_event.auth_cmpl.bd_name,
4274                           sizeof(BD_NAME), p_name, (BD_NAME_LEN));
4275         } else {
4276             sec_event.auth_cmpl.bd_name[0] = 0;
4277         }
4278         if (p_data->complt.reason != 0) {
4279             sec_event.auth_cmpl.fail_reason = BTA_DM_AUTH_CONVERT_SMP_CODE(((UINT8)p_data->complt.reason));
4280             /* delete this device entry from Sec Dev DB */
4281             bta_dm_remove_sec_dev_entry (bda);
4282         } else {
4283             sec_event.auth_cmpl.success = TRUE;
4284             if (!p_data->complt.smp_over_br) {
4285                 
4286             }
4287         }
4288
4289         if (bta_dm_cb.p_sec_cback) {
4290             //bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
4291             bta_dm_cb.p_sec_cback(BTA_DM_BLE_AUTH_CMPL_EVT, &sec_event);
4292         }
4293
4294         break;
4295
4296     default:
4297         status = BTM_NOT_AUTHORIZED;
4298         break;
4299     }
4300     return status;
4301 }
4302
4303 /*******************************************************************************
4304 **
4305 ** Function         bta_dm_ble_id_key_cback
4306 **
4307 ** Description      Callback for BLE local ID keys
4308 **
4309 **
4310 ** Returns          void
4311 **
4312 *******************************************************************************/
4313 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key)
4314 {
4315     UINT8   evt;
4316     tBTA_DM_SEC dm_key;
4317
4318     switch (key_type) {
4319     case BTM_BLE_KEY_TYPE_ID:
4320     case BTM_BLE_KEY_TYPE_ER:
4321         if (bta_dm_cb.p_sec_cback) {
4322             memcpy(&dm_key.ble_id_keys, p_key, sizeof(tBTM_BLE_LOCAL_KEYS));
4323
4324             evt = (key_type == BTM_BLE_KEY_TYPE_ID) ? BTA_DM_BLE_LOCAL_IR_EVT : \
4325                   BTA_DM_BLE_LOCAL_ER_EVT;
4326             bta_dm_cb.p_sec_cback(evt, &dm_key);
4327         }
4328         break;
4329
4330     default:
4331         APPL_TRACE_DEBUG("Unknown key type %d", key_type);
4332         break;
4333     }
4334     return;
4335
4336 }
4337
4338 /*******************************************************************************
4339 **
4340 ** Function         bta_dm_add_blekey
4341 **
4342 ** Description      This function adds an BLE Key to an security database entry.
4343 **                  This function shall only be called AFTER BTA_DmAddBleDevice has been called.
4344 **                  It is normally called during host startup to restore all required information
4345 **                  stored in the NVRAM.
4346 **
4347 ** Parameters:
4348 **
4349 *******************************************************************************/
4350 void bta_dm_add_blekey (tBTA_DM_MSG *p_data)
4351 {
4352     if (!BTM_SecAddBleKey (p_data->add_ble_key.bd_addr,
4353                            (tBTM_LE_KEY_VALUE *)&p_data->add_ble_key.blekey,
4354                            p_data->add_ble_key.key_type)) {
4355         APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Key for device %08x%04x",
4356                           (p_data->add_ble_key.bd_addr[0] << 24) + (p_data->add_ble_key.bd_addr[1] << 16) + \
4357                           (p_data->add_ble_key.bd_addr[2] << 8) + p_data->add_ble_key.bd_addr[3],
4358                           (p_data->add_ble_key.bd_addr[4] << 8) + p_data->add_ble_key.bd_addr[5]);
4359     }
4360 }
4361
4362 /*******************************************************************************
4363 **
4364 ** Function         bta_dm_add_ble_device
4365 **
4366 ** Description      This function adds an BLE device to an security database entry.
4367 **                  It is normally called during host startup to restore all required information
4368 **                  stored in the NVRAM.
4369 **
4370 ** Parameters:
4371 **
4372 *******************************************************************************/
4373 void bta_dm_add_ble_device (tBTA_DM_MSG *p_data)
4374 {
4375     if (!BTM_SecAddBleDevice (p_data->add_ble_device.bd_addr, NULL,
4376                               p_data->add_ble_device.dev_type  ,
4377                               p_data->add_ble_device.addr_type)) {
4378         APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Device for device %08x%04x",
4379                           (p_data->add_ble_device.bd_addr[0] << 24) + (p_data->add_ble_device.bd_addr[1] << 16) + \
4380                           (p_data->add_ble_device.bd_addr[2] << 8) + p_data->add_ble_device.bd_addr[3],
4381                           (p_data->add_ble_device.bd_addr[4] << 8) + p_data->add_ble_device.bd_addr[5]);
4382     }
4383 }
4384
4385 /*******************************************************************************
4386 **
4387 ** Function         bta_dm_add_ble_device
4388 **
4389 ** Description      This function adds an BLE device to an security database entry.
4390 **                  It is normally called during host startup to restore all required information
4391 **                  stored in the NVRAM.
4392 **
4393 ** Parameters:
4394 **
4395 *******************************************************************************/
4396 void bta_dm_ble_passkey_reply (tBTA_DM_MSG *p_data)
4397 {
4398     if (p_data->pin_reply.accept) {
4399         BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_SUCCESS, p_data->ble_passkey_reply.passkey);
4400     } else {
4401         BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED, p_data->ble_passkey_reply.passkey);
4402     }
4403
4404 }
4405
4406 /*******************************************************************************
4407 **
4408 ** Function         bta_dm_ble_confirm_reply
4409 **
4410 ** Description      This is response to SM numeric comparison request submitted
4411 **                  to application.
4412 **
4413 ** Parameters:
4414 **
4415 *******************************************************************************/
4416 void bta_dm_ble_confirm_reply (tBTA_DM_MSG *p_data)
4417 {
4418     if (p_data->confirm.accept) {
4419         BTM_BleConfirmReply(p_data->confirm.bd_addr, BTM_SUCCESS);
4420     } else {
4421         BTM_BleConfirmReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED);
4422     }
4423 }
4424
4425 /*******************************************************************************
4426 **
4427 ** Function         bta_dm_security_grant
4428 **
4429 ** Description      This function grant SMP security request access.
4430 **
4431 ** Parameters:
4432 **
4433 *******************************************************************************/
4434 void bta_dm_security_grant (tBTA_DM_MSG *p_data)
4435 {
4436     BTM_SecurityGrant(p_data->ble_sec_grant.bd_addr, p_data->ble_sec_grant.res);
4437 }
4438 #endif  ///SMP_INCLUDED == TRUE
4439
4440 /*******************************************************************************
4441 **
4442 ** Function         bta_dm_ble_set_bg_conn_type
4443 **
4444 ** Description      This function set the BLE background connection type
4445 **
4446 ** Parameters:
4447 **
4448 *******************************************************************************/
4449 void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data)
4450 {
4451     BTM_BleSetBgConnType(p_data->ble_set_bd_conn_type.bg_conn_type,
4452                          p_data->ble_set_bd_conn_type.p_select_cback);
4453 }
4454
4455 /*******************************************************************************
4456 **
4457 ** Function         bta_dm_ble_set_conn_params
4458 **
4459 ** Description      This function set the preferred connection parameters.
4460 **
4461 ** Parameters:
4462 **
4463 *******************************************************************************/
4464 void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data)
4465 {
4466     BTM_BleSetPrefConnParams(p_data->ble_set_conn_params.peer_bda,
4467                              p_data->ble_set_conn_params.conn_int_min,
4468                              p_data->ble_set_conn_params.conn_int_max,
4469                              p_data->ble_set_conn_params.slave_latency,
4470                              p_data->ble_set_conn_params.supervision_tout);
4471 }
4472
4473 /*******************************************************************************
4474 **
4475 ** Function         bta_dm_ble_set_conn_scan_params
4476 **
4477 ** Description      This function sets BLE scan parameters.
4478 **
4479 ** Parameters:
4480 **
4481 *******************************************************************************/
4482 void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data)
4483 {
4484     BTM_BleSetScanParams(p_data->ble_set_scan_params.client_if,
4485                          p_data->ble_set_scan_params.scan_int,
4486                          p_data->ble_set_scan_params.scan_window,
4487                          p_data->ble_set_scan_params.scan_mode,
4488                          p_data->ble_set_scan_params.scan_param_setup_cback);
4489 }
4490
4491 /*******************************************************************************
4492 **
4493 ** Function         bta_dm_ble_set_scan_fil_params
4494 **
4495 ** Description      This function sets BLE scan filter & parameters.
4496 **
4497 ** Parameters:
4498 **
4499 *******************************************************************************/
4500 void bta_dm_ble_set_scan_fil_params(tBTA_DM_MSG *p_data)
4501 {
4502     BTM_BleSetScanFilterParams (p_data->ble_set_scan_fil_params.client_if,
4503                                 p_data->ble_set_scan_fil_params.scan_int,
4504                                 p_data->ble_set_scan_fil_params.scan_window,
4505                                 p_data->ble_set_scan_fil_params.scan_mode,
4506                                 p_data->ble_set_scan_fil_params.addr_type_own,
4507                                 p_data->ble_set_scan_fil_params.scan_filter_policy,
4508                                 p_data->ble_set_scan_fil_params.scan_param_setup_cback);
4509 }
4510
4511
4512 /*******************************************************************************
4513 **
4514 ** Function         bta_dm_ble_set_conn_scan_params
4515 **
4516 ** Description      This function set the preferred connection scan parameters.
4517 **
4518 ** Parameters:
4519 **
4520 *******************************************************************************/
4521 void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data)
4522 {
4523     BTM_BleSetConnScanParams(p_data->ble_set_conn_scan_params.scan_int,
4524                              p_data->ble_set_conn_scan_params.scan_window);
4525 }
4526 /*******************************************************************************
4527 **
4528 ** Function         bta_dm_ble_update_conn_params
4529 **
4530 ** Description      This function update LE connection parameters.
4531 **
4532 ** Parameters:
4533 **
4534 *******************************************************************************/
4535 void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
4536 {
4537     if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr,
4538                                   p_data->ble_update_conn_params.min_int,
4539                                   p_data->ble_update_conn_params.max_int,
4540                                   p_data->ble_update_conn_params.latency,
4541                                   p_data->ble_update_conn_params.timeout)) {
4542         APPL_TRACE_ERROR("Update connection parameters failed!");
4543     }
4544 }
4545 /*******************************************************************************
4546 **
4547 ** Function         bta_dm_ble_disconnect
4548 **
4549 ** Description      This function disconnect the ble connection.
4550 **
4551 ** Parameters:
4552 **
4553 *******************************************************************************/
4554 void bta_dm_ble_disconnect (tBTA_DM_MSG *p_data)
4555 {
4556     L2CA_RemoveFixedChnl(L2CAP_ATT_CID, p_data->ble_disconnect.remote_bda);
4557 }
4558
4559 /*******************************************************************************
4560 **
4561 ** Function         bta_dm_ble_set_rand_address
4562 **
4563 ** Description      This function set the LE random address for the device.
4564 **
4565 ** Parameters:      rand_addr:the random address whitch should be setting
4566 ** Explanation:     This function added by Yulong at 2016/9/9
4567 *******************************************************************************/
4568 void bta_dm_ble_set_rand_address(tBTA_DM_MSG *p_data)
4569 {
4570     BOOLEAN set_flag = false;
4571     if (p_data->set_addr.addr_type != BLE_ADDR_RANDOM) {
4572         APPL_TRACE_ERROR("Invalid random adress type = %d\n", p_data->set_addr.addr_type);
4573         return;
4574     }
4575     //send the setting random address to BTM layer
4576     if ((set_flag = BTM_BleSetRandAddress(p_data->set_addr.address) != TRUE)){
4577         APPL_TRACE_ERROR("%s,set random address fail.", __func__);
4578     }
4579
4580 }
4581
4582 /*******************************************************************************
4583 **
4584 ** Function         bta_dm_ble_stop_advertising
4585 **
4586 ** Description      This function stop the BLE avdertising for the device.
4587 **
4588 ** Parameters:      void
4589 ** Explanation:     This function added by Yulong at 2016/10/19
4590 *******************************************************************************/
4591 void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data)
4592 {
4593     if (p_data->hdr.event != BTA_DM_API_BLE_STOP_ADV_EVT) {
4594         APPL_TRACE_ERROR("Invalid BTA event,cann't stop the BLE adverting\n");
4595     }
4596
4597     btm_ble_stop_adv();
4598 }
4599
4600
4601
4602 #if BLE_PRIVACY_SPT == TRUE
4603 /*******************************************************************************
4604 **
4605 ** Function         bta_dm_ble_config_local_privacy
4606 **
4607 ** Description      This function set the local device LE privacy settings.
4608 **
4609 ** Parameters:
4610 **
4611 *******************************************************************************/
4612 void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data)
4613 {
4614     BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable, p_data->ble_local_privacy.set_local_privacy_cback);
4615 }
4616 #endif
4617
4618 /*******************************************************************************
4619 **
4620 ** Function         bta_dm_ble_observe
4621 **
4622 ** Description      This function set the preferred connection scan parameters.
4623 **
4624 ** Parameters:
4625 **
4626 *******************************************************************************/
4627 void bta_dm_ble_observe (tBTA_DM_MSG *p_data)
4628 {
4629     tBTM_STATUS status;
4630     if (p_data->ble_observe.start) {
4631         /*Save the  callback to be called when a scan results are available */
4632         bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback;
4633
4634         if ((status = BTM_BleObserve(TRUE, p_data->ble_observe.duration,
4635                                      bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) {
4636             APPL_TRACE_WARNING(" %s start observe failed. status=0x%x\n", __FUNCTION__, status);
4637         }
4638
4639         if (p_data->ble_observe.p_start_scan_cback) {
4640             status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4641             p_data->ble_observe.p_start_scan_cback(status);
4642         }
4643     } else {
4644         bta_dm_search_cb.p_scan_cback = NULL;
4645         status = BTM_BleObserve(FALSE, 0, NULL, NULL);
4646
4647         if (status != BTM_CMD_STARTED){
4648             APPL_TRACE_WARNING(" %s stop observe failed, status=0x%x\n", __FUNCTION__, status);
4649         }
4650
4651         if (p_data->ble_observe.p_stop_scan_cback) {
4652             status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4653             p_data->ble_observe.p_stop_scan_cback(status);
4654         }
4655     }
4656 }
4657
4658 /*******************************************************************************
4659 **
4660 ** Function         bta_dm_ble_scan
4661 **
4662 ** Description      This function set the preferred connection scan parameters.
4663 **
4664 ** Parameters:
4665 **
4666 *******************************************************************************/
4667 void bta_dm_ble_scan (tBTA_DM_MSG *p_data)
4668 {
4669     tBTM_STATUS status;
4670     if (p_data->ble_scan.start) {
4671         /*Save the  callback to be called when a scan results are available */
4672         bta_dm_search_cb.p_scan_cback = p_data->ble_scan.p_cback;
4673
4674         if ((status = BTM_BleScan(TRUE, p_data->ble_scan.duration,
4675                                      bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) {
4676             APPL_TRACE_WARNING(" %s start scan failed. status=0x%x\n", __FUNCTION__, status);
4677         }
4678
4679         if (p_data->ble_scan.p_start_scan_cback) {
4680             status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4681             p_data->ble_scan.p_start_scan_cback(status);
4682         }
4683     } else {
4684         bta_dm_search_cb.p_scan_cback = NULL;
4685         status = BTM_BleScan(FALSE, 0, NULL, NULL);
4686
4687         if (status != BTM_CMD_STARTED){
4688             APPL_TRACE_WARNING(" %s stop scan failed, status=0x%x\n", __FUNCTION__, status);
4689         }
4690
4691         if (p_data->ble_scan.p_stop_scan_cback) {
4692             status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4693             p_data->ble_scan.p_stop_scan_cback(status);
4694         }
4695     }
4696 }
4697
4698 /*******************************************************************************
4699 **
4700 ** Function         bta_dm_ble_set_adv_params
4701 **
4702 ** Description      This function set the adv parameters.
4703 **
4704 ** Parameters:
4705 **
4706 *******************************************************************************/
4707 void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data)
4708 {
4709     BTM_BleSetAdvParams(p_data->ble_set_adv_params.adv_int_min,
4710                         p_data->ble_set_adv_params.adv_int_max,
4711                         p_data->ble_set_adv_params.p_dir_bda,
4712                         BTA_DM_BLE_ADV_CHNL_MAP);
4713 }
4714
4715 /*******************************************************************************
4716 **
4717 ** Function         bta_dm_ble_set_adv_params_all
4718 **
4719 ** Description      This function is called to set all of the advertising parameters.
4720 **
4721 ** Parameters:       None.
4722 **
4723 ** Returns          void
4724 **
4725 *******************************************************************************/
4726 void bta_dm_ble_set_adv_params_all  (tBTA_DM_MSG *p_data)
4727 {
4728     if (BTM_BleSetAdvParamsStartAdv(p_data->ble_set_adv_params_all.adv_int_min,
4729                                 p_data->ble_set_adv_params_all.adv_int_max,
4730                                 p_data->ble_set_adv_params_all.adv_type,
4731                                 p_data->ble_set_adv_params_all.addr_type_own,
4732                                 p_data->ble_set_adv_params_all.p_dir_bda,
4733                                 p_data->ble_set_adv_params_all.channel_map,
4734                                 p_data->ble_set_adv_params_all.adv_filter_policy,
4735                                 p_data->ble_set_adv_params_all.p_start_adv_cback) == BTM_SUCCESS) {
4736         APPL_TRACE_DEBUG("%s(), success to start ble adv.", __func__);
4737     } else {
4738         APPL_TRACE_ERROR("%s(), fail to start ble adv.", __func__);
4739     }
4740 }
4741
4742 /*******************************************************************************
4743 **
4744 ** Function         bta_dm_ble_set_adv_config
4745 **
4746 ** Description      This function set the customized ADV data configuration
4747 **
4748 ** Parameters:
4749 **
4750 *******************************************************************************/
4751 void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data)
4752 {
4753     tBTA_STATUS status = BTA_FAILURE;
4754
4755     if (BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask,
4756                             (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS) {
4757         status = BTA_SUCCESS;
4758     }
4759
4760     if (p_data->ble_set_adv_data.p_adv_data_cback) {
4761         (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
4762     }
4763 }
4764
4765 /*******************************************************************************
4766 **
4767 ** Function         bta_dm_ble_set_adv_config_raw
4768 **
4769 ** Description      This function set the customized ADV data configuration
4770 **
4771 ** Parameters:
4772 **
4773 *******************************************************************************/
4774 void bta_dm_ble_set_adv_config_raw (tBTA_DM_MSG *p_data)
4775 {
4776     tBTA_STATUS status = BTA_FAILURE;
4777
4778     if (BTM_BleWriteAdvDataRaw(p_data->ble_set_adv_data_raw.p_raw_adv,
4779                                p_data->ble_set_adv_data_raw.raw_adv_len) == BTM_SUCCESS) {
4780         status = BTA_SUCCESS;
4781     }
4782
4783     if (p_data->ble_set_adv_data_raw.p_adv_data_cback) {
4784         (*p_data->ble_set_adv_data_raw.p_adv_data_cback)(status);
4785     }
4786 }
4787
4788
4789 /*******************************************************************************
4790 **
4791 ** Function         bta_dm_ble_set_scan_rsp
4792 **
4793 ** Description      This function set the customized ADV scan resp. configuration
4794 **
4795 ** Parameters:
4796 **
4797 *******************************************************************************/
4798 void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data)
4799 {
4800     tBTA_STATUS status = BTA_FAILURE;
4801
4802     if (BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
4803                             (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS) {
4804         status = BTA_SUCCESS;
4805     }
4806
4807     if (p_data->ble_set_adv_data.p_adv_data_cback) {
4808         (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
4809     }
4810 }
4811
4812 /*******************************************************************************
4813 **
4814 ** Function         bta_dm_ble_set_scan_rsp_raw
4815 **
4816 ** Description      This function set the raw scan response data
4817 **
4818 ** Parameters:
4819 **
4820 *******************************************************************************/
4821 void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data)
4822 {
4823     tBTA_STATUS status = BTA_FAILURE;
4824
4825     if (BTM_BleWriteScanRspRaw(p_data->ble_set_adv_data_raw.p_raw_adv,
4826                                p_data->ble_set_adv_data_raw.raw_adv_len) == BTM_SUCCESS) {
4827         status = BTA_SUCCESS;
4828     }
4829
4830     if (p_data->ble_set_adv_data_raw.p_adv_data_cback) {
4831         (*p_data->ble_set_adv_data_raw.p_adv_data_cback)(status);
4832     }
4833 }
4834
4835 /*******************************************************************************
4836 **
4837 ** Function         bta_dm_ble_set_data_length
4838 **
4839 ** Description      This function set the maximum transmission packet size
4840 **
4841 ** Parameters
4842 **
4843 *******************************************************************************/
4844 void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data)
4845 {
4846     tACL_CONN *p_acl_cb = btm_bda_to_acl(p_data->ble_set_data_length.remote_bda, BT_TRANSPORT_LE);
4847      if (p_acl_cb == NULL) {
4848          APPL_TRACE_ERROR("%s error: Invalid connection remote_bda.", __func__);
4849          return;
4850      } else {
4851          p_acl_cb->p_set_pkt_data_cback = p_data->ble_set_data_length.p_set_pkt_data_cback;
4852      }
4853      UINT8 status = BTM_SetBleDataLength(p_data->ble_set_data_length.remote_bda,
4854                                          p_data->ble_set_data_length.tx_data_length);
4855      if (status != BTM_SUCCESS) {
4856         APPL_TRACE_ERROR("%s failed\n", __FUNCTION__);
4857         if (p_data->ble_set_data_length.p_set_pkt_data_cback) {
4858             if (p_acl_cb->data_length_params.tx_len == 0){
4859                 uint16_t length = controller_get_interface()->get_acl_data_size_ble();
4860                 p_acl_cb->data_length_params.rx_len = length;
4861                 p_acl_cb->data_length_params.tx_len = length;
4862             }
4863             (*p_data->ble_set_data_length.p_set_pkt_data_cback)(status, &p_acl_cb->data_length_params);
4864         }
4865     }
4866 }
4867
4868 /*******************************************************************************
4869 **
4870 ** Function         bta_dm_ble_broadcast
4871 **
4872 ** Description      Starts or stops LE broadcasts
4873 **
4874 ** Parameters:
4875 **
4876 *******************************************************************************/
4877 void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data)
4878 {
4879     tBTM_STATUS status = 0;
4880     BOOLEAN start = p_data->ble_observe.start;
4881
4882     status = BTM_BleBroadcast(start, p_data->ble_observe.p_stop_adv_cback);
4883
4884     if (p_data->ble_observe.p_stop_adv_cback){
4885         if (status != BTM_SUCCESS){
4886             APPL_TRACE_WARNING("%s, %s, status=0x%x\n", __func__,\
4887                     (start == TRUE) ? "start adv failed" : "stop adv failed", status);
4888         }
4889     }
4890
4891 }
4892
4893 /*******************************************************************************
4894 **
4895 ** Function         bta_dm_ble_multi_adv_enb
4896 **
4897 ** Description      This function enables a single advertising instance
4898 **
4899 ** Parameters:
4900 **
4901 *******************************************************************************/
4902 void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data)
4903 {
4904     tBTM_STATUS btm_status = 0;
4905
4906     bta_dm_cb.p_multi_adv_cback = p_data->ble_multi_adv_enb.p_cback;
4907     if (BTM_BleMaxMultiAdvInstanceCount() > 0 && NULL != p_data->ble_multi_adv_enb.p_ref) {
4908         btm_status = BTM_BleEnableAdvInstance((tBTM_BLE_ADV_PARAMS *)
4909                                               p_data->ble_multi_adv_enb.p_params,
4910                                               p_data->ble_multi_adv_enb.p_cback,
4911                                               p_data->ble_multi_adv_enb.p_ref);
4912     }
4913
4914     if (BTM_CMD_STARTED != btm_status) {
4915         bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_ENB_EVT, 0xFF,
4916                                     p_data->ble_multi_adv_enb.p_ref, BTA_FAILURE);
4917     }
4918 }
4919 /*******************************************************************************
4920 **
4921 ** Function         bta_dm_ble_multi_adv_param_upd
4922 **
4923 ** Description      This function updates multiple advertising instance parameters
4924 **
4925 ** Parameters:
4926 **
4927 *******************************************************************************/
4928 void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data)
4929 {
4930     tBTM_STATUS btm_status = 0;
4931     void *p_ref = NULL;
4932
4933     if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_param.inst_id > 0
4934             && p_data->ble_multi_adv_param.inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
4935         btm_status = BTM_BleUpdateAdvInstParam(p_data->ble_multi_adv_param.inst_id,
4936                                                (tBTM_BLE_ADV_PARAMS *)p_data->ble_multi_adv_param.p_params);
4937     }
4938
4939     if (BTM_CMD_STARTED != btm_status) {
4940         p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_param.inst_id);
4941         bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_PARAM_EVT,
4942                                     p_data->ble_multi_adv_param.inst_id, p_ref, BTA_FAILURE);
4943     }
4944 }
4945 /*******************************************************************************
4946 **
4947 ** Function         bta_dm_ble_multi_adv_data
4948 **
4949 ** Description      This function write multiple advertising instance adv data
4950 **                  or scan response data
4951 **
4952 ** Parameters:
4953 **
4954 *******************************************************************************/
4955 void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data)
4956 {
4957     tBTM_STATUS btm_status = 0;
4958     void *p_ref = NULL;
4959
4960     if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_data.inst_id > 0
4961             && p_data->ble_multi_adv_data.inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
4962         btm_status = BTM_BleCfgAdvInstData(p_data->ble_multi_adv_data.inst_id,
4963                                            p_data->ble_multi_adv_data.is_scan_rsp,
4964                                            p_data->ble_multi_adv_data.data_mask,
4965                                            (tBTM_BLE_ADV_DATA *)p_data->ble_multi_adv_data.p_data);
4966     }
4967
4968     if (BTM_CMD_STARTED != btm_status) {
4969         p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_data.inst_id);
4970         bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DATA_EVT,
4971                                     p_data->ble_multi_adv_data.inst_id, p_ref, BTA_FAILURE);
4972     }
4973
4974 }
4975 /*******************************************************************************
4976 **
4977 ** Function         btm_dm_ble_multi_adv_disable
4978 **
4979 ** Description      This function disable a single adv instance
4980 **
4981 ** Parameters:
4982 **
4983 *******************************************************************************/
4984 void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data)
4985 {
4986     tBTM_STATUS btm_status = 0;
4987     void *p_ref = NULL;
4988
4989     if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_disable.inst_id > 0
4990             && p_data->ble_multi_adv_disable.inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
4991         btm_status = BTM_BleDisableAdvInstance(p_data->ble_multi_adv_disable.inst_id);
4992     }
4993
4994     if (BTM_CMD_STARTED != btm_status) {
4995         p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_disable.inst_id);
4996         bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DISABLE_EVT,
4997                                     p_data->ble_multi_adv_disable.inst_id, p_ref, BTA_FAILURE);
4998     }
4999 }
5000
5001 /*******************************************************************************
5002 **
5003 ** Function         bta_dm_ble_setup_storage
5004 **
5005 ** Description      This function configures up the storage parameters for ADV batch scanning
5006 **
5007 ** Parameters:
5008 **
5009 *******************************************************************************/
5010 void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data)
5011 {
5012     tBTM_STATUS btm_status = 0;
5013     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5014
5015     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5016
5017     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5018         btm_status = BTM_BleSetStorageConfig(p_data->ble_set_storage.batch_scan_full_max,
5019                                              p_data->ble_set_storage.batch_scan_trunc_max,
5020                                              p_data->ble_set_storage.batch_scan_notify_threshold,
5021                                              p_data->ble_set_storage.p_setup_cback,
5022                                              p_data->ble_set_storage.p_thres_cback,
5023                                              p_data->ble_set_storage.p_read_rep_cback,
5024                                              p_data->ble_set_storage.ref_value);
5025     }
5026
5027     if (BTM_CMD_STARTED != btm_status)
5028         bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, p_data->ble_set_storage.ref_value,
5029                               btm_status);
5030 }
5031
5032 /*******************************************************************************
5033 **
5034 ** Function         bta_dm_ble_enable_batch_scan
5035 **
5036 ** Description      This function sets up the parameters and enables batch scan
5037 **
5038 ** Parameters:
5039 **
5040 *******************************************************************************/
5041 void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data)
5042 {
5043     tBTM_STATUS btm_status = 0;
5044     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5045
5046     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5047
5048     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5049         btm_status = BTM_BleEnableBatchScan(p_data->ble_enable_scan.scan_mode,
5050                                             p_data->ble_enable_scan.scan_int,
5051                                             p_data->ble_enable_scan.scan_window,
5052                                             p_data->ble_enable_scan.discard_rule,
5053                                             p_data->ble_enable_scan.addr_type,
5054                                             p_data->ble_enable_scan.ref_value);
5055     }
5056
5057     if (BTM_CMD_STARTED != btm_status)
5058         bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_ENABLE_EVT, p_data->ble_enable_scan.ref_value,
5059                               btm_status);
5060 }
5061
5062 /*******************************************************************************
5063 **
5064 ** Function         bta_dm_ble_disable_batch_scan
5065 **
5066 ** Description      This function disables the batch scan
5067 **
5068 ** Parameters:
5069 **
5070 *******************************************************************************/
5071 void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data)
5072 {
5073     UNUSED(p_data);
5074     tBTM_STATUS btm_status = 0;
5075     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5076
5077     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5078
5079     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5080         btm_status = BTM_BleDisableBatchScan(p_data->ble_disable_scan.ref_value);
5081     }
5082
5083     if (BTM_CMD_STARTED != btm_status)
5084         bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_DISABLE_EVT, p_data->ble_enable_scan.ref_value,
5085                               btm_status);
5086 }
5087
5088 /*******************************************************************************
5089 **
5090 ** Function         bta_dm_ble_read_scan_reports
5091 **
5092 ** Description      This function reads the batch scan reports
5093 **
5094 ** Parameters:
5095 **
5096 *******************************************************************************/
5097 void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data)
5098 {
5099     tBTM_STATUS btm_status = 0;
5100     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5101
5102     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5103
5104     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5105         btm_status = BTM_BleReadScanReports(p_data->ble_read_reports.scan_type,
5106                                             p_data->ble_read_reports.ref_value);
5107     }
5108
5109     if (BTM_CMD_STARTED != btm_status)
5110         bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, p_data->ble_enable_scan.ref_value,
5111                               btm_status);
5112 }
5113
5114 /*******************************************************************************
5115 **
5116 ** Function         bta_dm_ble_track_advertiser
5117 **
5118 ** Description      This function tracks the specific advertiser
5119 **
5120 ** Parameters:
5121 **
5122 *******************************************************************************/
5123 void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data)
5124 {
5125     tBTM_STATUS btm_status = 0;
5126     BD_ADDR bda;
5127     memset(&bda, 0 , sizeof(BD_ADDR));
5128     tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5129     tBTA_DM_BLE_TRACK_ADV_DATA track_adv_data;
5130
5131     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5132
5133     if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5134         btm_status = BTM_BleTrackAdvertiser((tBTM_BLE_TRACK_ADV_CBACK *)
5135                                             p_data->ble_track_advert.p_track_adv_cback,
5136                                             p_data->ble_track_advert.ref_value);
5137     }
5138
5139     if (BTM_CMD_STARTED != btm_status) {
5140         memset(&track_adv_data, 0, sizeof(tBTA_DM_BLE_TRACK_ADV_DATA));
5141         track_adv_data.advertiser_info_present = NO_ADV_INFO_PRESENT; /* Indicates failure */
5142         track_adv_data.client_if = (UINT8)p_data->ble_track_advert.ref_value;
5143         p_data->ble_track_advert.p_track_adv_cback(&track_adv_data);
5144     }
5145 }
5146
5147 /*******************************************************************************
5148 **
5149 ** Function         bta_ble_scan_setup_cb
5150 **
5151 ** Description      Handle the setup callback from BTM layer and forward it to app layer
5152 **
5153 ** Parameters:
5154 **
5155 *******************************************************************************/
5156 void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_value,
5157                            tBTM_STATUS status)
5158 {
5159     tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0;
5160
5161     APPL_TRACE_DEBUG("bta_ble_scan_setup_cb : evt: %d, ref_value: %d, status:%d", evt,
5162                      ref_value, status);
5163
5164     switch (evt) {
5165     case BTM_BLE_BATCH_SCAN_ENABLE_EVT:
5166         bta_evt = BTA_BLE_BATCH_SCAN_ENB_EVT;
5167         break;
5168     case BTM_BLE_BATCH_SCAN_CFG_STRG_EVT:
5169         bta_evt = BTA_BLE_BATCH_SCAN_CFG_STRG_EVT;
5170         break;
5171     case BTM_BLE_BATCH_SCAN_DISABLE_EVT:
5172         bta_evt = BTA_BLE_BATCH_SCAN_DIS_EVT;
5173         break;
5174     case BTM_BLE_BATCH_SCAN_PARAM_EVT:
5175         bta_evt = BTA_BLE_BATCH_SCAN_PARAM_EVT;
5176         break;
5177     default:
5178         break;
5179     }
5180
5181     if (NULL != bta_dm_cb.p_setup_cback) {
5182         bta_dm_cb.p_setup_cback(bta_evt, ref_value, status);
5183     }
5184 }
5185
5186
5187 #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
5188 /*******************************************************************************
5189 **
5190 ** Function         bta_ble_scan_pf_cmpl
5191 **
5192 ** Description      ADV payload filtering operation complete callback
5193 **
5194 **
5195 ** Returns         TRUE if handled, otherwise FALSE.
5196 **
5197 *******************************************************************************/
5198 static void bta_ble_scan_cfg_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op,
5199                                   tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status,
5200                                   tBTM_BLE_REF_VALUE ref_value)
5201 {
5202     tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
5203
5204     APPL_TRACE_DEBUG("bta_ble_scan_cfg_cmpl: %d, %d, %d, %d", action, cfg_op, avbl_space, status);
5205
5206     if (bta_dm_cb.p_scan_filt_cfg_cback) {
5207         bta_dm_cb.p_scan_filt_cfg_cback(action, cfg_op, avbl_space, st, ref_value);
5208     }
5209 }
5210
5211 /*******************************************************************************
5212 **
5213 ** Function         bta_dm_cfg_filter_cond
5214 **
5215 ** Description      This function configure adv payload filtering condition
5216 **
5217 ** Parameters:
5218 **
5219 *******************************************************************************/
5220 void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data)
5221 {
5222     tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5223     tBTA_STATUS status = BTA_FAILURE;
5224
5225     tBTM_BLE_VSC_CB cmn_vsc_cb;
5226
5227     APPL_TRACE_DEBUG("bta_dm_cfg_filter_cond");
5228     BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5229     if (0 != cmn_vsc_cb.filter_support) {
5230         if ((st = BTM_BleCfgFilterCondition(p_data->ble_cfg_filter_cond.action,
5231                                             p_data->ble_cfg_filter_cond.cond_type,
5232                                             (tBTM_BLE_PF_FILT_INDEX)p_data->ble_cfg_filter_cond.filt_index,
5233                                             (tBTM_BLE_PF_COND_PARAM *)p_data->ble_cfg_filter_cond.p_cond_param,
5234                                             bta_ble_scan_cfg_cmpl, p_data->ble_cfg_filter_cond.ref_value))
5235                 == BTM_CMD_STARTED) {
5236             bta_dm_cb.p_scan_filt_cfg_cback = p_data->ble_cfg_filter_cond.p_filt_cfg_cback;
5237             return;
5238         }
5239     }
5240
5241     if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback)
5242         p_data->ble_cfg_filter_cond.p_filt_cfg_cback(BTA_DM_BLE_PF_CONFIG_EVT,
5243                 p_data->ble_cfg_filter_cond.cond_type, 0, status,
5244                 p_data->ble_cfg_filter_cond.ref_value);
5245     return;
5246 }
5247
5248 /*******************************************************************************
5249 **
5250 ** Function         bta_dm_enable_scan_filter
5251 **
5252 ** Description      This function enable/disable adv payload filtering condition
5253 **
5254 ** Parameters:
5255 **
5256 *******************************************************************************/
5257 void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data)
5258 {
5259     tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5260     tBTA_STATUS status = BTA_FAILURE;
5261
5262     tBTM_BLE_VSC_CB cmn_vsc_cb;
5263     APPL_TRACE_DEBUG("bta_dm_enable_scan_filter");
5264     BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5265
5266     if (0 != cmn_vsc_cb.filter_support) {
5267         if ((st = BTM_BleEnableDisableFilterFeature(p_data->ble_enable_scan_filt.action,
5268                   p_data->ble_enable_scan_filt.p_filt_status_cback,
5269                   (tBTM_BLE_REF_VALUE)p_data->ble_enable_scan_filt.ref_value)) == BTM_CMD_STARTED) {
5270             bta_dm_cb.p_scan_filt_status_cback = p_data->ble_enable_scan_filt.p_filt_status_cback;
5271         }
5272         return;
5273     }
5274
5275     if (p_data->ble_enable_scan_filt.p_filt_status_cback)
5276         p_data->ble_enable_scan_filt.p_filt_status_cback (BTA_DM_BLE_PF_ENABLE_EVT,
5277                 p_data->ble_enable_scan_filt.ref_value, status);
5278
5279 }
5280
5281 /*******************************************************************************
5282 **
5283 ** Function         bta_dm_scan_filter_param_setup
5284 **
5285 ** Description      This function sets up scan filter params
5286 **
5287 ** Parameters:
5288 **
5289 *******************************************************************************/
5290 void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data)
5291 {
5292     tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5293     tBTA_STATUS status = BTA_FAILURE;
5294
5295     tBTM_BLE_VSC_CB cmn_vsc_cb;
5296
5297     APPL_TRACE_DEBUG("bta_dm_scan_filter_param_setup");
5298     BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5299     if (0 != cmn_vsc_cb.filter_support) {
5300         if ((st = BTM_BleAdvFilterParamSetup(p_data->ble_scan_filt_param_setup.action,
5301                                              p_data->ble_scan_filt_param_setup.filt_index,
5302                                              (tBTM_BLE_PF_FILT_PARAMS *)&p_data->ble_scan_filt_param_setup.filt_params,
5303                                              p_data->ble_scan_filt_param_setup.p_target,
5304                                              p_data->ble_scan_filt_param_setup.p_filt_param_cback,
5305                                              p_data->ble_scan_filt_param_setup.ref_value)) == BTM_CMD_STARTED) {
5306             bta_dm_cb.p_scan_filt_param_cback = p_data->ble_scan_filt_param_setup.p_filt_param_cback;
5307             return;
5308         }
5309     }
5310
5311     if (p_data->ble_scan_filt_param_setup.p_filt_param_cback)
5312         p_data->ble_scan_filt_param_setup.p_filt_param_cback (BTA_DM_BLE_PF_ENABLE_EVT, 0,
5313                 p_data->ble_scan_filt_param_setup.ref_value, status);
5314
5315     return;
5316 }
5317 #endif
5318
5319 /*******************************************************************************
5320 **
5321 ** Function         bta_ble_enable_scan_cmpl
5322 **
5323 ** Description      ADV payload filtering enable / disable complete callback
5324 **
5325 **
5326 ** Returns          None
5327 **
5328 *******************************************************************************/
5329 static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time,
5330                                      tBTM_BLE_RX_TIME_MS rx_time,
5331                                      tBTM_BLE_IDLE_TIME_MS idle_time,
5332                                      tBTM_BLE_ENERGY_USED  energy_used,
5333                                      tBTM_STATUS status)
5334 {
5335     tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
5336     tBTA_DM_CONTRL_STATE ctrl_state = 0;
5337 #if ((defined BTA_GATT_INCLUDED) &&  (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
5338     if (BTA_SUCCESS == st) {
5339         ctrl_state = bta_dm_pm_obtain_controller_state();
5340     }
5341 #endif  
5342     if (bta_dm_cb.p_energy_info_cback) {
5343         bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, ctrl_state, st);
5344     }
5345 }
5346
5347 /*******************************************************************************
5348 **
5349 ** Function         bta_dm_ble_get_energy_info
5350 **
5351 ** Description      This function obtains the energy info
5352 **
5353 ** Parameters:
5354 **
5355 *******************************************************************************/
5356 void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data)
5357 {
5358     tBTM_STATUS btm_status = 0;
5359
5360     bta_dm_cb.p_energy_info_cback = p_data->ble_energy_info.p_energy_info_cback;
5361     btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl);
5362     if (BTM_CMD_STARTED != btm_status) {
5363         bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status);
5364     }
5365 }
5366
5367 #if ((defined BTA_GATT_INCLUDED) &&  (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
5368 #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
5369 #define BTA_DM_GATT_CLOSE_DELAY_TOUT    1000
5370 #endif
5371
5372 /*******************************************************************************
5373 **
5374 ** Function         bta_dm_gattc_register
5375 **
5376 ** Description      Register with GATTC in DM if BLE is needed.
5377 **
5378 **
5379 ** Returns          void
5380 **
5381 *******************************************************************************/
5382 #if (GATTC_INCLUDED == TRUE)
5383 static void bta_dm_gattc_register(void)
5384 {
5385     tBT_UUID                app_uuid = {LEN_UUID_128, {0}};
5386
5387     if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF) {
5388         memset (&app_uuid.uu.uuid128, 0x87, LEN_UUID_128);
5389         BTA_GATTC_AppRegister(&app_uuid, bta_dm_gattc_callback);
5390     }
5391 }
5392 #endif /* GATTC_INCLUDED == TRUE */
5393 /*******************************************************************************
5394 **
5395 ** Function         btm_dm_start_disc_gatt_services
5396 **
5397 ** Description      This function starts a GATT service search request.
5398 **
5399 ** Parameters:
5400 **
5401 *******************************************************************************/
5402 static void btm_dm_start_disc_gatt_services (UINT16 conn_id)
5403 {
5404     tBT_UUID    *p_uuid = bta_dm_search_cb.p_srvc_uuid +
5405                           bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
5406
5407     p_uuid = bta_dm_search_cb.p_srvc_uuid +
5408              bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
5409
5410     /* always search for all services */
5411     BTA_GATTC_ServiceSearchRequest(conn_id, p_uuid);
5412 }
5413
5414 /*******************************************************************************
5415 **
5416 ** Function         bta_dm_gatt_disc_result
5417 **
5418 ** Description      This function process the GATT service search result.
5419 **
5420 ** Parameters:
5421 **
5422 *******************************************************************************/
5423 #if (GATTC_INCLUDED == TRUE)
5424 static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
5425 {
5426     tBTA_DM_SEARCH   result;
5427
5428     /*
5429         * This logic will not work for gatt case.  We are checking against the bluetooth profiles here
5430         * just copy the GATTID in raw data field and send it across.
5431         */
5432
5433
5434     if ( bta_dm_search_cb.ble_raw_used + sizeof(tBTA_GATT_ID) < bta_dm_search_cb.ble_raw_size ) {
5435         APPL_TRACE_DEBUG("ADDING BLE SERVICE uuid=0x%x, ble_ptr = %p, ble_raw_used = 0x%x",
5436                          service_id.uuid.uu.uuid16, bta_dm_search_cb.p_ble_rawdata, bta_dm_search_cb.ble_raw_used);
5437
5438         if (bta_dm_search_cb.p_ble_rawdata) {
5439             memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used), &service_id,
5440                    sizeof(service_id) );
5441
5442             bta_dm_search_cb.ble_raw_used += sizeof(service_id);
5443         } else {
5444             APPL_TRACE_ERROR("p_ble_rawdata is NULL");
5445         }
5446
5447     } else {
5448         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 );
5449     }
5450
5451     LOG_INFO("%s service_id_uuid_len=%d ", __func__, service_id.uuid.len);
5452     if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
5453
5454         /* send result back to app now, one by one */
5455         bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
5456         BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN - 1));
5457         result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
5458         memcpy(&result.disc_ble_res.service, &service_id.uuid, sizeof(tBT_UUID));
5459
5460         bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
5461     }
5462 }
5463 #endif /* #if (GATTC_INCLUDED == TRUE) */
5464 /*******************************************************************************
5465 **
5466 ** Function         bta_dm_gatt_disc_complete
5467 **
5468 ** Description      This function process the GATT service search complete.
5469 **
5470 ** Parameters:
5471 **
5472 *******************************************************************************/
5473 static void bta_dm_gatt_disc_complete(UINT16 conn_id, tBTA_GATT_STATUS status)
5474 {
5475     tBTA_DM_MSG *p_msg;
5476
5477     APPL_TRACE_DEBUG("bta_dm_gatt_disc_complete conn_id = %d", conn_id);
5478
5479     if (bta_dm_search_cb.uuid_to_search > 0) {
5480         bta_dm_search_cb.uuid_to_search --;
5481     }
5482
5483     if (status == BTA_GATT_OK && bta_dm_search_cb.uuid_to_search > 0) {
5484         btm_dm_start_disc_gatt_services(conn_id);
5485     } else {
5486         bta_dm_search_cb.uuid_to_search = 0;
5487
5488         /* no more services to be discovered */
5489         if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
5490             p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
5491             p_msg->disc_result.result.disc_res.result = (status == BTA_GATT_OK) ? BTA_SUCCESS : BTA_FAILURE;
5492             APPL_TRACE_DEBUG("%s service found: 0x%08x", __FUNCTION__,
5493                              bta_dm_search_cb.services_found);
5494             p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
5495             p_msg->disc_result.result.disc_res.num_uuids = 0;
5496             p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
5497             bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
5498             BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
5499                           bta_dm_get_remname(), (BD_NAME_LEN - 1));
5500
5501             /* make sure the string is terminated */
5502             p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
5503
5504             p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE;
5505             if ( bta_dm_search_cb.ble_raw_used > 0 ) {
5506                 p_msg->disc_result.result.disc_res.p_raw_data = osi_malloc(bta_dm_search_cb.ble_raw_used);
5507
5508                 memcpy( p_msg->disc_result.result.disc_res.p_raw_data,
5509                         bta_dm_search_cb.p_ble_rawdata,
5510                         bta_dm_search_cb.ble_raw_used );
5511
5512                 p_msg->disc_result.result.disc_res.raw_data_size = bta_dm_search_cb.ble_raw_used;
5513             } else {
5514                 p_msg->disc_result.result.disc_res.p_raw_data = NULL;
5515                 bta_dm_search_cb.p_ble_rawdata = 0;
5516             }
5517
5518             bta_sys_sendmsg(p_msg);
5519         }
5520
5521         if (conn_id != BTA_GATT_INVALID_CONN_ID) {
5522             /* start a GATT channel close delay timer */
5523             bta_sys_start_timer(&bta_dm_search_cb.gatt_close_timer, BTA_DM_DISC_CLOSE_TOUT_EVT,
5524                                 BTA_DM_GATT_CLOSE_DELAY_TOUT);
5525             bdcpy(bta_dm_search_cb.pending_close_bda, bta_dm_search_cb.peer_bdaddr);
5526         }
5527         bta_dm_search_cb.gatt_disc_active = FALSE;
5528     }
5529 }
5530
5531 /*******************************************************************************
5532 **
5533 ** Function         bta_dm_close_gatt_conn
5534 **
5535 ** Description      This function close the GATT connection after delay timeout.
5536 **
5537 ** Parameters:
5538 **
5539 *******************************************************************************/
5540 #if (GATTC_INCLUDED == TRUE)
5541 void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data)
5542 {
5543     UNUSED(p_data);
5544
5545     if (bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID) {
5546         BTA_GATTC_Close(bta_dm_search_cb.conn_id);
5547     }
5548
5549     memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
5550     bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
5551 }
5552 #endif /* #if (GATTC_INCLUDED == TRUE) */
5553 /*******************************************************************************
5554 **
5555 ** Function         btm_dm_start_gatt_discovery
5556 **
5557 ** Description      This is GATT initiate the service search by open a GATT connection
5558 **                  first.
5559 **
5560 ** Parameters:
5561 **
5562 *******************************************************************************/
5563 #if (GATTC_INCLUDED == TRUE)
5564 void btm_dm_start_gatt_discovery (BD_ADDR bd_addr)
5565 {
5566     bta_dm_search_cb.gatt_disc_active = TRUE;
5567
5568     /* connection is already open */
5569     if (bdcmp(bta_dm_search_cb.pending_close_bda, bd_addr) == 0 &&
5570             bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID) {
5571         memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
5572         bta_sys_stop_timer(&bta_dm_search_cb.gatt_close_timer);
5573         btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
5574     } else {
5575         BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE, BTA_GATT_TRANSPORT_LE);
5576     }
5577 }
5578 #endif /* #if (GATTC_INCLUDED == TRUE) */
5579 /*******************************************************************************
5580 **
5581 ** Function         bta_dm_cancel_gatt_discovery
5582 **
5583 ** Description      This is GATT cancel the GATT service search.
5584 **
5585 ** Parameters:
5586 **
5587 *******************************************************************************/
5588 #if (GATTC_INCLUDED == TRUE)
5589 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr)
5590 {
5591     if (bta_dm_search_cb.conn_id == BTA_GATT_INVALID_CONN_ID) {
5592         BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, TRUE);
5593     }
5594
5595     bta_dm_gatt_disc_complete(bta_dm_search_cb.conn_id, (tBTA_GATT_STATUS) BTA_GATT_ERROR);
5596 }
5597 #endif /* #if (GATTC_INCLUDED == TRUE) */
5598 /*******************************************************************************
5599 **
5600 ** Function         bta_dm_proc_open_evt
5601 **
5602 ** Description      process BTA_GATTC_OPEN_EVT in DM.
5603 **
5604 ** Parameters:
5605 **
5606 *******************************************************************************/
5607 void bta_dm_proc_open_evt(tBTA_GATTC_OPEN *p_data)
5608 {
5609     UINT8           *p1;
5610     UINT8           *p2;
5611
5612     p1 = bta_dm_search_cb.peer_bdaddr;
5613     p2 = p_data->remote_bda;
5614
5615     APPL_TRACE_DEBUG("DM Search state= %d search_cb.peer_dbaddr: [%08x%04x] connected_bda= [%08x%04x] ",
5616                      bta_dm_search_cb.state,
5617                      ((p1[0]) << 24) + ((p1[1]) << 16) + ((p1[2]) << 8) + (p1[3]),
5618                      ((p1[4]) << 8) + p1[5],
5619                      ((p2[0]) << 24) + ((p2[1]) << 16) + ((p2[2]) << 8) + (p2[3]),
5620                      ((p2[4]) << 8) + p2[5]);
5621
5622     APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d" ,
5623                      p_data->conn_id,
5624                      p_data->client_if,
5625                      p_data->status);
5626
5627     bta_dm_search_cb.conn_id = p_data->conn_id;
5628
5629     if (p_data->status == BTA_GATT_OK) {
5630         btm_dm_start_disc_gatt_services(p_data->conn_id);
5631     } else {
5632         bta_dm_gatt_disc_complete(BTA_GATT_INVALID_CONN_ID, p_data->status);
5633     }
5634 }
5635
5636 /*******************************************************************************
5637 **
5638 ** Function         bta_dm_gattc_callback
5639 **
5640 ** Description      This is GATT client callback function used in DM.
5641 **
5642 ** Parameters:
5643 **
5644 *******************************************************************************/
5645 #if (GATTC_INCLUDED == TRUE)
5646 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
5647 {
5648     APPL_TRACE_DEBUG("bta_dm_gattc_callback event = %d", event);
5649
5650     switch (event) {
5651     case BTA_GATTC_REG_EVT:
5652         APPL_TRACE_DEBUG("BTA_GATTC_REG_EVT client_if = %d",  p_data->reg_oper.client_if);
5653         if (p_data->reg_oper.status == BTA_GATT_OK) {
5654             bta_dm_search_cb.client_if = p_data->reg_oper.client_if;
5655         } else {
5656             bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF;
5657         }
5658         break;
5659
5660     case BTA_GATTC_OPEN_EVT:
5661         bta_dm_proc_open_evt(&p_data->open);
5662         break;
5663
5664     case BTA_GATTC_SEARCH_RES_EVT:
5665         bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid);
5666         break;
5667
5668     case BTA_GATTC_SEARCH_CMPL_EVT:
5669         if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
5670             bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
5671         }
5672         break;
5673
5674     case BTA_GATTC_CLOSE_EVT:
5675         APPL_TRACE_DEBUG("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason);
5676         /* in case of disconnect before search is completed */
5677         if ( (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) &&
5678                 (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) &&
5679                 !memcmp(p_data->close.remote_bda, bta_dm_search_cb.peer_bdaddr, BD_ADDR_LEN)) {
5680             bta_dm_gatt_disc_complete((UINT16)BTA_GATT_INVALID_CONN_ID,  (tBTA_GATT_STATUS) BTA_GATT_ERROR);
5681         }
5682         break;
5683
5684     default:
5685         break;
5686     }
5687 }
5688 #endif /* #if (GATTC_INCLUDED == TRUE) */
5689 #endif /* BTA_GATT_INCLUDED */
5690
5691 #if BLE_VND_INCLUDED == TRUE
5692 /*******************************************************************************
5693 **
5694 ** Function         bta_dm_ctrl_features_rd_cmpl_cback
5695 **
5696 ** Description      callback to handle controller feature read complete
5697 **
5698 ** Parameters:
5699 **
5700 *******************************************************************************/
5701 static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result)
5702 {
5703     APPL_TRACE_DEBUG("%s  status = %d ", __FUNCTION__, result);
5704     if (result == BTM_SUCCESS) {
5705         if (bta_dm_cb.p_sec_cback) {
5706             bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
5707         }
5708     } else {
5709         APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d", __FUNCTION__, result);
5710     }
5711
5712 }
5713 #endif /* BLE_VND_INCLUDED */
5714
5715 #endif  /* BLE_INCLUDED */