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