1 /******************************************************************************
3 * Copyright (C) 2003-2014 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This file contains the action functions for device manager state
24 ******************************************************************************/
26 #include "bt_target.h"
30 #include "bta_dm_int.h"
31 #include "bta_dm_co.h"
38 #include "gap_api.h" /* For GAP_BleReadPeerPrefConnParams */
40 #include "controller.h"
42 #define LOG_TAG "bt_bta_dm"
43 // #include "osi/include/log.h"
45 #if (GAP_INCLUDED == TRUE)
49 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
50 static void bta_dm_inq_cmpl_cb (void *p_result);
51 static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, BD_NAME bd_name);
52 static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name);
53 #if (SDP_INCLUDED == TRUE)
54 static void bta_dm_find_services ( BD_ADDR bd_addr);
55 #endif ///SDP_INCLUDED == TRUE
56 static void bta_dm_discover_next_device(void);
57 #if (SDP_INCLUDED == TRUE)
58 static void bta_dm_sdp_callback (UINT16 sdp_status);
59 #endif ///SDP_INCLUDED == TRUE
60 #if (SMP_INCLUDED == TRUE)
61 static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, UINT8 *service_name, UINT8 service_id, BOOLEAN is_originator);
62 static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, BOOLEAN min_16_digit);
63 static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, LINK_KEY key, UINT8 key_type);
64 static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, int result);
65 #endif ///SMP_INCLUDED == TRUE
66 static void bta_dm_local_name_cback(BD_ADDR bd_addr);
67 static BOOLEAN bta_dm_check_av(UINT16 event);
68 static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data);
71 static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
73 /* Extended Inquiry Response */
74 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE && SMP_INCLUDED == TRUE)
75 static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data);
76 #endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */
78 static void bta_dm_set_eir (char *local_name);
79 #if (SDP_INCLUDED == TRUE)
80 static void bta_dm_eir_search_services( tBTM_INQ_RESULTS *p_result,
81 tBTA_SERVICE_MASK *p_services_to_search,
82 tBTA_SERVICE_MASK *p_services_found);
83 #endif ///SDP_INCLUDED == TRUE
84 static void bta_dm_search_timer_cback (TIMER_LIST_ENT *p_tle);
85 static void bta_dm_disable_conn_down_timer_cback (TIMER_LIST_ENT *p_tle);
86 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
87 static void bta_dm_adjust_roles(BOOLEAN delay_role_switch);
88 #if (SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE)
89 static char *bta_dm_get_remname(void);
90 #endif ///SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE
91 #if (SMP_INCLUDED == TRUE)
92 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result);
93 #endif ///SMP_INCLUDED == TRUE
94 #if (SDP_INCLUDED == TRUE)
95 static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr, tBT_TRANSPORT transport);
96 static void bta_dm_discover_device(BD_ADDR remote_bd_addr);
97 #endif ///SDP_INCLUDED == TRUE
98 static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status );
99 static void bta_dm_disable_search_and_disc(void);
101 #if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
102 #if ((defined SMP_INCLUDED) && (SMP_INCLUDED == TRUE))
103 static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data);
104 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key);
105 #endif ///SMP_INCLUDED == TRUE
106 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
107 #if (GATTC_INCLUDED == TRUE)
108 static void bta_dm_gattc_register(void);
109 static void btm_dm_start_gatt_discovery(BD_ADDR bd_addr);
110 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr);
111 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
112 #endif // (GATTC_INCLUDED == TRUE)
113 extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void);
116 #if BLE_VND_INCLUDED == TRUE
117 static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result);
120 #ifndef BTA_DM_BLE_ADV_CHNL_MAP
121 #define BTA_DM_BLE_ADV_CHNL_MAP (BTM_BLE_ADV_CHNL_37|BTM_BLE_ADV_CHNL_38|BTM_BLE_ADV_CHNL_39)
124 #if (SMP_INCLUDED == TRUE)
125 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
126 #endif ///SMP_INCLUDED == TRUE
127 static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
128 static void bta_dm_observe_cmpl_cb(void *p_result);
129 static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle);
130 extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8 *p_uuid128);
131 static void bta_dm_disable_timer_cback(TIMER_LIST_ENT *p_tle);
134 const UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID] = {
135 UUID_SERVCLASS_PNP_INFORMATION, /* Reserved */
136 UUID_SERVCLASS_SERIAL_PORT, /* BTA_SPP_SERVICE_ID */
137 UUID_SERVCLASS_DIALUP_NETWORKING, /* BTA_DUN_SERVICE_ID */
138 UUID_SERVCLASS_AUDIO_SOURCE, /* BTA_A2DP_SOURCE_SERVICE_ID */
139 UUID_SERVCLASS_LAN_ACCESS_USING_PPP, /* BTA_LAP_SERVICE_ID */
140 UUID_SERVCLASS_HEADSET, /* BTA_HSP_HS_SERVICE_ID */
141 UUID_SERVCLASS_HF_HANDSFREE, /* BTA_HFP_HS_SERVICE_ID */
142 UUID_SERVCLASS_OBEX_OBJECT_PUSH, /* BTA_OPP_SERVICE_ID */
143 UUID_SERVCLASS_OBEX_FILE_TRANSFER, /* BTA_FTP_SERVICE_ID */
144 UUID_SERVCLASS_CORDLESS_TELEPHONY, /* BTA_CTP_SERVICE_ID */
145 UUID_SERVCLASS_INTERCOM, /* BTA_ICP_SERVICE_ID */
146 UUID_SERVCLASS_IRMC_SYNC, /* BTA_SYNC_SERVICE_ID */
147 UUID_SERVCLASS_DIRECT_PRINTING, /* BTA_BPP_SERVICE_ID */
148 UUID_SERVCLASS_IMAGING_RESPONDER, /* BTA_BIP_SERVICE_ID */
149 UUID_SERVCLASS_PANU, /* BTA_PANU_SERVICE_ID */
150 UUID_SERVCLASS_NAP, /* BTA_NAP_SERVICE_ID */
151 UUID_SERVCLASS_GN, /* BTA_GN_SERVICE_ID */
152 UUID_SERVCLASS_SAP, /* BTA_SAP_SERVICE_ID */
153 UUID_SERVCLASS_AUDIO_SINK, /* BTA_A2DP_SERVICE_ID */
154 UUID_SERVCLASS_AV_REMOTE_CONTROL, /* BTA_AVRCP_SERVICE_ID */
155 UUID_SERVCLASS_HUMAN_INTERFACE, /* BTA_HID_SERVICE_ID */
156 UUID_SERVCLASS_VIDEO_SINK, /* BTA_VDP_SERVICE_ID */
157 UUID_SERVCLASS_PBAP_PSE, /* BTA_PBAP_SERVICE_ID */
158 UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, /* BTA_HSP_SERVICE_ID */
159 UUID_SERVCLASS_AG_HANDSFREE, /* BTA_HFP_SERVICE_ID */
160 UUID_SERVCLASS_MESSAGE_ACCESS, /* BTA_MAP_SERVICE_ID */
161 UUID_SERVCLASS_MESSAGE_NOTIFICATION, /* BTA_MN_SERVICE_ID */
162 UUID_SERVCLASS_HDP_PROFILE, /* BTA_HDP_SERVICE_ID */
163 UUID_SERVCLASS_PBAP_PCE /* BTA_PCE_SERVICE_ID */
164 #if BLE_INCLUDED && BTA_GATT_INCLUDED
165 , UUID_PROTOCOL_ATT /* BTA_GATT_SERVICE_ID */
170 * NOTE : The number of element in bta_service_id_to_btm_srv_id_lkup_tbl should be matching with
171 * the value BTA_MAX_SERVICE_ID in bta_api.h
173 * i.e., If you add new Service ID for BTA, the correct security ID of the new service
174 * from Security service definitions (btm_api.h) should be added to this lookup table.
176 const UINT32 bta_service_id_to_btm_srv_id_lkup_tbl [BTA_MAX_SERVICE_ID] = {
178 BTM_SEC_SERVICE_SERIAL_PORT, /* BTA_SPP_SERVICE_ID */
179 BTM_SEC_SERVICE_DUN, /* BTA_DUN_SERVICE_ID */
180 BTM_SEC_SERVICE_AVDTP, /* BTA_AUDIO_SOURCE_SERVICE_ID */
181 BTM_SEC_SERVICE_LAN_ACCESS, /* BTA_LAP_SERVICE_ID */
182 BTM_SEC_SERVICE_HEADSET_AG, /* BTA_HSP_SERVICE_ID */
183 BTM_SEC_SERVICE_AG_HANDSFREE, /* BTA_HFP_SERVICE_ID */
184 BTM_SEC_SERVICE_OBEX, /* BTA_OPP_SERVICE_ID */
185 BTM_SEC_SERVICE_OBEX_FTP, /* BTA_FTP_SERVICE_ID */
186 BTM_SEC_SERVICE_CORDLESS, /* BTA_CTP_SERVICE_ID */
187 BTM_SEC_SERVICE_INTERCOM, /* BTA_ICP_SERVICE_ID */
188 BTM_SEC_SERVICE_IRMC_SYNC, /* BTA_SYNC_SERVICE_ID */
189 BTM_SEC_SERVICE_BPP_JOB, /* BTA_BPP_SERVICE_ID */
190 BTM_SEC_SERVICE_BIP, /* BTA_BIP_SERVICE_ID */
191 BTM_SEC_SERVICE_BNEP_PANU, /* BTA_PANU_SERVICE_ID */
192 BTM_SEC_SERVICE_BNEP_NAP, /* BTA_NAP_SERVICE_ID */
193 BTM_SEC_SERVICE_BNEP_GN, /* BTA_GN_SERVICE_ID */
194 BTM_SEC_SERVICE_SAP, /* BTA_SAP_SERVICE_ID */
195 BTM_SEC_SERVICE_AVDTP, /* BTA_A2DP_SERVICE_ID */
196 BTM_SEC_SERVICE_AVCTP, /* BTA_AVRCP_SERVICE_ID */
197 BTM_SEC_SERVICE_HIDH_SEC_CTRL, /* BTA_HID_SERVICE_ID */
198 BTM_SEC_SERVICE_AVDTP, /* BTA_VDP_SERVICE_ID */
199 BTM_SEC_SERVICE_PBAP, /* BTA_PBAP_SERVICE_ID */
200 BTM_SEC_SERVICE_HEADSET, /* BTA_HSP_HS_SERVICE_ID */
201 BTM_SEC_SERVICE_HF_HANDSFREE, /* BTA_HFP_HS_SERVICE_ID */
202 BTM_SEC_SERVICE_MAP, /* BTA_MAP_SERVICE_ID */
203 BTM_SEC_SERVICE_MAP, /* BTA_MN_SERVICE_ID */
204 BTM_SEC_SERVICE_HDP_SNK, /* BTA_HDP_SERVICE_ID */
205 BTM_SEC_SERVICE_PBAP /* BTA_PCE_SERVICE_ID */
206 #if BLE_INCLUDED && BTA_GATT_INCLUDED
207 , BTM_SEC_SERVICE_ATT /* BTA_GATT_SERVICE_ID */
212 /* bta security callback */
213 #if (SMP_INCLUDED == TRUE)
214 const tBTM_APPL_INFO bta_security = {
215 &bta_dm_authorize_cback,
217 &bta_dm_new_link_key_cback,
218 &bta_dm_authentication_complete_cback,
219 &bta_dm_bond_cancel_complete_cback,
220 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
225 #if BLE_INCLUDED == TRUE
226 &bta_dm_ble_smp_cback,
227 &bta_dm_ble_id_key_cback,
228 #endif ///BLE_INCLUDED == TRUE
231 #endif ///SMP_INCLUDED == TRUE
233 #if (SDP_INCLUDED == TRUE)
234 #define MAX_DISC_RAW_DATA_BUF (1024)
235 UINT8 g_disc_raw_data_buf[MAX_DISC_RAW_DATA_BUF];
236 #endif ///SDP_INCLUDED == TRUE
237 extern DEV_CLASS local_device_default_class;
239 /*******************************************************************************
241 ** Function bta_dm_enable
243 ** Description Initialises the BT device manager
248 *******************************************************************************/
249 void bta_dm_enable(tBTA_DM_MSG *p_data)
251 tBTA_SYS_HW_MSG *sys_enable_event;
252 tBTA_DM_ENABLE enable_event;
254 /* if already in use, return an error */
255 if ( bta_dm_cb.is_bta_dm_active == TRUE ) {
256 APPL_TRACE_WARNING("%s Device already started by another application", __func__);
257 memset(&enable_event, 0, sizeof(tBTA_DM_ENABLE));
258 enable_event.status = BTA_FAILURE;
259 if (p_data->enable.p_sec_cback != NULL) {
260 p_data->enable.p_sec_cback(BTA_DM_ENABLE_EVT, (tBTA_DM_SEC *)&enable_event);
265 /* first, register our callback to SYS HW manager */
266 bta_sys_hw_register( BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback );
268 /* make sure security callback is saved - if no callback, do not erase the previous one,
269 it could be an error recovery mechanism */
270 if ( p_data->enable.p_sec_cback != NULL ) {
271 bta_dm_cb.p_sec_cback = p_data->enable.p_sec_cback;
273 /* notify BTA DM is now active */
274 bta_dm_cb.is_bta_dm_active = TRUE;
276 /* send a message to BTA SYS */
277 if ((sys_enable_event = (tBTA_SYS_HW_MSG *) osi_malloc(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
278 sys_enable_event->hdr.event = BTA_SYS_API_ENABLE_EVT;
279 sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;
281 bta_sys_sendmsg(sys_enable_event);
285 /*******************************************************************************
287 * Function bta_dm_init_cb
289 * Description Initializes the bta_dm_cb control block
294 ******************************************************************************/
295 void bta_dm_init_cb(void)
297 memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
300 /*******************************************************************************
302 * Function bta_dm_deinit_cb
304 * Description De-initializes the bta_dm_cb control block
309 ******************************************************************************/
310 void bta_dm_deinit_cb(void)
312 bta_sys_free_timer(&bta_dm_cb.disable_timer);
313 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )
314 bta_sys_free_timer(&bta_dm_cb.app_ready_timer);
316 #if BTM_SSR_INCLUDED == TRUE
317 for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
318 for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
319 bta_sys_free_timer(&bta_dm_cb.pm_timer[i].timer[j]);
323 memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
326 /*******************************************************************************
328 ** Function bta_dm_sys_hw_cback
330 ** Description callback register to SYS to get HW status updates
335 *******************************************************************************/
336 static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
339 tBTA_DM_SEC_CBACK *temp_cback;
340 #if BLE_INCLUDED == TRUE
343 tBTA_BLE_LOCAL_ID_KEYS id_key;
346 APPL_TRACE_DEBUG("%s with event: %i", __func__, status);
348 /* On H/W error evt, report to the registered DM application callback */
349 if (status == BTA_SYS_HW_ERROR_EVT) {
350 if ( bta_dm_cb.p_sec_cback != NULL ) {
351 bta_dm_cb.p_sec_cback(BTA_DM_HW_ERROR_EVT, NULL);
356 if ( status == BTA_SYS_HW_OFF_EVT ) {
357 if ( bta_dm_cb.p_sec_cback != NULL ) {
358 bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL);
361 /* reinitialize the control block */
364 bta_sys_free_timer(&bta_dm_search_cb.search_timer);
365 #if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
366 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
367 bta_sys_free_timer(&bta_dm_search_cb.gatt_close_timer);
370 memset(&bta_dm_search_cb, 0x00, sizeof(bta_dm_search_cb));
372 /* unregister from SYS */
373 bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH );
374 /* notify BTA DM is now unactive */
375 bta_dm_cb.is_bta_dm_active = FALSE;
376 } else if ( status == BTA_SYS_HW_ON_EVT ) {
377 /* FIXME: We should not unregister as the SYS shall invoke this callback on a H/W error.
378 * We need to revisit when this platform has more than one BLuetooth H/W chip */
379 //bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH);
381 /* save security callback */
382 temp_cback = bta_dm_cb.p_sec_cback;
383 /* make sure the control block is properly initialized */
386 /* and retrieve the callback */
387 bta_dm_cb.p_sec_cback = temp_cback;
388 bta_dm_cb.is_bta_dm_active = TRUE;
390 bta_sys_free_timer(&bta_dm_search_cb.search_timer);
391 #if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
392 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
393 bta_sys_free_timer(&bta_dm_search_cb.gatt_close_timer);
396 /* hw is ready, go on with BTA DM initialization */
397 memset(&bta_dm_search_cb, 0x00, sizeof(bta_dm_search_cb));
398 #if (BTM_SSR_INCLUDED == TRUE)
399 memset(&bta_dm_conn_srvcs, 0x00, sizeof(bta_dm_conn_srvcs));
400 #endif ///BTM_SSR_INCLUDED == TRUE
401 memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB));
403 memcpy(dev_class, p_bta_dm_cfg->dev_class, sizeof(dev_class));
404 BTM_SetDeviceClass (dev_class);
406 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
407 /* load BLE local information: ID keys, ER if available */
408 bta_dm_co_ble_load_local_keys(&key_mask, er, &id_key);
410 if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ER) {
411 BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ER, (tBTM_BLE_LOCAL_KEYS *)&er);
413 if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ID) {
414 BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ID, (tBTM_BLE_LOCAL_KEYS *)&id_key);
416 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
417 bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
420 #if (SMP_INCLUDED == TRUE)
421 BTM_SecRegister((tBTM_APPL_INFO *)&bta_security);
422 #endif ///SMP_INCLUDED == TRUE
423 BTM_SetDefaultLinkSuperTout(p_bta_dm_cfg->link_timeout);
424 BTM_WritePageTimeout(p_bta_dm_cfg->page_timeout);
425 bta_dm_cb.cur_policy = p_bta_dm_cfg->policy_settings;
426 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
427 BTM_RegBusyLevelNotif (bta_dm_bl_change_cback, NULL, BTM_BL_UPDATE_MASK | BTM_BL_ROLE_CHG_MASK);
429 #if BLE_VND_INCLUDED == TRUE
430 BTM_BleReadControllerFeatures (bta_dm_ctrl_features_rd_cmpl_cback);
433 /* Earlier, we used to invoke BTM_ReadLocalAddr which was just copying the bd_addr
434 from the control block and invoking the callback which was sending the DM_ENABLE_EVT.
435 But then we have a few HCI commands being invoked above which were still in progress
436 when the ENABLE_EVT was sent. So modified this to fetch the local name which forces
437 the DM_ENABLE_EVT to be sent only after all the init steps are complete */
438 BTM_ReadLocalDeviceNameFromController((tBTM_CMPL_CB *)bta_dm_local_name_cback);
440 bta_sys_rm_register((tBTA_SYS_CONN_CBACK *)bta_dm_rm_cback);
441 #if (BTM_SSR_INCLUDED == TRUE)
442 /* initialize bluetooth low power manager */
444 #endif ///BTM_SSR_INCLUDED == TRUE
445 bta_sys_policy_register((tBTA_SYS_CONN_CBACK *)bta_dm_policy_cback);
447 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE)
448 bta_dm_gattc_register();
452 APPL_TRACE_DEBUG(" --- ignored event");
458 /*******************************************************************************
460 ** Function bta_dm_disable
462 ** Description Disables the BT device manager
467 *******************************************************************************/
468 void bta_dm_disable (tBTA_DM_MSG *p_data)
472 /* Set l2cap idle timeout to 0 (so BTE immediately disconnects ACL link after last channel is closed) */
473 L2CA_SetIdleTimeoutByBdAddr((UINT8 *)BT_BD_ANY, 0, BT_TRANSPORT_BR_EDR);
474 L2CA_SetIdleTimeoutByBdAddr((UINT8 *)BT_BD_ANY, 0, BT_TRANSPORT_LE);
476 /* disable all active subsystems */
477 bta_sys_disable(BTA_SYS_HW_BLUETOOTH);
479 BTM_SetDiscoverability(BTM_NON_DISCOVERABLE, 0, 0);
480 BTM_SetConnectability(BTM_NON_CONNECTABLE, 0, 0);
481 #if (BTM_SSR_INCLUDED == TRUE)
483 #endif ///BTM_SSR_INCLUDED == TRUE
484 bta_dm_disable_search_and_disc();
485 bta_dm_cb.disabling = TRUE;
487 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
488 BTM_BleClearBgConnDev();
491 if (BTM_GetNumAclLinks() == 0) {
492 #if (defined(BTA_DISABLE_DELAY) && BTA_DISABLE_DELAY > 0)
493 /* If BTA_DISABLE_DELAY is defined and greater than zero, then delay the shutdown by
494 * BTA_DISABLE_DELAY milliseconds
496 APPL_TRACE_WARNING("%s BTA_DISABLE_DELAY set to %d ms",
497 __FUNCTION__, BTA_DISABLE_DELAY);
498 bta_sys_stop_timer(&bta_dm_cb.disable_timer);
499 bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK *)&bta_dm_disable_conn_down_timer_cback;
500 bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, BTA_DISABLE_DELAY);
502 bta_dm_disable_conn_down_timer_cback(NULL);
505 bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK *)&bta_dm_disable_timer_cback;
506 bta_dm_cb.disable_timer.param = 0;
507 bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 5000);
510 #if BLE_PRIVACY_SPT == TRUE
511 btm_ble_resolving_list_cleanup (); //by TH, because cmn_ble_vsc_cb.max_filter has something mistake as btm_ble_adv_filter_cleanup
516 /*******************************************************************************
518 ** Function bta_dm_disable_timer_cback
520 ** Description Called if the disable timer expires
521 ** Used to close ACL connections which are still active
527 *******************************************************************************/
528 static void bta_dm_disable_timer_cback (TIMER_LIST_ENT *p_tle)
532 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
533 BOOLEAN trigger_disc = FALSE;
536 APPL_TRACE_EVENT(" bta_dm_disable_timer_cback trial %d ", p_tle->param);
538 if (BTM_GetNumAclLinks() && p_tle->param == 0) {
539 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
540 #if (BLE_INCLUDED == TRUE)
541 transport = bta_dm_cb.device_list.peer_device[i].transport;
543 btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, transport);
547 /* Retrigger disable timer in case ACL disconnect failed, DISABLE_EVT still need
548 to be sent out to avoid jave layer disable timeout */
550 bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK *)&bta_dm_disable_timer_cback;
551 bta_dm_cb.disable_timer.param = 1;
552 bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 1500);
555 bta_dm_cb.disabling = FALSE;
557 bta_sys_remove_uuid(UUID_SERVCLASS_PNP_INFORMATION);
558 bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL);
565 /*******************************************************************************
567 ** Function bta_dm_set_dev_name
569 ** Description Sets local device name
574 *******************************************************************************/
575 void bta_dm_set_dev_name (tBTA_DM_MSG *p_data)
578 BTM_SetLocalDeviceName((char *)p_data->set_name.name);
579 bta_dm_set_eir ((char *)p_data->set_name.name);
582 void bta_dm_update_white_list(tBTA_DM_MSG *p_data)
584 BTM_BleUpdateAdvWhitelist(p_data->white_list.add_remove, p_data->white_list.remote_addr, p_data->white_list.add_wl_cb);
587 void bta_dm_ble_read_adv_tx_power(tBTA_DM_MSG *p_data)
589 if (p_data->read_tx_power.read_tx_power_cb != NULL) {
590 BTM_BleReadAdvTxPower(p_data->read_tx_power.read_tx_power_cb);
592 APPL_TRACE_ERROR("%s(), the callback function cann't be NULL.", __func__);
596 void bta_dm_ble_read_rssi(tBTA_DM_MSG *p_data)
598 if (p_data->rssi.read_rssi_cb != NULL) {
599 BTM_ReadRSSI(p_data->rssi.remote_addr, p_data->rssi.read_rssi_cb);
601 APPL_TRACE_ERROR("%s(), the callback function cann't be NULL.", __func__);
605 /*******************************************************************************
607 ** Function bta_dm_set_visibility
609 ** Description Sets discoverability, connectability and pairability
614 *******************************************************************************/
615 void bta_dm_set_visibility(tBTA_DM_MSG *p_data)
617 UINT16 window, interval;
618 UINT16 le_disc_mode = BTM_BleReadDiscoverability();
619 UINT16 disc_mode = BTM_ReadDiscoverability(&window, &interval);
620 UINT16 le_conn_mode = BTM_BleReadConnectability();
621 UINT16 conn_mode = BTM_ReadConnectability(&window, &interval);
623 /* set modes for Discoverability and connectability if not ignore */
624 if (p_data->set_visibility.disc_mode != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE)) {
625 if ((p_data->set_visibility.disc_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE)
626 p_data->set_visibility.disc_mode =
627 ((p_data->set_visibility.disc_mode & ~BTA_DM_LE_IGNORE) | le_disc_mode);
629 if ((p_data->set_visibility.disc_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE)
630 p_data->set_visibility.disc_mode =
631 ((p_data->set_visibility.disc_mode & ~BTA_DM_IGNORE) | disc_mode);
633 BTM_SetDiscoverability(p_data->set_visibility.disc_mode,
634 bta_dm_cb.inquiry_scan_window,
635 bta_dm_cb.inquiry_scan_interval);
638 if (p_data->set_visibility.conn_mode != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE)) {
639 if ((p_data->set_visibility.conn_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE)
640 p_data->set_visibility.conn_mode =
641 ((p_data->set_visibility.conn_mode & ~BTA_DM_LE_IGNORE) | le_conn_mode);
643 if ((p_data->set_visibility.conn_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE)
644 p_data->set_visibility.conn_mode =
645 ((p_data->set_visibility.conn_mode & ~BTA_DM_IGNORE) | conn_mode);
647 BTM_SetConnectability(p_data->set_visibility.conn_mode,
648 bta_dm_cb.page_scan_window,
649 bta_dm_cb.page_scan_interval);
652 /* Send False or True if not ignore */
653 if (p_data->set_visibility.pair_mode != BTA_DM_IGNORE ) {
655 if (p_data->set_visibility.pair_mode == BTA_DM_NON_PAIRABLE) {
656 bta_dm_cb.disable_pair_mode = TRUE;
658 bta_dm_cb.disable_pair_mode = FALSE;
663 /* Send False or True if not ignore */
664 if (p_data->set_visibility.conn_paired_only != BTA_DM_IGNORE) {
666 if (p_data->set_visibility.conn_paired_only == BTA_DM_CONN_ALL) {
667 bta_dm_cb.conn_paired_only = FALSE;
669 bta_dm_cb.conn_paired_only = TRUE;
674 /* Change mode if either mode is not ignore */
675 if (p_data->set_visibility.pair_mode != BTA_DM_IGNORE || p_data->set_visibility.conn_paired_only != BTA_DM_IGNORE) {
676 BTM_SetPairableMode((BOOLEAN)(!(bta_dm_cb.disable_pair_mode)), bta_dm_cb.conn_paired_only);
681 /*******************************************************************************
683 ** Function bta_dm_process_remove_device
685 ** Description Removes device, Disconnects ACL link if required.
687 *******************************************************************************/
688 void bta_dm_process_remove_device(BD_ADDR bd_addr)
690 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
691 /* need to remove all pending background connection before unpair */
692 BTA_GATTC_CancelOpen(0, bd_addr, FALSE);
695 BTM_SecDeleteDevice(bd_addr);
697 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
698 /* remove all cached GATT information */
699 BTA_GATTC_Refresh(bd_addr);
702 if (bta_dm_cb.p_sec_cback) {
703 tBTA_DM_SEC sec_event;
704 bdcpy(sec_event.link_down.bd_addr, bd_addr);
705 sec_event.link_down.status = HCI_SUCCESS;
706 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event);
710 /*******************************************************************************
712 ** Function bta_dm_remove_device
714 ** Description Removes device, disconnects ACL link if required.
716 *******************************************************************************/
717 void bta_dm_remove_device(tBTA_DM_MSG *p_data)
719 tBTA_DM_API_REMOVE_DEVICE *p_dev = &p_data->remove_dev;
724 BD_ADDR other_address;
725 bdcpy(other_address, p_dev->bd_addr);
727 /* If ACL exists for the device in the remove_bond message*/
728 BOOLEAN continue_delete_dev = FALSE;
729 UINT8 other_transport = BT_TRANSPORT_INVALID;
731 if (BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_LE) ||
732 BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_BR_EDR)) {
733 APPL_TRACE_DEBUG("%s: ACL Up count %d", __func__, bta_dm_cb.device_list.count);
734 continue_delete_dev = FALSE;
736 /* Take the link down first, and mark the device for removal when disconnected */
737 for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
738 if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_dev->bd_addr)) {
739 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
740 btm_remove_acl( p_dev->bd_addr, bta_dm_cb.device_list.peer_device[i].transport);
741 APPL_TRACE_DEBUG("%s:transport = %d", __func__,
742 bta_dm_cb.device_list.peer_device[i].transport);
744 /* save the other transport to check if device is connected on other_transport */
745 if (bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_LE) {
746 other_transport = BT_TRANSPORT_BR_EDR;
748 other_transport = BT_TRANSPORT_LE;
754 continue_delete_dev = TRUE;
757 // If it is DUMO device and device is paired as different address, unpair that device
758 // if different address
759 BOOLEAN continue_delete_other_dev = FALSE;
760 if ((other_transport && (BTM_ReadConnectedTransportAddress(other_address, other_transport))) ||
761 (!other_transport && (BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_BR_EDR) ||
762 BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_LE)))) {
763 continue_delete_other_dev = FALSE;
764 /* Take the link down first, and mark the device for removal when disconnected */
765 for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
766 if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, other_address)) {
767 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
768 btm_remove_acl(other_address, bta_dm_cb.device_list.peer_device[i].transport);
773 APPL_TRACE_DEBUG("%s: continue to delete the other dev ", __func__);
774 continue_delete_other_dev = TRUE;
777 /* Delete the device mentioned in the msg */
778 if (continue_delete_dev) {
779 bta_dm_process_remove_device(p_dev->bd_addr);
782 /* Delete the other paired device too */
783 BD_ADDR dummy_bda = {0};
784 if (continue_delete_other_dev && (bdcmp(other_address, dummy_bda) != 0)) {
785 bta_dm_process_remove_device(other_address);
789 /*******************************************************************************
791 ** Function bta_dm_add_device
793 ** Description This function adds a Link Key to an security database entry.
794 ** It is normally called during host startup to restore all required information
795 ** stored in the NVRAM.
797 *******************************************************************************/
798 void bta_dm_add_device (tBTA_DM_MSG *p_data)
800 tBTA_DM_API_ADD_DEVICE *p_dev = &p_data->add_dev;
803 UINT32 trusted_services_mask[BTM_SEC_SERVICE_ARRAY_SIZE];
805 UINT8 btm_mask_index = 0;
807 memset (trusted_services_mask, 0, sizeof(trusted_services_mask));
809 /* If not all zeros, the device class has been specified */
810 if (p_dev->dc_known) {
811 p_dc = (UINT8 *)p_dev->dc;
814 if (p_dev->link_key_known) {
815 p_lc = (UINT8 *)p_dev->link_key;
818 if (p_dev->is_trusted) {
819 /* covert BTA service mask to BTM mask */
820 while (p_dev->tm && (index < BTA_MAX_SERVICE_ID)) {
821 if (p_dev->tm & (UINT32)(1 << index)) {
823 btm_mask_index = bta_service_id_to_btm_srv_id_lkup_tbl[index] / BTM_SEC_ARRAY_BITS;
824 trusted_services_mask[btm_mask_index] |= (UINT32)(1 << (bta_service_id_to_btm_srv_id_lkup_tbl[index] - (UINT32)(btm_mask_index * 32)));
826 p_dev->tm &= (UINT32)(~(1 << index));
833 if (!BTM_SecAddDevice (p_dev->bd_addr, p_dc, p_dev->bd_name, p_dev->features,
834 trusted_services_mask, p_lc, p_dev->key_type, p_dev->io_cap,
835 p_dev->pin_length)) {
836 APPL_TRACE_ERROR ("BTA_DM: Error adding device %08x%04x",
837 (p_dev->bd_addr[0] << 24) + (p_dev->bd_addr[1] << 16) + (p_dev->bd_addr[2] << 8) + p_dev->bd_addr[3],
838 (p_dev->bd_addr[4] << 8) + p_dev->bd_addr[5]);
842 /*******************************************************************************
844 ** Function bta_dm_close_acl
846 ** Description This function forces to close the connection to a remote device
847 ** and optionaly remove the device from security database if
850 *******************************************************************************/
851 void bta_dm_close_acl(tBTA_DM_MSG *p_data)
853 tBTA_DM_API_REMOVE_ACL *p_remove_acl = &p_data->remove_acl;
856 APPL_TRACE_DEBUG("bta_dm_close_acl");
858 if (BTM_IsAclConnectionUp(p_remove_acl->bd_addr, p_remove_acl->transport)) {
859 for (index = 0; index < bta_dm_cb.device_list.count; index ++) {
860 if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, p_remove_acl->bd_addr)) {
864 if (index != bta_dm_cb.device_list.count) {
865 if (p_remove_acl->remove_dev) {
866 bta_dm_cb.device_list.peer_device[index].remove_dev_pending = TRUE;
869 APPL_TRACE_ERROR("unknown device, remove ACL failed");
871 /* Disconnect the ACL link */
872 btm_remove_acl(p_remove_acl->bd_addr, p_remove_acl->transport);
874 /* if to remove the device from security database ? do it now */
875 else if (p_remove_acl->remove_dev) {
876 if (!BTM_SecDeleteDevice(p_remove_acl->bd_addr)) {
877 APPL_TRACE_ERROR("delete device from security database failed.");
879 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
880 /* need to remove all pending background connection if any */
881 BTA_GATTC_CancelOpen(0, p_remove_acl->bd_addr, FALSE);
882 /* remove all cached GATT information */
883 BTA_GATTC_Refresh(p_remove_acl->bd_addr);
886 /* otherwise, no action needed */
890 /*******************************************************************************
892 ** Function bta_dm_remove_all_acl
894 ** Description This function forces to close all the ACL links specified by link type
896 *******************************************************************************/
897 void bta_dm_remove_all_acl(tBTA_DM_MSG *p_data)
899 const tBTA_DM_LINK_TYPE link_type = p_data->remove_all_acl.link_type;
900 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
902 APPL_TRACE_DEBUG("%s link type = %d", __func__, link_type);
904 for (UINT8 i = 0; i < bta_dm_cb.device_list.count; i++) {
906 bdcpy(addr, bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
907 #if defined (BLE_INCLUDED) && (BLE_INCLUDED == TRUE)
908 transport = bta_dm_cb.device_list.peer_device[i].transport;
910 if ((link_type == BTA_DM_LINK_TYPE_ALL) ||
911 ((link_type == BTA_DM_LINK_TYPE_LE) && (transport == BT_TRANSPORT_LE)) ||
912 ((link_type == BTA_DM_LINK_TYPE_BR_EDR) && (transport == BT_TRANSPORT_BR_EDR))) {
913 /* Disconnect the ACL link */
914 btm_remove_acl(addr, transport);
920 /*******************************************************************************
922 ** Function bta_dm_bond
924 ** Description Bonds with peer device
929 *******************************************************************************/
930 #if (SMP_INCLUDED == TRUE)
931 void bta_dm_bond (tBTA_DM_MSG *p_data)
934 tBTA_DM_SEC sec_event;
937 if (p_data->bond.transport == BTA_TRANSPORT_UNKNOWN) {
938 status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 );
940 status = BTM_SecBondByTransport ( p_data->bond.bd_addr, p_data->bond.transport, 0, NULL, 0 );
944 if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED)) {
946 memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
947 bdcpy(sec_event.auth_cmpl.bd_addr, p_data->bond.bd_addr);
948 p_name = BTM_SecReadDevName(p_data->bond.bd_addr);
949 if (p_name != NULL) {
950 memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN - 1));
951 sec_event.auth_cmpl.bd_name[BD_NAME_LEN - 1] = 0;
954 /* taken care of by memset [above]
955 sec_event.auth_cmpl.key_present = FALSE;
956 sec_event.auth_cmpl.success = FALSE;
958 sec_event.auth_cmpl.fail_reason = HCI_ERR_ILLEGAL_COMMAND;
959 if (status == BTM_SUCCESS) {
960 sec_event.auth_cmpl.success = TRUE;
962 /* delete this device entry from Sec Dev DB */
963 bta_dm_remove_sec_dev_entry(p_data->bond.bd_addr);
965 bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
970 /*******************************************************************************
972 ** Function bta_dm_bond_cancel
974 ** Description Cancels bonding with a peer device
979 *******************************************************************************/
980 void bta_dm_bond_cancel (tBTA_DM_MSG *p_data)
983 tBTA_DM_SEC sec_event;
985 APPL_TRACE_EVENT(" bta_dm_bond_cancel ");
986 status = BTM_SecBondCancel ( p_data->bond_cancel.bd_addr );
988 if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED && status != BTM_SUCCESS)) {
989 sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
991 bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
996 /*******************************************************************************
998 ** Function bta_dm_pin_reply
1000 ** Description Send the pin_reply to a request from BTM
1005 *******************************************************************************/
1006 void bta_dm_pin_reply (tBTA_DM_MSG *p_data)
1008 UINT32 trusted_mask[BTM_SEC_SERVICE_ARRAY_SIZE];
1009 UINT32 *current_trusted_mask;
1011 current_trusted_mask = BTM_ReadTrustedMask(p_data->pin_reply.bd_addr);
1013 if (current_trusted_mask) {
1014 memcpy(trusted_mask, current_trusted_mask, sizeof(trusted_mask));
1016 memset(trusted_mask, 0, sizeof(trusted_mask));
1019 if (p_data->pin_reply.accept) {
1021 BTM_PINCodeReply(p_data->pin_reply.bd_addr, BTM_SUCCESS, p_data->pin_reply.pin_len, p_data->pin_reply.p_pin, trusted_mask );
1023 BTM_PINCodeReply(p_data->pin_reply.bd_addr, BTM_NOT_AUTHORIZED, 0, NULL, trusted_mask );
1027 #endif ///SMP_INCLUDED == TRUE
1029 /*******************************************************************************
1031 ** Function bta_dm_policy_cback
1033 ** Description process the link policy changes
1037 *******************************************************************************/
1038 static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
1040 tBTA_DM_PEER_DEVICE *p_dev = NULL;
1041 UINT16 policy = app_id;
1042 UINT32 mask = (UINT32)(1 << id);
1045 p_dev = bta_dm_find_peer_device(peer_addr);
1048 APPL_TRACE_DEBUG(" bta_dm_policy_cback cmd:%d, policy:0x%x",
1051 case BTA_SYS_PLCY_SET:
1055 /* restore the default link policy */
1056 p_dev->link_policy |= policy;
1057 BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy));
1060 case BTA_SYS_PLCY_CLR:
1064 /* clear the policy from the default link policy */
1065 p_dev->link_policy &= (~policy);
1066 BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy));
1068 if (policy & (HCI_ENABLE_SNIFF_MODE | HCI_ENABLE_PARK_MODE)) {
1069 /* if clearing sniff/park, wake the link */
1070 #if (BTM_SSR_INCLUDED == TRUE)
1071 bta_dm_pm_active(p_dev->peer_bdaddr);
1072 #endif ///BTM_SSR_INCLUDED == TRUE
1076 case BTA_SYS_PLCY_DEF_SET:
1077 /* want to restore/set the role switch policy */
1078 bta_dm_cb.role_policy_mask &= ~mask;
1079 if (0 == bta_dm_cb.role_policy_mask) {
1080 /* if nobody wants to insist on the role */
1081 bta_dm_cb.cur_policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
1082 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
1086 case BTA_SYS_PLCY_DEF_CLR:
1087 /* want to remove the role switch policy */
1088 bta_dm_cb.role_policy_mask |= mask;
1089 bta_dm_cb.cur_policy &= ~HCI_ENABLE_MASTER_SLAVE_SWITCH;
1090 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
1095 /*******************************************************************************
1097 ** Function bta_dm_confirm
1099 ** Description Send the user confirm request reply in response to a
1104 *******************************************************************************/
1105 #if (SMP_INCLUDED == TRUE)
1106 void bta_dm_confirm(tBTA_DM_MSG *p_data)
1108 tBTM_STATUS res = BTM_NOT_AUTHORIZED;
1110 if (p_data->confirm.accept == TRUE) {
1113 BTM_ConfirmReqReply(res, p_data->confirm.bd_addr);
1115 #endif ///SMP_INCLUDED == TRUE
1117 /*******************************************************************************
1119 ** Function bta_dm_loc_oob
1121 ** Description Retrieve the OOB data from the local LM
1125 *******************************************************************************/
1126 #if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
1127 void bta_dm_loc_oob(tBTA_DM_MSG *p_data)
1130 BTM_ReadLocalOobData();
1133 /*******************************************************************************
1135 ** Function bta_dm_ci_io_req_act
1137 ** Description respond to the IO capabilities request from BTM
1141 *******************************************************************************/
1142 void bta_dm_ci_io_req_act(tBTA_DM_MSG *p_data)
1144 tBTM_AUTH_REQ auth_req = BTM_AUTH_AP_NO;
1145 if (p_data->ci_io_req.auth_req) {
1146 auth_req = BTM_AUTH_AP_YES;
1148 BTM_IoCapRsp(p_data->ci_io_req.bd_addr, p_data->ci_io_req.io_cap,
1149 p_data->ci_io_req.oob_data, auth_req);
1152 /*******************************************************************************
1154 ** Function bta_dm_ci_rmt_oob_act
1156 ** Description respond to the OOB data request for the remote device from BTM
1161 *******************************************************************************/
1162 void bta_dm_ci_rmt_oob_act(tBTA_DM_MSG *p_data)
1164 tBTM_STATUS res = BTM_NOT_AUTHORIZED;
1166 if (p_data->ci_rmt_oob.accept == TRUE) {
1169 BTM_RemoteOobDataReply(res, p_data->ci_rmt_oob.bd_addr,
1170 p_data->ci_rmt_oob.c, p_data->ci_rmt_oob.r );
1172 #endif /* BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE */
1174 /*******************************************************************************
1176 ** Function bta_dm_search_start
1178 ** Description Starts an inquiry
1183 *******************************************************************************/
1184 void bta_dm_search_start (tBTA_DM_MSG *p_data)
1186 tBTM_INQUIRY_CMPL result;
1188 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE)
1189 UINT16 len = (UINT16)(sizeof(tBT_UUID) * p_data->search.num_uuid);
1190 bta_dm_gattc_register();
1193 APPL_TRACE_DEBUG("%s avoid_scatter=%d", __func__, p_bta_dm_cfg->avoid_scatter);
1195 if (p_bta_dm_cfg->avoid_scatter &&
1196 (p_data->search.rs_res == BTA_DM_RS_NONE) && bta_dm_check_av(BTA_DM_API_SEARCH_EVT)) {
1197 memcpy(&bta_dm_cb.search_msg, &p_data->search, sizeof(tBTA_DM_API_SEARCH));
1201 BTM_ClearInqDb(NULL);
1202 /* save search params */
1203 bta_dm_search_cb.p_search_cback = p_data->search.p_cback;
1204 bta_dm_search_cb.services = p_data->search.services;
1206 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE)
1207 utl_freebuf((void **)&bta_dm_search_cb.p_srvc_uuid);
1209 if ((bta_dm_search_cb.num_uuid = p_data->search.num_uuid) != 0 &&
1210 p_data->search.p_uuid != NULL) {
1211 if ((bta_dm_search_cb.p_srvc_uuid = (tBT_UUID *)osi_malloc(len)) == NULL) {
1212 APPL_TRACE_ERROR("%s no resources", __func__);
1214 result.status = BTA_FAILURE;
1215 result.num_resp = 0;
1216 bta_dm_inq_cmpl_cb ((void *)&result);
1220 memcpy(bta_dm_search_cb.p_srvc_uuid, p_data->search.p_uuid, len);
1223 result.status = BTM_StartInquiry( (tBTM_INQ_PARMS *)&p_data->search.inq_params,
1224 bta_dm_inq_results_cb,
1225 (tBTM_CMPL_CB *) bta_dm_inq_cmpl_cb);
1227 APPL_TRACE_EVENT("%s status=%d", __func__, result.status);
1228 if (result.status != BTM_CMD_STARTED) {
1229 result.num_resp = 0;
1230 bta_dm_inq_cmpl_cb ((void *)&result);
1234 /*******************************************************************************
1236 ** Function bta_dm_search_cancel
1238 ** Description Cancels an ongoing search for devices
1243 *******************************************************************************/
1244 void bta_dm_search_cancel (tBTA_DM_MSG *p_data)
1249 if (BTM_IsInquiryActive()) {
1250 if (BTM_CancelInquiry() != BTM_CMD_STARTED) {
1251 bta_dm_search_cancel_notify(NULL);
1252 p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
1253 if (p_msg != NULL) {
1254 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1255 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1256 bta_sys_sendmsg(p_msg);
1259 /* flag a search cancel is pending */
1260 bta_dm_search_cb.cancel_pending = TRUE;
1263 /* If no Service Search going on then issue cancel remote name in case it is active */
1264 else if (!bta_dm_search_cb.name_discover_done) {
1265 BTM_CancelRemoteDeviceName();
1267 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1268 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1269 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1270 bta_sys_sendmsg(p_msg);
1274 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1275 p_msg->hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
1276 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1277 bta_sys_sendmsg(p_msg);
1281 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE && GATTC_INCLUDED == TRUE
1282 if (bta_dm_search_cb.gatt_disc_active) {
1283 bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
1288 /*******************************************************************************
1290 ** Function bta_dm_discover
1292 ** Description Discovers services on a remote device
1297 *******************************************************************************/
1298 #if (SDP_INCLUDED == TRUE)
1299 void bta_dm_discover (tBTA_DM_MSG *p_data)
1301 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && GATTC_INCLUDED == TRUE
1302 UINT16 len = (UINT16)(sizeof(tBT_UUID) * p_data->discover.num_uuid);
1304 APPL_TRACE_EVENT("%s services_to_search=0x%04X, sdp_search=%d", __func__,
1305 p_data->discover.services, p_data->discover.sdp_search);
1307 /* save the search condition */
1308 bta_dm_search_cb.services = p_data->discover.services;
1310 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && GATTC_INCLUDED == TRUE
1311 bta_dm_gattc_register();
1312 utl_freebuf((void **)&bta_dm_search_cb.p_srvc_uuid);
1313 if ((bta_dm_search_cb.num_uuid = p_data->discover.num_uuid) != 0 &&
1314 p_data->discover.p_uuid != NULL) {
1315 if ((bta_dm_search_cb.p_srvc_uuid = (tBT_UUID *)osi_malloc(len)) == NULL) {
1316 p_data->discover.p_cback(BTA_DM_DISC_CMPL_EVT, NULL);
1319 memcpy(bta_dm_search_cb.p_srvc_uuid, p_data->discover.p_uuid, len);
1321 bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid;
1324 bta_dm_search_cb.p_search_cback = p_data->discover.p_cback;
1325 bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
1326 bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
1327 bta_dm_search_cb.service_index = 0;
1328 bta_dm_search_cb.services_found = 0;
1329 bta_dm_search_cb.peer_name[0] = 0;
1330 bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
1331 bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead (p_data->discover.bd_addr);
1332 bta_dm_search_cb.transport = p_data->discover.transport;
1334 bta_dm_search_cb.name_discover_done = FALSE;
1335 memcpy(&bta_dm_search_cb.uuid, &p_data->discover.uuid, sizeof(tSDP_UUID));
1336 bta_dm_discover_device(p_data->discover.bd_addr);
1339 /*******************************************************************************
1341 ** Function bta_dm_di_disc_cmpl
1343 ** Description Sends event to application when DI discovery complete
1347 *******************************************************************************/
1348 void bta_dm_di_disc_cmpl(tBTA_DM_MSG *p_data)
1350 tBTA_DM_DI_DISC_CMPL di_disc;
1352 memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL));
1353 bdcpy(di_disc.bd_addr, bta_dm_search_cb.peer_bdaddr);
1355 if ((p_data->hdr.offset == SDP_SUCCESS)
1356 || (p_data->hdr.offset == SDP_DB_FULL)) {
1357 di_disc.num_record = SDP_GetNumDiRecords(bta_dm_di_cb.p_di_db);
1359 di_disc.result = BTA_FAILURE;
1362 bta_dm_di_cb.p_di_db = NULL;
1363 bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT, (tBTA_DM_SEARCH *) &di_disc);
1366 /*******************************************************************************
1368 ** Function bta_dm_di_disc_callback
1370 ** Description This function queries a remote device for DI information.
1375 *******************************************************************************/
1376 static void bta_dm_di_disc_callback(UINT16 result)
1380 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1381 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1382 p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT;
1383 p_msg->hdr.offset = result;
1384 bta_sys_sendmsg(p_msg);
1387 #endif ///SDP_INCLUDED == TRUE
1388 /*******************************************************************************
1390 ** Function bta_dm_disable_search_and_disc
1392 ** Description Cancels an ongoing search or discovery for devices in case of
1393 ** a Bluetooth disable
1398 *******************************************************************************/
1399 static void bta_dm_disable_search_and_disc (void)
1401 #if (SDP_INCLUDED == TRUE)
1402 tBTA_DM_DI_DISC_CMPL di_disc;
1403 #endif ///SDP_INCLUDED == TRUE
1404 if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
1405 bta_dm_search_cancel(NULL);
1407 #if (SDP_INCLUDED == TRUE)
1408 if (bta_dm_di_cb.p_di_db != NULL) {
1409 memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL));
1410 bdcpy(di_disc.bd_addr, bta_dm_search_cb.peer_bdaddr);
1411 di_disc.result = BTA_FAILURE;
1413 bta_dm_di_cb.p_di_db = NULL;
1414 bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT, NULL);
1416 #endif ///SDP_INCLUDED == TRUE
1419 /*******************************************************************************
1421 ** Function bta_dm_di_disc
1423 ** Description This function queries a remote device for DI information.
1428 *******************************************************************************/
1429 #if (SDP_INCLUDED == TRUE)
1430 void bta_dm_di_disc (tBTA_DM_MSG *p_data)
1432 UINT16 result = BTA_FAILURE;
1435 bta_dm_search_cb.p_search_cback = p_data->di_disc.p_cback;
1436 bdcpy(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.bd_addr);
1437 bta_dm_di_cb.p_di_db = p_data->di_disc.p_sdp_db;
1439 if ((bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(BTA_DM_SDP_DB_SIZE)) != NULL) {
1440 if ( SDP_DiDiscover(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.p_sdp_db,
1441 p_data->di_disc.len, bta_dm_di_disc_callback) == SDP_SUCCESS) {
1442 result = BTA_SUCCESS;
1445 APPL_TRACE_ERROR("No buffer to start DI discovery");
1448 if ( result == BTA_FAILURE &&
1449 (p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1450 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1451 p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT;
1452 p_data->hdr.offset = result;
1453 bta_sys_sendmsg(p_msg);
1456 #endif ///SDP_INCLUDED == TRUE
1458 /*******************************************************************************
1460 ** Function bta_dm_read_remote_device_name
1462 ** Description Initiate to get remote device name
1464 ** Returns TRUE if started to get remote name
1466 *******************************************************************************/
1467 #if (SDP_INCLUDED == TRUE)
1468 static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr, tBT_TRANSPORT transport)
1470 tBTM_STATUS btm_status;
1472 APPL_TRACE_DEBUG("bta_dm_read_remote_device_name");
1474 bdcpy(bta_dm_search_cb.peer_bdaddr, bd_addr);
1475 bta_dm_search_cb.peer_name[0] = 0;
1477 btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
1478 (tBTM_CMPL_CB *) bta_dm_remname_cback,
1481 if ( btm_status == BTM_CMD_STARTED ) {
1482 APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is started");
1485 } else if ( btm_status == BTM_BUSY ) {
1486 APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is busy");
1488 /* Remote name discovery is on going now so BTM cannot notify through "bta_dm_remname_cback" */
1489 /* adding callback to get notified that current reading remore name done */
1490 BTM_SecAddRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1494 APPL_TRACE_WARNING("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
1499 #endif ///SDP_INCLUDED == TRUE
1501 /*******************************************************************************
1503 ** Function bta_dm_inq_cmpl
1505 ** Description Process the inquiry complete event from BTM
1509 *******************************************************************************/
1510 void bta_dm_inq_cmpl (tBTA_DM_MSG *p_data)
1513 tBTA_DM_SEARCH data;
1515 APPL_TRACE_DEBUG("bta_dm_inq_cmpl");
1517 data.inq_cmpl.num_resps = p_data->inq_cmpl.num;
1518 bta_dm_search_cb.p_search_cback(BTA_DM_INQ_CMPL_EVT, &data);
1520 if ((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbFirst()) != NULL) {
1521 /* start name and service discovery from the first device on inquiry result */
1522 bta_dm_search_cb.name_discover_done = FALSE;
1523 bta_dm_search_cb.peer_name[0] = 0;
1524 #if (SDP_INCLUDED == TRUE)
1525 bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
1526 #endif ///SDP_INCLUDED == TRUE
1528 /* no devices, search complete */
1529 bta_dm_search_cb.services = 0;
1531 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1532 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1533 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1534 bta_sys_sendmsg(p_msg);
1539 /*******************************************************************************
1541 ** Function bta_dm_rmt_name
1543 ** Description Process the remote name result from BTM
1547 *******************************************************************************/
1548 void bta_dm_rmt_name (tBTA_DM_MSG *p_data)
1550 APPL_TRACE_DEBUG("bta_dm_rmt_name");
1552 if ( p_data->rem_name.result.disc_res.bd_name[0] && bta_dm_search_cb.p_btm_inq_info) {
1553 bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name = TRUE;
1555 #if (SDP_INCLUDED == TRUE)
1556 bta_dm_discover_device(bta_dm_search_cb.peer_bdaddr);
1557 #endif ///SDP_INCLUDED == TRUE
1560 /*******************************************************************************
1562 ** Function bta_dm_disc_rmt_name
1564 ** Description Process the remote name result from BTM when application
1565 ** wants to find the name for a bdaddr
1569 *******************************************************************************/
1570 void bta_dm_disc_rmt_name (tBTA_DM_MSG *p_data)
1572 tBTM_INQ_INFO *p_btm_inq_info;
1574 APPL_TRACE_DEBUG("bta_dm_disc_rmt_name");
1576 p_btm_inq_info = BTM_InqDbRead (p_data->rem_name.result.disc_res.bd_addr);
1577 if ( p_btm_inq_info ) {
1578 if ( p_data->rem_name.result.disc_res.bd_name[0] ) {
1579 p_btm_inq_info->appl_knows_rem_name = TRUE;
1582 #if (SDP_INCLUDED == TRUE)
1583 bta_dm_discover_device(p_data->rem_name.result.disc_res.bd_addr);
1584 #endif ///SDP_INCLUDED == TRUE
1587 /*******************************************************************************
1589 ** Function bta_dm_sdp_result
1591 ** Description Process the discovery result from sdp
1595 *******************************************************************************/
1596 #if (SDP_INCLUDED == TRUE)
1597 void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
1599 tSDP_DISC_REC *p_sdp_rec = NULL;
1601 BOOLEAN scn_found = FALSE;
1602 UINT16 service = 0xFFFF;
1603 tSDP_PROTOCOL_ELEM pe;
1605 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1606 tBT_UUID *p_uuid = bta_dm_search_cb.p_srvc_uuid;
1607 tBTA_DM_SEARCH result;
1608 tBT_UUID service_uuid;
1611 UINT32 num_uuids = 0;
1612 UINT8 uuid_list[32][MAX_UUID_SIZE]; // assuming a max of 32 services
1614 if ((p_data->sdp_event.sdp_result == SDP_SUCCESS)
1615 || (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH)
1616 || (p_data->sdp_event.sdp_result == SDP_DB_FULL)) {
1617 APPL_TRACE_DEBUG("sdp_result::0x%x", p_data->sdp_event.sdp_result);
1620 if ( bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID + 1) ) {
1621 p_sdp_rec = SDP_FindServiceUUIDInDb(bta_dm_search_cb.p_sdp_db, &bta_dm_search_cb.uuid, p_sdp_rec);
1622 if (p_sdp_rec && SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
1623 bta_dm_search_cb.peer_scn = (UINT8) pe.params[0];
1627 service = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1];
1628 p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, service, p_sdp_rec);
1630 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1631 /* finished with BR/EDR services, now we check the result for GATT based service UUID */
1632 if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID) {
1633 if (bta_dm_search_cb.uuid_to_search != 0 && p_uuid != NULL) {
1634 p_uuid += (bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search);
1635 /* only support 16 bits UUID for now */
1636 service = p_uuid->uu.uuid16;
1638 /* all GATT based services */
1640 /* find a service record, report it */
1641 p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db,
1644 if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) {
1645 /* send result back to app now, one by one */
1646 bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1647 BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN));
1648 result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
1649 result.disc_ble_res.service.len = service_uuid.len;
1650 result.disc_ble_res.service.uu.uuid16 = service_uuid.uu.uuid16;
1652 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
1656 if (bta_dm_search_cb.uuid_to_search > 0) {
1660 } while (p_sdp_rec);
1664 /* SDP_DB_FULL means some records with the
1665 required attributes were received */
1666 if (((p_data->sdp_event.sdp_result == SDP_DB_FULL) &&
1667 bta_dm_search_cb.services != BTA_ALL_SERVICE_MASK) ||
1668 (p_sdp_rec != NULL)) {
1669 if (service != UUID_SERVCLASS_PNP_INFORMATION && service != 0) {
1670 UINT16 tmp_svc = 0xFFFF;
1671 bta_dm_search_cb.services_found |=
1672 (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index - 1));
1673 tmp_svc = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1];
1674 /* Add to the list of UUIDs */
1675 sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]);
1681 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK &&
1682 bta_dm_search_cb.services_to_search == 0) {
1683 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1684 if ( bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID &&
1685 bta_dm_search_cb.uuid_to_search > 0) {
1686 bta_dm_search_cb.uuid_to_search --;
1689 if (bta_dm_search_cb.uuid_to_search == 0 ||
1690 bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID)
1692 bta_dm_search_cb.service_index++;
1693 } else { /* regular one service per search or PNP search */
1696 } while (bta_dm_search_cb.service_index <= BTA_MAX_SERVICE_ID);
1698 APPL_TRACE_DEBUG("%s services_found = %04x", __FUNCTION__,
1699 bta_dm_search_cb.services_found);
1701 /* Collect the 128-bit services here and put them into the list */
1702 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) {
1706 /* find a service record, report it */
1707 p_sdp_rec = SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec);
1709 if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid)) {
1710 memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE);
1714 } while (p_sdp_rec);
1716 /* if there are more services to search for */
1717 if (bta_dm_search_cb.services_to_search) {
1718 /* Free up the p_sdp_db before checking the next one */
1719 bta_dm_free_sdp_db(NULL);
1720 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
1723 /* start next bd_addr if necessary */
1725 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1728 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1729 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1730 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
1731 p_msg->disc_result.result.disc_res.p_raw_data = NULL;
1732 p_msg->disc_result.result.disc_res.raw_data_size = 0;
1733 p_msg->disc_result.result.disc_res.num_uuids = num_uuids;
1734 p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
1735 if (num_uuids > 0) {
1736 p_msg->disc_result.result.disc_res.p_uuid_list = (UINT8 *)osi_malloc(num_uuids * MAX_UUID_SIZE);
1737 if (p_msg->disc_result.result.disc_res.p_uuid_list) {
1738 memcpy(p_msg->disc_result.result.disc_res.p_uuid_list, uuid_list,
1739 num_uuids * MAX_UUID_SIZE);
1741 p_msg->disc_result.result.disc_res.num_uuids = 0;
1742 APPL_TRACE_ERROR("%s: Unable to allocate memory for uuid_list", __func__);
1745 //copy the raw_data to the discovery result structure
1748 if ( bta_dm_search_cb.p_sdp_db != NULL && bta_dm_search_cb.p_sdp_db->raw_used != 0 &&
1749 bta_dm_search_cb.p_sdp_db->raw_data != NULL) {
1751 "%s raw_data used = 0x%x raw_data_ptr = %p", __func__,
1752 bta_dm_search_cb.p_sdp_db->raw_used,
1753 bta_dm_search_cb.p_sdp_db->raw_data);
1755 p_msg->disc_result.result.disc_res.p_raw_data = osi_malloc(bta_dm_search_cb.p_sdp_db->raw_used);
1756 if ( NULL != p_msg->disc_result.result.disc_res.p_raw_data ) {
1757 memcpy( p_msg->disc_result.result.disc_res.p_raw_data,
1758 bta_dm_search_cb.p_sdp_db->raw_data,
1759 bta_dm_search_cb.p_sdp_db->raw_used );
1761 p_msg->disc_result.result.disc_res.raw_data_size =
1762 bta_dm_search_cb.p_sdp_db->raw_used;
1765 APPL_TRACE_DEBUG("%s Alloc failed to allocate %d bytes !!", __func__,
1766 bta_dm_search_cb.p_sdp_db->raw_used);
1769 bta_dm_search_cb.p_sdp_db->raw_data = NULL; //no need to free this - it is a global assigned.
1770 bta_dm_search_cb.p_sdp_db->raw_used = 0;
1771 bta_dm_search_cb.p_sdp_db->raw_size = 0;
1773 APPL_TRACE_DEBUG("%s raw data size is 0 or raw_data is null!!", __func__);
1775 /* Done with p_sdp_db. Free it */
1776 bta_dm_free_sdp_db(NULL);
1777 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
1779 //Piggy back the SCN over result field
1781 p_msg->disc_result.result.disc_res.result = (3 + bta_dm_search_cb.peer_scn);
1782 p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK;
1784 APPL_TRACE_EVENT(" Piggy back the SCN over result field SCN=%d", bta_dm_search_cb.peer_scn);
1787 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1788 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
1789 bta_dm_get_remname(), (BD_NAME_LEN - 1));
1791 /* make sure the string is null terminated */
1792 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
1794 bta_sys_sendmsg(p_msg);
1798 /* conn failed. No need for timer */
1799 if (p_data->sdp_event.sdp_result == SDP_CONN_FAILED || p_data->sdp_event.sdp_result == SDP_CONN_REJECTED
1800 || p_data->sdp_event.sdp_result == SDP_SECURITY_ERR) {
1801 bta_dm_search_cb.wait_disc = FALSE;
1804 /* not able to connect go to next device */
1805 osi_free(bta_dm_search_cb.p_sdp_db);
1806 bta_dm_search_cb.p_sdp_db = NULL;
1808 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1810 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1811 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1812 p_msg->disc_result.result.disc_res.result = BTA_FAILURE;
1813 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
1814 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1815 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
1816 bta_dm_get_remname(), (BD_NAME_LEN - 1));
1818 /* make sure the string is null terminated */
1819 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
1821 bta_sys_sendmsg(p_msg);
1825 #endif ///SDP_INCLUDE == TRUE
1827 /*******************************************************************************
1829 ** Function bta_dm_search_cmpl
1831 ** Description Sends event to application
1835 *******************************************************************************/
1836 void bta_dm_search_cmpl (tBTA_DM_MSG *p_data)
1838 APPL_TRACE_EVENT("%s", __func__);
1840 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE)
1841 utl_freebuf((void **)&bta_dm_search_cb.p_srvc_uuid);
1844 if (p_data->hdr.layer_specific == BTA_DM_API_DI_DISCOVER_EVT) {
1845 #if (SDP_INCLUDED == TRUE)
1846 bta_dm_di_disc_cmpl(p_data);
1847 #endif ///SDP_INCLUDED == TRUE
1849 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, NULL);
1853 /*******************************************************************************
1855 ** Function bta_dm_disc_result
1857 ** Description Service discovery result when discovering services on a device
1861 *******************************************************************************/
1862 void bta_dm_disc_result (tBTA_DM_MSG *p_data)
1864 APPL_TRACE_EVENT("%s", __func__);
1866 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1867 /* if any BR/EDR service discovery has been done, report the event */
1868 if ((bta_dm_search_cb.services & ((BTA_ALL_SERVICE_MASK | BTA_USER_SERVICE_MASK ) & ~BTA_BLE_SERVICE_MASK)))
1870 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
1872 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
1874 /* send a message to change state */
1875 if (p_msg != NULL) {
1876 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1877 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1878 bta_sys_sendmsg(p_msg);
1882 /*******************************************************************************
1884 ** Function bta_dm_search_result
1886 ** Description Service discovery result while searching for devices
1890 *******************************************************************************/
1891 void bta_dm_search_result (tBTA_DM_MSG *p_data)
1893 APPL_TRACE_DEBUG("%s searching:0x%04x, result:0x%04x", __func__,
1894 bta_dm_search_cb.services,
1895 p_data->disc_result.result.disc_res.services);
1897 /* call back if application wants name discovery or found services that application is searching */
1898 if (( !bta_dm_search_cb.services )
1899 || (( bta_dm_search_cb.services ) && ( p_data->disc_result.result.disc_res.services ))) {
1900 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
1903 /* if searching did not initiate to create link */
1904 if (!bta_dm_search_cb.wait_disc ) {
1905 /* if service searching is done with EIR, don't search next device */
1906 if ( bta_dm_search_cb.p_btm_inq_info ) {
1907 bta_dm_discover_next_device();
1910 /* wait until link is disconnected or timeout */
1911 bta_dm_search_cb.sdp_results = TRUE;
1912 bta_dm_search_cb.search_timer.p_cback = (TIMER_CBACK *)&bta_dm_search_timer_cback;
1913 bta_sys_start_timer(&bta_dm_search_cb.search_timer, 0, 1000 * (L2CAP_LINK_INACTIVITY_TOUT + 1) );
1918 /*******************************************************************************
1920 ** Function bta_dm_search_timer_cback
1922 ** Description Called when ACL disconnect time is over
1927 *******************************************************************************/
1928 static void bta_dm_search_timer_cback (TIMER_LIST_ENT *p_tle)
1932 APPL_TRACE_EVENT("%s", __func__);
1933 bta_dm_search_cb.wait_disc = FALSE;
1935 /* proceed with next device */
1936 bta_dm_discover_next_device();
1941 /*******************************************************************************
1943 ** Function bta_dm_free_sdp_db
1945 ** Description Frees SDP data base
1949 *******************************************************************************/
1950 #if (SDP_INCLUDED == TRUE)
1951 void bta_dm_free_sdp_db (tBTA_DM_MSG *p_data)
1954 if (bta_dm_search_cb.p_sdp_db) {
1955 osi_free(bta_dm_search_cb.p_sdp_db);
1956 bta_dm_search_cb.p_sdp_db = NULL;
1959 #endif ///SDP_INCLUDED == TRUE
1961 /*******************************************************************************
1963 ** Function bta_dm_queue_search
1965 ** Description Queues search command while search is being cancelled
1969 *******************************************************************************/
1970 void bta_dm_queue_search (tBTA_DM_MSG *p_data)
1972 if (bta_dm_search_cb.p_search_queue) {
1973 osi_free(bta_dm_search_cb.p_search_queue);
1976 bta_dm_search_cb.p_search_queue = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_SEARCH));
1977 memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_SEARCH));
1981 /*******************************************************************************
1983 ** Function bta_dm_queue_disc
1985 ** Description Queues discovery command while search is being cancelled
1989 *******************************************************************************/
1990 #if (SDP_INCLUDED == TRUE)
1991 void bta_dm_queue_disc (tBTA_DM_MSG *p_data)
1993 if (bta_dm_search_cb.p_search_queue) {
1994 osi_free(bta_dm_search_cb.p_search_queue);
1997 bta_dm_search_cb.p_search_queue = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_DISCOVER));
1998 memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_DISCOVER));
2000 #endif ///SDP_INCLUDED == TRUE
2002 /*******************************************************************************
2004 ** Function bta_dm_search_clear_queue
2006 ** Description Clears the queue if API search cancel is called
2010 *******************************************************************************/
2011 void bta_dm_search_clear_queue (tBTA_DM_MSG *p_data)
2014 if (bta_dm_search_cb.p_search_queue) {
2015 osi_free(bta_dm_search_cb.p_search_queue);
2016 bta_dm_search_cb.p_search_queue = NULL;
2020 /*******************************************************************************
2022 ** Function bta_dm_search_cancel_cmpl
2024 ** Description Search cancel is complete
2028 *******************************************************************************/
2029 void bta_dm_search_cancel_cmpl (tBTA_DM_MSG *p_data)
2032 if (bta_dm_search_cb.p_search_queue) {
2033 bta_sys_sendmsg(bta_dm_search_cb.p_search_queue);
2034 bta_dm_search_cb.p_search_queue = NULL;
2039 /*******************************************************************************
2041 ** Function bta_dm_search_cancel_transac_cmpl
2043 ** Description Current Service Discovery or remote name procedure is
2044 ** completed after search cancellation
2048 *******************************************************************************/
2049 #if (SDP_INCLUDED == TRUE)
2050 void bta_dm_search_cancel_transac_cmpl(tBTA_DM_MSG *p_data)
2053 if (bta_dm_search_cb.p_sdp_db) {
2054 osi_free(bta_dm_search_cb.p_sdp_db);
2055 bta_dm_search_cb.p_sdp_db = NULL;
2058 bta_dm_search_cancel_notify(NULL);
2060 #endif ///SDP_INCLUDED == TRUE
2063 /*******************************************************************************
2065 ** Function bta_dm_search_cancel_notify
2067 ** Description Notify application that search has been cancelled
2071 *******************************************************************************/
2072 void bta_dm_search_cancel_notify (tBTA_DM_MSG *p_data)
2075 if (bta_dm_search_cb.p_search_cback) {
2076 bta_dm_search_cb.p_search_cback(BTA_DM_SEARCH_CANCEL_CMPL_EVT, NULL);
2078 if (!bta_dm_search_cb.name_discover_done) {
2079 BTM_CancelRemoteDeviceName();
2081 #if (BLE_INCLUDED == TRUE) && (BTA_GATT_INCLUDED == TRUE) && (SDP_INCLUDED == TRUE) && (GATTC_INCLUDED) == TRUE
2082 if (bta_dm_search_cb.gatt_disc_active) {
2083 bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
2089 /*******************************************************************************
2091 ** Function bta_dm_find_services
2093 ** Description Starts discovery on a device
2097 *******************************************************************************/
2098 #if (SDP_INCLUDED == TRUE)
2099 static void bta_dm_find_services ( BD_ADDR bd_addr)
2104 memset (&uuid, 0, sizeof(tSDP_UUID));
2106 while (bta_dm_search_cb.service_index < BTA_MAX_SERVICE_ID) {
2107 tBTA_SERVICE_MASK this_service_mask = (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index));
2108 if ( bta_dm_search_cb.services_to_search & this_service_mask) {
2109 if ((bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(BTA_DM_SDP_DB_SIZE)) != NULL) {
2110 APPL_TRACE_DEBUG("bta_dm_search_cb.services = %04x***********", bta_dm_search_cb.services);
2111 /* try to search all services by search based on L2CAP UUID */
2112 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK ) {
2113 APPL_TRACE_DEBUG("%s services_to_search=%08x", __func__, bta_dm_search_cb.services_to_search);
2114 if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK) {
2115 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[0];
2116 bta_dm_search_cb.services_to_search &= ~BTA_RES_SERVICE_MASK;
2118 uuid.uu.uuid16 = UUID_PROTOCOL_L2CAP;
2119 bta_dm_search_cb.services_to_search = 0;
2122 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
2123 /* for LE only profile */
2124 if (this_service_mask == BTA_BLE_SERVICE_MASK) {
2125 if (bta_dm_search_cb.uuid_to_search > 0 && bta_dm_search_cb.p_srvc_uuid) {
2127 (const void *)(bta_dm_search_cb.p_srvc_uuid + \
2128 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search),
2131 bta_dm_search_cb.uuid_to_search -- ;
2133 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index];
2136 /* last one? clear the BLE service bit if all discovery has been done */
2137 if (bta_dm_search_cb.uuid_to_search == 0)
2138 bta_dm_search_cb.services_to_search &=
2139 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
2144 /* remove the service from services to be searched */
2145 bta_dm_search_cb.services_to_search &=
2146 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
2147 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index];
2151 if (uuid.len == 0) {
2152 uuid.len = LEN_UUID_16;
2155 if (this_service_mask == BTA_USER_SERVICE_MASK) {
2156 memcpy(&uuid, &bta_dm_search_cb.uuid, sizeof(tSDP_UUID));
2159 APPL_TRACE_DEBUG("%s search UUID = %04x", __func__, uuid.uu.uuid16);
2160 SDP_InitDiscoveryDb (bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1, &uuid, 0, NULL);
2162 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
2163 bta_dm_search_cb.p_sdp_db->raw_data = g_disc_raw_data_buf;
2165 bta_dm_search_cb.p_sdp_db->raw_size = MAX_DISC_RAW_DATA_BUF;
2167 if (!SDP_ServiceSearchAttributeRequest (bd_addr, bta_dm_search_cb.p_sdp_db, &bta_dm_sdp_callback)) {
2168 /* if discovery not successful with this device
2169 proceed to next one */
2170 osi_free(bta_dm_search_cb.p_sdp_db);
2171 bta_dm_search_cb.p_sdp_db = NULL;
2172 bta_dm_search_cb.service_index = BTA_MAX_SERVICE_ID;
2175 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
2176 if ((this_service_mask == BTA_BLE_SERVICE_MASK &&
2177 bta_dm_search_cb.uuid_to_search == 0) ||
2178 this_service_mask != BTA_BLE_SERVICE_MASK)
2180 bta_dm_search_cb.service_index++;
2184 APPL_TRACE_ERROR("#### Failed to allocate SDP DB buffer! ####");
2188 bta_dm_search_cb.service_index++;
2191 /* no more services to be discovered */
2192 if (bta_dm_search_cb.service_index >= BTA_MAX_SERVICE_ID) {
2193 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
2194 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
2195 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
2196 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2197 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
2198 bta_dm_get_remname(), (BD_NAME_LEN - 1));
2200 /* make sure the string is terminated */
2201 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
2203 bta_sys_sendmsg(p_msg);
2207 #endif ///SDP_INCLUDED == TRUE
2209 /*******************************************************************************
2211 ** Function bta_dm_discover_next_device
2213 ** Description Starts discovery on the next device in Inquiry data base
2217 *******************************************************************************/
2218 static void bta_dm_discover_next_device(void)
2223 APPL_TRACE_DEBUG("bta_dm_discover_next_device");
2225 /* searching next device on inquiry result */
2226 if ((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbNext(bta_dm_search_cb.p_btm_inq_info)) != NULL) {
2227 bta_dm_search_cb.name_discover_done = FALSE;
2228 bta_dm_search_cb.peer_name[0] = 0;
2229 #if (SDP_INCLUDED == TRUE)
2230 bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
2231 #endif ///SDP_INCLUDED == TRUE
2233 /* no devices, search complete */
2234 bta_dm_search_cb.services = 0;
2236 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
2237 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
2238 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
2239 bta_sys_sendmsg(p_msg);
2244 /*******************************************************************************
2246 ** Function bta_dm_discover_device
2248 ** Description Starts name and service discovery on the device
2252 *******************************************************************************/
2253 #if (SDP_INCLUDED == TRUE)
2254 static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
2257 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
2259 #if BLE_INCLUDED == TRUE
2260 if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN) {
2261 tBT_DEVICE_TYPE dev_type;
2262 tBLE_ADDR_TYPE addr_type;
2264 BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
2265 if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM) {
2266 transport = BT_TRANSPORT_LE;
2269 transport = bta_dm_search_cb.transport;
2273 /* Reset transport state for next discovery */
2274 bta_dm_search_cb.transport = BTA_TRANSPORT_UNKNOWN;
2276 APPL_TRACE_DEBUG("%s BDA:0x%02X%02X%02X%02X%02X%02X", __func__,
2277 remote_bd_addr[0], remote_bd_addr[1],
2278 remote_bd_addr[2], remote_bd_addr[3],
2279 remote_bd_addr[4], remote_bd_addr[5]);
2281 bdcpy(bta_dm_search_cb.peer_bdaddr, remote_bd_addr);
2283 APPL_TRACE_DEBUG("%s name_discover_done = %d p_btm_inq_info %p state = %d, transport=%d",
2285 bta_dm_search_cb.name_discover_done,
2286 bta_dm_search_cb.p_btm_inq_info,
2287 bta_dm_search_cb.state,
2290 if (bta_dm_search_cb.p_btm_inq_info) {
2291 APPL_TRACE_DEBUG("%s appl_knows_rem_name %d", __func__,
2292 bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name);
2295 if ((bta_dm_search_cb.p_btm_inq_info)
2296 && (bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE)
2297 && (bta_dm_search_cb.state == BTA_DM_SEARCH_ACTIVE)) {
2298 /* Do not perform RNR for LE devices at inquiry complete*/
2299 bta_dm_search_cb.name_discover_done = TRUE;
2302 /* if name discovery is not done and application needs remote name */
2303 if ((!bta_dm_search_cb.name_discover_done)
2304 && (( bta_dm_search_cb.p_btm_inq_info == NULL )
2305 || (bta_dm_search_cb.p_btm_inq_info && (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name)))) {
2306 if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport) == TRUE) {
2310 /* starting name discovery failed */
2311 bta_dm_search_cb.name_discover_done = TRUE;
2314 /* if application wants to discover service */
2315 if ( bta_dm_search_cb.services ) {
2316 /* initialize variables */
2317 bta_dm_search_cb.service_index = 0;
2318 bta_dm_search_cb.services_found = 0;
2319 bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
2320 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE
2321 bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid;
2323 if ((bta_dm_search_cb.p_btm_inq_info != NULL) &&
2324 bta_dm_search_cb.services != BTA_USER_SERVICE_MASK
2325 && (bta_dm_search_cb.sdp_search == FALSE)) {
2326 /* check if EIR provides the information of supported services */
2327 bta_dm_eir_search_services( &bta_dm_search_cb.p_btm_inq_info->results,
2328 &bta_dm_search_cb.services_to_search,
2329 &bta_dm_search_cb.services_found );
2332 /* if seaching with EIR is not completed */
2333 if (bta_dm_search_cb.services_to_search) {
2334 /* check whether connection already exists to the device
2335 if connection exists, we don't have to wait for ACL
2336 link to go down to start search on next device */
2337 if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR)) {
2338 bta_dm_search_cb.wait_disc = FALSE;
2340 bta_dm_search_cb.wait_disc = TRUE;
2343 #if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE)
2344 if ( bta_dm_search_cb.p_btm_inq_info ) {
2345 APPL_TRACE_DEBUG("%s p_btm_inq_info %p results.device_type 0x%x services_to_search 0x%x",
2347 bta_dm_search_cb.p_btm_inq_info,
2348 bta_dm_search_cb.p_btm_inq_info->results.device_type,
2349 bta_dm_search_cb.services_to_search);
2352 if (transport == BT_TRANSPORT_LE) {
2353 if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK) {
2354 //set the raw data buffer here
2355 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
2356 bta_dm_search_cb.p_ble_rawdata = g_disc_raw_data_buf;
2358 bta_dm_search_cb.ble_raw_size = MAX_DISC_RAW_DATA_BUF;
2359 bta_dm_search_cb.ble_raw_used = 0;
2361 /* start GATT for service discovery */
2362 btm_dm_start_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
2368 bta_dm_search_cb.sdp_results = FALSE;
2369 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
2375 /* name discovery and service discovery are done for this device */
2376 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
2377 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
2378 /* initialize the data structure - includes p_raw_data and raw_data_size */
2379 memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES));
2380 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
2381 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
2382 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2383 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
2384 (char *)bta_dm_search_cb.peer_name, (BD_NAME_LEN - 1));
2386 /* make sure the string is terminated */
2387 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
2389 bta_sys_sendmsg(p_msg);
2393 /*******************************************************************************
2395 ** Function bta_dm_sdp_callback
2397 ** Description Callback from sdp with discovery status
2401 *******************************************************************************/
2402 static void bta_dm_sdp_callback (UINT16 sdp_status)
2405 tBTA_DM_SDP_RESULT *p_msg;
2407 if ((p_msg = (tBTA_DM_SDP_RESULT *) osi_malloc(sizeof(tBTA_DM_SDP_RESULT))) != NULL) {
2408 p_msg->hdr.event = BTA_DM_SDP_RESULT_EVT;
2409 p_msg->sdp_result = sdp_status;
2410 bta_sys_sendmsg(p_msg);
2414 #endif ///SDP_INCLUDED == TRUE
2415 /*******************************************************************************
2417 ** Function bta_dm_inq_results_cb
2419 ** Description Inquiry results callback from BTM
2423 *******************************************************************************/
2424 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
2427 tBTA_DM_SEARCH result;
2428 tBTM_INQ_INFO *p_inq_info;
2429 UINT16 service_class;
2431 bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
2432 memcpy(result.inq_res.dev_class, p_inq->dev_class, DEV_CLASS_LEN);
2433 BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class);
2434 result.inq_res.is_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? TRUE : FALSE;
2435 result.inq_res.rssi = p_inq->rssi;
2437 #if (BLE_INCLUDED == TRUE)
2438 result.inq_res.ble_addr_type = p_inq->ble_addr_type;
2439 result.inq_res.inq_result_type = p_inq->inq_result_type;
2440 result.inq_res.device_type = p_inq->device_type;
2441 result.inq_res.flag = p_inq->flag;
2444 /* application will parse EIR to find out remote device name */
2445 result.inq_res.p_eir = p_eir;
2447 if ((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL) {
2448 /* initialize remt_name_not_required to FALSE so that we get the name by default */
2449 result.inq_res.remt_name_not_required = FALSE;
2453 if (bta_dm_search_cb.p_search_cback) {
2454 bta_dm_search_cb.p_search_cback(BTA_DM_INQ_RES_EVT, &result);
2458 /* application indicates if it knows the remote name, inside the callback
2459 copy that to the inquiry data base*/
2460 if (result.inq_res.remt_name_not_required) {
2461 p_inq_info->appl_knows_rem_name = TRUE;
2470 /*******************************************************************************
2472 ** Function bta_dm_inq_cmpl_cb
2474 ** Description Inquiry complete callback from BTM
2478 *******************************************************************************/
2479 static void bta_dm_inq_cmpl_cb (void *p_result)
2483 if (bta_dm_search_cb.cancel_pending == FALSE) {
2484 APPL_TRACE_DEBUG("%s", __FUNCTION__);
2485 p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
2486 if (p_msg != NULL) {
2487 p_msg->inq_cmpl.hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
2488 p_msg->inq_cmpl.num = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
2489 bta_sys_sendmsg(p_msg);
2492 bta_dm_search_cb.cancel_pending = FALSE;
2493 bta_dm_search_cancel_notify(NULL);
2495 p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
2496 if (p_msg != NULL) {
2497 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
2498 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
2499 bta_sys_sendmsg(p_msg);
2504 /*******************************************************************************
2506 ** Function bta_dm_service_search_remname_cback
2508 ** Description Remote name call back from BTM during service discovery
2512 *******************************************************************************/
2513 static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, BD_NAME bd_name)
2515 tBTM_REMOTE_DEV_NAME rem_name;
2516 tBTM_STATUS btm_status;
2519 APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback name=<%s>", bd_name);
2521 /* if this is what we are looking for */
2522 if (!bdcmp( bta_dm_search_cb.peer_bdaddr, bd_addr)) {
2523 rem_name.length = strlen((char *)bd_name);
2524 if (rem_name.length > (BD_NAME_LEN - 1)) {
2525 rem_name.length = (BD_NAME_LEN - 1);
2526 rem_name.remote_bd_name[(BD_NAME_LEN - 1)] = 0;
2528 BCM_STRNCPY_S((char *)rem_name.remote_bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
2529 rem_name.status = BTM_SUCCESS;
2531 bta_dm_remname_cback(&rem_name);
2533 /* get name of device */
2534 btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
2535 (tBTM_CMPL_CB *) bta_dm_remname_cback,
2536 BT_TRANSPORT_BR_EDR);
2537 if ( btm_status == BTM_BUSY ) {
2538 /* wait for next chance(notification of remote name discovery done) */
2539 APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName is busy");
2540 } else if ( btm_status != BTM_CMD_STARTED ) {
2541 /* if failed to start getting remote name then continue */
2542 APPL_TRACE_WARNING("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
2544 rem_name.length = 0;
2545 rem_name.remote_bd_name[0] = 0;
2546 rem_name.status = btm_status;
2547 bta_dm_remname_cback(&rem_name);
2553 /*******************************************************************************
2555 ** Function bta_dm_remname_cback
2557 ** Description Remote name complete call back from BTM
2561 *******************************************************************************/
2562 static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
2564 tBTA_DM_REM_NAME *p_msg;
2566 APPL_TRACE_DEBUG("bta_dm_remname_cback len = %d name=<%s>", p_remote_name->length,
2567 p_remote_name->remote_bd_name);
2569 /* remote name discovery is done but it could be failed */
2570 bta_dm_search_cb.name_discover_done = TRUE;
2571 BCM_STRNCPY_S((char *)bta_dm_search_cb.peer_name, sizeof(BD_NAME), (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
2572 bta_dm_search_cb.peer_name[BD_NAME_LEN] = 0;
2574 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
2576 #if BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE
2577 if (bta_dm_search_cb.transport == BT_TRANSPORT_LE ) {
2578 GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
2582 if ((p_msg = (tBTA_DM_REM_NAME *) osi_malloc(sizeof(tBTA_DM_REM_NAME))) != NULL) {
2583 bdcpy (p_msg->result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2584 BCM_STRNCPY_S((char *)p_msg->result.disc_res.bd_name, sizeof(BD_NAME), (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
2586 /* make sure the string is null terminated */
2587 p_msg->result.disc_res.bd_name[BD_NAME_LEN] = 0;
2589 p_msg->hdr.event = BTA_DM_REMT_NAME_EVT;
2590 bta_sys_sendmsg(p_msg);
2595 /*******************************************************************************
2597 ** Function bta_dm_authorize_cback
2599 ** Description cback requesting authorization
2603 *******************************************************************************/
2604 #if (SMP_INCLUDED == TRUE)
2605 static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
2606 UINT8 *service_name, UINT8 service_id, BOOLEAN is_originator)
2608 tBTA_DM_SEC sec_event;
2610 UNUSED(service_name);
2611 UNUSED(is_originator);
2613 bdcpy(sec_event.authorize.bd_addr, bd_addr);
2614 memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN);
2616 BCM_STRNCPY_S((char *)sec_event.authorize.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
2618 /* make sure the string is null terminated */
2619 sec_event.authorize.bd_name[BD_NAME_LEN - 1] = 0;
2621 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
2622 sec_event.authorize.service = service_id;
2625 while (index < BTA_MAX_SERVICE_ID) {
2626 /* get the BTA service id corresponding to BTM id */
2627 if (bta_service_id_to_btm_srv_id_lkup_tbl[index] == service_id) {
2628 sec_event.authorize.service = index;
2635 /* if supported service callback otherwise not authorized */
2636 if (bta_dm_cb.p_sec_cback && (index < BTA_MAX_SERVICE_ID
2637 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
2638 /* pass through JV service ID */
2639 || (service_id >= BTA_FIRST_JV_SERVICE_ID && service_id <= BTA_LAST_JV_SERVICE_ID)
2642 bta_dm_cb.p_sec_cback(BTA_DM_AUTHORIZE_EVT, &sec_event);
2643 return BTM_CMD_STARTED;
2645 return BTM_NOT_AUTHORIZED;
2652 /*******************************************************************************
2654 ** Function bta_dm_pinname_cback
2656 ** Description Callback requesting pin_key
2660 *******************************************************************************/
2661 static void bta_dm_pinname_cback (void *p_data)
2663 tBTM_REMOTE_DEV_NAME *p_result = (tBTM_REMOTE_DEV_NAME *)p_data;
2664 tBTA_DM_SEC sec_event;
2665 UINT32 bytes_to_copy;
2666 tBTA_DM_SEC_EVT event = bta_dm_cb.pin_evt;
2668 if (BTA_DM_SP_CFM_REQ_EVT == event) {
2669 /* Retrieved saved device class and bd_addr */
2670 bdcpy(sec_event.cfm_req.bd_addr, bta_dm_cb.pin_bd_addr);
2671 BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_cb.pin_dev_class);
2673 if (p_result && p_result->status == BTM_SUCCESS) {
2674 bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1))
2675 ? p_result->length : (BD_NAME_LEN - 1);
2676 memcpy(sec_event.cfm_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
2677 sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2678 } else { /* No name found */
2679 sec_event.cfm_req.bd_name[0] = 0;
2682 sec_event.key_notif.passkey = bta_dm_cb.num_val; /* get PIN code numeric number */
2684 /* 1 additional event data fields for this event */
2685 sec_event.cfm_req.just_works = bta_dm_cb.just_works;
2687 /* Retrieved saved device class and bd_addr */
2688 bdcpy(sec_event.pin_req.bd_addr, bta_dm_cb.pin_bd_addr);
2689 BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_cb.pin_dev_class);
2691 if (p_result && p_result->status == BTM_SUCCESS) {
2692 bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1))
2693 ? p_result->length : (BD_NAME_LEN - 1);
2694 memcpy(sec_event.pin_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
2695 sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2696 } else { /* No name found */
2697 sec_event.pin_req.bd_name[0] = 0;
2700 event = bta_dm_cb.pin_evt;
2701 sec_event.key_notif.passkey = bta_dm_cb.num_val; /* get PIN code numeric number */
2704 if ( bta_dm_cb.p_sec_cback ) {
2705 bta_dm_cb.p_sec_cback(event, &sec_event);
2709 /*******************************************************************************
2711 ** Function bta_dm_pin_cback
2713 ** Description Callback requesting pin_key
2717 *******************************************************************************/
2718 static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
2719 BOOLEAN min_16_digit)
2721 tBTA_DM_SEC sec_event;
2723 if (!bta_dm_cb.p_sec_cback) {
2724 return BTM_NOT_AUTHORIZED;
2727 /* If the device name is not known, save bdaddr and devclass and initiate a name request */
2728 if (bd_name[0] == 0) {
2729 bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
2730 bdcpy(bta_dm_cb.pin_bd_addr, bd_addr);
2731 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
2732 if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2733 return BTM_CMD_STARTED;
2736 APPL_TRACE_WARNING(" bta_dm_pin_cback() -> Failed to start Remote Name Request ");
2739 bdcpy(sec_event.pin_req.bd_addr, bd_addr);
2740 BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
2741 BCM_STRNCPY_S((char *)sec_event.pin_req.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
2742 sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2743 sec_event.pin_req.min_16_digit = min_16_digit;
2745 bta_dm_cb.p_sec_cback(BTA_DM_PIN_REQ_EVT, &sec_event);
2746 return BTM_CMD_STARTED;
2749 /*******************************************************************************
2751 ** Function bta_dm_new_link_key_cback
2753 ** Description Callback from BTM to notify new link key
2757 *******************************************************************************/
2758 static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
2759 BD_NAME bd_name, LINK_KEY key, UINT8 key_type)
2761 tBTA_DM_SEC sec_event;
2762 tBTA_DM_AUTH_CMPL *p_auth_cmpl;
2766 memset (&sec_event, 0, sizeof(tBTA_DM_SEC));
2768 /* Not AMP Key type */
2769 if (key_type != HCI_LKEY_TYPE_AMP_WIFI && key_type != HCI_LKEY_TYPE_AMP_UWB) {
2770 event = BTA_DM_AUTH_CMPL_EVT;
2771 p_auth_cmpl = &sec_event.auth_cmpl;
2773 bdcpy(p_auth_cmpl->bd_addr, bd_addr);
2775 memcpy(p_auth_cmpl->bd_name, bd_name, (BD_NAME_LEN - 1));
2776 p_auth_cmpl->bd_name[BD_NAME_LEN - 1] = 0;
2778 p_auth_cmpl->key_present = TRUE;
2779 p_auth_cmpl->key_type = key_type;
2780 p_auth_cmpl->success = TRUE;
2782 memcpy(p_auth_cmpl->key, key, LINK_KEY_LEN);
2783 sec_event.auth_cmpl.fail_reason = HCI_SUCCESS;
2785 #if BLE_INCLUDED == TRUE
2786 // Report the BR link key based on the BR/EDR address and type
2787 BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
2789 if (bta_dm_cb.p_sec_cback) {
2790 bta_dm_cb.p_sec_cback(event, &sec_event);
2793 APPL_TRACE_WARNING("%s() Received AMP Key", __func__);
2796 return BTM_CMD_STARTED;
2800 /*******************************************************************************
2802 ** Function bta_dm_authentication_complete_cback
2804 ** Description Authentication complete callback from BTM
2808 *******************************************************************************/
2809 static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, int result)
2811 tBTA_DM_SEC sec_event;
2814 if (result != BTM_SUCCESS) {
2815 memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
2816 bdcpy(sec_event.auth_cmpl.bd_addr, bd_addr);
2818 memcpy(sec_event.auth_cmpl.bd_name, bd_name, (BD_NAME_LEN - 1));
2819 sec_event.auth_cmpl.bd_name[BD_NAME_LEN - 1] = 0;
2821 #if BLE_INCLUDED == TRUE
2822 // Report the BR link key based on the BR/EDR address and type
2823 BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
2825 sec_event.auth_cmpl.fail_reason = (UINT8)result;
2827 if (bta_dm_cb.p_sec_cback) {
2828 bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
2831 bta_dm_remove_sec_dev_entry(bd_addr);
2837 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2838 /*******************************************************************************
2840 ** Function bta_dm_sp_cback
2842 ** Description simple pairing callback from BTM
2846 *******************************************************************************/
2847 static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
2849 tBTM_STATUS status = BTM_CMD_STARTED;
2850 tBTA_DM_SEC sec_event;
2851 tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT;
2853 APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event);
2854 if (!bta_dm_cb.p_sec_cback) {
2855 return BTM_NOT_AUTHORIZED;
2860 case BTM_SP_IO_REQ_EVT:
2861 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2862 /* translate auth_req */
2863 bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap,
2864 &p_data->io_req.oob_data, &p_data->io_req.auth_req, p_data->io_req.is_orig);
2866 #if BTM_OOB_INCLUDED == FALSE
2867 status = BTM_SUCCESS;
2870 APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
2872 case BTM_SP_IO_RSP_EVT:
2873 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2874 bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap,
2875 p_data->io_rsp.oob_data, p_data->io_rsp.auth_req );
2879 case BTM_SP_CFM_REQ_EVT:
2880 pin_evt = BTA_DM_SP_CFM_REQ_EVT;
2881 bta_dm_cb.just_works = sec_event.cfm_req.just_works = p_data->cfm_req.just_works;
2882 sec_event.cfm_req.loc_auth_req = p_data->cfm_req.loc_auth_req;
2883 sec_event.cfm_req.rmt_auth_req = p_data->cfm_req.rmt_auth_req;
2884 sec_event.cfm_req.loc_io_caps = p_data->cfm_req.loc_io_caps;
2885 sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps;
2887 /* continue to next case */
2888 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2889 /* Passkey entry mode, mobile device with output capability is very
2890 unlikely to receive key request, so skip this event */
2891 /*case BTM_SP_KEY_REQ_EVT: */
2892 case BTM_SP_KEY_NOTIF_EVT:
2894 if (BTM_SP_CFM_REQ_EVT == event) {
2895 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
2896 call remote name request using values from cfm_req */
2897 if (p_data->cfm_req.bd_name[0] == 0) {
2898 bta_dm_cb.pin_evt = pin_evt;
2899 bdcpy(bta_dm_cb.pin_bd_addr, p_data->cfm_req.bd_addr);
2900 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class);
2901 if ((BTM_ReadRemoteDeviceName(p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
2902 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2903 return BTM_CMD_STARTED;
2905 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
2907 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
2908 copy these values into key_notif from cfm_req */
2909 bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
2910 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class);
2911 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
2912 (char *)p_data->cfm_req.bd_name, (BD_NAME_LEN - 1));
2913 sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
2917 bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
2918 if (BTM_SP_KEY_NOTIF_EVT == event) {
2919 /* If the device name is not known, save bdaddr and devclass
2920 and initiate a name request with values from key_notif */
2921 if (p_data->key_notif.bd_name[0] == 0) {
2922 bta_dm_cb.pin_evt = pin_evt;
2923 bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
2924 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
2925 if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback,
2926 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2927 return BTM_CMD_STARTED;
2929 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
2931 bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
2932 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
2933 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
2934 (char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
2935 sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
2939 bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
2943 #if BTM_OOB_INCLUDED == TRUE
2944 case BTM_SP_LOC_OOB_EVT:
2945 bta_dm_co_loc_oob((BOOLEAN)(p_data->loc_oob.status == BTM_SUCCESS),
2946 p_data->loc_oob.c, p_data->loc_oob.r);
2949 case BTM_SP_RMT_OOB_EVT:
2950 /* If the device name is not known, save bdaddr and devclass and initiate a name request */
2951 if (p_data->rmt_oob.bd_name[0] == 0) {
2952 bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
2953 bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
2954 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class);
2955 if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback,
2956 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2957 return BTM_CMD_STARTED;
2959 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
2962 bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
2963 BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
2964 BCM_STRNCPY_S((char *)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char *)p_data->rmt_oob.bd_name, (BD_NAME_LEN - 1));
2965 sec_event.rmt_oob.bd_name[BD_NAME_LEN - 1] = 0;
2967 bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
2969 bta_dm_co_rmt_oob(p_data->rmt_oob.bd_addr);
2972 case BTM_SP_COMPLT_EVT:
2973 /* do not report this event - handled by link_key_callback or auth_complete_callback */
2976 case BTM_SP_KEYPRESS_EVT:
2977 memcpy(&sec_event.key_press, &p_data->key_press, sizeof(tBTM_SP_KEYPRESS));
2978 bta_dm_cb.p_sec_cback(BTA_DM_SP_KEYPRESS_EVT, &sec_event);
2981 case BTM_SP_UPGRADE_EVT:
2982 bta_dm_co_lk_upgrade(p_data->upgrade.bd_addr, &p_data->upgrade.upgrade );
2986 status = BTM_NOT_AUTHORIZED;
2989 APPL_TRACE_EVENT("dm status: %d", status);
2992 #endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */
2994 #endif ///SMP_INCLUDED == TRUE
2997 /*******************************************************************************
2999 ** Function bta_dm_local_name_cback
3001 ** Description Callback from btm after local name is read
3006 *******************************************************************************/
3007 static void bta_dm_local_name_cback(UINT8 *p_name)
3009 tBTA_DM_SEC sec_event;
3012 sec_event.enable.status = BTA_SUCCESS;
3014 if (bta_dm_cb.p_sec_cback) {
3015 bta_dm_cb.p_sec_cback(BTA_DM_ENABLE_EVT, &sec_event);
3020 /*******************************************************************************
3022 ** Function bta_dm_bl_change_cback
3024 ** Description Callback from btm when acl connection goes up or down
3029 *******************************************************************************/
3030 static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
3032 tBTA_DM_ACL_CHANGE *p_msg;
3034 if ((p_msg = (tBTA_DM_ACL_CHANGE *) osi_malloc(sizeof(tBTA_DM_ACL_CHANGE))) != NULL) {
3035 p_msg->event = p_data->event;
3036 p_msg->is_new = FALSE;
3038 switch (p_msg->event) {
3039 case BTM_BL_CONN_EVT:
3040 p_msg->is_new = TRUE;
3041 bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
3042 #if BLE_INCLUDED == TRUE
3043 p_msg->transport = p_data->conn.transport;
3044 p_msg->handle = p_data->conn.handle;
3047 case BTM_BL_DISCN_EVT:
3048 bdcpy(p_msg->bd_addr, p_data->discn.p_bda);
3049 #if BLE_INCLUDED == TRUE
3050 p_msg->transport = p_data->discn.transport;
3051 p_msg->handle = p_data->discn.handle;
3054 case BTM_BL_UPDATE_EVT:
3055 p_msg->busy_level = p_data->update.busy_level;
3056 p_msg->busy_level_flags = p_data->update.busy_level_flags;
3058 case BTM_BL_ROLE_CHG_EVT:
3059 p_msg->new_role = p_data->role_chg.new_role;
3060 p_msg->hci_status = p_data->role_chg.hci_status;
3061 bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda);
3063 case BTM_BL_COLLISION_EVT:
3064 bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
3068 p_msg->hdr.event = BTA_DM_ACL_CHANGE_EVT;
3069 bta_sys_sendmsg(p_msg);
3075 /*******************************************************************************
3077 ** Function bta_dm_rs_cback
3079 ** Description Receives the role switch complete event
3083 *******************************************************************************/
3084 static void bta_dm_rs_cback (tBTM_ROLE_SWITCH_CMPL *p1)
3087 APPL_TRACE_WARNING("bta_dm_rs_cback:%d", bta_dm_cb.rs_event);
3088 if (bta_dm_cb.rs_event == BTA_DM_API_SEARCH_EVT) {
3089 bta_dm_cb.search_msg.rs_res = BTA_DM_RS_OK; /* do not care about the result for now */
3090 bta_dm_cb.rs_event = 0;
3091 bta_dm_search_start((tBTA_DM_MSG *)&bta_dm_cb.search_msg);
3095 /*******************************************************************************
3097 ** Function bta_dm_check_av
3099 ** Description This function checks if AV is active
3100 ** if yes, make sure the AV link is master
3102 ** Returns BOOLEAN - TRUE, if switch is in progress
3104 *******************************************************************************/
3105 static BOOLEAN bta_dm_check_av(UINT16 event)
3107 BOOLEAN avoid_roleswitch = FALSE;
3108 BOOLEAN switching = FALSE;
3110 tBTA_DM_PEER_DEVICE *p_dev;
3112 #if defined(BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY) && (BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY == TRUE)
3114 /* avoid role switch upon inquiry if a2dp is actively streaming as it
3115 introduces an audioglitch due to FW scheduling delays (unavoidable) */
3116 if (event == BTA_DM_API_SEARCH_EVT) {
3117 avoid_roleswitch = TRUE;
3121 APPL_TRACE_WARNING("bta_dm_check_av:%d", bta_dm_cb.cur_av_count);
3122 if (bta_dm_cb.cur_av_count) {
3123 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3124 p_dev = &bta_dm_cb.device_list.peer_device[i];
3125 APPL_TRACE_WARNING("[%d]: state:%d, info:x%x, avoid_rs %d",
3126 i, p_dev->conn_state, p_dev->info, avoid_roleswitch);
3127 if ((p_dev->conn_state == BTA_DM_CONNECTED) && (p_dev->info & BTA_DM_DI_AV_ACTIVE) &&
3128 (avoid_roleswitch == FALSE)) {
3129 /* make master and take away the role switch policy */
3130 if (BTM_CMD_STARTED == BTM_SwitchRole (p_dev->peer_bdaddr, HCI_ROLE_MASTER, (tBTM_CMPL_CB *)bta_dm_rs_cback)) {
3131 /* the role switch command is actually sent */
3132 bta_dm_cb.rs_event = event;
3135 /* else either already master or can not switch for some reasons */
3136 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr);
3144 /*******************************************************************************
3146 ** Function bta_dm_acl_change
3148 ** Description Process BTA_DM_ACL_CHANGE_EVT
3153 *******************************************************************************/
3154 void bta_dm_acl_change(tBTA_DM_MSG *p_data)
3160 BOOLEAN is_new = p_data->acl_change.is_new;
3161 BD_ADDR_PTR p_bda = p_data->acl_change.bd_addr;
3162 BOOLEAN need_policy_change = FALSE;
3163 BOOLEAN issue_unpair_cb = FALSE;
3165 tBTA_DM_PEER_DEVICE *p_dev;
3166 memset(&conn, 0, sizeof(tBTA_DM_SEC));
3168 switch (p_data->acl_change.event) {
3169 case BTM_BL_UPDATE_EVT: /* busy level update */
3170 if ( bta_dm_cb.p_sec_cback ) {
3171 conn.busy_level.level = p_data->acl_change.busy_level;
3172 conn.busy_level.level_flags = p_data->acl_change.busy_level_flags;
3173 bta_dm_cb.p_sec_cback(BTA_DM_BUSY_LEVEL_EVT, &conn);
3177 case BTM_BL_ROLE_CHG_EVT: /* role change event */
3178 p_dev = bta_dm_find_peer_device(p_bda);
3180 APPL_TRACE_DEBUG("bta_dm_acl_change role chg info:x%x new_role:%d dev count:%d",
3181 p_dev->info, p_data->acl_change.new_role, bta_dm_cb.device_list.count);
3182 if (p_dev->info & BTA_DM_DI_AV_ACTIVE) {
3183 /* there's AV activity on this link */
3184 if (p_data->acl_change.new_role == HCI_ROLE_SLAVE && bta_dm_cb.device_list.count > 1
3185 && p_data->acl_change.hci_status == HCI_SUCCESS) {
3186 /* more than one connections and the AV connection is role switched to slave
3187 * switch it back to master and remove the switch policy */
3188 BTM_SwitchRole(p_bda, BTM_ROLE_MASTER, NULL);
3189 need_policy_change = TRUE;
3190 } else if (p_bta_dm_cfg->avoid_scatter && (p_data->acl_change.new_role == HCI_ROLE_MASTER)) {
3191 /* if the link updated to be master include AV activities, remove the switch policy */
3192 need_policy_change = TRUE;
3195 if (need_policy_change) {
3196 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr);
3199 /* there's AV no activity on this link and role switch happened
3200 * check if AV is active
3201 * if so, make sure the AV link is master */
3204 bta_sys_notify_role_chg(p_data->acl_change.bd_addr, p_data->acl_change.new_role, p_data->acl_change.hci_status);
3205 bdcpy(conn.role_chg.bd_addr, p_bda);
3206 conn.role_chg.new_role = (UINT8) p_data->acl_change.new_role;
3207 if ( bta_dm_cb.p_sec_cback ) {
3208 bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, (tBTA_DM_SEC *)&conn);
3214 /* Collision report from Stack: Notify profiles */
3215 if (p_data->acl_change.event == BTM_BL_COLLISION_EVT) {
3216 bta_sys_notify_collision (p_bda);
3221 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3222 if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
3223 #if BLE_INCLUDED == TRUE
3224 && bta_dm_cb.device_list.peer_device[i].conn_handle == p_data->acl_change.handle
3232 if (i == bta_dm_cb.device_list.count) {
3233 if (bta_dm_cb.device_list.count < BTA_DM_NUM_PEER_DEVICE) {
3234 bdcpy(bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].peer_bdaddr, p_bda);
3235 bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].link_policy = bta_dm_cb.cur_policy;
3236 bta_dm_cb.device_list.count++;
3237 #if BLE_INCLUDED == TRUE
3238 bta_dm_cb.device_list.peer_device[i].conn_handle = p_data->acl_change.handle;
3239 if (p_data->acl_change.transport == BT_TRANSPORT_LE) {
3240 bta_dm_cb.device_list.le_count++;
3244 APPL_TRACE_ERROR("%s max active connection reached, no resources", __func__);
3249 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED;
3250 bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE;
3251 bdcpy(conn.link_up.bd_addr, p_bda);
3252 bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE;
3253 #if BLE_INCLUDED == TRUE
3254 conn.link_up.link_type = p_data->acl_change.transport;
3255 bta_dm_cb.device_list.peer_device[i].transport = p_data->acl_change.transport;
3258 if (((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
3259 ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p))) {
3260 /* both local and remote devices support SSR */
3261 bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR;
3263 APPL_TRACE_DEBUG("%s info: 0x%x", __func__, bta_dm_cb.device_list.peer_device[i].info);
3265 if (bta_dm_cb.p_sec_cback) {
3266 bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, (tBTA_DM_SEC *)&conn);
3269 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3270 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
3271 #if BLE_INCLUDED == TRUE
3272 || bta_dm_cb.device_list.peer_device[i].transport != p_data->acl_change.transport
3278 if ( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING ) {
3279 if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr)) {
3280 issue_unpair_cb = TRUE;
3283 APPL_TRACE_DEBUG("%s: Unpairing: issue unpair CB = %d ", __FUNCTION__, issue_unpair_cb);
3286 conn.link_down.is_removed = bta_dm_cb.device_list.peer_device[i].remove_dev_pending;
3288 for (; i < bta_dm_cb.device_list.count ; i++) {
3289 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]));
3293 if (bta_dm_cb.device_list.count) {
3294 bta_dm_cb.device_list.count--;
3296 #if BLE_INCLUDED == TRUE
3297 if ((p_data->acl_change.transport == BT_TRANSPORT_LE) &&
3298 (bta_dm_cb.device_list.le_count)) {
3299 bta_dm_cb.device_list.le_count--;
3301 conn.link_down.link_type = p_data->acl_change.transport;
3304 if (bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda)) {
3305 bta_dm_search_cb.wait_disc = FALSE;
3307 if (bta_dm_search_cb.sdp_results) {
3308 APPL_TRACE_EVENT(" timer stopped ");
3309 bta_sys_stop_timer(&bta_dm_search_cb.search_timer);
3310 bta_dm_discover_next_device();
3315 if (bta_dm_cb.disabling) {
3316 if (!BTM_GetNumAclLinks()) {
3317 bta_sys_stop_timer(&bta_dm_cb.disable_timer);
3318 bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK *)&bta_dm_disable_conn_down_timer_cback;
3320 * Start a timer to make sure that the profiles
3321 * get the disconnect event.
3323 bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 1000);
3326 if (conn.link_down.is_removed) {
3327 BTM_SecDeleteDevice(p_bda);
3328 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
3329 /* need to remove all pending background connection */
3330 BTA_GATTC_CancelOpen(0, p_bda, FALSE);
3331 /* remove all cached GATT information */
3332 BTA_GATTC_Refresh(p_bda);
3336 bdcpy(conn.link_down.bd_addr, p_bda);
3337 conn.link_down.reason = (UINT8) btm_get_acl_disc_reason_code();
3338 if ( bta_dm_cb.p_sec_cback ) {
3339 bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn);
3340 if ( issue_unpair_cb ) {
3341 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn);
3346 bta_dm_adjust_roles(TRUE);
3349 /*******************************************************************************
3351 ** Function bta_dm_disable_conn_down_timer_cback
3353 ** Description Sends disable event to application
3358 *******************************************************************************/
3359 static void bta_dm_disable_conn_down_timer_cback (TIMER_LIST_ENT *p_tle)
3362 tBTA_SYS_HW_MSG *sys_enable_event;
3363 #if (BTM_SSR_INCLUDED == TRUE)
3364 /* disable the power managment module */
3365 bta_dm_disable_pm();
3366 #endif ///BTM_SSR_INCLUDED == TRUE
3367 /* register our callback to SYS HW manager */
3368 bta_sys_hw_register( BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback );
3370 /* send a message to BTA SYS */
3371 if ((sys_enable_event = (tBTA_SYS_HW_MSG *) osi_malloc(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
3372 sys_enable_event->hdr.event = BTA_SYS_API_DISABLE_EVT;
3373 sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;
3374 bta_sys_sendmsg(sys_enable_event);
3377 bta_dm_cb.disabling = FALSE;
3381 /*******************************************************************************
3383 ** Function bta_dm_rm_cback
3385 ** Description Role management callback from sys
3390 *******************************************************************************/
3391 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
3394 tBTA_PREF_ROLES role;
3395 tBTA_DM_PEER_DEVICE *p_dev;
3397 p_dev = bta_dm_find_peer_device(peer_addr);
3398 if ( status == BTA_SYS_CONN_OPEN) {
3400 /* Do not set to connected if we are in the middle of unpairing. When AV stream is
3401 * started it fakes out a SYS_CONN_OPEN to potentially trigger a role switch command.
3402 * But this should not be done if we are in the middle of unpairing.
3404 if (p_dev->conn_state != BTA_DM_UNPAIRING) {
3405 p_dev->conn_state = BTA_DM_CONNECTED;
3408 for (j = 1; j <= p_bta_dm_rm_cfg[0].app_id; j++) {
3409 if (((p_bta_dm_rm_cfg[j].app_id == app_id) || (p_bta_dm_rm_cfg[j].app_id == BTA_ALL_APP_ID))
3410 && (p_bta_dm_rm_cfg[j].id == id)) {
3411 role = p_bta_dm_rm_cfg[j].cfg;
3413 if (role > p_dev->pref_role ) {
3414 p_dev->pref_role = role;
3422 if ((BTA_ID_AV == id) || (BTA_ID_AVK == id)) {
3423 if ( status == BTA_SYS_CONN_BUSY) {
3425 p_dev->info |= BTA_DM_DI_AV_ACTIVE;
3427 /* AV calls bta_sys_conn_open with the A2DP stream count as app_id */
3428 if (BTA_ID_AV == id) {
3429 #if (BTM_SSR_INCLUDED == TRUE)
3430 bta_dm_cb.cur_av_count = bta_dm_get_av_count();
3431 #endif ///BTM_SSR_INCLUDED == TRUE
3433 } else if ( status == BTA_SYS_CONN_IDLE) {
3435 p_dev->info &= ~BTA_DM_DI_AV_ACTIVE;
3438 /* get cur_av_count from connected services */
3439 if (BTA_ID_AV == id) {
3440 #if (BTM_SSR_INCLUDED == TRUE)
3441 bta_dm_cb.cur_av_count = bta_dm_get_av_count();
3442 #endif ///BTM_SSR_INCLUDED == TRUE
3445 APPL_TRACE_WARNING("bta_dm_rm_cback:%d, status:%d", bta_dm_cb.cur_av_count, status);
3448 /* Don't adjust roles for each busy/idle state transition to avoid
3449 excessive switch requests when individual profile busy/idle status
3451 if ((status != BTA_SYS_CONN_BUSY) && (status != BTA_SYS_CONN_IDLE)) {
3452 bta_dm_adjust_roles(FALSE);
3456 /*******************************************************************************
3458 ** Function bta_dm_delay_role_switch_cback
3460 ** Description Callback from btm to delay a role switch
3464 *******************************************************************************/
3465 static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle)
3468 APPL_TRACE_EVENT("bta_dm_delay_role_switch_cback: initiating Delayed RS");
3469 bta_dm_adjust_roles (FALSE);
3472 /*******************************************************************************
3474 ** Function bta_dm_remove_sec_dev_entry
3476 ** Description Removes device entry from Security device DB if ACL connection with
3477 ** remtoe device does not exist, else schedule for dev entry removal upon
3482 *******************************************************************************/
3483 #if (SMP_INCLUDED == TRUE)
3484 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
3487 if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
3488 BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR)) {
3489 APPL_TRACE_DEBUG("%s ACL is not down. Schedule for Dev Removal when ACL closes",
3491 BTM_SecClearSecurityFlags (remote_bd_addr);
3492 for (index = 0; index < bta_dm_cb.device_list.count; index ++) {
3493 if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, remote_bd_addr)) {
3497 if (index != bta_dm_cb.device_list.count) {
3498 bta_dm_cb.device_list.peer_device[index].remove_dev_pending = TRUE;
3500 APPL_TRACE_ERROR(" %s Device does not exist in DB", __FUNCTION__);
3503 BTM_SecDeleteDevice (remote_bd_addr);
3504 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
3505 /* need to remove all pending background connection */
3506 BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
3507 /* remove all cached GATT information */
3508 BTA_GATTC_Refresh(remote_bd_addr);
3512 #endif ///SMP_INCLUDED == TRUE
3515 /*******************************************************************************
3517 ** Function bta_dm_adjust_roles
3519 ** Description Adjust roles
3524 *******************************************************************************/
3525 static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
3529 BOOLEAN set_master_role = FALSE;
3530 #if BLE_INCLUDED == TRUE
3531 UINT8 br_count = bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count;
3533 UINT8 br_count = bta_dm_cb.device_list.count;
3537 /* the configuration is no scatternet
3538 * or AV connection exists and there are more than one ACL link */
3539 if ( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
3540 (bta_dm_cb.cur_av_count && br_count > 1) ) {
3542 L2CA_SetDesireRole (HCI_ROLE_MASTER);
3543 set_master_role = TRUE;
3547 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3548 if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED
3549 #if BLE_INCLUDED == TRUE
3550 && bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_BR_EDR
3553 if (!set_master_role && (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE)
3554 && (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET)) {
3555 L2CA_SetDesireRole (HCI_ROLE_MASTER);
3556 set_master_role = TRUE;
3559 if ((bta_dm_cb.device_list.peer_device[i].pref_role == BTA_MASTER_ROLE_ONLY)
3560 || (br_count > 1)) {
3562 /* Initiating immediate role switch with certain remote devices
3563 has caused issues due to role switch colliding with link encryption setup and
3564 causing encryption (and in turn the link) to fail . These device . Firmware
3565 versions are stored in a blacklist and role switch with these devices are
3566 delayed to avoid the collision with link encryption setup */
3568 if (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_SLAVE_ROLE_ONLY &&
3569 delay_role_switch == FALSE) {
3570 BTM_SwitchRole (bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
3571 HCI_ROLE_MASTER, NULL);
3573 bta_dm_cb.switch_delay_timer.p_cback =
3574 (TIMER_CBACK *)&bta_dm_delay_role_switch_cback;
3575 bta_sys_start_timer(&bta_dm_cb.switch_delay_timer, 0, 500);
3583 if (!set_master_role) {
3585 L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
3590 L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
3596 /*******************************************************************************
3598 ** Function bta_dm_get_remname
3600 ** Description Returns a pointer to the remote name stored in the DM control
3601 ** block if it exists, or from the BTM memory.
3603 ** Returns char * - Pointer to the remote device name
3604 *******************************************************************************/
3605 #if (SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE)
3606 static char *bta_dm_get_remname(void)
3608 char *p_name = (char *)bta_dm_search_cb.peer_name;
3611 /* If the name isn't already stored, try retrieving from BTM */
3612 if (*p_name == '\0')
3613 if ((p_temp = BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr)) != NULL) {
3619 #endif ///SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE
3621 /*******************************************************************************
3623 ** Function bta_dm_bond_cancel_complete_cback
3625 ** Description Authentication complete callback from BTM
3629 *******************************************************************************/
3630 #if (SMP_INCLUDED == TRUE)
3631 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result)
3634 tBTA_DM_SEC sec_event;
3636 if (result == BTM_SUCCESS) {
3637 sec_event.bond_cancel_cmpl.result = BTA_SUCCESS;
3639 sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
3642 if (bta_dm_cb.p_sec_cback) {
3643 bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
3646 #endif ///SMP_INCLUDED == TRUE
3648 /*******************************************************************************
3650 ** Function bta_dm_set_eir
3652 ** Description This function creates EIR tagged data and writes it to controller.
3656 *******************************************************************************/
3657 static void bta_dm_set_eir (char *local_name)
3662 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3665 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3666 UINT8 custom_uuid_idx;
3667 #endif // BTA_EIR_SERVER_NUM_CUSTOM_UUID
3668 #endif // BTA_EIR_CANNED_UUID_LIST
3669 #if (BTM_EIR_DEFAULT_FEC_REQUIRED == FALSE)
3670 UINT8 free_eir_length = HCI_EXT_INQ_RESPONSE_LEN;
3671 #else // BTM_EIR_DEFAULT_FEC_REQUIRED
3672 UINT8 free_eir_length = HCI_DM5_PACKET_SIZE;
3673 #endif // BTM_EIR_DEFAULT_FEC_REQUIRED
3676 UINT8 local_name_len;
3678 /* wait until complete to disable */
3679 if (bta_dm_cb.disable_timer.in_use) {
3683 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )
3684 /* wait until App is ready */
3685 if (bta_dm_cb.app_ready_timer.in_use) {
3689 /* if local name is not provided, get it from controller */
3690 if ( local_name == NULL ) {
3691 if ( BTM_ReadLocalDeviceName( &local_name ) != BTM_SUCCESS ) {
3692 APPL_TRACE_ERROR("Fail to read local device name for EIR");
3695 #endif // BTA_EIR_CANNED_UUID_LIST
3697 /* Allocate a buffer to hold HCI command */
3698 if ((p_buf = (BT_HDR *)osi_malloc(BTM_CMD_BUF_SIZE)) == NULL) {
3699 APPL_TRACE_ERROR("bta_dm_set_eir couldn't allocate buffer");
3702 p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET;
3704 memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN );
3706 APPL_TRACE_DEBUG("BTA is generating EIR");
3709 local_name_len = strlen( local_name );
3714 data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3715 /* if local name is longer than minimum length of shortened name */
3716 /* check whether it needs to be shortened or not */
3717 if ( local_name_len > p_bta_dm_eir_cfg->bta_dm_eir_min_name_len ) {
3718 /* get number of UUID 16-bit list */
3719 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3720 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / LEN_UUID_16;
3721 #else // BTA_EIR_CANNED_UUID_LIST
3722 max_num_uuid = (free_eir_length - 2) / LEN_UUID_16;
3723 data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p,
3724 max_num_uuid, &num_uuid );
3725 p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET; /* reset p */
3726 #endif // BTA_EIR_CANNED_UUID_LIST
3728 /* if UUID doesn't fit remaing space, shorten local name */
3729 if ( local_name_len > (free_eir_length - 4 - num_uuid * LEN_UUID_16)) {
3730 APPL_TRACE_WARNING("BTA EIR: local name is shortened");
3731 local_name_len = p_bta_dm_eir_cfg->bta_dm_eir_min_name_len;
3732 data_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE;
3734 data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3738 UINT8_TO_STREAM(p, local_name_len + 1);
3739 UINT8_TO_STREAM(p, data_type);
3741 if (local_name != NULL) {
3742 memcpy(p, local_name, local_name_len);
3743 p += local_name_len;
3745 free_eir_length -= local_name_len + 2;
3747 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3748 /* if UUID list is provided as static data in configuration */
3749 if (( p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len > 0 )
3750 && (p_bta_dm_eir_cfg->bta_dm_eir_uuid16)) {
3751 if ( free_eir_length > LEN_UUID_16 + 2) {
3752 free_eir_length -= 2;
3754 if ( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len) {
3755 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / LEN_UUID_16;
3756 data_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3757 } else { /* not enough room for all UUIDs */
3758 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3759 num_uuid = free_eir_length / LEN_UUID_16;
3760 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3762 UINT8_TO_STREAM(p, num_uuid * LEN_UUID_16 + 1);
3763 UINT8_TO_STREAM(p, data_type);
3764 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_uuid16, num_uuid * LEN_UUID_16 );
3765 p += num_uuid * LEN_UUID_16;
3766 free_eir_length -= num_uuid * LEN_UUID_16;
3769 #else /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3770 /* if UUID list is dynamic */
3771 if ( free_eir_length >= 2) {
3776 max_num_uuid = (free_eir_length - 2) / LEN_UUID_16;
3777 data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p, max_num_uuid, &num_uuid );
3779 if ( data_type == BTM_EIR_MORE_16BITS_UUID_TYPE ) {
3780 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3782 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3784 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) {
3785 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_16) {
3786 if ( num_uuid < max_num_uuid ) {
3787 UINT16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid16);
3790 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3791 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3797 #endif /* (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3799 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_16 + 1);
3800 UINT8_TO_STREAM(p_type, data_type);
3801 free_eir_length -= num_uuid * LEN_UUID_16 + 2;
3803 #endif /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3805 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3806 /* Adding 32-bit UUID list */
3807 if ( free_eir_length >= 2) {
3811 data_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE;
3813 max_num_uuid = (free_eir_length - 2) / LEN_UUID_32;
3815 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) {
3816 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_32) {
3817 if ( num_uuid < max_num_uuid ) {
3818 UINT32_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid32);
3821 data_type = BTM_EIR_MORE_32BITS_UUID_TYPE;
3822 APPL_TRACE_WARNING("BTA EIR: UUID 32-bit list is truncated");
3828 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_32 + 1);
3829 UINT8_TO_STREAM(p_type, data_type);
3830 free_eir_length -= num_uuid * LEN_UUID_32 + 2;
3833 /* Adding 128-bit UUID list */
3834 if ( free_eir_length >= 2) {
3838 data_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE;
3840 max_num_uuid = (free_eir_length - 2) / LEN_UUID_128;
3842 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) {
3843 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_128) {
3844 if ( num_uuid < max_num_uuid ) {
3845 ARRAY16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid128);
3848 data_type = BTM_EIR_MORE_128BITS_UUID_TYPE;
3849 APPL_TRACE_WARNING("BTA EIR: UUID 128-bit list is truncated");
3855 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_128 + 1);
3856 UINT8_TO_STREAM(p_type, data_type);
3857 free_eir_length -= num_uuid * LEN_UUID_128 + 2;
3859 #endif /* ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3861 /* if Flags are provided in configuration */
3862 if (( p_bta_dm_eir_cfg->bta_dm_eir_flag_len > 0 )
3863 && ( p_bta_dm_eir_cfg->bta_dm_eir_flags )
3864 && ( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2 )) {
3865 UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 1);
3866 UINT8_TO_STREAM(p, BTM_EIR_FLAGS_TYPE);
3867 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_flags,
3868 p_bta_dm_eir_cfg->bta_dm_eir_flag_len);
3869 p += p_bta_dm_eir_cfg->bta_dm_eir_flag_len;
3870 free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2;
3873 /* if Manufacturer Specific are provided in configuration */
3874 if (( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len > 0 )
3875 && ( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec )
3876 && ( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2 )) {
3879 UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 1);
3880 UINT8_TO_STREAM(p, BTM_EIR_MANUFACTURER_SPECIFIC_TYPE);
3881 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec,
3882 p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len);
3883 p += p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len;
3884 free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2;
3890 /* if Inquiry Tx Resp Power compiled */
3891 if ((p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power) &&
3892 (free_eir_length >= 3)) {
3893 UINT8_TO_STREAM(p, 2); /* Length field */
3894 UINT8_TO_STREAM(p, BTM_EIR_TX_POWER_LEVEL_TYPE);
3895 UINT8_TO_STREAM(p, *(p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power));
3896 free_eir_length -= 3;
3899 if ( free_eir_length ) {
3900 UINT8_TO_STREAM(p, 0); /* terminator of significant part */
3903 BTM_WriteEIR( p_buf );
3907 /*******************************************************************************
3909 ** Function bta_dm_eir_search_services
3911 ** Description This function searches services in received EIR
3915 *******************************************************************************/
3916 #if (SDP_INCLUDED == TRUE)
3917 static void bta_dm_eir_search_services( tBTM_INQ_RESULTS *p_result,
3918 tBTA_SERVICE_MASK *p_services_to_search,
3919 tBTA_SERVICE_MASK *p_services_found)
3921 tBTA_SERVICE_MASK service_index = 0;
3922 tBTM_EIR_SEARCH_RESULT result;
3924 APPL_TRACE_DEBUG("BTA searching services in EIR of BDA:0x%02X%02X%02X%02X%02X%02X",
3925 p_result->remote_bd_addr[0], p_result->remote_bd_addr[1],
3926 p_result->remote_bd_addr[2], p_result->remote_bd_addr[3],
3927 p_result->remote_bd_addr[4], p_result->remote_bd_addr[5]);
3929 APPL_TRACE_DEBUG(" with services_to_search=0x%08X", *p_services_to_search);
3931 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
3932 /* always do GATT based service discovery by SDP instead of from EIR */
3933 /* if GATT based service is also to be put in EIR, need to modify this */
3934 while (service_index < (BTA_MAX_SERVICE_ID - 1))
3936 while (service_index < BTA_MAX_SERVICE_ID)
3939 if ( *p_services_to_search
3940 & (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index))) {
3941 result = BTM_HasInquiryEirService( p_result,
3942 bta_service_id_to_uuid_lkup_tbl[service_index] );
3944 /* Searching for HSP v1.2 only device */
3945 if ((result != BTM_EIR_FOUND) &&
3946 (bta_service_id_to_uuid_lkup_tbl[service_index] == UUID_SERVCLASS_HEADSET)) {
3947 result = BTM_HasInquiryEirService (p_result, UUID_SERVCLASS_HEADSET_HS);
3950 if ( result == BTM_EIR_FOUND ) {
3951 /* If Plug and Play service record, need to check to see if Broadcom stack */
3952 /* However, EIR data doesn't have EXT_BRCM_VERSION so just skip it */
3953 if ( bta_service_id_to_uuid_lkup_tbl[service_index]
3954 != UUID_SERVCLASS_PNP_INFORMATION ) {
3956 *p_services_found |=
3957 (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index));
3958 /* remove the service from services to be searched */
3959 *p_services_to_search &=
3960 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
3962 } else if ( result == BTM_EIR_NOT_FOUND ) {
3963 /* remove the service from services to be searched */
3964 *p_services_to_search &=
3965 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
3972 APPL_TRACE_ERROR("BTA EIR search result, services_to_search=0x%08X, services_found=0x%08X",
3973 *p_services_to_search, *p_services_found);
3975 #endif ///SDP_INCLUDED == TRUE
3977 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3978 /*******************************************************************************
3980 ** Function bta_dm_eir_update_uuid
3982 ** Description This function adds or removes service UUID in EIR database.
3986 *******************************************************************************/
3987 void bta_dm_eir_update_uuid(UINT16 uuid16, BOOLEAN adding)
3989 /* if this UUID is not advertised in EIR */
3990 if ( !BTM_HasEirService( p_bta_dm_eir_cfg->uuid_mask, uuid16 )) {
3995 APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid16);
3997 BTM_AddEirService( bta_dm_cb.eir_uuid, uuid16 );
3999 APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid16);
4001 BTM_RemoveEirService( bta_dm_cb.eir_uuid, uuid16 );
4004 bta_dm_set_eir (NULL);
4006 APPL_TRACE_EVENT("bta_dm_eir_update_uuid UUID bit mask=0x%08X %08X",
4007 bta_dm_cb.eir_uuid[1], bta_dm_cb.eir_uuid[0] );
4011 /*******************************************************************************
4013 ** Function bta_dm_enable_test_mode
4015 ** Description enable test mode
4020 *******************************************************************************/
4021 void bta_dm_enable_test_mode(tBTA_DM_MSG *p_data)
4024 BTM_EnableTestMode();
4027 /*******************************************************************************
4029 ** Function bta_dm_disable_test_mode
4031 ** Description disable test mode
4036 *******************************************************************************/
4037 void bta_dm_disable_test_mode(tBTA_DM_MSG *p_data)
4040 BTM_DeviceReset(NULL);
4043 /*******************************************************************************
4045 ** Function bta_dm_execute_callback
4047 ** Description Just execute a generic call back in the context of the BTU/BTA tack
4052 *******************************************************************************/
4053 void bta_dm_execute_callback(tBTA_DM_MSG *p_data)
4056 if (p_data->exec_cback.p_exec_cback == NULL) {
4060 p_data->exec_cback.p_exec_cback(p_data->exec_cback.p_param);
4063 /*******************************************************************************
4065 ** Function bta_dm_encrypt_cback
4067 ** Description link encryption complete callback.
4071 *******************************************************************************/
4072 void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
4074 tBTA_STATUS bta_status = BTA_SUCCESS;
4075 tBTA_DM_ENCRYPT_CBACK *p_callback = NULL;
4079 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
4080 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bd_addr) == 0 &&
4081 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) {
4086 if (i < bta_dm_cb.device_list.count) {
4087 p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback;
4088 bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL;
4094 case BTM_WRONG_MODE:
4095 bta_status = BTA_WRONG_MODE;
4097 case BTM_NO_RESOURCES:
4098 bta_status = BTA_NO_RESOURCES;
4101 bta_status = BTA_BUSY;
4104 bta_status = BTA_FAILURE;
4108 APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=%p", bta_status, p_callback);
4111 (*p_callback)(bd_addr, transport, bta_status);
4115 /*******************************************************************************
4117 ** Function bta_dm_set_encryption
4119 ** Description This function to encrypt the link
4123 *******************************************************************************/
4124 #if (SMP_INCLUDED == TRUE)
4125 void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
4129 APPL_TRACE_DEBUG("bta_dm_set_encryption\n"); //todo
4130 if (!p_data->set_encryption.p_callback) {
4131 APPL_TRACE_ERROR("bta_dm_set_encryption callback is not provided\n");
4134 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
4135 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_data->set_encryption.bd_addr) == 0 &&
4136 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) {
4140 if (i < bta_dm_cb.device_list.count) {
4141 if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback) {
4142 APPL_TRACE_ERROR("earlier enc was not done for same device\n");
4143 (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr,
4144 p_data->set_encryption.transport,
4149 if (BTM_SetEncryption(p_data->set_encryption.bd_addr, p_data->set_encryption.transport,
4150 bta_dm_encrypt_cback, &p_data->set_encryption.sec_act)
4151 == BTM_CMD_STARTED) {
4152 bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_data->set_encryption.p_callback;
4155 APPL_TRACE_ERROR("%s, not find peer_bdaddr or peer_bdaddr connection state error", __func__);
4158 #endif ///SMP_INCLUDED == TRUE
4160 #if (BLE_INCLUDED == TRUE)
4161 /*******************************************************************************
4163 ** Function bta_dm_observe_results_cb
4165 ** Description Callback for BLE Observe result
4170 *******************************************************************************/
4171 static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
4173 tBTA_DM_SEARCH result;
4174 tBTM_INQ_INFO *p_inq_info;
4175 APPL_TRACE_DEBUG("bta_dm_observe_results_cb")
4177 bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
4178 result.inq_res.rssi = p_inq->rssi;
4179 result.inq_res.ble_addr_type = p_inq->ble_addr_type;
4180 result.inq_res.inq_result_type = p_inq->inq_result_type;
4181 result.inq_res.device_type = p_inq->device_type;
4182 result.inq_res.flag = p_inq->flag;
4183 result.inq_res.adv_data_len = p_inq->adv_data_len;
4184 result.inq_res.scan_rsp_len = p_inq->scan_rsp_len;
4186 /* application will parse EIR to find out remote device name */
4187 result.inq_res.p_eir = p_eir;
4189 if ((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL) {
4190 /* initialize remt_name_not_required to FALSE so that we get the name by default */
4191 result.inq_res.remt_name_not_required = FALSE;
4194 if (bta_dm_search_cb.p_scan_cback) {
4195 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result);
4199 /* application indicates if it knows the remote name, inside the callback
4200 copy that to the inquiry data base*/
4201 if (result.inq_res.remt_name_not_required) {
4202 p_inq_info->appl_knows_rem_name = TRUE;
4207 /*******************************************************************************
4209 ** Function bta_dm_observe_cmpl_cb
4211 ** Description Callback for BLE Observe complete
4216 *******************************************************************************/
4217 static void bta_dm_observe_cmpl_cb (void *p_result)
4219 tBTA_DM_SEARCH data;
4221 APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb");
4223 data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
4224 if (bta_dm_search_cb.p_scan_cback) {
4225 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
4229 #if (SMP_INCLUDED == TRUE)
4230 /*******************************************************************************
4232 ** Function bta_dm_ble_smp_cback
4234 ** Description Callback for BLE SMP
4239 *******************************************************************************/
4240 static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data)
4242 tBTM_STATUS status = BTM_SUCCESS;
4243 tBTA_DM_SEC sec_event;
4244 char *p_name = NULL;
4246 if (!bta_dm_cb.p_sec_cback) {
4247 return BTM_NOT_AUTHORIZED;
4250 memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
4252 case BTM_LE_IO_REQ_EVT:
4253 // #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
4255 bta_dm_co_ble_io_req(bda,
4256 &p_data->io_req.io_cap,
4257 &p_data->io_req.oob_data,
4258 &p_data->io_req.auth_req,
4259 &p_data->io_req.max_key_size,
4260 &p_data->io_req.init_keys,
4261 &p_data->io_req.resp_keys);
4263 #if BTM_OOB_INCLUDED == FALSE
4264 status = BTM_SUCCESS;
4266 APPL_TRACE_EVENT("io mitm: %d oob_data:%d\n", p_data->io_req.auth_req, p_data->io_req.oob_data);
4270 case BTM_LE_SEC_REQUEST_EVT:
4271 bdcpy(sec_event.ble_req.bd_addr, bda);
4272 p_name = BTM_SecReadDevName(bda);
4273 if (p_name != NULL) {
4274 BCM_STRNCPY_S((char *)sec_event.ble_req.bd_name,
4275 sizeof(BD_NAME), p_name, (BD_NAME_LEN));
4277 sec_event.ble_req.bd_name[0] = 0;
4279 sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
4280 bta_dm_cb.p_sec_cback(BTA_DM_BLE_SEC_REQ_EVT, &sec_event);
4283 case BTM_LE_KEY_NOTIF_EVT:
4284 bdcpy(sec_event.key_notif.bd_addr, bda);
4285 p_name = BTM_SecReadDevName(bda);
4286 if (p_name != NULL) {
4287 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,
4288 sizeof(BD_NAME), p_name, (BD_NAME_LEN));
4290 sec_event.key_notif.bd_name[0] = 0;
4292 sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
4293 sec_event.key_notif.passkey = p_data->key_notif;
4294 bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_NOTIF_EVT, &sec_event);
4297 case BTM_LE_KEY_REQ_EVT:
4298 bdcpy(sec_event.ble_req.bd_addr, bda);
4299 bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_REQ_EVT, &sec_event);
4302 case BTM_LE_OOB_REQ_EVT:
4303 bdcpy(sec_event.ble_req.bd_addr, bda);
4304 bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event);
4307 case BTM_LE_NC_REQ_EVT:
4308 bdcpy(sec_event.key_notif.bd_addr, bda);
4309 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN));
4310 sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
4311 sec_event.key_notif.passkey = p_data->key_notif;
4312 bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
4315 case BTM_LE_KEY_EVT:
4316 bdcpy(sec_event.ble_key.bd_addr, bda);
4317 sec_event.ble_key.key_type = p_data->key.key_type;
4318 sec_event.ble_key.p_key_value = p_data->key.p_key_value;
4319 bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event);
4322 case BTM_LE_COMPLT_EVT:
4323 bdcpy(sec_event.auth_cmpl.bd_addr, bda);
4324 #if BLE_INCLUDED == TRUE
4325 BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
4327 p_name = BTM_SecReadDevName(bda);
4328 if (p_name != NULL) {
4329 BCM_STRNCPY_S((char *)sec_event.auth_cmpl.bd_name,
4330 sizeof(BD_NAME), p_name, (BD_NAME_LEN));
4332 sec_event.auth_cmpl.bd_name[0] = 0;
4334 if (p_data->complt.reason != 0) {
4335 sec_event.auth_cmpl.fail_reason = BTA_DM_AUTH_CONVERT_SMP_CODE(((UINT8)p_data->complt.reason));
4336 /* delete this device entry from Sec Dev DB */
4337 bta_dm_remove_sec_dev_entry (bda);
4339 sec_event.auth_cmpl.success = TRUE;
4340 if (!p_data->complt.smp_over_br) {
4345 if (bta_dm_cb.p_sec_cback) {
4346 //bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
4347 bta_dm_cb.p_sec_cback(BTA_DM_BLE_AUTH_CMPL_EVT, &sec_event);
4353 status = BTM_NOT_AUTHORIZED;
4359 /*******************************************************************************
4361 ** Function bta_dm_ble_id_key_cback
4363 ** Description Callback for BLE local ID keys
4368 *******************************************************************************/
4369 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key)
4375 case BTM_BLE_KEY_TYPE_ID:
4376 case BTM_BLE_KEY_TYPE_ER:
4377 if (bta_dm_cb.p_sec_cback) {
4378 memcpy(&dm_key.ble_id_keys, p_key, sizeof(tBTM_BLE_LOCAL_KEYS));
4380 evt = (key_type == BTM_BLE_KEY_TYPE_ID) ? BTA_DM_BLE_LOCAL_IR_EVT : \
4381 BTA_DM_BLE_LOCAL_ER_EVT;
4382 bta_dm_cb.p_sec_cback(evt, &dm_key);
4387 APPL_TRACE_DEBUG("Unknown key type %d", key_type);
4394 /*******************************************************************************
4396 ** Function bta_dm_add_blekey
4398 ** Description This function adds an BLE Key to an security database entry.
4399 ** This function shall only be called AFTER BTA_DmAddBleDevice has been called.
4400 ** It is normally called during host startup to restore all required information
4401 ** stored in the NVRAM.
4405 *******************************************************************************/
4406 void bta_dm_add_blekey (tBTA_DM_MSG *p_data)
4408 if (!BTM_SecAddBleKey (p_data->add_ble_key.bd_addr,
4409 (tBTM_LE_KEY_VALUE *)&p_data->add_ble_key.blekey,
4410 p_data->add_ble_key.key_type)) {
4411 APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Key for device %08x%04x",
4412 (p_data->add_ble_key.bd_addr[0] << 24) + (p_data->add_ble_key.bd_addr[1] << 16) + \
4413 (p_data->add_ble_key.bd_addr[2] << 8) + p_data->add_ble_key.bd_addr[3],
4414 (p_data->add_ble_key.bd_addr[4] << 8) + p_data->add_ble_key.bd_addr[5]);
4418 /*******************************************************************************
4420 ** Function bta_dm_add_ble_device
4422 ** Description This function adds an BLE device to an security database entry.
4423 ** It is normally called during host startup to restore all required information
4424 ** stored in the NVRAM.
4428 *******************************************************************************/
4429 void bta_dm_add_ble_device (tBTA_DM_MSG *p_data)
4431 if (!BTM_SecAddBleDevice (p_data->add_ble_device.bd_addr, NULL,
4432 p_data->add_ble_device.dev_type ,
4433 p_data->add_ble_device.addr_type)) {
4434 APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Device for device %08x%04x",
4435 (p_data->add_ble_device.bd_addr[0] << 24) + (p_data->add_ble_device.bd_addr[1] << 16) + \
4436 (p_data->add_ble_device.bd_addr[2] << 8) + p_data->add_ble_device.bd_addr[3],
4437 (p_data->add_ble_device.bd_addr[4] << 8) + p_data->add_ble_device.bd_addr[5]);
4441 /*******************************************************************************
4443 ** Function bta_dm_add_ble_device
4445 ** Description This function adds an BLE device to an security database entry.
4446 ** It is normally called during host startup to restore all required information
4447 ** stored in the NVRAM.
4451 *******************************************************************************/
4452 void bta_dm_ble_passkey_reply (tBTA_DM_MSG *p_data)
4454 if (p_data->pin_reply.accept) {
4455 BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_SUCCESS, p_data->ble_passkey_reply.passkey);
4457 BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED, p_data->ble_passkey_reply.passkey);
4462 /*******************************************************************************
4464 ** Function bta_dm_ble_confirm_reply
4466 ** Description This is response to SM numeric comparison request submitted
4471 *******************************************************************************/
4472 void bta_dm_ble_confirm_reply (tBTA_DM_MSG *p_data)
4474 if (p_data->confirm.accept) {
4475 BTM_BleConfirmReply(p_data->confirm.bd_addr, BTM_SUCCESS);
4477 BTM_BleConfirmReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED);
4481 /*******************************************************************************
4483 ** Function bta_dm_security_grant
4485 ** Description This function grant SMP security request access.
4489 *******************************************************************************/
4490 void bta_dm_security_grant (tBTA_DM_MSG *p_data)
4492 BTM_SecurityGrant(p_data->ble_sec_grant.bd_addr, p_data->ble_sec_grant.res);
4494 #endif ///SMP_INCLUDED == TRUE
4496 /*******************************************************************************
4498 ** Function bta_dm_ble_set_bg_conn_type
4500 ** Description This function set the BLE background connection type
4504 *******************************************************************************/
4505 void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data)
4507 BTM_BleSetBgConnType(p_data->ble_set_bd_conn_type.bg_conn_type,
4508 p_data->ble_set_bd_conn_type.p_select_cback);
4511 /*******************************************************************************
4513 ** Function bta_dm_ble_set_conn_params
4515 ** Description This function set the preferred connection parameters.
4519 *******************************************************************************/
4520 void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data)
4522 BTM_BleSetPrefConnParams(p_data->ble_set_conn_params.peer_bda,
4523 p_data->ble_set_conn_params.conn_int_min,
4524 p_data->ble_set_conn_params.conn_int_max,
4525 p_data->ble_set_conn_params.slave_latency,
4526 p_data->ble_set_conn_params.supervision_tout);
4529 /*******************************************************************************
4531 ** Function bta_dm_ble_set_conn_scan_params
4533 ** Description This function sets BLE scan parameters.
4537 *******************************************************************************/
4538 void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data)
4540 BTM_BleSetScanParams(p_data->ble_set_scan_params.client_if,
4541 p_data->ble_set_scan_params.scan_int,
4542 p_data->ble_set_scan_params.scan_window,
4543 p_data->ble_set_scan_params.scan_mode,
4544 p_data->ble_set_scan_params.scan_param_setup_cback);
4547 /*******************************************************************************
4549 ** Function bta_dm_ble_set_scan_fil_params
4551 ** Description This function sets BLE scan filter & parameters.
4555 *******************************************************************************/
4556 void bta_dm_ble_set_scan_fil_params(tBTA_DM_MSG *p_data)
4558 BTM_BleSetScanFilterParams (p_data->ble_set_scan_fil_params.client_if,
4559 p_data->ble_set_scan_fil_params.scan_int,
4560 p_data->ble_set_scan_fil_params.scan_window,
4561 p_data->ble_set_scan_fil_params.scan_mode,
4562 p_data->ble_set_scan_fil_params.addr_type_own,
4563 p_data->ble_set_scan_fil_params.scan_filter_policy,
4564 p_data->ble_set_scan_fil_params.scan_param_setup_cback);
4568 /*******************************************************************************
4570 ** Function bta_dm_ble_set_conn_scan_params
4572 ** Description This function set the preferred connection scan parameters.
4576 *******************************************************************************/
4577 void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data)
4579 BTM_BleSetConnScanParams(p_data->ble_set_conn_scan_params.scan_int,
4580 p_data->ble_set_conn_scan_params.scan_window);
4582 /*******************************************************************************
4584 ** Function bta_dm_ble_update_conn_params
4586 ** Description This function update LE connection parameters.
4590 *******************************************************************************/
4591 void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
4593 if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr,
4594 p_data->ble_update_conn_params.min_int,
4595 p_data->ble_update_conn_params.max_int,
4596 p_data->ble_update_conn_params.latency,
4597 p_data->ble_update_conn_params.timeout)) {
4598 APPL_TRACE_ERROR("Update connection parameters failed!");
4601 /*******************************************************************************
4603 ** Function bta_dm_ble_disconnect
4605 ** Description This function disconnect the ble connection.
4609 *******************************************************************************/
4610 void bta_dm_ble_disconnect (tBTA_DM_MSG *p_data)
4612 L2CA_RemoveFixedChnl(L2CAP_ATT_CID, p_data->ble_disconnect.remote_bda);
4615 /*******************************************************************************
4617 ** Function bta_dm_ble_set_rand_address
4619 ** Description This function set the LE random address for the device.
4621 ** Parameters: rand_addr:the random address whitch should be setting
4622 ** Explanation: This function added by Yulong at 2016/9/9
4623 *******************************************************************************/
4624 void bta_dm_ble_set_rand_address(tBTA_DM_MSG *p_data)
4626 BOOLEAN set_flag = false;
4627 if (p_data->set_addr.addr_type != BLE_ADDR_RANDOM) {
4628 APPL_TRACE_ERROR("Invalid random adress type = %d\n", p_data->set_addr.addr_type);
4631 //send the setting random address to BTM layer
4632 if ((set_flag = BTM_BleSetRandAddress(p_data->set_addr.address) != TRUE)){
4633 APPL_TRACE_ERROR("%s,set random address fail.", __func__);
4638 /*******************************************************************************
4640 ** Function bta_dm_ble_stop_advertising
4642 ** Description This function stop the BLE avdertising for the device.
4645 ** Explanation: This function added by Yulong at 2016/10/19
4646 *******************************************************************************/
4647 void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data)
4649 if (p_data->hdr.event != BTA_DM_API_BLE_STOP_ADV_EVT) {
4650 APPL_TRACE_ERROR("Invalid BTA event,cann't stop the BLE adverting\n");
4658 #if BLE_PRIVACY_SPT == TRUE
4659 /*******************************************************************************
4661 ** Function bta_dm_ble_config_local_privacy
4663 ** Description This function set the local device LE privacy settings.
4667 *******************************************************************************/
4668 void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data)
4670 BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable, p_data->ble_local_privacy.set_local_privacy_cback);
4674 /*******************************************************************************
4676 ** Function bta_dm_ble_observe
4678 ** Description This function set the preferred connection scan parameters.
4682 *******************************************************************************/
4683 void bta_dm_ble_observe (tBTA_DM_MSG *p_data)
4686 if (p_data->ble_observe.start) {
4687 /*Save the callback to be called when a scan results are available */
4688 bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback;
4690 if ((status = BTM_BleObserve(TRUE, p_data->ble_observe.duration,
4691 bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) {
4692 APPL_TRACE_WARNING(" %s start observe failed. status=0x%x\n", __FUNCTION__, status);
4695 if (p_data->ble_observe.p_start_scan_cback) {
4696 status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4697 p_data->ble_observe.p_start_scan_cback(status);
4700 bta_dm_search_cb.p_scan_cback = NULL;
4701 status = BTM_BleObserve(FALSE, 0, NULL, NULL);
4703 if (status != BTM_CMD_STARTED){
4704 APPL_TRACE_WARNING(" %s stop observe failed, status=0x%x\n", __FUNCTION__, status);
4707 if (p_data->ble_observe.p_stop_scan_cback) {
4708 status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4709 p_data->ble_observe.p_stop_scan_cback(status);
4714 /*******************************************************************************
4716 ** Function bta_dm_ble_scan
4718 ** Description This function set the preferred connection scan parameters.
4722 *******************************************************************************/
4723 void bta_dm_ble_scan (tBTA_DM_MSG *p_data)
4726 if (p_data->ble_scan.start) {
4727 /*Save the callback to be called when a scan results are available */
4728 bta_dm_search_cb.p_scan_cback = p_data->ble_scan.p_cback;
4730 if ((status = BTM_BleScan(TRUE, p_data->ble_scan.duration,
4731 bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) {
4732 APPL_TRACE_WARNING(" %s start scan failed. status=0x%x\n", __FUNCTION__, status);
4735 if (p_data->ble_scan.p_start_scan_cback) {
4736 status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4737 p_data->ble_scan.p_start_scan_cback(status);
4740 bta_dm_search_cb.p_scan_cback = NULL;
4741 status = BTM_BleScan(FALSE, 0, NULL, NULL);
4743 if (status != BTM_CMD_STARTED){
4744 APPL_TRACE_WARNING(" %s stop scan failed, status=0x%x\n", __FUNCTION__, status);
4747 if (p_data->ble_scan.p_stop_scan_cback) {
4748 status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4749 p_data->ble_scan.p_stop_scan_cback(status);
4754 /*******************************************************************************
4756 ** Function bta_dm_ble_set_adv_params
4758 ** Description This function set the adv parameters.
4762 *******************************************************************************/
4763 void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data)
4765 BTM_BleSetAdvParams(p_data->ble_set_adv_params.adv_int_min,
4766 p_data->ble_set_adv_params.adv_int_max,
4767 p_data->ble_set_adv_params.p_dir_bda,
4768 BTA_DM_BLE_ADV_CHNL_MAP);
4771 /*******************************************************************************
4773 ** Function bta_dm_ble_set_adv_params_all
4775 ** Description This function is called to set all of the advertising parameters.
4777 ** Parameters: None.
4781 *******************************************************************************/
4782 void bta_dm_ble_set_adv_params_all (tBTA_DM_MSG *p_data)
4784 if (BTM_BleSetAdvParamsStartAdv(p_data->ble_set_adv_params_all.adv_int_min,
4785 p_data->ble_set_adv_params_all.adv_int_max,
4786 p_data->ble_set_adv_params_all.adv_type,
4787 p_data->ble_set_adv_params_all.addr_type_own,
4788 p_data->ble_set_adv_params_all.p_dir_bda,
4789 p_data->ble_set_adv_params_all.channel_map,
4790 p_data->ble_set_adv_params_all.adv_filter_policy,
4791 p_data->ble_set_adv_params_all.p_start_adv_cback) == BTM_SUCCESS) {
4792 APPL_TRACE_DEBUG("%s(), success to start ble adv.", __func__);
4794 APPL_TRACE_ERROR("%s(), fail to start ble adv.", __func__);
4798 /*******************************************************************************
4800 ** Function bta_dm_ble_set_adv_config
4802 ** Description This function set the customized ADV data configuration
4806 *******************************************************************************/
4807 void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data)
4809 tBTA_STATUS status = BTA_FAILURE;
4811 if (BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask,
4812 (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS) {
4813 status = BTA_SUCCESS;
4816 if (p_data->ble_set_adv_data.p_adv_data_cback) {
4817 (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
4821 /*******************************************************************************
4823 ** Function bta_dm_ble_set_adv_config_raw
4825 ** Description This function set the customized ADV data configuration
4829 *******************************************************************************/
4830 void bta_dm_ble_set_adv_config_raw (tBTA_DM_MSG *p_data)
4832 tBTA_STATUS status = BTA_FAILURE;
4834 if (BTM_BleWriteAdvDataRaw(p_data->ble_set_adv_data_raw.p_raw_adv,
4835 p_data->ble_set_adv_data_raw.raw_adv_len) == BTM_SUCCESS) {
4836 status = BTA_SUCCESS;
4839 if (p_data->ble_set_adv_data_raw.p_adv_data_cback) {
4840 (*p_data->ble_set_adv_data_raw.p_adv_data_cback)(status);
4845 /*******************************************************************************
4847 ** Function bta_dm_ble_set_scan_rsp
4849 ** Description This function set the customized ADV scan resp. configuration
4853 *******************************************************************************/
4854 void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data)
4856 tBTA_STATUS status = BTA_FAILURE;
4858 if (BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
4859 (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS) {
4860 status = BTA_SUCCESS;
4863 if (p_data->ble_set_adv_data.p_adv_data_cback) {
4864 (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
4868 /*******************************************************************************
4870 ** Function bta_dm_ble_set_scan_rsp_raw
4872 ** Description This function set the raw scan response data
4876 *******************************************************************************/
4877 void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data)
4879 tBTA_STATUS status = BTA_FAILURE;
4881 if (BTM_BleWriteScanRspRaw(p_data->ble_set_adv_data_raw.p_raw_adv,
4882 p_data->ble_set_adv_data_raw.raw_adv_len) == BTM_SUCCESS) {
4883 status = BTA_SUCCESS;
4886 if (p_data->ble_set_adv_data_raw.p_adv_data_cback) {
4887 (*p_data->ble_set_adv_data_raw.p_adv_data_cback)(status);
4891 /*******************************************************************************
4893 ** Function bta_dm_ble_set_data_length
4895 ** Description This function set the maximum transmission packet size
4899 *******************************************************************************/
4900 void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data)
4902 tACL_CONN *p_acl_cb = btm_bda_to_acl(p_data->ble_set_data_length.remote_bda, BT_TRANSPORT_LE);
4903 if (p_acl_cb == NULL) {
4904 APPL_TRACE_ERROR("%s error: Invalid connection remote_bda.", __func__);
4907 p_acl_cb->p_set_pkt_data_cback = p_data->ble_set_data_length.p_set_pkt_data_cback;
4909 UINT8 status = BTM_SetBleDataLength(p_data->ble_set_data_length.remote_bda,
4910 p_data->ble_set_data_length.tx_data_length);
4911 if (status != BTM_SUCCESS) {
4912 APPL_TRACE_ERROR("%s failed\n", __FUNCTION__);
4913 if (p_data->ble_set_data_length.p_set_pkt_data_cback) {
4914 if (p_acl_cb->data_length_params.tx_len == 0){
4915 uint16_t length = controller_get_interface()->get_acl_data_size_ble();
4916 p_acl_cb->data_length_params.rx_len = length;
4917 p_acl_cb->data_length_params.tx_len = length;
4919 (*p_data->ble_set_data_length.p_set_pkt_data_cback)(status, &p_acl_cb->data_length_params);
4924 /*******************************************************************************
4926 ** Function bta_dm_ble_broadcast
4928 ** Description Starts or stops LE broadcasts
4932 *******************************************************************************/
4933 void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data)
4935 tBTM_STATUS status = 0;
4936 BOOLEAN start = p_data->ble_observe.start;
4938 status = BTM_BleBroadcast(start, p_data->ble_observe.p_stop_adv_cback);
4940 if (p_data->ble_observe.p_stop_adv_cback){
4941 if (status != BTM_SUCCESS){
4942 APPL_TRACE_WARNING("%s, %s, status=0x%x\n", __func__,\
4943 (start == TRUE) ? "start adv failed" : "stop adv failed", status);
4949 /*******************************************************************************
4951 ** Function bta_dm_ble_multi_adv_enb
4953 ** Description This function enables a single advertising instance
4957 *******************************************************************************/
4958 void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data)
4960 tBTM_STATUS btm_status = 0;
4962 bta_dm_cb.p_multi_adv_cback = p_data->ble_multi_adv_enb.p_cback;
4963 if (BTM_BleMaxMultiAdvInstanceCount() > 0 && NULL != p_data->ble_multi_adv_enb.p_ref) {
4964 btm_status = BTM_BleEnableAdvInstance((tBTM_BLE_ADV_PARAMS *)
4965 p_data->ble_multi_adv_enb.p_params,
4966 p_data->ble_multi_adv_enb.p_cback,
4967 p_data->ble_multi_adv_enb.p_ref);
4970 if (BTM_CMD_STARTED != btm_status) {
4971 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_ENB_EVT, 0xFF,
4972 p_data->ble_multi_adv_enb.p_ref, BTA_FAILURE);
4975 /*******************************************************************************
4977 ** Function bta_dm_ble_multi_adv_param_upd
4979 ** Description This function updates multiple advertising instance parameters
4983 *******************************************************************************/
4984 void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data)
4986 tBTM_STATUS btm_status = 0;
4989 if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_param.inst_id > 0
4990 && p_data->ble_multi_adv_param.inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
4991 btm_status = BTM_BleUpdateAdvInstParam(p_data->ble_multi_adv_param.inst_id,
4992 (tBTM_BLE_ADV_PARAMS *)p_data->ble_multi_adv_param.p_params);
4995 if (BTM_CMD_STARTED != btm_status) {
4996 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_param.inst_id);
4997 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_PARAM_EVT,
4998 p_data->ble_multi_adv_param.inst_id, p_ref, BTA_FAILURE);
5001 /*******************************************************************************
5003 ** Function bta_dm_ble_multi_adv_data
5005 ** Description This function write multiple advertising instance adv data
5006 ** or scan response data
5010 *******************************************************************************/
5011 void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data)
5013 tBTM_STATUS btm_status = 0;
5016 if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_data.inst_id > 0
5017 && p_data->ble_multi_adv_data.inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
5018 btm_status = BTM_BleCfgAdvInstData(p_data->ble_multi_adv_data.inst_id,
5019 p_data->ble_multi_adv_data.is_scan_rsp,
5020 p_data->ble_multi_adv_data.data_mask,
5021 (tBTM_BLE_ADV_DATA *)p_data->ble_multi_adv_data.p_data);
5024 if (BTM_CMD_STARTED != btm_status) {
5025 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_data.inst_id);
5026 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DATA_EVT,
5027 p_data->ble_multi_adv_data.inst_id, p_ref, BTA_FAILURE);
5031 /*******************************************************************************
5033 ** Function btm_dm_ble_multi_adv_disable
5035 ** Description This function disable a single adv instance
5039 *******************************************************************************/
5040 void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data)
5042 tBTM_STATUS btm_status = 0;
5045 if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_disable.inst_id > 0
5046 && p_data->ble_multi_adv_disable.inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
5047 btm_status = BTM_BleDisableAdvInstance(p_data->ble_multi_adv_disable.inst_id);
5050 if (BTM_CMD_STARTED != btm_status) {
5051 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_disable.inst_id);
5052 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DISABLE_EVT,
5053 p_data->ble_multi_adv_disable.inst_id, p_ref, BTA_FAILURE);
5057 /*******************************************************************************
5059 ** Function bta_dm_ble_setup_storage
5061 ** Description This function configures up the storage parameters for ADV batch scanning
5065 *******************************************************************************/
5066 void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data)
5068 tBTM_STATUS btm_status = 0;
5069 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5071 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5073 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5074 btm_status = BTM_BleSetStorageConfig(p_data->ble_set_storage.batch_scan_full_max,
5075 p_data->ble_set_storage.batch_scan_trunc_max,
5076 p_data->ble_set_storage.batch_scan_notify_threshold,
5077 p_data->ble_set_storage.p_setup_cback,
5078 p_data->ble_set_storage.p_thres_cback,
5079 p_data->ble_set_storage.p_read_rep_cback,
5080 p_data->ble_set_storage.ref_value);
5083 if (BTM_CMD_STARTED != btm_status)
5084 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, p_data->ble_set_storage.ref_value,
5088 /*******************************************************************************
5090 ** Function bta_dm_ble_enable_batch_scan
5092 ** Description This function sets up the parameters and enables batch scan
5096 *******************************************************************************/
5097 void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data)
5099 tBTM_STATUS btm_status = 0;
5100 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5102 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5104 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5105 btm_status = BTM_BleEnableBatchScan(p_data->ble_enable_scan.scan_mode,
5106 p_data->ble_enable_scan.scan_int,
5107 p_data->ble_enable_scan.scan_window,
5108 p_data->ble_enable_scan.discard_rule,
5109 p_data->ble_enable_scan.addr_type,
5110 p_data->ble_enable_scan.ref_value);
5113 if (BTM_CMD_STARTED != btm_status)
5114 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_ENABLE_EVT, p_data->ble_enable_scan.ref_value,
5118 /*******************************************************************************
5120 ** Function bta_dm_ble_disable_batch_scan
5122 ** Description This function disables the batch scan
5126 *******************************************************************************/
5127 void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data)
5130 tBTM_STATUS btm_status = 0;
5131 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5133 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5135 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5136 btm_status = BTM_BleDisableBatchScan(p_data->ble_disable_scan.ref_value);
5139 if (BTM_CMD_STARTED != btm_status)
5140 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_DISABLE_EVT, p_data->ble_enable_scan.ref_value,
5144 /*******************************************************************************
5146 ** Function bta_dm_ble_read_scan_reports
5148 ** Description This function reads the batch scan reports
5152 *******************************************************************************/
5153 void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data)
5155 tBTM_STATUS btm_status = 0;
5156 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5158 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5160 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5161 btm_status = BTM_BleReadScanReports(p_data->ble_read_reports.scan_type,
5162 p_data->ble_read_reports.ref_value);
5165 if (BTM_CMD_STARTED != btm_status)
5166 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, p_data->ble_enable_scan.ref_value,
5170 /*******************************************************************************
5172 ** Function bta_dm_ble_track_advertiser
5174 ** Description This function tracks the specific advertiser
5178 *******************************************************************************/
5179 void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data)
5181 tBTM_STATUS btm_status = 0;
5183 memset(&bda, 0 , sizeof(BD_ADDR));
5184 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5185 tBTA_DM_BLE_TRACK_ADV_DATA track_adv_data;
5187 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5189 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5190 btm_status = BTM_BleTrackAdvertiser((tBTM_BLE_TRACK_ADV_CBACK *)
5191 p_data->ble_track_advert.p_track_adv_cback,
5192 p_data->ble_track_advert.ref_value);
5195 if (BTM_CMD_STARTED != btm_status) {
5196 memset(&track_adv_data, 0, sizeof(tBTA_DM_BLE_TRACK_ADV_DATA));
5197 track_adv_data.advertiser_info_present = NO_ADV_INFO_PRESENT; /* Indicates failure */
5198 track_adv_data.client_if = (UINT8)p_data->ble_track_advert.ref_value;
5199 p_data->ble_track_advert.p_track_adv_cback(&track_adv_data);
5203 /*******************************************************************************
5205 ** Function bta_ble_scan_setup_cb
5207 ** Description Handle the setup callback from BTM layer and forward it to app layer
5211 *******************************************************************************/
5212 void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_value,
5215 tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0;
5217 APPL_TRACE_DEBUG("bta_ble_scan_setup_cb : evt: %d, ref_value: %d, status:%d", evt,
5221 case BTM_BLE_BATCH_SCAN_ENABLE_EVT:
5222 bta_evt = BTA_BLE_BATCH_SCAN_ENB_EVT;
5224 case BTM_BLE_BATCH_SCAN_CFG_STRG_EVT:
5225 bta_evt = BTA_BLE_BATCH_SCAN_CFG_STRG_EVT;
5227 case BTM_BLE_BATCH_SCAN_DISABLE_EVT:
5228 bta_evt = BTA_BLE_BATCH_SCAN_DIS_EVT;
5230 case BTM_BLE_BATCH_SCAN_PARAM_EVT:
5231 bta_evt = BTA_BLE_BATCH_SCAN_PARAM_EVT;
5237 if (NULL != bta_dm_cb.p_setup_cback) {
5238 bta_dm_cb.p_setup_cback(bta_evt, ref_value, status);
5243 #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
5244 /*******************************************************************************
5246 ** Function bta_ble_scan_pf_cmpl
5248 ** Description ADV payload filtering operation complete callback
5251 ** Returns TRUE if handled, otherwise FALSE.
5253 *******************************************************************************/
5254 static void bta_ble_scan_cfg_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op,
5255 tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status,
5256 tBTM_BLE_REF_VALUE ref_value)
5258 tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
5260 APPL_TRACE_DEBUG("bta_ble_scan_cfg_cmpl: %d, %d, %d, %d", action, cfg_op, avbl_space, status);
5262 if (bta_dm_cb.p_scan_filt_cfg_cback) {
5263 bta_dm_cb.p_scan_filt_cfg_cback(action, cfg_op, avbl_space, st, ref_value);
5267 /*******************************************************************************
5269 ** Function bta_dm_cfg_filter_cond
5271 ** Description This function configure adv payload filtering condition
5275 *******************************************************************************/
5276 void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data)
5278 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5279 tBTA_STATUS status = BTA_FAILURE;
5281 tBTM_BLE_VSC_CB cmn_vsc_cb;
5283 APPL_TRACE_DEBUG("bta_dm_cfg_filter_cond");
5284 BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5285 if (0 != cmn_vsc_cb.filter_support) {
5286 if ((st = BTM_BleCfgFilterCondition(p_data->ble_cfg_filter_cond.action,
5287 p_data->ble_cfg_filter_cond.cond_type,
5288 (tBTM_BLE_PF_FILT_INDEX)p_data->ble_cfg_filter_cond.filt_index,
5289 (tBTM_BLE_PF_COND_PARAM *)p_data->ble_cfg_filter_cond.p_cond_param,
5290 bta_ble_scan_cfg_cmpl, p_data->ble_cfg_filter_cond.ref_value))
5291 == BTM_CMD_STARTED) {
5292 bta_dm_cb.p_scan_filt_cfg_cback = p_data->ble_cfg_filter_cond.p_filt_cfg_cback;
5297 if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback)
5298 p_data->ble_cfg_filter_cond.p_filt_cfg_cback(BTA_DM_BLE_PF_CONFIG_EVT,
5299 p_data->ble_cfg_filter_cond.cond_type, 0, status,
5300 p_data->ble_cfg_filter_cond.ref_value);
5304 /*******************************************************************************
5306 ** Function bta_dm_enable_scan_filter
5308 ** Description This function enable/disable adv payload filtering condition
5312 *******************************************************************************/
5313 void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data)
5315 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5316 tBTA_STATUS status = BTA_FAILURE;
5318 tBTM_BLE_VSC_CB cmn_vsc_cb;
5319 APPL_TRACE_DEBUG("bta_dm_enable_scan_filter");
5320 BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5322 if (0 != cmn_vsc_cb.filter_support) {
5323 if ((st = BTM_BleEnableDisableFilterFeature(p_data->ble_enable_scan_filt.action,
5324 p_data->ble_enable_scan_filt.p_filt_status_cback,
5325 (tBTM_BLE_REF_VALUE)p_data->ble_enable_scan_filt.ref_value)) == BTM_CMD_STARTED) {
5326 bta_dm_cb.p_scan_filt_status_cback = p_data->ble_enable_scan_filt.p_filt_status_cback;
5331 if (p_data->ble_enable_scan_filt.p_filt_status_cback)
5332 p_data->ble_enable_scan_filt.p_filt_status_cback (BTA_DM_BLE_PF_ENABLE_EVT,
5333 p_data->ble_enable_scan_filt.ref_value, status);
5337 /*******************************************************************************
5339 ** Function bta_dm_scan_filter_param_setup
5341 ** Description This function sets up scan filter params
5345 *******************************************************************************/
5346 void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data)
5348 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5349 tBTA_STATUS status = BTA_FAILURE;
5351 tBTM_BLE_VSC_CB cmn_vsc_cb;
5353 APPL_TRACE_DEBUG("bta_dm_scan_filter_param_setup");
5354 BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5355 if (0 != cmn_vsc_cb.filter_support) {
5356 if ((st = BTM_BleAdvFilterParamSetup(p_data->ble_scan_filt_param_setup.action,
5357 p_data->ble_scan_filt_param_setup.filt_index,
5358 (tBTM_BLE_PF_FILT_PARAMS *)&p_data->ble_scan_filt_param_setup.filt_params,
5359 p_data->ble_scan_filt_param_setup.p_target,
5360 p_data->ble_scan_filt_param_setup.p_filt_param_cback,
5361 p_data->ble_scan_filt_param_setup.ref_value)) == BTM_CMD_STARTED) {
5362 bta_dm_cb.p_scan_filt_param_cback = p_data->ble_scan_filt_param_setup.p_filt_param_cback;
5367 if (p_data->ble_scan_filt_param_setup.p_filt_param_cback)
5368 p_data->ble_scan_filt_param_setup.p_filt_param_cback (BTA_DM_BLE_PF_ENABLE_EVT, 0,
5369 p_data->ble_scan_filt_param_setup.ref_value, status);
5375 /*******************************************************************************
5377 ** Function bta_ble_enable_scan_cmpl
5379 ** Description ADV payload filtering enable / disable complete callback
5384 *******************************************************************************/
5385 static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time,
5386 tBTM_BLE_RX_TIME_MS rx_time,
5387 tBTM_BLE_IDLE_TIME_MS idle_time,
5388 tBTM_BLE_ENERGY_USED energy_used,
5391 tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
5392 tBTA_DM_CONTRL_STATE ctrl_state = 0;
5393 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
5394 if (BTA_SUCCESS == st) {
5395 ctrl_state = bta_dm_pm_obtain_controller_state();
5398 if (bta_dm_cb.p_energy_info_cback) {
5399 bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, ctrl_state, st);
5403 /*******************************************************************************
5405 ** Function bta_dm_ble_get_energy_info
5407 ** Description This function obtains the energy info
5411 *******************************************************************************/
5412 void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data)
5414 tBTM_STATUS btm_status = 0;
5416 bta_dm_cb.p_energy_info_cback = p_data->ble_energy_info.p_energy_info_cback;
5417 btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl);
5418 if (BTM_CMD_STARTED != btm_status) {
5419 bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status);
5423 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
5424 #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
5425 #define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000
5428 /*******************************************************************************
5430 ** Function bta_dm_gattc_register
5432 ** Description Register with GATTC in DM if BLE is needed.
5437 *******************************************************************************/
5438 #if (GATTC_INCLUDED == TRUE)
5439 static void bta_dm_gattc_register(void)
5441 tBT_UUID app_uuid = {LEN_UUID_128, {0}};
5443 if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF) {
5444 memset (&app_uuid.uu.uuid128, 0x87, LEN_UUID_128);
5445 BTA_GATTC_AppRegister(&app_uuid, bta_dm_gattc_callback);
5448 #endif /* GATTC_INCLUDED == TRUE */
5449 /*******************************************************************************
5451 ** Function btm_dm_start_disc_gatt_services
5453 ** Description This function starts a GATT service search request.
5457 *******************************************************************************/
5458 static void btm_dm_start_disc_gatt_services (UINT16 conn_id)
5460 tBT_UUID *p_uuid = bta_dm_search_cb.p_srvc_uuid +
5461 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
5463 p_uuid = bta_dm_search_cb.p_srvc_uuid +
5464 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
5466 /* always search for all services */
5467 BTA_GATTC_ServiceSearchRequest(conn_id, p_uuid);
5470 /*******************************************************************************
5472 ** Function bta_dm_gatt_disc_result
5474 ** Description This function process the GATT service search result.
5478 *******************************************************************************/
5479 #if (GATTC_INCLUDED == TRUE)
5480 static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
5482 tBTA_DM_SEARCH result;
5485 * This logic will not work for gatt case. We are checking against the bluetooth profiles here
5486 * just copy the GATTID in raw data field and send it across.
5490 if ( bta_dm_search_cb.ble_raw_used + sizeof(tBTA_GATT_ID) < bta_dm_search_cb.ble_raw_size ) {
5491 APPL_TRACE_DEBUG("ADDING BLE SERVICE uuid=0x%x, ble_ptr = %p, ble_raw_used = 0x%x",
5492 service_id.uuid.uu.uuid16, bta_dm_search_cb.p_ble_rawdata, bta_dm_search_cb.ble_raw_used);
5494 if (bta_dm_search_cb.p_ble_rawdata) {
5495 memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used), &service_id,
5496 sizeof(service_id) );
5498 bta_dm_search_cb.ble_raw_used += sizeof(service_id);
5500 APPL_TRACE_ERROR("p_ble_rawdata is NULL");
5504 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 );
5507 LOG_INFO("%s service_id_uuid_len=%d ", __func__, service_id.uuid.len);
5508 if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
5510 /* send result back to app now, one by one */
5511 bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
5512 BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN - 1));
5513 result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
5514 memcpy(&result.disc_ble_res.service, &service_id.uuid, sizeof(tBT_UUID));
5516 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
5519 #endif /* #if (GATTC_INCLUDED == TRUE) */
5520 /*******************************************************************************
5522 ** Function bta_dm_gatt_disc_complete
5524 ** Description This function process the GATT service search complete.
5528 *******************************************************************************/
5529 static void bta_dm_gatt_disc_complete(UINT16 conn_id, tBTA_GATT_STATUS status)
5533 APPL_TRACE_DEBUG("bta_dm_gatt_disc_complete conn_id = %d", conn_id);
5535 if (bta_dm_search_cb.uuid_to_search > 0) {
5536 bta_dm_search_cb.uuid_to_search --;
5539 if (status == BTA_GATT_OK && bta_dm_search_cb.uuid_to_search > 0) {
5540 btm_dm_start_disc_gatt_services(conn_id);
5542 bta_dm_search_cb.uuid_to_search = 0;
5544 /* no more services to be discovered */
5545 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
5546 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
5547 p_msg->disc_result.result.disc_res.result = (status == BTA_GATT_OK) ? BTA_SUCCESS : BTA_FAILURE;
5548 APPL_TRACE_DEBUG("%s service found: 0x%08x", __FUNCTION__,
5549 bta_dm_search_cb.services_found);
5550 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
5551 p_msg->disc_result.result.disc_res.num_uuids = 0;
5552 p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
5553 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
5554 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
5555 bta_dm_get_remname(), (BD_NAME_LEN - 1));
5557 /* make sure the string is terminated */
5558 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
5560 p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE;
5561 if ( bta_dm_search_cb.ble_raw_used > 0 ) {
5562 p_msg->disc_result.result.disc_res.p_raw_data = osi_malloc(bta_dm_search_cb.ble_raw_used);
5564 memcpy( p_msg->disc_result.result.disc_res.p_raw_data,
5565 bta_dm_search_cb.p_ble_rawdata,
5566 bta_dm_search_cb.ble_raw_used );
5568 p_msg->disc_result.result.disc_res.raw_data_size = bta_dm_search_cb.ble_raw_used;
5570 p_msg->disc_result.result.disc_res.p_raw_data = NULL;
5571 bta_dm_search_cb.p_ble_rawdata = 0;
5574 bta_sys_sendmsg(p_msg);
5577 if (conn_id != BTA_GATT_INVALID_CONN_ID) {
5578 /* start a GATT channel close delay timer */
5579 bta_sys_start_timer(&bta_dm_search_cb.gatt_close_timer, BTA_DM_DISC_CLOSE_TOUT_EVT,
5580 BTA_DM_GATT_CLOSE_DELAY_TOUT);
5581 bdcpy(bta_dm_search_cb.pending_close_bda, bta_dm_search_cb.peer_bdaddr);
5583 bta_dm_search_cb.gatt_disc_active = FALSE;
5587 /*******************************************************************************
5589 ** Function bta_dm_close_gatt_conn
5591 ** Description This function close the GATT connection after delay timeout.
5595 *******************************************************************************/
5596 #if (GATTC_INCLUDED == TRUE)
5597 void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data)
5601 if (bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID) {
5602 BTA_GATTC_Close(bta_dm_search_cb.conn_id);
5605 memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
5606 bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
5608 #endif /* #if (GATTC_INCLUDED == TRUE) */
5609 /*******************************************************************************
5611 ** Function btm_dm_start_gatt_discovery
5613 ** Description This is GATT initiate the service search by open a GATT connection
5618 *******************************************************************************/
5619 #if (GATTC_INCLUDED == TRUE)
5620 void btm_dm_start_gatt_discovery (BD_ADDR bd_addr)
5622 bta_dm_search_cb.gatt_disc_active = TRUE;
5624 /* connection is already open */
5625 if (bdcmp(bta_dm_search_cb.pending_close_bda, bd_addr) == 0 &&
5626 bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID) {
5627 memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
5628 bta_sys_stop_timer(&bta_dm_search_cb.gatt_close_timer);
5629 btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
5631 BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE, BTA_GATT_TRANSPORT_LE);
5634 #endif /* #if (GATTC_INCLUDED == TRUE) */
5635 /*******************************************************************************
5637 ** Function bta_dm_cancel_gatt_discovery
5639 ** Description This is GATT cancel the GATT service search.
5643 *******************************************************************************/
5644 #if (GATTC_INCLUDED == TRUE)
5645 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr)
5647 if (bta_dm_search_cb.conn_id == BTA_GATT_INVALID_CONN_ID) {
5648 BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, TRUE);
5651 bta_dm_gatt_disc_complete(bta_dm_search_cb.conn_id, (tBTA_GATT_STATUS) BTA_GATT_ERROR);
5653 #endif /* #if (GATTC_INCLUDED == TRUE) */
5654 /*******************************************************************************
5656 ** Function bta_dm_proc_open_evt
5658 ** Description process BTA_GATTC_OPEN_EVT in DM.
5662 *******************************************************************************/
5663 void bta_dm_proc_open_evt(tBTA_GATTC_OPEN *p_data)
5668 p1 = bta_dm_search_cb.peer_bdaddr;
5669 p2 = p_data->remote_bda;
5671 APPL_TRACE_DEBUG("DM Search state= %d search_cb.peer_dbaddr: [%08x%04x] connected_bda= [%08x%04x] ",
5672 bta_dm_search_cb.state,
5673 ((p1[0]) << 24) + ((p1[1]) << 16) + ((p1[2]) << 8) + (p1[3]),
5674 ((p1[4]) << 8) + p1[5],
5675 ((p2[0]) << 24) + ((p2[1]) << 16) + ((p2[2]) << 8) + (p2[3]),
5676 ((p2[4]) << 8) + p2[5]);
5678 APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d" ,
5683 bta_dm_search_cb.conn_id = p_data->conn_id;
5685 if (p_data->status == BTA_GATT_OK) {
5686 btm_dm_start_disc_gatt_services(p_data->conn_id);
5688 bta_dm_gatt_disc_complete(BTA_GATT_INVALID_CONN_ID, p_data->status);
5692 /*******************************************************************************
5694 ** Function bta_dm_gattc_callback
5696 ** Description This is GATT client callback function used in DM.
5700 *******************************************************************************/
5701 #if (GATTC_INCLUDED == TRUE)
5702 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
5704 APPL_TRACE_DEBUG("bta_dm_gattc_callback event = %d", event);
5707 case BTA_GATTC_REG_EVT:
5708 APPL_TRACE_DEBUG("BTA_GATTC_REG_EVT client_if = %d", p_data->reg_oper.client_if);
5709 if (p_data->reg_oper.status == BTA_GATT_OK) {
5710 bta_dm_search_cb.client_if = p_data->reg_oper.client_if;
5712 bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF;
5716 case BTA_GATTC_OPEN_EVT:
5717 bta_dm_proc_open_evt(&p_data->open);
5720 case BTA_GATTC_SEARCH_RES_EVT:
5721 bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid);
5724 case BTA_GATTC_SEARCH_CMPL_EVT:
5725 if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
5726 bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
5730 case BTA_GATTC_CLOSE_EVT:
5731 APPL_TRACE_DEBUG("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason);
5732 /* in case of disconnect before search is completed */
5733 if ( (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) &&
5734 (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) &&
5735 !memcmp(p_data->close.remote_bda, bta_dm_search_cb.peer_bdaddr, BD_ADDR_LEN)) {
5736 bta_dm_gatt_disc_complete((UINT16)BTA_GATT_INVALID_CONN_ID, (tBTA_GATT_STATUS) BTA_GATT_ERROR);
5744 #endif /* #if (GATTC_INCLUDED == TRUE) */
5745 #endif /* BTA_GATT_INCLUDED */
5747 #if BLE_VND_INCLUDED == TRUE
5748 /*******************************************************************************
5750 ** Function bta_dm_ctrl_features_rd_cmpl_cback
5752 ** Description callback to handle controller feature read complete
5756 *******************************************************************************/
5757 static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result)
5759 APPL_TRACE_DEBUG("%s status = %d ", __FUNCTION__, result);
5760 if (result == BTM_SUCCESS) {
5761 if (bta_dm_cb.p_sec_cback) {
5762 bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
5765 APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d", __FUNCTION__, result);
5769 #endif /* BLE_VND_INCLUDED */
5771 #endif /* BLE_INCLUDED */