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_sys_hw_cback
289 ** Description callback register to SYS to get HW status updates
294 *******************************************************************************/
295 static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
298 tBTA_DM_SEC_CBACK *temp_cback;
299 #if BLE_INCLUDED == TRUE
302 tBTA_BLE_LOCAL_ID_KEYS id_key;
305 APPL_TRACE_DEBUG("%s with event: %i", __func__, status);
307 /* On H/W error evt, report to the registered DM application callback */
308 if (status == BTA_SYS_HW_ERROR_EVT) {
309 if ( bta_dm_cb.p_sec_cback != NULL ) {
310 bta_dm_cb.p_sec_cback(BTA_DM_HW_ERROR_EVT, NULL);
315 if ( status == BTA_SYS_HW_OFF_EVT ) {
316 if ( bta_dm_cb.p_sec_cback != NULL ) {
317 bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL);
320 /* reinitialize the control block */
321 memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
323 /* unregister from SYS */
324 bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH );
325 /* notify BTA DM is now unactive */
326 bta_dm_cb.is_bta_dm_active = FALSE;
327 } else if ( status == BTA_SYS_HW_ON_EVT ) {
328 /* FIXME: We should not unregister as the SYS shall invoke this callback on a H/W error.
329 * We need to revisit when this platform has more than one BLuetooth H/W chip */
330 //bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH);
332 /* save security callback */
333 temp_cback = bta_dm_cb.p_sec_cback;
334 /* make sure the control block is properly initialized */
335 memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
336 /* and retrieve the callback */
337 bta_dm_cb.p_sec_cback = temp_cback;
338 bta_dm_cb.is_bta_dm_active = TRUE;
340 /* hw is ready, go on with BTA DM initialization */
341 memset(&bta_dm_search_cb, 0x00, sizeof(bta_dm_search_cb));
342 #if (BTM_SSR_INCLUDED == TRUE)
343 memset(&bta_dm_conn_srvcs, 0x00, sizeof(bta_dm_conn_srvcs));
344 #endif ///BTM_SSR_INCLUDED == TRUE
345 memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB));
347 memcpy(dev_class, p_bta_dm_cfg->dev_class, sizeof(dev_class));
348 BTM_SetDeviceClass (dev_class);
350 #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
351 /* load BLE local information: ID keys, ER if available */
352 bta_dm_co_ble_load_local_keys(&key_mask, er, &id_key);
354 if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ER) {
355 BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ER, (tBTM_BLE_LOCAL_KEYS *)&er);
357 if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ID) {
358 BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ID, (tBTM_BLE_LOCAL_KEYS *)&id_key);
360 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
361 bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
364 #if (SMP_INCLUDED == TRUE)
365 BTM_SecRegister((tBTM_APPL_INFO *)&bta_security);
366 #endif ///SMP_INCLUDED == TRUE
367 BTM_SetDefaultLinkSuperTout(p_bta_dm_cfg->link_timeout);
368 BTM_WritePageTimeout(p_bta_dm_cfg->page_timeout);
369 bta_dm_cb.cur_policy = p_bta_dm_cfg->policy_settings;
370 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
371 BTM_RegBusyLevelNotif (bta_dm_bl_change_cback, NULL, BTM_BL_UPDATE_MASK | BTM_BL_ROLE_CHG_MASK);
373 #if BLE_VND_INCLUDED == TRUE
374 BTM_BleReadControllerFeatures (bta_dm_ctrl_features_rd_cmpl_cback);
377 /* Earlier, we used to invoke BTM_ReadLocalAddr which was just copying the bd_addr
378 from the control block and invoking the callback which was sending the DM_ENABLE_EVT.
379 But then we have a few HCI commands being invoked above which were still in progress
380 when the ENABLE_EVT was sent. So modified this to fetch the local name which forces
381 the DM_ENABLE_EVT to be sent only after all the init steps are complete */
382 BTM_ReadLocalDeviceNameFromController((tBTM_CMPL_CB *)bta_dm_local_name_cback);
384 bta_sys_rm_register((tBTA_SYS_CONN_CBACK *)bta_dm_rm_cback);
385 #if (BTM_SSR_INCLUDED == TRUE)
386 /* initialize bluetooth low power manager */
388 #endif ///BTM_SSR_INCLUDED == TRUE
389 bta_sys_policy_register((tBTA_SYS_CONN_CBACK *)bta_dm_policy_cback);
391 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE)
392 bta_dm_gattc_register();
396 APPL_TRACE_DEBUG(" --- ignored event");
402 /*******************************************************************************
404 ** Function bta_dm_disable
406 ** Description Disables the BT device manager
411 *******************************************************************************/
412 void bta_dm_disable (tBTA_DM_MSG *p_data)
416 /* Set l2cap idle timeout to 0 (so BTE immediately disconnects ACL link after last channel is closed) */
417 L2CA_SetIdleTimeoutByBdAddr((UINT8 *)BT_BD_ANY, 0, BT_TRANSPORT_BR_EDR);
418 L2CA_SetIdleTimeoutByBdAddr((UINT8 *)BT_BD_ANY, 0, BT_TRANSPORT_LE);
420 /* disable all active subsystems */
421 bta_sys_disable(BTA_SYS_HW_BLUETOOTH);
423 BTM_SetDiscoverability(BTM_NON_DISCOVERABLE, 0, 0);
424 BTM_SetConnectability(BTM_NON_CONNECTABLE, 0, 0);
425 #if (BTM_SSR_INCLUDED == TRUE)
427 #endif ///BTM_SSR_INCLUDED == TRUE
428 bta_dm_disable_search_and_disc();
429 bta_dm_cb.disabling = TRUE;
431 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
432 BTM_BleClearBgConnDev();
435 if (BTM_GetNumAclLinks() == 0) {
436 #if (defined(BTA_DISABLE_DELAY) && BTA_DISABLE_DELAY > 0)
437 /* If BTA_DISABLE_DELAY is defined and greater than zero, then delay the shutdown by
438 * BTA_DISABLE_DELAY milliseconds
440 APPL_TRACE_WARNING("%s BTA_DISABLE_DELAY set to %d ms",
441 __FUNCTION__, BTA_DISABLE_DELAY);
442 bta_sys_stop_timer(&bta_dm_cb.disable_timer);
443 bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK *)&bta_dm_disable_conn_down_timer_cback;
444 bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, BTA_DISABLE_DELAY);
446 bta_dm_disable_conn_down_timer_cback(NULL);
449 bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK *)&bta_dm_disable_timer_cback;
450 bta_dm_cb.disable_timer.param = 0;
451 bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 5000);
454 #if BLE_PRIVACY_SPT == TRUE
455 btm_ble_resolving_list_cleanup (); //by TH, because cmn_ble_vsc_cb.max_filter has something mistake as btm_ble_adv_filter_cleanup
460 /*******************************************************************************
462 ** Function bta_dm_disable_timer_cback
464 ** Description Called if the disable timer expires
465 ** Used to close ACL connections which are still active
471 *******************************************************************************/
472 static void bta_dm_disable_timer_cback (TIMER_LIST_ENT *p_tle)
476 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
477 BOOLEAN trigger_disc = FALSE;
480 APPL_TRACE_EVENT(" bta_dm_disable_timer_cback trial %d ", p_tle->param);
482 if (BTM_GetNumAclLinks() && p_tle->param == 0) {
483 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
484 #if (BLE_INCLUDED == TRUE)
485 transport = bta_dm_cb.device_list.peer_device[i].transport;
487 btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, transport);
491 /* Retrigger disable timer in case ACL disconnect failed, DISABLE_EVT still need
492 to be sent out to avoid jave layer disable timeout */
494 bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK *)&bta_dm_disable_timer_cback;
495 bta_dm_cb.disable_timer.param = 1;
496 bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 1500);
499 bta_dm_cb.disabling = FALSE;
501 bta_sys_remove_uuid(UUID_SERVCLASS_PNP_INFORMATION);
502 bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL);
509 /*******************************************************************************
511 ** Function bta_dm_set_dev_name
513 ** Description Sets local device name
518 *******************************************************************************/
519 void bta_dm_set_dev_name (tBTA_DM_MSG *p_data)
522 BTM_SetLocalDeviceName((char *)p_data->set_name.name);
523 bta_dm_set_eir ((char *)p_data->set_name.name);
526 void bta_dm_update_white_list(tBTA_DM_MSG *p_data)
528 BTM_BleUpdateAdvWhitelist(p_data->white_list.add_remove, p_data->white_list.remote_addr, p_data->white_list.add_wl_cb);
531 void bta_dm_ble_read_adv_tx_power(tBTA_DM_MSG *p_data)
533 if (p_data->read_tx_power.read_tx_power_cb != NULL) {
534 BTM_BleReadAdvTxPower(p_data->read_tx_power.read_tx_power_cb);
536 APPL_TRACE_ERROR("%s(), the callback function cann't be NULL.", __func__);
540 void bta_dm_ble_read_rssi(tBTA_DM_MSG *p_data)
542 if (p_data->rssi.read_rssi_cb != NULL) {
543 BTM_ReadRSSI(p_data->rssi.remote_addr, p_data->rssi.read_rssi_cb);
545 APPL_TRACE_ERROR("%s(), the callback function cann't be NULL.", __func__);
549 /*******************************************************************************
551 ** Function bta_dm_set_visibility
553 ** Description Sets discoverability, connectability and pairability
558 *******************************************************************************/
559 void bta_dm_set_visibility(tBTA_DM_MSG *p_data)
561 UINT16 window, interval;
562 UINT16 le_disc_mode = BTM_BleReadDiscoverability();
563 UINT16 disc_mode = BTM_ReadDiscoverability(&window, &interval);
564 UINT16 le_conn_mode = BTM_BleReadConnectability();
565 UINT16 conn_mode = BTM_ReadConnectability(&window, &interval);
567 /* set modes for Discoverability and connectability if not ignore */
568 if (p_data->set_visibility.disc_mode != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE)) {
569 if ((p_data->set_visibility.disc_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE)
570 p_data->set_visibility.disc_mode =
571 ((p_data->set_visibility.disc_mode & ~BTA_DM_LE_IGNORE) | le_disc_mode);
573 if ((p_data->set_visibility.disc_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE)
574 p_data->set_visibility.disc_mode =
575 ((p_data->set_visibility.disc_mode & ~BTA_DM_IGNORE) | disc_mode);
577 BTM_SetDiscoverability(p_data->set_visibility.disc_mode,
578 bta_dm_cb.inquiry_scan_window,
579 bta_dm_cb.inquiry_scan_interval);
582 if (p_data->set_visibility.conn_mode != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE)) {
583 if ((p_data->set_visibility.conn_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE)
584 p_data->set_visibility.conn_mode =
585 ((p_data->set_visibility.conn_mode & ~BTA_DM_LE_IGNORE) | le_conn_mode);
587 if ((p_data->set_visibility.conn_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE)
588 p_data->set_visibility.conn_mode =
589 ((p_data->set_visibility.conn_mode & ~BTA_DM_IGNORE) | conn_mode);
591 BTM_SetConnectability(p_data->set_visibility.conn_mode,
592 bta_dm_cb.page_scan_window,
593 bta_dm_cb.page_scan_interval);
596 /* Send False or True if not ignore */
597 if (p_data->set_visibility.pair_mode != BTA_DM_IGNORE ) {
599 if (p_data->set_visibility.pair_mode == BTA_DM_NON_PAIRABLE) {
600 bta_dm_cb.disable_pair_mode = TRUE;
602 bta_dm_cb.disable_pair_mode = FALSE;
607 /* Send False or True if not ignore */
608 if (p_data->set_visibility.conn_paired_only != BTA_DM_IGNORE) {
610 if (p_data->set_visibility.conn_paired_only == BTA_DM_CONN_ALL) {
611 bta_dm_cb.conn_paired_only = FALSE;
613 bta_dm_cb.conn_paired_only = TRUE;
618 /* Change mode if either mode is not ignore */
619 if (p_data->set_visibility.pair_mode != BTA_DM_IGNORE || p_data->set_visibility.conn_paired_only != BTA_DM_IGNORE) {
620 BTM_SetPairableMode((BOOLEAN)(!(bta_dm_cb.disable_pair_mode)), bta_dm_cb.conn_paired_only);
625 /*******************************************************************************
627 ** Function bta_dm_process_remove_device
629 ** Description Removes device, Disconnects ACL link if required.
631 *******************************************************************************/
632 void bta_dm_process_remove_device(BD_ADDR bd_addr)
634 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
635 /* need to remove all pending background connection before unpair */
636 BTA_GATTC_CancelOpen(0, bd_addr, FALSE);
639 BTM_SecDeleteDevice(bd_addr);
641 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
642 /* remove all cached GATT information */
643 BTA_GATTC_Refresh(bd_addr);
646 if (bta_dm_cb.p_sec_cback) {
647 tBTA_DM_SEC sec_event;
648 bdcpy(sec_event.link_down.bd_addr, bd_addr);
649 sec_event.link_down.status = HCI_SUCCESS;
650 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event);
654 /*******************************************************************************
656 ** Function bta_dm_remove_device
658 ** Description Removes device, disconnects ACL link if required.
660 *******************************************************************************/
661 void bta_dm_remove_device(tBTA_DM_MSG *p_data)
663 tBTA_DM_API_REMOVE_DEVICE *p_dev = &p_data->remove_dev;
668 BD_ADDR other_address;
669 bdcpy(other_address, p_dev->bd_addr);
671 /* If ACL exists for the device in the remove_bond message*/
672 BOOLEAN continue_delete_dev = FALSE;
673 UINT8 other_transport = BT_TRANSPORT_INVALID;
675 if (BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_LE) ||
676 BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_BR_EDR)) {
677 APPL_TRACE_DEBUG("%s: ACL Up count %d", __func__, bta_dm_cb.device_list.count);
678 continue_delete_dev = FALSE;
680 /* Take the link down first, and mark the device for removal when disconnected */
681 for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
682 if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_dev->bd_addr)) {
683 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
684 btm_remove_acl( p_dev->bd_addr, bta_dm_cb.device_list.peer_device[i].transport);
685 APPL_TRACE_DEBUG("%s:transport = %d", __func__,
686 bta_dm_cb.device_list.peer_device[i].transport);
688 /* save the other transport to check if device is connected on other_transport */
689 if (bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_LE) {
690 other_transport = BT_TRANSPORT_BR_EDR;
692 other_transport = BT_TRANSPORT_LE;
698 continue_delete_dev = TRUE;
701 // If it is DUMO device and device is paired as different address, unpair that device
702 // if different address
703 BOOLEAN continue_delete_other_dev = FALSE;
704 if ((other_transport && (BTM_ReadConnectedTransportAddress(other_address, other_transport))) ||
705 (!other_transport && (BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_BR_EDR) ||
706 BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_LE)))) {
707 continue_delete_other_dev = FALSE;
708 /* Take the link down first, and mark the device for removal when disconnected */
709 for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
710 if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, other_address)) {
711 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
712 btm_remove_acl(other_address, bta_dm_cb.device_list.peer_device[i].transport);
717 APPL_TRACE_DEBUG("%s: continue to delete the other dev ", __func__);
718 continue_delete_other_dev = TRUE;
721 /* Delete the device mentioned in the msg */
722 if (continue_delete_dev) {
723 bta_dm_process_remove_device(p_dev->bd_addr);
726 /* Delete the other paired device too */
727 BD_ADDR dummy_bda = {0};
728 if (continue_delete_other_dev && (bdcmp(other_address, dummy_bda) != 0)) {
729 bta_dm_process_remove_device(other_address);
733 /*******************************************************************************
735 ** Function bta_dm_add_device
737 ** Description This function adds a Link Key to an security database entry.
738 ** It is normally called during host startup to restore all required information
739 ** stored in the NVRAM.
741 *******************************************************************************/
742 void bta_dm_add_device (tBTA_DM_MSG *p_data)
744 tBTA_DM_API_ADD_DEVICE *p_dev = &p_data->add_dev;
747 UINT32 trusted_services_mask[BTM_SEC_SERVICE_ARRAY_SIZE];
749 UINT8 btm_mask_index = 0;
751 memset (trusted_services_mask, 0, sizeof(trusted_services_mask));
753 /* If not all zeros, the device class has been specified */
754 if (p_dev->dc_known) {
755 p_dc = (UINT8 *)p_dev->dc;
758 if (p_dev->link_key_known) {
759 p_lc = (UINT8 *)p_dev->link_key;
762 if (p_dev->is_trusted) {
763 /* covert BTA service mask to BTM mask */
764 while (p_dev->tm && (index < BTA_MAX_SERVICE_ID)) {
765 if (p_dev->tm & (UINT32)(1 << index)) {
767 btm_mask_index = bta_service_id_to_btm_srv_id_lkup_tbl[index] / BTM_SEC_ARRAY_BITS;
768 trusted_services_mask[btm_mask_index] |= (UINT32)(1 << (bta_service_id_to_btm_srv_id_lkup_tbl[index] - (UINT32)(btm_mask_index * 32)));
770 p_dev->tm &= (UINT32)(~(1 << index));
777 if (!BTM_SecAddDevice (p_dev->bd_addr, p_dc, p_dev->bd_name, p_dev->features,
778 trusted_services_mask, p_lc, p_dev->key_type, p_dev->io_cap,
779 p_dev->pin_length)) {
780 APPL_TRACE_ERROR ("BTA_DM: Error adding device %08x%04x",
781 (p_dev->bd_addr[0] << 24) + (p_dev->bd_addr[1] << 16) + (p_dev->bd_addr[2] << 8) + p_dev->bd_addr[3],
782 (p_dev->bd_addr[4] << 8) + p_dev->bd_addr[5]);
786 /*******************************************************************************
788 ** Function bta_dm_close_acl
790 ** Description This function forces to close the connection to a remote device
791 ** and optionaly remove the device from security database if
794 *******************************************************************************/
795 void bta_dm_close_acl(tBTA_DM_MSG *p_data)
797 tBTA_DM_API_REMOVE_ACL *p_remove_acl = &p_data->remove_acl;
800 APPL_TRACE_DEBUG("bta_dm_close_acl");
802 if (BTM_IsAclConnectionUp(p_remove_acl->bd_addr, p_remove_acl->transport)) {
803 for (index = 0; index < bta_dm_cb.device_list.count; index ++) {
804 if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, p_remove_acl->bd_addr)) {
808 if (index != bta_dm_cb.device_list.count) {
809 if (p_remove_acl->remove_dev) {
810 bta_dm_cb.device_list.peer_device[index].remove_dev_pending = TRUE;
813 APPL_TRACE_ERROR("unknown device, remove ACL failed");
815 /* Disconnect the ACL link */
816 btm_remove_acl(p_remove_acl->bd_addr, p_remove_acl->transport);
818 /* if to remove the device from security database ? do it now */
819 else if (p_remove_acl->remove_dev) {
820 if (!BTM_SecDeleteDevice(p_remove_acl->bd_addr)) {
821 APPL_TRACE_ERROR("delete device from security database failed.");
823 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
824 /* need to remove all pending background connection if any */
825 BTA_GATTC_CancelOpen(0, p_remove_acl->bd_addr, FALSE);
826 /* remove all cached GATT information */
827 BTA_GATTC_Refresh(p_remove_acl->bd_addr);
830 /* otherwise, no action needed */
834 /*******************************************************************************
836 ** Function bta_dm_remove_all_acl
838 ** Description This function forces to close all the ACL links specified by link type
840 *******************************************************************************/
841 void bta_dm_remove_all_acl(tBTA_DM_MSG *p_data)
843 const tBTA_DM_LINK_TYPE link_type = p_data->remove_all_acl.link_type;
844 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
846 APPL_TRACE_DEBUG("%s link type = %d", __func__, link_type);
848 for (UINT8 i = 0; i < bta_dm_cb.device_list.count; i++) {
850 bdcpy(addr, bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
851 #if defined (BLE_INCLUDED) && (BLE_INCLUDED == TRUE)
852 transport = bta_dm_cb.device_list.peer_device[i].transport;
854 if ((link_type == BTA_DM_LINK_TYPE_ALL) ||
855 ((link_type == BTA_DM_LINK_TYPE_LE) && (transport == BT_TRANSPORT_LE)) ||
856 ((link_type == BTA_DM_LINK_TYPE_BR_EDR) && (transport == BT_TRANSPORT_BR_EDR))) {
857 /* Disconnect the ACL link */
858 btm_remove_acl(addr, transport);
864 /*******************************************************************************
866 ** Function bta_dm_bond
868 ** Description Bonds with peer device
873 *******************************************************************************/
874 #if (SMP_INCLUDED == TRUE)
875 void bta_dm_bond (tBTA_DM_MSG *p_data)
878 tBTA_DM_SEC sec_event;
881 if (p_data->bond.transport == BTA_TRANSPORT_UNKNOWN) {
882 status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 );
884 status = BTM_SecBondByTransport ( p_data->bond.bd_addr, p_data->bond.transport, 0, NULL, 0 );
888 if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED)) {
890 memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
891 bdcpy(sec_event.auth_cmpl.bd_addr, p_data->bond.bd_addr);
892 p_name = BTM_SecReadDevName(p_data->bond.bd_addr);
893 if (p_name != NULL) {
894 memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN - 1));
895 sec_event.auth_cmpl.bd_name[BD_NAME_LEN - 1] = 0;
898 /* taken care of by memset [above]
899 sec_event.auth_cmpl.key_present = FALSE;
900 sec_event.auth_cmpl.success = FALSE;
902 sec_event.auth_cmpl.fail_reason = HCI_ERR_ILLEGAL_COMMAND;
903 if (status == BTM_SUCCESS) {
904 sec_event.auth_cmpl.success = TRUE;
906 /* delete this device entry from Sec Dev DB */
907 bta_dm_remove_sec_dev_entry(p_data->bond.bd_addr);
909 bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
914 /*******************************************************************************
916 ** Function bta_dm_bond_cancel
918 ** Description Cancels bonding with a peer device
923 *******************************************************************************/
924 void bta_dm_bond_cancel (tBTA_DM_MSG *p_data)
927 tBTA_DM_SEC sec_event;
929 APPL_TRACE_EVENT(" bta_dm_bond_cancel ");
930 status = BTM_SecBondCancel ( p_data->bond_cancel.bd_addr );
932 if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED && status != BTM_SUCCESS)) {
933 sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
935 bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
940 /*******************************************************************************
942 ** Function bta_dm_pin_reply
944 ** Description Send the pin_reply to a request from BTM
949 *******************************************************************************/
950 void bta_dm_pin_reply (tBTA_DM_MSG *p_data)
952 UINT32 trusted_mask[BTM_SEC_SERVICE_ARRAY_SIZE];
953 UINT32 *current_trusted_mask;
955 current_trusted_mask = BTM_ReadTrustedMask(p_data->pin_reply.bd_addr);
957 if (current_trusted_mask) {
958 memcpy(trusted_mask, current_trusted_mask, sizeof(trusted_mask));
960 memset(trusted_mask, 0, sizeof(trusted_mask));
963 if (p_data->pin_reply.accept) {
965 BTM_PINCodeReply(p_data->pin_reply.bd_addr, BTM_SUCCESS, p_data->pin_reply.pin_len, p_data->pin_reply.p_pin, trusted_mask );
967 BTM_PINCodeReply(p_data->pin_reply.bd_addr, BTM_NOT_AUTHORIZED, 0, NULL, trusted_mask );
971 #endif ///SMP_INCLUDED == TRUE
973 /*******************************************************************************
975 ** Function bta_dm_policy_cback
977 ** Description process the link policy changes
981 *******************************************************************************/
982 static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
984 tBTA_DM_PEER_DEVICE *p_dev = NULL;
985 UINT16 policy = app_id;
986 UINT32 mask = (UINT32)(1 << id);
989 p_dev = bta_dm_find_peer_device(peer_addr);
992 APPL_TRACE_DEBUG(" bta_dm_policy_cback cmd:%d, policy:0x%x",
995 case BTA_SYS_PLCY_SET:
999 /* restore the default link policy */
1000 p_dev->link_policy |= policy;
1001 BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy));
1004 case BTA_SYS_PLCY_CLR:
1008 /* clear the policy from the default link policy */
1009 p_dev->link_policy &= (~policy);
1010 BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy));
1012 if (policy & (HCI_ENABLE_SNIFF_MODE | HCI_ENABLE_PARK_MODE)) {
1013 /* if clearing sniff/park, wake the link */
1014 #if (BTM_SSR_INCLUDED == TRUE)
1015 bta_dm_pm_active(p_dev->peer_bdaddr);
1016 #endif ///BTM_SSR_INCLUDED == TRUE
1020 case BTA_SYS_PLCY_DEF_SET:
1021 /* want to restore/set the role switch policy */
1022 bta_dm_cb.role_policy_mask &= ~mask;
1023 if (0 == bta_dm_cb.role_policy_mask) {
1024 /* if nobody wants to insist on the role */
1025 bta_dm_cb.cur_policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
1026 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
1030 case BTA_SYS_PLCY_DEF_CLR:
1031 /* want to remove the role switch policy */
1032 bta_dm_cb.role_policy_mask |= mask;
1033 bta_dm_cb.cur_policy &= ~HCI_ENABLE_MASTER_SLAVE_SWITCH;
1034 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
1039 /*******************************************************************************
1041 ** Function bta_dm_confirm
1043 ** Description Send the user confirm request reply in response to a
1048 *******************************************************************************/
1049 #if (SMP_INCLUDED == TRUE)
1050 void bta_dm_confirm(tBTA_DM_MSG *p_data)
1052 tBTM_STATUS res = BTM_NOT_AUTHORIZED;
1054 if (p_data->confirm.accept == TRUE) {
1057 BTM_ConfirmReqReply(res, p_data->confirm.bd_addr);
1059 #endif ///SMP_INCLUDED == TRUE
1061 /*******************************************************************************
1063 ** Function bta_dm_loc_oob
1065 ** Description Retrieve the OOB data from the local LM
1069 *******************************************************************************/
1070 #if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
1071 void bta_dm_loc_oob(tBTA_DM_MSG *p_data)
1074 BTM_ReadLocalOobData();
1077 /*******************************************************************************
1079 ** Function bta_dm_ci_io_req_act
1081 ** Description respond to the IO capabilities request from BTM
1085 *******************************************************************************/
1086 void bta_dm_ci_io_req_act(tBTA_DM_MSG *p_data)
1088 tBTM_AUTH_REQ auth_req = BTM_AUTH_AP_NO;
1089 if (p_data->ci_io_req.auth_req) {
1090 auth_req = BTM_AUTH_AP_YES;
1092 BTM_IoCapRsp(p_data->ci_io_req.bd_addr, p_data->ci_io_req.io_cap,
1093 p_data->ci_io_req.oob_data, auth_req);
1096 /*******************************************************************************
1098 ** Function bta_dm_ci_rmt_oob_act
1100 ** Description respond to the OOB data request for the remote device from BTM
1105 *******************************************************************************/
1106 void bta_dm_ci_rmt_oob_act(tBTA_DM_MSG *p_data)
1108 tBTM_STATUS res = BTM_NOT_AUTHORIZED;
1110 if (p_data->ci_rmt_oob.accept == TRUE) {
1113 BTM_RemoteOobDataReply(res, p_data->ci_rmt_oob.bd_addr,
1114 p_data->ci_rmt_oob.c, p_data->ci_rmt_oob.r );
1116 #endif /* BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE */
1118 /*******************************************************************************
1120 ** Function bta_dm_search_start
1122 ** Description Starts an inquiry
1127 *******************************************************************************/
1128 void bta_dm_search_start (tBTA_DM_MSG *p_data)
1130 tBTM_INQUIRY_CMPL result;
1132 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE)
1133 UINT16 len = (UINT16)(sizeof(tBT_UUID) * p_data->search.num_uuid);
1134 bta_dm_gattc_register();
1137 APPL_TRACE_DEBUG("%s avoid_scatter=%d", __func__, p_bta_dm_cfg->avoid_scatter);
1139 if (p_bta_dm_cfg->avoid_scatter &&
1140 (p_data->search.rs_res == BTA_DM_RS_NONE) && bta_dm_check_av(BTA_DM_API_SEARCH_EVT)) {
1141 memcpy(&bta_dm_cb.search_msg, &p_data->search, sizeof(tBTA_DM_API_SEARCH));
1145 BTM_ClearInqDb(NULL);
1146 /* save search params */
1147 bta_dm_search_cb.p_search_cback = p_data->search.p_cback;
1148 bta_dm_search_cb.services = p_data->search.services;
1150 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE)
1151 utl_freebuf((void **)&bta_dm_search_cb.p_srvc_uuid);
1153 if ((bta_dm_search_cb.num_uuid = p_data->search.num_uuid) != 0 &&
1154 p_data->search.p_uuid != NULL) {
1155 if ((bta_dm_search_cb.p_srvc_uuid = (tBT_UUID *)osi_malloc(len)) == NULL) {
1156 APPL_TRACE_ERROR("%s no resources", __func__);
1158 result.status = BTA_FAILURE;
1159 result.num_resp = 0;
1160 bta_dm_inq_cmpl_cb ((void *)&result);
1164 memcpy(bta_dm_search_cb.p_srvc_uuid, p_data->search.p_uuid, len);
1167 result.status = BTM_StartInquiry( (tBTM_INQ_PARMS *)&p_data->search.inq_params,
1168 bta_dm_inq_results_cb,
1169 (tBTM_CMPL_CB *) bta_dm_inq_cmpl_cb);
1171 APPL_TRACE_EVENT("%s status=%d", __func__, result.status);
1172 if (result.status != BTM_CMD_STARTED) {
1173 result.num_resp = 0;
1174 bta_dm_inq_cmpl_cb ((void *)&result);
1178 /*******************************************************************************
1180 ** Function bta_dm_search_cancel
1182 ** Description Cancels an ongoing search for devices
1187 *******************************************************************************/
1188 void bta_dm_search_cancel (tBTA_DM_MSG *p_data)
1193 if (BTM_IsInquiryActive()) {
1194 if (BTM_CancelInquiry() != BTM_CMD_STARTED) {
1195 bta_dm_search_cancel_notify(NULL);
1196 p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
1197 if (p_msg != NULL) {
1198 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1199 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1200 bta_sys_sendmsg(p_msg);
1203 /* flag a search cancel is pending */
1204 bta_dm_search_cb.cancel_pending = TRUE;
1207 /* If no Service Search going on then issue cancel remote name in case it is active */
1208 else if (!bta_dm_search_cb.name_discover_done) {
1209 BTM_CancelRemoteDeviceName();
1211 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1212 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1213 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1214 bta_sys_sendmsg(p_msg);
1218 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1219 p_msg->hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
1220 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1221 bta_sys_sendmsg(p_msg);
1225 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE && GATTC_INCLUDED == TRUE
1226 if (bta_dm_search_cb.gatt_disc_active) {
1227 bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
1232 /*******************************************************************************
1234 ** Function bta_dm_discover
1236 ** Description Discovers services on a remote device
1241 *******************************************************************************/
1242 #if (SDP_INCLUDED == TRUE)
1243 void bta_dm_discover (tBTA_DM_MSG *p_data)
1245 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && GATTC_INCLUDED == TRUE
1246 UINT16 len = (UINT16)(sizeof(tBT_UUID) * p_data->discover.num_uuid);
1248 APPL_TRACE_EVENT("%s services_to_search=0x%04X, sdp_search=%d", __func__,
1249 p_data->discover.services, p_data->discover.sdp_search);
1251 /* save the search condition */
1252 bta_dm_search_cb.services = p_data->discover.services;
1254 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && GATTC_INCLUDED == TRUE
1255 bta_dm_gattc_register();
1256 utl_freebuf((void **)&bta_dm_search_cb.p_srvc_uuid);
1257 if ((bta_dm_search_cb.num_uuid = p_data->discover.num_uuid) != 0 &&
1258 p_data->discover.p_uuid != NULL) {
1259 if ((bta_dm_search_cb.p_srvc_uuid = (tBT_UUID *)osi_malloc(len)) == NULL) {
1260 p_data->discover.p_cback(BTA_DM_DISC_CMPL_EVT, NULL);
1263 memcpy(bta_dm_search_cb.p_srvc_uuid, p_data->discover.p_uuid, len);
1265 bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid;
1268 bta_dm_search_cb.p_search_cback = p_data->discover.p_cback;
1269 bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
1270 bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
1271 bta_dm_search_cb.service_index = 0;
1272 bta_dm_search_cb.services_found = 0;
1273 bta_dm_search_cb.peer_name[0] = 0;
1274 bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
1275 bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead (p_data->discover.bd_addr);
1276 bta_dm_search_cb.transport = p_data->discover.transport;
1278 bta_dm_search_cb.name_discover_done = FALSE;
1279 memcpy(&bta_dm_search_cb.uuid, &p_data->discover.uuid, sizeof(tSDP_UUID));
1280 bta_dm_discover_device(p_data->discover.bd_addr);
1283 /*******************************************************************************
1285 ** Function bta_dm_di_disc_cmpl
1287 ** Description Sends event to application when DI discovery complete
1291 *******************************************************************************/
1292 void bta_dm_di_disc_cmpl(tBTA_DM_MSG *p_data)
1294 tBTA_DM_DI_DISC_CMPL di_disc;
1296 memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL));
1297 bdcpy(di_disc.bd_addr, bta_dm_search_cb.peer_bdaddr);
1299 if ((p_data->hdr.offset == SDP_SUCCESS)
1300 || (p_data->hdr.offset == SDP_DB_FULL)) {
1301 di_disc.num_record = SDP_GetNumDiRecords(bta_dm_di_cb.p_di_db);
1303 di_disc.result = BTA_FAILURE;
1306 bta_dm_di_cb.p_di_db = NULL;
1307 bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT, (tBTA_DM_SEARCH *) &di_disc);
1310 /*******************************************************************************
1312 ** Function bta_dm_di_disc_callback
1314 ** Description This function queries a remote device for DI information.
1319 *******************************************************************************/
1320 static void bta_dm_di_disc_callback(UINT16 result)
1324 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1325 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1326 p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT;
1327 p_msg->hdr.offset = result;
1328 bta_sys_sendmsg(p_msg);
1331 #endif ///SDP_INCLUDED == TRUE
1332 /*******************************************************************************
1334 ** Function bta_dm_disable_search_and_disc
1336 ** Description Cancels an ongoing search or discovery for devices in case of
1337 ** a Bluetooth disable
1342 *******************************************************************************/
1343 static void bta_dm_disable_search_and_disc (void)
1345 #if (SDP_INCLUDED == TRUE)
1346 tBTA_DM_DI_DISC_CMPL di_disc;
1347 #endif ///SDP_INCLUDED == TRUE
1348 if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
1349 bta_dm_search_cancel(NULL);
1351 #if (SDP_INCLUDED == TRUE)
1352 if (bta_dm_di_cb.p_di_db != NULL) {
1353 memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL));
1354 bdcpy(di_disc.bd_addr, bta_dm_search_cb.peer_bdaddr);
1355 di_disc.result = BTA_FAILURE;
1357 bta_dm_di_cb.p_di_db = NULL;
1358 bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT, NULL);
1360 #endif ///SDP_INCLUDED == TRUE
1363 /*******************************************************************************
1365 ** Function bta_dm_di_disc
1367 ** Description This function queries a remote device for DI information.
1372 *******************************************************************************/
1373 #if (SDP_INCLUDED == TRUE)
1374 void bta_dm_di_disc (tBTA_DM_MSG *p_data)
1376 UINT16 result = BTA_FAILURE;
1379 bta_dm_search_cb.p_search_cback = p_data->di_disc.p_cback;
1380 bdcpy(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.bd_addr);
1381 bta_dm_di_cb.p_di_db = p_data->di_disc.p_sdp_db;
1383 if ((bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(BTA_DM_SDP_DB_SIZE)) != NULL) {
1384 if ( SDP_DiDiscover(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.p_sdp_db,
1385 p_data->di_disc.len, bta_dm_di_disc_callback) == SDP_SUCCESS) {
1386 result = BTA_SUCCESS;
1389 APPL_TRACE_ERROR("No buffer to start DI discovery");
1392 if ( result == BTA_FAILURE &&
1393 (p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1394 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1395 p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT;
1396 p_data->hdr.offset = result;
1397 bta_sys_sendmsg(p_msg);
1400 #endif ///SDP_INCLUDED == TRUE
1402 /*******************************************************************************
1404 ** Function bta_dm_read_remote_device_name
1406 ** Description Initiate to get remote device name
1408 ** Returns TRUE if started to get remote name
1410 *******************************************************************************/
1411 #if (SDP_INCLUDED == TRUE)
1412 static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr, tBT_TRANSPORT transport)
1414 tBTM_STATUS btm_status;
1416 APPL_TRACE_DEBUG("bta_dm_read_remote_device_name");
1418 bdcpy(bta_dm_search_cb.peer_bdaddr, bd_addr);
1419 bta_dm_search_cb.peer_name[0] = 0;
1421 btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
1422 (tBTM_CMPL_CB *) bta_dm_remname_cback,
1425 if ( btm_status == BTM_CMD_STARTED ) {
1426 APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is started");
1429 } else if ( btm_status == BTM_BUSY ) {
1430 APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is busy");
1432 /* Remote name discovery is on going now so BTM cannot notify through "bta_dm_remname_cback" */
1433 /* adding callback to get notified that current reading remore name done */
1434 BTM_SecAddRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1438 APPL_TRACE_WARNING("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
1443 #endif ///SDP_INCLUDED == TRUE
1445 /*******************************************************************************
1447 ** Function bta_dm_inq_cmpl
1449 ** Description Process the inquiry complete event from BTM
1453 *******************************************************************************/
1454 void bta_dm_inq_cmpl (tBTA_DM_MSG *p_data)
1457 tBTA_DM_SEARCH data;
1459 APPL_TRACE_DEBUG("bta_dm_inq_cmpl");
1461 data.inq_cmpl.num_resps = p_data->inq_cmpl.num;
1462 bta_dm_search_cb.p_search_cback(BTA_DM_INQ_CMPL_EVT, &data);
1464 if ((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbFirst()) != NULL) {
1465 /* start name and service discovery from the first device on inquiry result */
1466 bta_dm_search_cb.name_discover_done = FALSE;
1467 bta_dm_search_cb.peer_name[0] = 0;
1468 #if (SDP_INCLUDED == TRUE)
1469 bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
1470 #endif ///SDP_INCLUDED == TRUE
1472 /* no devices, search complete */
1473 bta_dm_search_cb.services = 0;
1475 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1476 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1477 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1478 bta_sys_sendmsg(p_msg);
1483 /*******************************************************************************
1485 ** Function bta_dm_rmt_name
1487 ** Description Process the remote name result from BTM
1491 *******************************************************************************/
1492 void bta_dm_rmt_name (tBTA_DM_MSG *p_data)
1494 APPL_TRACE_DEBUG("bta_dm_rmt_name");
1496 if ( p_data->rem_name.result.disc_res.bd_name[0] && bta_dm_search_cb.p_btm_inq_info) {
1497 bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name = TRUE;
1499 #if (SDP_INCLUDED == TRUE)
1500 bta_dm_discover_device(bta_dm_search_cb.peer_bdaddr);
1501 #endif ///SDP_INCLUDED == TRUE
1504 /*******************************************************************************
1506 ** Function bta_dm_disc_rmt_name
1508 ** Description Process the remote name result from BTM when application
1509 ** wants to find the name for a bdaddr
1513 *******************************************************************************/
1514 void bta_dm_disc_rmt_name (tBTA_DM_MSG *p_data)
1516 tBTM_INQ_INFO *p_btm_inq_info;
1518 APPL_TRACE_DEBUG("bta_dm_disc_rmt_name");
1520 p_btm_inq_info = BTM_InqDbRead (p_data->rem_name.result.disc_res.bd_addr);
1521 if ( p_btm_inq_info ) {
1522 if ( p_data->rem_name.result.disc_res.bd_name[0] ) {
1523 p_btm_inq_info->appl_knows_rem_name = TRUE;
1526 #if (SDP_INCLUDED == TRUE)
1527 bta_dm_discover_device(p_data->rem_name.result.disc_res.bd_addr);
1528 #endif ///SDP_INCLUDED == TRUE
1531 /*******************************************************************************
1533 ** Function bta_dm_sdp_result
1535 ** Description Process the discovery result from sdp
1539 *******************************************************************************/
1540 #if (SDP_INCLUDED == TRUE)
1541 void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
1543 tSDP_DISC_REC *p_sdp_rec = NULL;
1545 BOOLEAN scn_found = FALSE;
1546 UINT16 service = 0xFFFF;
1547 tSDP_PROTOCOL_ELEM pe;
1549 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1550 tBT_UUID *p_uuid = bta_dm_search_cb.p_srvc_uuid;
1551 tBTA_DM_SEARCH result;
1552 tBT_UUID service_uuid;
1555 UINT32 num_uuids = 0;
1556 UINT8 uuid_list[32][MAX_UUID_SIZE]; // assuming a max of 32 services
1558 if ((p_data->sdp_event.sdp_result == SDP_SUCCESS)
1559 || (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH)
1560 || (p_data->sdp_event.sdp_result == SDP_DB_FULL)) {
1561 APPL_TRACE_DEBUG("sdp_result::0x%x", p_data->sdp_event.sdp_result);
1564 if ( bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID + 1) ) {
1565 p_sdp_rec = SDP_FindServiceUUIDInDb(bta_dm_search_cb.p_sdp_db, &bta_dm_search_cb.uuid, p_sdp_rec);
1566 if (p_sdp_rec && SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
1567 bta_dm_search_cb.peer_scn = (UINT8) pe.params[0];
1571 service = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1];
1572 p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, service, p_sdp_rec);
1574 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1575 /* finished with BR/EDR services, now we check the result for GATT based service UUID */
1576 if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID) {
1577 if (bta_dm_search_cb.uuid_to_search != 0 && p_uuid != NULL) {
1578 p_uuid += (bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search);
1579 /* only support 16 bits UUID for now */
1580 service = p_uuid->uu.uuid16;
1582 /* all GATT based services */
1584 /* find a service record, report it */
1585 p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db,
1588 if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) {
1589 /* send result back to app now, one by one */
1590 bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1591 BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN));
1592 result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
1593 result.disc_ble_res.service.len = service_uuid.len;
1594 result.disc_ble_res.service.uu.uuid16 = service_uuid.uu.uuid16;
1596 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
1600 if (bta_dm_search_cb.uuid_to_search > 0) {
1604 } while (p_sdp_rec);
1608 /* SDP_DB_FULL means some records with the
1609 required attributes were received */
1610 if (((p_data->sdp_event.sdp_result == SDP_DB_FULL) &&
1611 bta_dm_search_cb.services != BTA_ALL_SERVICE_MASK) ||
1612 (p_sdp_rec != NULL)) {
1613 if (service != UUID_SERVCLASS_PNP_INFORMATION && service != 0) {
1614 UINT16 tmp_svc = 0xFFFF;
1615 bta_dm_search_cb.services_found |=
1616 (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index - 1));
1617 tmp_svc = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1];
1618 /* Add to the list of UUIDs */
1619 sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]);
1625 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK &&
1626 bta_dm_search_cb.services_to_search == 0) {
1627 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1628 if ( bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID &&
1629 bta_dm_search_cb.uuid_to_search > 0) {
1630 bta_dm_search_cb.uuid_to_search --;
1633 if (bta_dm_search_cb.uuid_to_search == 0 ||
1634 bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID)
1636 bta_dm_search_cb.service_index++;
1637 } else { /* regular one service per search or PNP search */
1640 } while (bta_dm_search_cb.service_index <= BTA_MAX_SERVICE_ID);
1642 APPL_TRACE_DEBUG("%s services_found = %04x", __FUNCTION__,
1643 bta_dm_search_cb.services_found);
1645 /* Collect the 128-bit services here and put them into the list */
1646 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) {
1650 /* find a service record, report it */
1651 p_sdp_rec = SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec);
1653 if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid)) {
1654 memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE);
1658 } while (p_sdp_rec);
1660 /* if there are more services to search for */
1661 if (bta_dm_search_cb.services_to_search) {
1662 /* Free up the p_sdp_db before checking the next one */
1663 bta_dm_free_sdp_db(NULL);
1664 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
1667 /* start next bd_addr if necessary */
1669 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1672 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1673 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1674 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
1675 p_msg->disc_result.result.disc_res.p_raw_data = NULL;
1676 p_msg->disc_result.result.disc_res.raw_data_size = 0;
1677 p_msg->disc_result.result.disc_res.num_uuids = num_uuids;
1678 p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
1679 if (num_uuids > 0) {
1680 p_msg->disc_result.result.disc_res.p_uuid_list = (UINT8 *)osi_malloc(num_uuids * MAX_UUID_SIZE);
1681 if (p_msg->disc_result.result.disc_res.p_uuid_list) {
1682 memcpy(p_msg->disc_result.result.disc_res.p_uuid_list, uuid_list,
1683 num_uuids * MAX_UUID_SIZE);
1685 p_msg->disc_result.result.disc_res.num_uuids = 0;
1686 APPL_TRACE_ERROR("%s: Unable to allocate memory for uuid_list", __func__);
1689 //copy the raw_data to the discovery result structure
1692 if ( bta_dm_search_cb.p_sdp_db != NULL && bta_dm_search_cb.p_sdp_db->raw_used != 0 &&
1693 bta_dm_search_cb.p_sdp_db->raw_data != NULL) {
1695 "%s raw_data used = 0x%x raw_data_ptr = %p", __func__,
1696 bta_dm_search_cb.p_sdp_db->raw_used,
1697 bta_dm_search_cb.p_sdp_db->raw_data);
1699 p_msg->disc_result.result.disc_res.p_raw_data = osi_malloc(bta_dm_search_cb.p_sdp_db->raw_used);
1700 if ( NULL != p_msg->disc_result.result.disc_res.p_raw_data ) {
1701 memcpy( p_msg->disc_result.result.disc_res.p_raw_data,
1702 bta_dm_search_cb.p_sdp_db->raw_data,
1703 bta_dm_search_cb.p_sdp_db->raw_used );
1705 p_msg->disc_result.result.disc_res.raw_data_size =
1706 bta_dm_search_cb.p_sdp_db->raw_used;
1709 APPL_TRACE_DEBUG("%s Alloc failed to allocate %d bytes !!", __func__,
1710 bta_dm_search_cb.p_sdp_db->raw_used);
1713 bta_dm_search_cb.p_sdp_db->raw_data = NULL; //no need to free this - it is a global assigned.
1714 bta_dm_search_cb.p_sdp_db->raw_used = 0;
1715 bta_dm_search_cb.p_sdp_db->raw_size = 0;
1717 APPL_TRACE_DEBUG("%s raw data size is 0 or raw_data is null!!", __func__);
1719 /* Done with p_sdp_db. Free it */
1720 bta_dm_free_sdp_db(NULL);
1721 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
1723 //Piggy back the SCN over result field
1725 p_msg->disc_result.result.disc_res.result = (3 + bta_dm_search_cb.peer_scn);
1726 p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK;
1728 APPL_TRACE_EVENT(" Piggy back the SCN over result field SCN=%d", bta_dm_search_cb.peer_scn);
1731 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1732 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
1733 bta_dm_get_remname(), (BD_NAME_LEN - 1));
1735 /* make sure the string is null terminated */
1736 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
1738 bta_sys_sendmsg(p_msg);
1742 /* conn failed. No need for timer */
1743 if (p_data->sdp_event.sdp_result == SDP_CONN_FAILED || p_data->sdp_event.sdp_result == SDP_CONN_REJECTED
1744 || p_data->sdp_event.sdp_result == SDP_SECURITY_ERR) {
1745 bta_dm_search_cb.wait_disc = FALSE;
1748 /* not able to connect go to next device */
1749 osi_free(bta_dm_search_cb.p_sdp_db);
1750 bta_dm_search_cb.p_sdp_db = NULL;
1752 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1754 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1755 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1756 p_msg->disc_result.result.disc_res.result = BTA_FAILURE;
1757 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
1758 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1759 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
1760 bta_dm_get_remname(), (BD_NAME_LEN - 1));
1762 /* make sure the string is null terminated */
1763 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
1765 bta_sys_sendmsg(p_msg);
1769 #endif ///SDP_INCLUDE == TRUE
1771 /*******************************************************************************
1773 ** Function bta_dm_search_cmpl
1775 ** Description Sends event to application
1779 *******************************************************************************/
1780 void bta_dm_search_cmpl (tBTA_DM_MSG *p_data)
1782 APPL_TRACE_EVENT("%s", __func__);
1784 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE)
1785 utl_freebuf((void **)&bta_dm_search_cb.p_srvc_uuid);
1788 if (p_data->hdr.layer_specific == BTA_DM_API_DI_DISCOVER_EVT) {
1789 #if (SDP_INCLUDED == TRUE)
1790 bta_dm_di_disc_cmpl(p_data);
1791 #endif ///SDP_INCLUDED == TRUE
1793 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, NULL);
1797 /*******************************************************************************
1799 ** Function bta_dm_disc_result
1801 ** Description Service discovery result when discovering services on a device
1805 *******************************************************************************/
1806 void bta_dm_disc_result (tBTA_DM_MSG *p_data)
1808 APPL_TRACE_EVENT("%s", __func__);
1810 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1811 /* if any BR/EDR service discovery has been done, report the event */
1812 if ((bta_dm_search_cb.services & ((BTA_ALL_SERVICE_MASK | BTA_USER_SERVICE_MASK ) & ~BTA_BLE_SERVICE_MASK)))
1814 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
1816 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
1818 /* send a message to change state */
1819 if (p_msg != NULL) {
1820 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1821 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1822 bta_sys_sendmsg(p_msg);
1826 /*******************************************************************************
1828 ** Function bta_dm_search_result
1830 ** Description Service discovery result while searching for devices
1834 *******************************************************************************/
1835 void bta_dm_search_result (tBTA_DM_MSG *p_data)
1837 APPL_TRACE_DEBUG("%s searching:0x%04x, result:0x%04x", __func__,
1838 bta_dm_search_cb.services,
1839 p_data->disc_result.result.disc_res.services);
1841 /* call back if application wants name discovery or found services that application is searching */
1842 if (( !bta_dm_search_cb.services )
1843 || (( bta_dm_search_cb.services ) && ( p_data->disc_result.result.disc_res.services ))) {
1844 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
1847 /* if searching did not initiate to create link */
1848 if (!bta_dm_search_cb.wait_disc ) {
1849 /* if service searching is done with EIR, don't search next device */
1850 if ( bta_dm_search_cb.p_btm_inq_info ) {
1851 bta_dm_discover_next_device();
1854 /* wait until link is disconnected or timeout */
1855 bta_dm_search_cb.sdp_results = TRUE;
1856 bta_dm_search_cb.search_timer.p_cback = (TIMER_CBACK *)&bta_dm_search_timer_cback;
1857 bta_sys_start_timer(&bta_dm_search_cb.search_timer, 0, 1000 * (L2CAP_LINK_INACTIVITY_TOUT + 1) );
1862 /*******************************************************************************
1864 ** Function bta_dm_search_timer_cback
1866 ** Description Called when ACL disconnect time is over
1871 *******************************************************************************/
1872 static void bta_dm_search_timer_cback (TIMER_LIST_ENT *p_tle)
1876 APPL_TRACE_EVENT("%s", __func__);
1877 bta_dm_search_cb.wait_disc = FALSE;
1879 /* proceed with next device */
1880 bta_dm_discover_next_device();
1885 /*******************************************************************************
1887 ** Function bta_dm_free_sdp_db
1889 ** Description Frees SDP data base
1893 *******************************************************************************/
1894 #if (SDP_INCLUDED == TRUE)
1895 void bta_dm_free_sdp_db (tBTA_DM_MSG *p_data)
1898 if (bta_dm_search_cb.p_sdp_db) {
1899 osi_free(bta_dm_search_cb.p_sdp_db);
1900 bta_dm_search_cb.p_sdp_db = NULL;
1903 #endif ///SDP_INCLUDED == TRUE
1905 /*******************************************************************************
1907 ** Function bta_dm_queue_search
1909 ** Description Queues search command while search is being cancelled
1913 *******************************************************************************/
1914 void bta_dm_queue_search (tBTA_DM_MSG *p_data)
1916 if (bta_dm_search_cb.p_search_queue) {
1917 osi_free(bta_dm_search_cb.p_search_queue);
1920 bta_dm_search_cb.p_search_queue = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_SEARCH));
1921 memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_SEARCH));
1925 /*******************************************************************************
1927 ** Function bta_dm_queue_disc
1929 ** Description Queues discovery command while search is being cancelled
1933 *******************************************************************************/
1934 #if (SDP_INCLUDED == TRUE)
1935 void bta_dm_queue_disc (tBTA_DM_MSG *p_data)
1937 if (bta_dm_search_cb.p_search_queue) {
1938 osi_free(bta_dm_search_cb.p_search_queue);
1941 bta_dm_search_cb.p_search_queue = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_DISCOVER));
1942 memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_DISCOVER));
1944 #endif ///SDP_INCLUDED == TRUE
1946 /*******************************************************************************
1948 ** Function bta_dm_search_clear_queue
1950 ** Description Clears the queue if API search cancel is called
1954 *******************************************************************************/
1955 void bta_dm_search_clear_queue (tBTA_DM_MSG *p_data)
1958 if (bta_dm_search_cb.p_search_queue) {
1959 osi_free(bta_dm_search_cb.p_search_queue);
1960 bta_dm_search_cb.p_search_queue = NULL;
1964 /*******************************************************************************
1966 ** Function bta_dm_search_cancel_cmpl
1968 ** Description Search cancel is complete
1972 *******************************************************************************/
1973 void bta_dm_search_cancel_cmpl (tBTA_DM_MSG *p_data)
1976 if (bta_dm_search_cb.p_search_queue) {
1977 bta_sys_sendmsg(bta_dm_search_cb.p_search_queue);
1978 bta_dm_search_cb.p_search_queue = NULL;
1983 /*******************************************************************************
1985 ** Function bta_dm_search_cancel_transac_cmpl
1987 ** Description Current Service Discovery or remote name procedure is
1988 ** completed after search cancellation
1992 *******************************************************************************/
1993 #if (SDP_INCLUDED == TRUE)
1994 void bta_dm_search_cancel_transac_cmpl(tBTA_DM_MSG *p_data)
1997 if (bta_dm_search_cb.p_sdp_db) {
1998 osi_free(bta_dm_search_cb.p_sdp_db);
1999 bta_dm_search_cb.p_sdp_db = NULL;
2002 bta_dm_search_cancel_notify(NULL);
2004 #endif ///SDP_INCLUDED == TRUE
2007 /*******************************************************************************
2009 ** Function bta_dm_search_cancel_notify
2011 ** Description Notify application that search has been cancelled
2015 *******************************************************************************/
2016 void bta_dm_search_cancel_notify (tBTA_DM_MSG *p_data)
2019 if (bta_dm_search_cb.p_search_cback) {
2020 bta_dm_search_cb.p_search_cback(BTA_DM_SEARCH_CANCEL_CMPL_EVT, NULL);
2022 if (!bta_dm_search_cb.name_discover_done) {
2023 BTM_CancelRemoteDeviceName();
2025 #if (BLE_INCLUDED == TRUE) && (BTA_GATT_INCLUDED == TRUE) && (SDP_INCLUDED == TRUE) && (GATTC_INCLUDED) == TRUE
2026 if (bta_dm_search_cb.gatt_disc_active) {
2027 bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
2033 /*******************************************************************************
2035 ** Function bta_dm_find_services
2037 ** Description Starts discovery on a device
2041 *******************************************************************************/
2042 #if (SDP_INCLUDED == TRUE)
2043 static void bta_dm_find_services ( BD_ADDR bd_addr)
2048 memset (&uuid, 0, sizeof(tSDP_UUID));
2050 while (bta_dm_search_cb.service_index < BTA_MAX_SERVICE_ID) {
2051 tBTA_SERVICE_MASK this_service_mask = (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index));
2052 if ( bta_dm_search_cb.services_to_search & this_service_mask) {
2053 if ((bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(BTA_DM_SDP_DB_SIZE)) != NULL) {
2054 APPL_TRACE_DEBUG("bta_dm_search_cb.services = %04x***********", bta_dm_search_cb.services);
2055 /* try to search all services by search based on L2CAP UUID */
2056 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK ) {
2057 APPL_TRACE_DEBUG("%s services_to_search=%08x", __func__, bta_dm_search_cb.services_to_search);
2058 if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK) {
2059 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[0];
2060 bta_dm_search_cb.services_to_search &= ~BTA_RES_SERVICE_MASK;
2062 uuid.uu.uuid16 = UUID_PROTOCOL_L2CAP;
2063 bta_dm_search_cb.services_to_search = 0;
2066 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
2067 /* for LE only profile */
2068 if (this_service_mask == BTA_BLE_SERVICE_MASK) {
2069 if (bta_dm_search_cb.uuid_to_search > 0 && bta_dm_search_cb.p_srvc_uuid) {
2071 (const void *)(bta_dm_search_cb.p_srvc_uuid + \
2072 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search),
2075 bta_dm_search_cb.uuid_to_search -- ;
2077 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index];
2080 /* last one? clear the BLE service bit if all discovery has been done */
2081 if (bta_dm_search_cb.uuid_to_search == 0)
2082 bta_dm_search_cb.services_to_search &=
2083 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
2088 /* remove the service from services to be searched */
2089 bta_dm_search_cb.services_to_search &=
2090 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
2091 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index];
2095 if (uuid.len == 0) {
2096 uuid.len = LEN_UUID_16;
2099 if (this_service_mask == BTA_USER_SERVICE_MASK) {
2100 memcpy(&uuid, &bta_dm_search_cb.uuid, sizeof(tSDP_UUID));
2103 APPL_TRACE_DEBUG("%s search UUID = %04x", __func__, uuid.uu.uuid16);
2104 SDP_InitDiscoveryDb (bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1, &uuid, 0, NULL);
2106 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
2107 bta_dm_search_cb.p_sdp_db->raw_data = g_disc_raw_data_buf;
2109 bta_dm_search_cb.p_sdp_db->raw_size = MAX_DISC_RAW_DATA_BUF;
2111 if (!SDP_ServiceSearchAttributeRequest (bd_addr, bta_dm_search_cb.p_sdp_db, &bta_dm_sdp_callback)) {
2112 /* if discovery not successful with this device
2113 proceed to next one */
2114 osi_free(bta_dm_search_cb.p_sdp_db);
2115 bta_dm_search_cb.p_sdp_db = NULL;
2116 bta_dm_search_cb.service_index = BTA_MAX_SERVICE_ID;
2119 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
2120 if ((this_service_mask == BTA_BLE_SERVICE_MASK &&
2121 bta_dm_search_cb.uuid_to_search == 0) ||
2122 this_service_mask != BTA_BLE_SERVICE_MASK)
2124 bta_dm_search_cb.service_index++;
2128 APPL_TRACE_ERROR("#### Failed to allocate SDP DB buffer! ####");
2132 bta_dm_search_cb.service_index++;
2135 /* no more services to be discovered */
2136 if (bta_dm_search_cb.service_index >= BTA_MAX_SERVICE_ID) {
2137 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
2138 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
2139 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
2140 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2141 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
2142 bta_dm_get_remname(), (BD_NAME_LEN - 1));
2144 /* make sure the string is terminated */
2145 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
2147 bta_sys_sendmsg(p_msg);
2151 #endif ///SDP_INCLUDED == TRUE
2153 /*******************************************************************************
2155 ** Function bta_dm_discover_next_device
2157 ** Description Starts discovery on the next device in Inquiry data base
2161 *******************************************************************************/
2162 static void bta_dm_discover_next_device(void)
2167 APPL_TRACE_DEBUG("bta_dm_discover_next_device");
2169 /* searching next device on inquiry result */
2170 if ((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbNext(bta_dm_search_cb.p_btm_inq_info)) != NULL) {
2171 bta_dm_search_cb.name_discover_done = FALSE;
2172 bta_dm_search_cb.peer_name[0] = 0;
2173 #if (SDP_INCLUDED == TRUE)
2174 bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
2175 #endif ///SDP_INCLUDED == TRUE
2177 /* no devices, search complete */
2178 bta_dm_search_cb.services = 0;
2180 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
2181 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
2182 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
2183 bta_sys_sendmsg(p_msg);
2188 /*******************************************************************************
2190 ** Function bta_dm_discover_device
2192 ** Description Starts name and service discovery on the device
2196 *******************************************************************************/
2197 #if (SDP_INCLUDED == TRUE)
2198 static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
2201 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
2203 #if BLE_INCLUDED == TRUE
2204 if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN) {
2205 tBT_DEVICE_TYPE dev_type;
2206 tBLE_ADDR_TYPE addr_type;
2208 BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
2209 if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM) {
2210 transport = BT_TRANSPORT_LE;
2213 transport = bta_dm_search_cb.transport;
2217 /* Reset transport state for next discovery */
2218 bta_dm_search_cb.transport = BTA_TRANSPORT_UNKNOWN;
2220 APPL_TRACE_DEBUG("%s BDA:0x%02X%02X%02X%02X%02X%02X", __func__,
2221 remote_bd_addr[0], remote_bd_addr[1],
2222 remote_bd_addr[2], remote_bd_addr[3],
2223 remote_bd_addr[4], remote_bd_addr[5]);
2225 bdcpy(bta_dm_search_cb.peer_bdaddr, remote_bd_addr);
2227 APPL_TRACE_DEBUG("%s name_discover_done = %d p_btm_inq_info %p state = %d, transport=%d",
2229 bta_dm_search_cb.name_discover_done,
2230 bta_dm_search_cb.p_btm_inq_info,
2231 bta_dm_search_cb.state,
2234 if (bta_dm_search_cb.p_btm_inq_info) {
2235 APPL_TRACE_DEBUG("%s appl_knows_rem_name %d", __func__,
2236 bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name);
2239 if ((bta_dm_search_cb.p_btm_inq_info)
2240 && (bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE)
2241 && (bta_dm_search_cb.state == BTA_DM_SEARCH_ACTIVE)) {
2242 /* Do not perform RNR for LE devices at inquiry complete*/
2243 bta_dm_search_cb.name_discover_done = TRUE;
2246 /* if name discovery is not done and application needs remote name */
2247 if ((!bta_dm_search_cb.name_discover_done)
2248 && (( bta_dm_search_cb.p_btm_inq_info == NULL )
2249 || (bta_dm_search_cb.p_btm_inq_info && (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name)))) {
2250 if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport) == TRUE) {
2254 /* starting name discovery failed */
2255 bta_dm_search_cb.name_discover_done = TRUE;
2258 /* if application wants to discover service */
2259 if ( bta_dm_search_cb.services ) {
2260 /* initialize variables */
2261 bta_dm_search_cb.service_index = 0;
2262 bta_dm_search_cb.services_found = 0;
2263 bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
2264 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE
2265 bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid;
2267 if ((bta_dm_search_cb.p_btm_inq_info != NULL) &&
2268 bta_dm_search_cb.services != BTA_USER_SERVICE_MASK
2269 && (bta_dm_search_cb.sdp_search == FALSE)) {
2270 /* check if EIR provides the information of supported services */
2271 bta_dm_eir_search_services( &bta_dm_search_cb.p_btm_inq_info->results,
2272 &bta_dm_search_cb.services_to_search,
2273 &bta_dm_search_cb.services_found );
2276 /* if seaching with EIR is not completed */
2277 if (bta_dm_search_cb.services_to_search) {
2278 /* check whether connection already exists to the device
2279 if connection exists, we don't have to wait for ACL
2280 link to go down to start search on next device */
2281 if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR)) {
2282 bta_dm_search_cb.wait_disc = FALSE;
2284 bta_dm_search_cb.wait_disc = TRUE;
2287 #if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE)
2288 if ( bta_dm_search_cb.p_btm_inq_info ) {
2289 APPL_TRACE_DEBUG("%s p_btm_inq_info %p results.device_type 0x%x services_to_search 0x%x",
2291 bta_dm_search_cb.p_btm_inq_info,
2292 bta_dm_search_cb.p_btm_inq_info->results.device_type,
2293 bta_dm_search_cb.services_to_search);
2296 if (transport == BT_TRANSPORT_LE) {
2297 if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK) {
2298 //set the raw data buffer here
2299 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
2300 bta_dm_search_cb.p_ble_rawdata = g_disc_raw_data_buf;
2302 bta_dm_search_cb.ble_raw_size = MAX_DISC_RAW_DATA_BUF;
2303 bta_dm_search_cb.ble_raw_used = 0;
2305 /* start GATT for service discovery */
2306 btm_dm_start_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
2312 bta_dm_search_cb.sdp_results = FALSE;
2313 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
2319 /* name discovery and service discovery are done for this device */
2320 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
2321 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
2322 /* initialize the data structure - includes p_raw_data and raw_data_size */
2323 memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES));
2324 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
2325 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
2326 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2327 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
2328 (char *)bta_dm_search_cb.peer_name, (BD_NAME_LEN - 1));
2330 /* make sure the string is terminated */
2331 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
2333 bta_sys_sendmsg(p_msg);
2337 /*******************************************************************************
2339 ** Function bta_dm_sdp_callback
2341 ** Description Callback from sdp with discovery status
2345 *******************************************************************************/
2346 static void bta_dm_sdp_callback (UINT16 sdp_status)
2349 tBTA_DM_SDP_RESULT *p_msg;
2351 if ((p_msg = (tBTA_DM_SDP_RESULT *) osi_malloc(sizeof(tBTA_DM_SDP_RESULT))) != NULL) {
2352 p_msg->hdr.event = BTA_DM_SDP_RESULT_EVT;
2353 p_msg->sdp_result = sdp_status;
2354 bta_sys_sendmsg(p_msg);
2358 #endif ///SDP_INCLUDED == TRUE
2359 /*******************************************************************************
2361 ** Function bta_dm_inq_results_cb
2363 ** Description Inquiry results callback from BTM
2367 *******************************************************************************/
2368 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
2371 tBTA_DM_SEARCH result;
2372 tBTM_INQ_INFO *p_inq_info;
2373 UINT16 service_class;
2375 bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
2376 memcpy(result.inq_res.dev_class, p_inq->dev_class, DEV_CLASS_LEN);
2377 BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class);
2378 result.inq_res.is_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? TRUE : FALSE;
2379 result.inq_res.rssi = p_inq->rssi;
2381 #if (BLE_INCLUDED == TRUE)
2382 result.inq_res.ble_addr_type = p_inq->ble_addr_type;
2383 result.inq_res.inq_result_type = p_inq->inq_result_type;
2384 result.inq_res.device_type = p_inq->device_type;
2385 result.inq_res.flag = p_inq->flag;
2388 /* application will parse EIR to find out remote device name */
2389 result.inq_res.p_eir = p_eir;
2391 if ((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL) {
2392 /* initialize remt_name_not_required to FALSE so that we get the name by default */
2393 result.inq_res.remt_name_not_required = FALSE;
2397 if (bta_dm_search_cb.p_search_cback) {
2398 bta_dm_search_cb.p_search_cback(BTA_DM_INQ_RES_EVT, &result);
2402 /* application indicates if it knows the remote name, inside the callback
2403 copy that to the inquiry data base*/
2404 if (result.inq_res.remt_name_not_required) {
2405 p_inq_info->appl_knows_rem_name = TRUE;
2414 /*******************************************************************************
2416 ** Function bta_dm_inq_cmpl_cb
2418 ** Description Inquiry complete callback from BTM
2422 *******************************************************************************/
2423 static void bta_dm_inq_cmpl_cb (void *p_result)
2427 if (bta_dm_search_cb.cancel_pending == FALSE) {
2428 APPL_TRACE_DEBUG("%s", __FUNCTION__);
2429 p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
2430 if (p_msg != NULL) {
2431 p_msg->inq_cmpl.hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
2432 p_msg->inq_cmpl.num = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
2433 bta_sys_sendmsg(p_msg);
2436 bta_dm_search_cb.cancel_pending = FALSE;
2437 bta_dm_search_cancel_notify(NULL);
2439 p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
2440 if (p_msg != NULL) {
2441 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
2442 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
2443 bta_sys_sendmsg(p_msg);
2448 /*******************************************************************************
2450 ** Function bta_dm_service_search_remname_cback
2452 ** Description Remote name call back from BTM during service discovery
2456 *******************************************************************************/
2457 static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, BD_NAME bd_name)
2459 tBTM_REMOTE_DEV_NAME rem_name;
2460 tBTM_STATUS btm_status;
2463 APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback name=<%s>", bd_name);
2465 /* if this is what we are looking for */
2466 if (!bdcmp( bta_dm_search_cb.peer_bdaddr, bd_addr)) {
2467 rem_name.length = strlen((char *)bd_name);
2468 if (rem_name.length > (BD_NAME_LEN - 1)) {
2469 rem_name.length = (BD_NAME_LEN - 1);
2470 rem_name.remote_bd_name[(BD_NAME_LEN - 1)] = 0;
2472 BCM_STRNCPY_S((char *)rem_name.remote_bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
2473 rem_name.status = BTM_SUCCESS;
2475 bta_dm_remname_cback(&rem_name);
2477 /* get name of device */
2478 btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
2479 (tBTM_CMPL_CB *) bta_dm_remname_cback,
2480 BT_TRANSPORT_BR_EDR);
2481 if ( btm_status == BTM_BUSY ) {
2482 /* wait for next chance(notification of remote name discovery done) */
2483 APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName is busy");
2484 } else if ( btm_status != BTM_CMD_STARTED ) {
2485 /* if failed to start getting remote name then continue */
2486 APPL_TRACE_WARNING("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
2488 rem_name.length = 0;
2489 rem_name.remote_bd_name[0] = 0;
2490 rem_name.status = btm_status;
2491 bta_dm_remname_cback(&rem_name);
2497 /*******************************************************************************
2499 ** Function bta_dm_remname_cback
2501 ** Description Remote name complete call back from BTM
2505 *******************************************************************************/
2506 static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
2508 tBTA_DM_REM_NAME *p_msg;
2510 APPL_TRACE_DEBUG("bta_dm_remname_cback len = %d name=<%s>", p_remote_name->length,
2511 p_remote_name->remote_bd_name);
2513 /* remote name discovery is done but it could be failed */
2514 bta_dm_search_cb.name_discover_done = TRUE;
2515 BCM_STRNCPY_S((char *)bta_dm_search_cb.peer_name, sizeof(BD_NAME), (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
2516 bta_dm_search_cb.peer_name[BD_NAME_LEN] = 0;
2518 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
2520 #if BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE
2521 if (bta_dm_search_cb.transport == BT_TRANSPORT_LE ) {
2522 GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
2526 if ((p_msg = (tBTA_DM_REM_NAME *) osi_malloc(sizeof(tBTA_DM_REM_NAME))) != NULL) {
2527 bdcpy (p_msg->result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2528 BCM_STRNCPY_S((char *)p_msg->result.disc_res.bd_name, sizeof(BD_NAME), (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
2530 /* make sure the string is null terminated */
2531 p_msg->result.disc_res.bd_name[BD_NAME_LEN] = 0;
2533 p_msg->hdr.event = BTA_DM_REMT_NAME_EVT;
2534 bta_sys_sendmsg(p_msg);
2539 /*******************************************************************************
2541 ** Function bta_dm_authorize_cback
2543 ** Description cback requesting authorization
2547 *******************************************************************************/
2548 #if (SMP_INCLUDED == TRUE)
2549 static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
2550 UINT8 *service_name, UINT8 service_id, BOOLEAN is_originator)
2552 tBTA_DM_SEC sec_event;
2554 UNUSED(service_name);
2555 UNUSED(is_originator);
2557 bdcpy(sec_event.authorize.bd_addr, bd_addr);
2558 memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN);
2560 BCM_STRNCPY_S((char *)sec_event.authorize.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
2562 /* make sure the string is null terminated */
2563 sec_event.authorize.bd_name[BD_NAME_LEN - 1] = 0;
2565 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
2566 sec_event.authorize.service = service_id;
2569 while (index < BTA_MAX_SERVICE_ID) {
2570 /* get the BTA service id corresponding to BTM id */
2571 if (bta_service_id_to_btm_srv_id_lkup_tbl[index] == service_id) {
2572 sec_event.authorize.service = index;
2579 /* if supported service callback otherwise not authorized */
2580 if (bta_dm_cb.p_sec_cback && (index < BTA_MAX_SERVICE_ID
2581 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
2582 /* pass through JV service ID */
2583 || (service_id >= BTA_FIRST_JV_SERVICE_ID && service_id <= BTA_LAST_JV_SERVICE_ID)
2586 bta_dm_cb.p_sec_cback(BTA_DM_AUTHORIZE_EVT, &sec_event);
2587 return BTM_CMD_STARTED;
2589 return BTM_NOT_AUTHORIZED;
2596 /*******************************************************************************
2598 ** Function bta_dm_pinname_cback
2600 ** Description Callback requesting pin_key
2604 *******************************************************************************/
2605 static void bta_dm_pinname_cback (void *p_data)
2607 tBTM_REMOTE_DEV_NAME *p_result = (tBTM_REMOTE_DEV_NAME *)p_data;
2608 tBTA_DM_SEC sec_event;
2609 UINT32 bytes_to_copy;
2610 tBTA_DM_SEC_EVT event = bta_dm_cb.pin_evt;
2612 if (BTA_DM_SP_CFM_REQ_EVT == event) {
2613 /* Retrieved saved device class and bd_addr */
2614 bdcpy(sec_event.cfm_req.bd_addr, bta_dm_cb.pin_bd_addr);
2615 BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_cb.pin_dev_class);
2617 if (p_result && p_result->status == BTM_SUCCESS) {
2618 bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1))
2619 ? p_result->length : (BD_NAME_LEN - 1);
2620 memcpy(sec_event.cfm_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
2621 sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2622 } else { /* No name found */
2623 sec_event.cfm_req.bd_name[0] = 0;
2626 sec_event.key_notif.passkey = bta_dm_cb.num_val; /* get PIN code numeric number */
2628 /* 1 additional event data fields for this event */
2629 sec_event.cfm_req.just_works = bta_dm_cb.just_works;
2631 /* Retrieved saved device class and bd_addr */
2632 bdcpy(sec_event.pin_req.bd_addr, bta_dm_cb.pin_bd_addr);
2633 BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_cb.pin_dev_class);
2635 if (p_result && p_result->status == BTM_SUCCESS) {
2636 bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1))
2637 ? p_result->length : (BD_NAME_LEN - 1);
2638 memcpy(sec_event.pin_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
2639 sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2640 } else { /* No name found */
2641 sec_event.pin_req.bd_name[0] = 0;
2644 event = bta_dm_cb.pin_evt;
2645 sec_event.key_notif.passkey = bta_dm_cb.num_val; /* get PIN code numeric number */
2648 if ( bta_dm_cb.p_sec_cback ) {
2649 bta_dm_cb.p_sec_cback(event, &sec_event);
2653 /*******************************************************************************
2655 ** Function bta_dm_pin_cback
2657 ** Description Callback requesting pin_key
2661 *******************************************************************************/
2662 static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
2663 BOOLEAN min_16_digit)
2665 tBTA_DM_SEC sec_event;
2667 if (!bta_dm_cb.p_sec_cback) {
2668 return BTM_NOT_AUTHORIZED;
2671 /* If the device name is not known, save bdaddr and devclass and initiate a name request */
2672 if (bd_name[0] == 0) {
2673 bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
2674 bdcpy(bta_dm_cb.pin_bd_addr, bd_addr);
2675 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
2676 if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2677 return BTM_CMD_STARTED;
2680 APPL_TRACE_WARNING(" bta_dm_pin_cback() -> Failed to start Remote Name Request ");
2683 bdcpy(sec_event.pin_req.bd_addr, bd_addr);
2684 BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
2685 BCM_STRNCPY_S((char *)sec_event.pin_req.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
2686 sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2687 sec_event.pin_req.min_16_digit = min_16_digit;
2689 bta_dm_cb.p_sec_cback(BTA_DM_PIN_REQ_EVT, &sec_event);
2690 return BTM_CMD_STARTED;
2693 /*******************************************************************************
2695 ** Function bta_dm_new_link_key_cback
2697 ** Description Callback from BTM to notify new link key
2701 *******************************************************************************/
2702 static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
2703 BD_NAME bd_name, LINK_KEY key, UINT8 key_type)
2705 tBTA_DM_SEC sec_event;
2706 tBTA_DM_AUTH_CMPL *p_auth_cmpl;
2710 memset (&sec_event, 0, sizeof(tBTA_DM_SEC));
2712 /* Not AMP Key type */
2713 if (key_type != HCI_LKEY_TYPE_AMP_WIFI && key_type != HCI_LKEY_TYPE_AMP_UWB) {
2714 event = BTA_DM_AUTH_CMPL_EVT;
2715 p_auth_cmpl = &sec_event.auth_cmpl;
2717 bdcpy(p_auth_cmpl->bd_addr, bd_addr);
2719 memcpy(p_auth_cmpl->bd_name, bd_name, (BD_NAME_LEN - 1));
2720 p_auth_cmpl->bd_name[BD_NAME_LEN - 1] = 0;
2722 p_auth_cmpl->key_present = TRUE;
2723 p_auth_cmpl->key_type = key_type;
2724 p_auth_cmpl->success = TRUE;
2726 memcpy(p_auth_cmpl->key, key, LINK_KEY_LEN);
2727 sec_event.auth_cmpl.fail_reason = HCI_SUCCESS;
2729 #if BLE_INCLUDED == TRUE
2730 // Report the BR link key based on the BR/EDR address and type
2731 BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
2733 if (bta_dm_cb.p_sec_cback) {
2734 bta_dm_cb.p_sec_cback(event, &sec_event);
2737 APPL_TRACE_WARNING("%s() Received AMP Key", __func__);
2740 return BTM_CMD_STARTED;
2744 /*******************************************************************************
2746 ** Function bta_dm_authentication_complete_cback
2748 ** Description Authentication complete callback from BTM
2752 *******************************************************************************/
2753 static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, int result)
2755 tBTA_DM_SEC sec_event;
2758 if (result != BTM_SUCCESS) {
2759 memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
2760 bdcpy(sec_event.auth_cmpl.bd_addr, bd_addr);
2762 memcpy(sec_event.auth_cmpl.bd_name, bd_name, (BD_NAME_LEN - 1));
2763 sec_event.auth_cmpl.bd_name[BD_NAME_LEN - 1] = 0;
2765 #if BLE_INCLUDED == TRUE
2766 // Report the BR link key based on the BR/EDR address and type
2767 BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
2769 sec_event.auth_cmpl.fail_reason = (UINT8)result;
2771 if (bta_dm_cb.p_sec_cback) {
2772 bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
2775 bta_dm_remove_sec_dev_entry(bd_addr);
2781 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2782 /*******************************************************************************
2784 ** Function bta_dm_sp_cback
2786 ** Description simple pairing callback from BTM
2790 *******************************************************************************/
2791 static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
2793 tBTM_STATUS status = BTM_CMD_STARTED;
2794 tBTA_DM_SEC sec_event;
2795 tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT;
2797 APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event);
2798 if (!bta_dm_cb.p_sec_cback) {
2799 return BTM_NOT_AUTHORIZED;
2804 case BTM_SP_IO_REQ_EVT:
2805 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2806 /* translate auth_req */
2807 bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap,
2808 &p_data->io_req.oob_data, &p_data->io_req.auth_req, p_data->io_req.is_orig);
2810 #if BTM_OOB_INCLUDED == FALSE
2811 status = BTM_SUCCESS;
2814 APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
2816 case BTM_SP_IO_RSP_EVT:
2817 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2818 bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap,
2819 p_data->io_rsp.oob_data, p_data->io_rsp.auth_req );
2823 case BTM_SP_CFM_REQ_EVT:
2824 pin_evt = BTA_DM_SP_CFM_REQ_EVT;
2825 bta_dm_cb.just_works = sec_event.cfm_req.just_works = p_data->cfm_req.just_works;
2826 sec_event.cfm_req.loc_auth_req = p_data->cfm_req.loc_auth_req;
2827 sec_event.cfm_req.rmt_auth_req = p_data->cfm_req.rmt_auth_req;
2828 sec_event.cfm_req.loc_io_caps = p_data->cfm_req.loc_io_caps;
2829 sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps;
2831 /* continue to next case */
2832 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2833 /* Passkey entry mode, mobile device with output capability is very
2834 unlikely to receive key request, so skip this event */
2835 /*case BTM_SP_KEY_REQ_EVT: */
2836 case BTM_SP_KEY_NOTIF_EVT:
2838 if (BTM_SP_CFM_REQ_EVT == event) {
2839 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
2840 call remote name request using values from cfm_req */
2841 if (p_data->cfm_req.bd_name[0] == 0) {
2842 bta_dm_cb.pin_evt = pin_evt;
2843 bdcpy(bta_dm_cb.pin_bd_addr, p_data->cfm_req.bd_addr);
2844 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class);
2845 if ((BTM_ReadRemoteDeviceName(p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
2846 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2847 return BTM_CMD_STARTED;
2849 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
2851 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
2852 copy these values into key_notif from cfm_req */
2853 bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
2854 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class);
2855 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
2856 (char *)p_data->cfm_req.bd_name, (BD_NAME_LEN - 1));
2857 sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
2861 bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
2862 if (BTM_SP_KEY_NOTIF_EVT == event) {
2863 /* If the device name is not known, save bdaddr and devclass
2864 and initiate a name request with values from key_notif */
2865 if (p_data->key_notif.bd_name[0] == 0) {
2866 bta_dm_cb.pin_evt = pin_evt;
2867 bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
2868 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
2869 if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback,
2870 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2871 return BTM_CMD_STARTED;
2873 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
2875 bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
2876 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
2877 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
2878 (char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
2879 sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
2883 bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
2887 #if BTM_OOB_INCLUDED == TRUE
2888 case BTM_SP_LOC_OOB_EVT:
2889 bta_dm_co_loc_oob((BOOLEAN)(p_data->loc_oob.status == BTM_SUCCESS),
2890 p_data->loc_oob.c, p_data->loc_oob.r);
2893 case BTM_SP_RMT_OOB_EVT:
2894 /* If the device name is not known, save bdaddr and devclass and initiate a name request */
2895 if (p_data->rmt_oob.bd_name[0] == 0) {
2896 bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
2897 bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
2898 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class);
2899 if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback,
2900 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2901 return BTM_CMD_STARTED;
2903 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
2906 bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
2907 BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
2908 BCM_STRNCPY_S((char *)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char *)p_data->rmt_oob.bd_name, (BD_NAME_LEN - 1));
2909 sec_event.rmt_oob.bd_name[BD_NAME_LEN - 1] = 0;
2911 bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
2913 bta_dm_co_rmt_oob(p_data->rmt_oob.bd_addr);
2916 case BTM_SP_COMPLT_EVT:
2917 /* do not report this event - handled by link_key_callback or auth_complete_callback */
2920 case BTM_SP_KEYPRESS_EVT:
2921 memcpy(&sec_event.key_press, &p_data->key_press, sizeof(tBTM_SP_KEYPRESS));
2922 bta_dm_cb.p_sec_cback(BTA_DM_SP_KEYPRESS_EVT, &sec_event);
2925 case BTM_SP_UPGRADE_EVT:
2926 bta_dm_co_lk_upgrade(p_data->upgrade.bd_addr, &p_data->upgrade.upgrade );
2930 status = BTM_NOT_AUTHORIZED;
2933 APPL_TRACE_EVENT("dm status: %d", status);
2936 #endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */
2938 #endif ///SMP_INCLUDED == TRUE
2941 /*******************************************************************************
2943 ** Function bta_dm_local_name_cback
2945 ** Description Callback from btm after local name is read
2950 *******************************************************************************/
2951 static void bta_dm_local_name_cback(UINT8 *p_name)
2953 tBTA_DM_SEC sec_event;
2956 sec_event.enable.status = BTA_SUCCESS;
2958 if (bta_dm_cb.p_sec_cback) {
2959 bta_dm_cb.p_sec_cback(BTA_DM_ENABLE_EVT, &sec_event);
2964 /*******************************************************************************
2966 ** Function bta_dm_bl_change_cback
2968 ** Description Callback from btm when acl connection goes up or down
2973 *******************************************************************************/
2974 static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
2976 tBTA_DM_ACL_CHANGE *p_msg;
2978 if ((p_msg = (tBTA_DM_ACL_CHANGE *) osi_malloc(sizeof(tBTA_DM_ACL_CHANGE))) != NULL) {
2979 p_msg->event = p_data->event;
2980 p_msg->is_new = FALSE;
2982 switch (p_msg->event) {
2983 case BTM_BL_CONN_EVT:
2984 p_msg->is_new = TRUE;
2985 bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
2986 #if BLE_INCLUDED == TRUE
2987 p_msg->transport = p_data->conn.transport;
2988 p_msg->handle = p_data->conn.handle;
2991 case BTM_BL_DISCN_EVT:
2992 bdcpy(p_msg->bd_addr, p_data->discn.p_bda);
2993 #if BLE_INCLUDED == TRUE
2994 p_msg->transport = p_data->discn.transport;
2995 p_msg->handle = p_data->discn.handle;
2998 case BTM_BL_UPDATE_EVT:
2999 p_msg->busy_level = p_data->update.busy_level;
3000 p_msg->busy_level_flags = p_data->update.busy_level_flags;
3002 case BTM_BL_ROLE_CHG_EVT:
3003 p_msg->new_role = p_data->role_chg.new_role;
3004 p_msg->hci_status = p_data->role_chg.hci_status;
3005 bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda);
3007 case BTM_BL_COLLISION_EVT:
3008 bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
3012 p_msg->hdr.event = BTA_DM_ACL_CHANGE_EVT;
3013 bta_sys_sendmsg(p_msg);
3019 /*******************************************************************************
3021 ** Function bta_dm_rs_cback
3023 ** Description Receives the role switch complete event
3027 *******************************************************************************/
3028 static void bta_dm_rs_cback (tBTM_ROLE_SWITCH_CMPL *p1)
3031 APPL_TRACE_WARNING("bta_dm_rs_cback:%d", bta_dm_cb.rs_event);
3032 if (bta_dm_cb.rs_event == BTA_DM_API_SEARCH_EVT) {
3033 bta_dm_cb.search_msg.rs_res = BTA_DM_RS_OK; /* do not care about the result for now */
3034 bta_dm_cb.rs_event = 0;
3035 bta_dm_search_start((tBTA_DM_MSG *)&bta_dm_cb.search_msg);
3039 /*******************************************************************************
3041 ** Function bta_dm_check_av
3043 ** Description This function checks if AV is active
3044 ** if yes, make sure the AV link is master
3046 ** Returns BOOLEAN - TRUE, if switch is in progress
3048 *******************************************************************************/
3049 static BOOLEAN bta_dm_check_av(UINT16 event)
3051 BOOLEAN avoid_roleswitch = FALSE;
3052 BOOLEAN switching = FALSE;
3054 tBTA_DM_PEER_DEVICE *p_dev;
3056 #if defined(BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY) && (BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY == TRUE)
3058 /* avoid role switch upon inquiry if a2dp is actively streaming as it
3059 introduces an audioglitch due to FW scheduling delays (unavoidable) */
3060 if (event == BTA_DM_API_SEARCH_EVT) {
3061 avoid_roleswitch = TRUE;
3065 APPL_TRACE_WARNING("bta_dm_check_av:%d", bta_dm_cb.cur_av_count);
3066 if (bta_dm_cb.cur_av_count) {
3067 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3068 p_dev = &bta_dm_cb.device_list.peer_device[i];
3069 APPL_TRACE_WARNING("[%d]: state:%d, info:x%x, avoid_rs %d",
3070 i, p_dev->conn_state, p_dev->info, avoid_roleswitch);
3071 if ((p_dev->conn_state == BTA_DM_CONNECTED) && (p_dev->info & BTA_DM_DI_AV_ACTIVE) &&
3072 (avoid_roleswitch == FALSE)) {
3073 /* make master and take away the role switch policy */
3074 if (BTM_CMD_STARTED == BTM_SwitchRole (p_dev->peer_bdaddr, HCI_ROLE_MASTER, (tBTM_CMPL_CB *)bta_dm_rs_cback)) {
3075 /* the role switch command is actually sent */
3076 bta_dm_cb.rs_event = event;
3079 /* else either already master or can not switch for some reasons */
3080 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr);
3088 /*******************************************************************************
3090 ** Function bta_dm_acl_change
3092 ** Description Process BTA_DM_ACL_CHANGE_EVT
3097 *******************************************************************************/
3098 void bta_dm_acl_change(tBTA_DM_MSG *p_data)
3104 BOOLEAN is_new = p_data->acl_change.is_new;
3105 BD_ADDR_PTR p_bda = p_data->acl_change.bd_addr;
3106 BOOLEAN need_policy_change = FALSE;
3107 BOOLEAN issue_unpair_cb = FALSE;
3109 tBTA_DM_PEER_DEVICE *p_dev;
3110 memset(&conn, 0, sizeof(tBTA_DM_SEC));
3112 switch (p_data->acl_change.event) {
3113 case BTM_BL_UPDATE_EVT: /* busy level update */
3114 if ( bta_dm_cb.p_sec_cback ) {
3115 conn.busy_level.level = p_data->acl_change.busy_level;
3116 conn.busy_level.level_flags = p_data->acl_change.busy_level_flags;
3117 bta_dm_cb.p_sec_cback(BTA_DM_BUSY_LEVEL_EVT, &conn);
3121 case BTM_BL_ROLE_CHG_EVT: /* role change event */
3122 p_dev = bta_dm_find_peer_device(p_bda);
3124 APPL_TRACE_DEBUG("bta_dm_acl_change role chg info:x%x new_role:%d dev count:%d",
3125 p_dev->info, p_data->acl_change.new_role, bta_dm_cb.device_list.count);
3126 if (p_dev->info & BTA_DM_DI_AV_ACTIVE) {
3127 /* there's AV activity on this link */
3128 if (p_data->acl_change.new_role == HCI_ROLE_SLAVE && bta_dm_cb.device_list.count > 1
3129 && p_data->acl_change.hci_status == HCI_SUCCESS) {
3130 /* more than one connections and the AV connection is role switched to slave
3131 * switch it back to master and remove the switch policy */
3132 BTM_SwitchRole(p_bda, BTM_ROLE_MASTER, NULL);
3133 need_policy_change = TRUE;
3134 } else if (p_bta_dm_cfg->avoid_scatter && (p_data->acl_change.new_role == HCI_ROLE_MASTER)) {
3135 /* if the link updated to be master include AV activities, remove the switch policy */
3136 need_policy_change = TRUE;
3139 if (need_policy_change) {
3140 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr);
3143 /* there's AV no activity on this link and role switch happened
3144 * check if AV is active
3145 * if so, make sure the AV link is master */
3148 bta_sys_notify_role_chg(p_data->acl_change.bd_addr, p_data->acl_change.new_role, p_data->acl_change.hci_status);
3149 bdcpy(conn.role_chg.bd_addr, p_bda);
3150 conn.role_chg.new_role = (UINT8) p_data->acl_change.new_role;
3151 if ( bta_dm_cb.p_sec_cback ) {
3152 bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, (tBTA_DM_SEC *)&conn);
3158 /* Collision report from Stack: Notify profiles */
3159 if (p_data->acl_change.event == BTM_BL_COLLISION_EVT) {
3160 bta_sys_notify_collision (p_bda);
3165 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3166 if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
3167 #if BLE_INCLUDED == TRUE
3168 && bta_dm_cb.device_list.peer_device[i].conn_handle == p_data->acl_change.handle
3176 if (i == bta_dm_cb.device_list.count) {
3177 if (bta_dm_cb.device_list.count < BTA_DM_NUM_PEER_DEVICE) {
3178 bdcpy(bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].peer_bdaddr, p_bda);
3179 bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].link_policy = bta_dm_cb.cur_policy;
3180 bta_dm_cb.device_list.count++;
3181 #if BLE_INCLUDED == TRUE
3182 bta_dm_cb.device_list.peer_device[i].conn_handle = p_data->acl_change.handle;
3183 if (p_data->acl_change.transport == BT_TRANSPORT_LE) {
3184 bta_dm_cb.device_list.le_count++;
3188 APPL_TRACE_ERROR("%s max active connection reached, no resources", __func__);
3193 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED;
3194 bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE;
3195 bdcpy(conn.link_up.bd_addr, p_bda);
3196 bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE;
3197 #if BLE_INCLUDED == TRUE
3198 conn.link_up.link_type = p_data->acl_change.transport;
3199 bta_dm_cb.device_list.peer_device[i].transport = p_data->acl_change.transport;
3202 if (((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
3203 ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p))) {
3204 /* both local and remote devices support SSR */
3205 bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR;
3207 APPL_TRACE_DEBUG("%s info: 0x%x", __func__, bta_dm_cb.device_list.peer_device[i].info);
3209 if (bta_dm_cb.p_sec_cback) {
3210 bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, (tBTA_DM_SEC *)&conn);
3213 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3214 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
3215 #if BLE_INCLUDED == TRUE
3216 || bta_dm_cb.device_list.peer_device[i].transport != p_data->acl_change.transport
3222 if ( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING ) {
3223 if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr)) {
3224 issue_unpair_cb = TRUE;
3227 APPL_TRACE_DEBUG("%s: Unpairing: issue unpair CB = %d ", __FUNCTION__, issue_unpair_cb);
3230 conn.link_down.is_removed = bta_dm_cb.device_list.peer_device[i].remove_dev_pending;
3232 for (; i < bta_dm_cb.device_list.count ; i++) {
3233 memcpy(&bta_dm_cb.device_list.peer_device[i], &bta_dm_cb.device_list.peer_device[i + 1], sizeof(bta_dm_cb.device_list.peer_device[i]));
3237 if (bta_dm_cb.device_list.count) {
3238 bta_dm_cb.device_list.count--;
3240 #if BLE_INCLUDED == TRUE
3241 if ((p_data->acl_change.transport == BT_TRANSPORT_LE) &&
3242 (bta_dm_cb.device_list.le_count)) {
3243 bta_dm_cb.device_list.le_count--;
3245 conn.link_down.link_type = p_data->acl_change.transport;
3248 if (bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda)) {
3249 bta_dm_search_cb.wait_disc = FALSE;
3251 if (bta_dm_search_cb.sdp_results) {
3252 APPL_TRACE_EVENT(" timer stopped ");
3253 bta_sys_stop_timer(&bta_dm_search_cb.search_timer);
3254 bta_dm_discover_next_device();
3259 if (bta_dm_cb.disabling) {
3260 if (!BTM_GetNumAclLinks()) {
3261 bta_sys_stop_timer(&bta_dm_cb.disable_timer);
3262 bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK *)&bta_dm_disable_conn_down_timer_cback;
3264 * Start a timer to make sure that the profiles
3265 * get the disconnect event.
3267 bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 1000);
3270 if (conn.link_down.is_removed) {
3271 BTM_SecDeleteDevice(p_bda);
3272 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
3273 /* need to remove all pending background connection */
3274 BTA_GATTC_CancelOpen(0, p_bda, FALSE);
3275 /* remove all cached GATT information */
3276 BTA_GATTC_Refresh(p_bda);
3280 bdcpy(conn.link_down.bd_addr, p_bda);
3281 conn.link_down.reason = (UINT8) btm_get_acl_disc_reason_code();
3282 if ( bta_dm_cb.p_sec_cback ) {
3283 bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn);
3284 if ( issue_unpair_cb ) {
3285 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn);
3290 bta_dm_adjust_roles(TRUE);
3293 /*******************************************************************************
3295 ** Function bta_dm_disable_conn_down_timer_cback
3297 ** Description Sends disable event to application
3302 *******************************************************************************/
3303 static void bta_dm_disable_conn_down_timer_cback (TIMER_LIST_ENT *p_tle)
3306 tBTA_SYS_HW_MSG *sys_enable_event;
3307 #if (BTM_SSR_INCLUDED == TRUE)
3308 /* disable the power managment module */
3309 bta_dm_disable_pm();
3310 #endif ///BTM_SSR_INCLUDED == TRUE
3311 /* register our callback to SYS HW manager */
3312 bta_sys_hw_register( BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback );
3314 /* send a message to BTA SYS */
3315 if ((sys_enable_event = (tBTA_SYS_HW_MSG *) osi_malloc(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
3316 sys_enable_event->hdr.event = BTA_SYS_API_DISABLE_EVT;
3317 sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;
3318 bta_sys_sendmsg(sys_enable_event);
3321 bta_dm_cb.disabling = FALSE;
3325 /*******************************************************************************
3327 ** Function bta_dm_rm_cback
3329 ** Description Role management callback from sys
3334 *******************************************************************************/
3335 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
3338 tBTA_PREF_ROLES role;
3339 tBTA_DM_PEER_DEVICE *p_dev;
3341 p_dev = bta_dm_find_peer_device(peer_addr);
3342 if ( status == BTA_SYS_CONN_OPEN) {
3344 /* Do not set to connected if we are in the middle of unpairing. When AV stream is
3345 * started it fakes out a SYS_CONN_OPEN to potentially trigger a role switch command.
3346 * But this should not be done if we are in the middle of unpairing.
3348 if (p_dev->conn_state != BTA_DM_UNPAIRING) {
3349 p_dev->conn_state = BTA_DM_CONNECTED;
3352 for (j = 1; j <= p_bta_dm_rm_cfg[0].app_id; j++) {
3353 if (((p_bta_dm_rm_cfg[j].app_id == app_id) || (p_bta_dm_rm_cfg[j].app_id == BTA_ALL_APP_ID))
3354 && (p_bta_dm_rm_cfg[j].id == id)) {
3355 role = p_bta_dm_rm_cfg[j].cfg;
3357 if (role > p_dev->pref_role ) {
3358 p_dev->pref_role = role;
3366 if ((BTA_ID_AV == id) || (BTA_ID_AVK == id)) {
3367 if ( status == BTA_SYS_CONN_BUSY) {
3369 p_dev->info |= BTA_DM_DI_AV_ACTIVE;
3371 /* AV calls bta_sys_conn_open with the A2DP stream count as app_id */
3372 if (BTA_ID_AV == id) {
3373 #if (BTM_SSR_INCLUDED == TRUE)
3374 bta_dm_cb.cur_av_count = bta_dm_get_av_count();
3375 #endif ///BTM_SSR_INCLUDED == TRUE
3377 } else if ( status == BTA_SYS_CONN_IDLE) {
3379 p_dev->info &= ~BTA_DM_DI_AV_ACTIVE;
3382 /* get cur_av_count from connected services */
3383 if (BTA_ID_AV == id) {
3384 #if (BTM_SSR_INCLUDED == TRUE)
3385 bta_dm_cb.cur_av_count = bta_dm_get_av_count();
3386 #endif ///BTM_SSR_INCLUDED == TRUE
3389 APPL_TRACE_WARNING("bta_dm_rm_cback:%d, status:%d", bta_dm_cb.cur_av_count, status);
3392 /* Don't adjust roles for each busy/idle state transition to avoid
3393 excessive switch requests when individual profile busy/idle status
3395 if ((status != BTA_SYS_CONN_BUSY) && (status != BTA_SYS_CONN_IDLE)) {
3396 bta_dm_adjust_roles(FALSE);
3400 /*******************************************************************************
3402 ** Function bta_dm_delay_role_switch_cback
3404 ** Description Callback from btm to delay a role switch
3408 *******************************************************************************/
3409 static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle)
3412 APPL_TRACE_EVENT("bta_dm_delay_role_switch_cback: initiating Delayed RS");
3413 bta_dm_adjust_roles (FALSE);
3416 /*******************************************************************************
3418 ** Function bta_dm_remove_sec_dev_entry
3420 ** Description Removes device entry from Security device DB if ACL connection with
3421 ** remtoe device does not exist, else schedule for dev entry removal upon
3426 *******************************************************************************/
3427 #if (SMP_INCLUDED == TRUE)
3428 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
3431 if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
3432 BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR)) {
3433 APPL_TRACE_DEBUG("%s ACL is not down. Schedule for Dev Removal when ACL closes",
3435 BTM_SecClearSecurityFlags (remote_bd_addr);
3436 for (index = 0; index < bta_dm_cb.device_list.count; index ++) {
3437 if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, remote_bd_addr)) {
3441 if (index != bta_dm_cb.device_list.count) {
3442 bta_dm_cb.device_list.peer_device[index].remove_dev_pending = TRUE;
3444 APPL_TRACE_ERROR(" %s Device does not exist in DB", __FUNCTION__);
3447 BTM_SecDeleteDevice (remote_bd_addr);
3448 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
3449 /* need to remove all pending background connection */
3450 BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
3451 /* remove all cached GATT information */
3452 BTA_GATTC_Refresh(remote_bd_addr);
3456 #endif ///SMP_INCLUDED == TRUE
3459 /*******************************************************************************
3461 ** Function bta_dm_adjust_roles
3463 ** Description Adjust roles
3468 *******************************************************************************/
3469 static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
3473 BOOLEAN set_master_role = FALSE;
3474 #if BLE_INCLUDED == TRUE
3475 UINT8 br_count = bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count;
3477 UINT8 br_count = bta_dm_cb.device_list.count;
3481 /* the configuration is no scatternet
3482 * or AV connection exists and there are more than one ACL link */
3483 if ( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
3484 (bta_dm_cb.cur_av_count && br_count > 1) ) {
3486 L2CA_SetDesireRole (HCI_ROLE_MASTER);
3487 set_master_role = TRUE;
3491 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3492 if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED
3493 #if BLE_INCLUDED == TRUE
3494 && bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_BR_EDR
3497 if (!set_master_role && (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE)
3498 && (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET)) {
3499 L2CA_SetDesireRole (HCI_ROLE_MASTER);
3500 set_master_role = TRUE;
3503 if ((bta_dm_cb.device_list.peer_device[i].pref_role == BTA_MASTER_ROLE_ONLY)
3504 || (br_count > 1)) {
3506 /* Initiating immediate role switch with certain remote devices
3507 has caused issues due to role switch colliding with link encryption setup and
3508 causing encryption (and in turn the link) to fail . These device . Firmware
3509 versions are stored in a blacklist and role switch with these devices are
3510 delayed to avoid the collision with link encryption setup */
3512 if (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_SLAVE_ROLE_ONLY &&
3513 delay_role_switch == FALSE) {
3514 BTM_SwitchRole (bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
3515 HCI_ROLE_MASTER, NULL);
3517 bta_dm_cb.switch_delay_timer.p_cback =
3518 (TIMER_CBACK *)&bta_dm_delay_role_switch_cback;
3519 bta_sys_start_timer(&bta_dm_cb.switch_delay_timer, 0, 500);
3527 if (!set_master_role) {
3529 L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
3534 L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
3540 /*******************************************************************************
3542 ** Function bta_dm_get_remname
3544 ** Description Returns a pointer to the remote name stored in the DM control
3545 ** block if it exists, or from the BTM memory.
3547 ** Returns char * - Pointer to the remote device name
3548 *******************************************************************************/
3549 #if (SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE)
3550 static char *bta_dm_get_remname(void)
3552 char *p_name = (char *)bta_dm_search_cb.peer_name;
3555 /* If the name isn't already stored, try retrieving from BTM */
3556 if (*p_name == '\0')
3557 if ((p_temp = BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr)) != NULL) {
3563 #endif ///SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE
3565 /*******************************************************************************
3567 ** Function bta_dm_bond_cancel_complete_cback
3569 ** Description Authentication complete callback from BTM
3573 *******************************************************************************/
3574 #if (SMP_INCLUDED == TRUE)
3575 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result)
3578 tBTA_DM_SEC sec_event;
3580 if (result == BTM_SUCCESS) {
3581 sec_event.bond_cancel_cmpl.result = BTA_SUCCESS;
3583 sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
3586 if (bta_dm_cb.p_sec_cback) {
3587 bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
3590 #endif ///SMP_INCLUDED == TRUE
3592 /*******************************************************************************
3594 ** Function bta_dm_set_eir
3596 ** Description This function creates EIR tagged data and writes it to controller.
3600 *******************************************************************************/
3601 static void bta_dm_set_eir (char *local_name)
3606 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3609 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3610 UINT8 custom_uuid_idx;
3611 #endif // BTA_EIR_SERVER_NUM_CUSTOM_UUID
3612 #endif // BTA_EIR_CANNED_UUID_LIST
3613 #if (BTM_EIR_DEFAULT_FEC_REQUIRED == FALSE)
3614 UINT8 free_eir_length = HCI_EXT_INQ_RESPONSE_LEN;
3615 #else // BTM_EIR_DEFAULT_FEC_REQUIRED
3616 UINT8 free_eir_length = HCI_DM5_PACKET_SIZE;
3617 #endif // BTM_EIR_DEFAULT_FEC_REQUIRED
3620 UINT8 local_name_len;
3622 /* wait until complete to disable */
3623 if (bta_dm_cb.disable_timer.in_use) {
3627 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )
3628 /* wait until App is ready */
3629 if (bta_dm_cb.app_ready_timer.in_use) {
3633 /* if local name is not provided, get it from controller */
3634 if ( local_name == NULL ) {
3635 if ( BTM_ReadLocalDeviceName( &local_name ) != BTM_SUCCESS ) {
3636 APPL_TRACE_ERROR("Fail to read local device name for EIR");
3639 #endif // BTA_EIR_CANNED_UUID_LIST
3641 /* Allocate a buffer to hold HCI command */
3642 if ((p_buf = (BT_HDR *)osi_malloc(BTM_CMD_BUF_SIZE)) == NULL) {
3643 APPL_TRACE_ERROR("bta_dm_set_eir couldn't allocate buffer");
3646 p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET;
3648 memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN );
3650 APPL_TRACE_DEBUG("BTA is generating EIR");
3653 local_name_len = strlen( local_name );
3658 data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3659 /* if local name is longer than minimum length of shortened name */
3660 /* check whether it needs to be shortened or not */
3661 if ( local_name_len > p_bta_dm_eir_cfg->bta_dm_eir_min_name_len ) {
3662 /* get number of UUID 16-bit list */
3663 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3664 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / LEN_UUID_16;
3665 #else // BTA_EIR_CANNED_UUID_LIST
3666 max_num_uuid = (free_eir_length - 2) / LEN_UUID_16;
3667 data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p,
3668 max_num_uuid, &num_uuid );
3669 p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET; /* reset p */
3670 #endif // BTA_EIR_CANNED_UUID_LIST
3672 /* if UUID doesn't fit remaing space, shorten local name */
3673 if ( local_name_len > (free_eir_length - 4 - num_uuid * LEN_UUID_16)) {
3674 APPL_TRACE_WARNING("BTA EIR: local name is shortened");
3675 local_name_len = p_bta_dm_eir_cfg->bta_dm_eir_min_name_len;
3676 data_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE;
3678 data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3682 UINT8_TO_STREAM(p, local_name_len + 1);
3683 UINT8_TO_STREAM(p, data_type);
3685 if (local_name != NULL) {
3686 memcpy(p, local_name, local_name_len);
3687 p += local_name_len;
3689 free_eir_length -= local_name_len + 2;
3691 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3692 /* if UUID list is provided as static data in configuration */
3693 if (( p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len > 0 )
3694 && (p_bta_dm_eir_cfg->bta_dm_eir_uuid16)) {
3695 if ( free_eir_length > LEN_UUID_16 + 2) {
3696 free_eir_length -= 2;
3698 if ( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len) {
3699 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / LEN_UUID_16;
3700 data_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3701 } else { /* not enough room for all UUIDs */
3702 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3703 num_uuid = free_eir_length / LEN_UUID_16;
3704 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3706 UINT8_TO_STREAM(p, num_uuid * LEN_UUID_16 + 1);
3707 UINT8_TO_STREAM(p, data_type);
3708 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_uuid16, num_uuid * LEN_UUID_16 );
3709 p += num_uuid * LEN_UUID_16;
3710 free_eir_length -= num_uuid * LEN_UUID_16;
3713 #else /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3714 /* if UUID list is dynamic */
3715 if ( free_eir_length >= 2) {
3720 max_num_uuid = (free_eir_length - 2) / LEN_UUID_16;
3721 data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p, max_num_uuid, &num_uuid );
3723 if ( data_type == BTM_EIR_MORE_16BITS_UUID_TYPE ) {
3724 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3726 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3728 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) {
3729 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_16) {
3730 if ( num_uuid < max_num_uuid ) {
3731 UINT16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid16);
3734 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3735 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3741 #endif /* (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3743 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_16 + 1);
3744 UINT8_TO_STREAM(p_type, data_type);
3745 free_eir_length -= num_uuid * LEN_UUID_16 + 2;
3747 #endif /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3749 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3750 /* Adding 32-bit UUID list */
3751 if ( free_eir_length >= 2) {
3755 data_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE;
3757 max_num_uuid = (free_eir_length - 2) / LEN_UUID_32;
3759 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) {
3760 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_32) {
3761 if ( num_uuid < max_num_uuid ) {
3762 UINT32_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid32);
3765 data_type = BTM_EIR_MORE_32BITS_UUID_TYPE;
3766 APPL_TRACE_WARNING("BTA EIR: UUID 32-bit list is truncated");
3772 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_32 + 1);
3773 UINT8_TO_STREAM(p_type, data_type);
3774 free_eir_length -= num_uuid * LEN_UUID_32 + 2;
3777 /* Adding 128-bit UUID list */
3778 if ( free_eir_length >= 2) {
3782 data_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE;
3784 max_num_uuid = (free_eir_length - 2) / LEN_UUID_128;
3786 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) {
3787 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_128) {
3788 if ( num_uuid < max_num_uuid ) {
3789 ARRAY16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid128);
3792 data_type = BTM_EIR_MORE_128BITS_UUID_TYPE;
3793 APPL_TRACE_WARNING("BTA EIR: UUID 128-bit list is truncated");
3799 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_128 + 1);
3800 UINT8_TO_STREAM(p_type, data_type);
3801 free_eir_length -= num_uuid * LEN_UUID_128 + 2;
3803 #endif /* ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3805 /* if Flags are provided in configuration */
3806 if (( p_bta_dm_eir_cfg->bta_dm_eir_flag_len > 0 )
3807 && ( p_bta_dm_eir_cfg->bta_dm_eir_flags )
3808 && ( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2 )) {
3809 UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 1);
3810 UINT8_TO_STREAM(p, BTM_EIR_FLAGS_TYPE);
3811 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_flags,
3812 p_bta_dm_eir_cfg->bta_dm_eir_flag_len);
3813 p += p_bta_dm_eir_cfg->bta_dm_eir_flag_len;
3814 free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2;
3817 /* if Manufacturer Specific are provided in configuration */
3818 if (( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len > 0 )
3819 && ( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec )
3820 && ( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2 )) {
3823 UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 1);
3824 UINT8_TO_STREAM(p, BTM_EIR_MANUFACTURER_SPECIFIC_TYPE);
3825 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec,
3826 p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len);
3827 p += p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len;
3828 free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2;
3834 /* if Inquiry Tx Resp Power compiled */
3835 if ((p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power) &&
3836 (free_eir_length >= 3)) {
3837 UINT8_TO_STREAM(p, 2); /* Length field */
3838 UINT8_TO_STREAM(p, BTM_EIR_TX_POWER_LEVEL_TYPE);
3839 UINT8_TO_STREAM(p, *(p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power));
3840 free_eir_length -= 3;
3843 if ( free_eir_length ) {
3844 UINT8_TO_STREAM(p, 0); /* terminator of significant part */
3847 BTM_WriteEIR( p_buf );
3851 /*******************************************************************************
3853 ** Function bta_dm_eir_search_services
3855 ** Description This function searches services in received EIR
3859 *******************************************************************************/
3860 #if (SDP_INCLUDED == TRUE)
3861 static void bta_dm_eir_search_services( tBTM_INQ_RESULTS *p_result,
3862 tBTA_SERVICE_MASK *p_services_to_search,
3863 tBTA_SERVICE_MASK *p_services_found)
3865 tBTA_SERVICE_MASK service_index = 0;
3866 tBTM_EIR_SEARCH_RESULT result;
3868 APPL_TRACE_DEBUG("BTA searching services in EIR of BDA:0x%02X%02X%02X%02X%02X%02X",
3869 p_result->remote_bd_addr[0], p_result->remote_bd_addr[1],
3870 p_result->remote_bd_addr[2], p_result->remote_bd_addr[3],
3871 p_result->remote_bd_addr[4], p_result->remote_bd_addr[5]);
3873 APPL_TRACE_DEBUG(" with services_to_search=0x%08X", *p_services_to_search);
3875 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
3876 /* always do GATT based service discovery by SDP instead of from EIR */
3877 /* if GATT based service is also to be put in EIR, need to modify this */
3878 while (service_index < (BTA_MAX_SERVICE_ID - 1))
3880 while (service_index < BTA_MAX_SERVICE_ID)
3883 if ( *p_services_to_search
3884 & (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index))) {
3885 result = BTM_HasInquiryEirService( p_result,
3886 bta_service_id_to_uuid_lkup_tbl[service_index] );
3888 /* Searching for HSP v1.2 only device */
3889 if ((result != BTM_EIR_FOUND) &&
3890 (bta_service_id_to_uuid_lkup_tbl[service_index] == UUID_SERVCLASS_HEADSET)) {
3891 result = BTM_HasInquiryEirService (p_result, UUID_SERVCLASS_HEADSET_HS);
3894 if ( result == BTM_EIR_FOUND ) {
3895 /* If Plug and Play service record, need to check to see if Broadcom stack */
3896 /* However, EIR data doesn't have EXT_BRCM_VERSION so just skip it */
3897 if ( bta_service_id_to_uuid_lkup_tbl[service_index]
3898 != UUID_SERVCLASS_PNP_INFORMATION ) {
3900 *p_services_found |=
3901 (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index));
3902 /* remove the service from services to be searched */
3903 *p_services_to_search &=
3904 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
3906 } else if ( result == BTM_EIR_NOT_FOUND ) {
3907 /* remove the service from services to be searched */
3908 *p_services_to_search &=
3909 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
3916 APPL_TRACE_ERROR("BTA EIR search result, services_to_search=0x%08X, services_found=0x%08X",
3917 *p_services_to_search, *p_services_found);
3919 #endif ///SDP_INCLUDED == TRUE
3921 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3922 /*******************************************************************************
3924 ** Function bta_dm_eir_update_uuid
3926 ** Description This function adds or removes service UUID in EIR database.
3930 *******************************************************************************/
3931 void bta_dm_eir_update_uuid(UINT16 uuid16, BOOLEAN adding)
3933 /* if this UUID is not advertised in EIR */
3934 if ( !BTM_HasEirService( p_bta_dm_eir_cfg->uuid_mask, uuid16 )) {
3939 APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid16);
3941 BTM_AddEirService( bta_dm_cb.eir_uuid, uuid16 );
3943 APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid16);
3945 BTM_RemoveEirService( bta_dm_cb.eir_uuid, uuid16 );
3948 bta_dm_set_eir (NULL);
3950 APPL_TRACE_EVENT("bta_dm_eir_update_uuid UUID bit mask=0x%08X %08X",
3951 bta_dm_cb.eir_uuid[1], bta_dm_cb.eir_uuid[0] );
3955 /*******************************************************************************
3957 ** Function bta_dm_enable_test_mode
3959 ** Description enable test mode
3964 *******************************************************************************/
3965 void bta_dm_enable_test_mode(tBTA_DM_MSG *p_data)
3968 BTM_EnableTestMode();
3971 /*******************************************************************************
3973 ** Function bta_dm_disable_test_mode
3975 ** Description disable test mode
3980 *******************************************************************************/
3981 void bta_dm_disable_test_mode(tBTA_DM_MSG *p_data)
3984 BTM_DeviceReset(NULL);
3987 /*******************************************************************************
3989 ** Function bta_dm_execute_callback
3991 ** Description Just execute a generic call back in the context of the BTU/BTA tack
3996 *******************************************************************************/
3997 void bta_dm_execute_callback(tBTA_DM_MSG *p_data)
4000 if (p_data->exec_cback.p_exec_cback == NULL) {
4004 p_data->exec_cback.p_exec_cback(p_data->exec_cback.p_param);
4007 /*******************************************************************************
4009 ** Function bta_dm_encrypt_cback
4011 ** Description link encryption complete callback.
4015 *******************************************************************************/
4016 void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
4018 tBTA_STATUS bta_status = BTA_SUCCESS;
4019 tBTA_DM_ENCRYPT_CBACK *p_callback = NULL;
4023 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
4024 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bd_addr) == 0 &&
4025 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) {
4030 if (i < bta_dm_cb.device_list.count) {
4031 p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback;
4032 bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL;
4038 case BTM_WRONG_MODE:
4039 bta_status = BTA_WRONG_MODE;
4041 case BTM_NO_RESOURCES:
4042 bta_status = BTA_NO_RESOURCES;
4045 bta_status = BTA_BUSY;
4048 bta_status = BTA_FAILURE;
4052 APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=%p", bta_status, p_callback);
4055 (*p_callback)(bd_addr, transport, bta_status);
4059 /*******************************************************************************
4061 ** Function bta_dm_set_encryption
4063 ** Description This function to encrypt the link
4067 *******************************************************************************/
4068 #if (SMP_INCLUDED == TRUE)
4069 void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
4073 APPL_TRACE_DEBUG("bta_dm_set_encryption\n"); //todo
4074 if (!p_data->set_encryption.p_callback) {
4075 APPL_TRACE_ERROR("bta_dm_set_encryption callback is not provided\n");
4078 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
4079 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_data->set_encryption.bd_addr) == 0 &&
4080 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) {
4084 if (i < bta_dm_cb.device_list.count) {
4085 if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback) {
4086 APPL_TRACE_ERROR("earlier enc was not done for same device\n");
4087 (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr,
4088 p_data->set_encryption.transport,
4093 if (BTM_SetEncryption(p_data->set_encryption.bd_addr, p_data->set_encryption.transport,
4094 bta_dm_encrypt_cback, &p_data->set_encryption.sec_act)
4095 == BTM_CMD_STARTED) {
4096 bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_data->set_encryption.p_callback;
4099 APPL_TRACE_ERROR("%s, not find peer_bdaddr or peer_bdaddr connection state error", __func__);
4102 #endif ///SMP_INCLUDED == TRUE
4104 #if (BLE_INCLUDED == TRUE)
4105 /*******************************************************************************
4107 ** Function bta_dm_observe_results_cb
4109 ** Description Callback for BLE Observe result
4114 *******************************************************************************/
4115 static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
4117 tBTA_DM_SEARCH result;
4118 tBTM_INQ_INFO *p_inq_info;
4119 APPL_TRACE_DEBUG("bta_dm_observe_results_cb")
4121 bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
4122 result.inq_res.rssi = p_inq->rssi;
4123 result.inq_res.ble_addr_type = p_inq->ble_addr_type;
4124 result.inq_res.inq_result_type = p_inq->inq_result_type;
4125 result.inq_res.device_type = p_inq->device_type;
4126 result.inq_res.flag = p_inq->flag;
4127 result.inq_res.adv_data_len = p_inq->adv_data_len;
4128 result.inq_res.scan_rsp_len = p_inq->scan_rsp_len;
4130 /* application will parse EIR to find out remote device name */
4131 result.inq_res.p_eir = p_eir;
4133 if ((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL) {
4134 /* initialize remt_name_not_required to FALSE so that we get the name by default */
4135 result.inq_res.remt_name_not_required = FALSE;
4138 if (bta_dm_search_cb.p_scan_cback) {
4139 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result);
4143 /* application indicates if it knows the remote name, inside the callback
4144 copy that to the inquiry data base*/
4145 if (result.inq_res.remt_name_not_required) {
4146 p_inq_info->appl_knows_rem_name = TRUE;
4151 /*******************************************************************************
4153 ** Function bta_dm_observe_cmpl_cb
4155 ** Description Callback for BLE Observe complete
4160 *******************************************************************************/
4161 static void bta_dm_observe_cmpl_cb (void *p_result)
4163 tBTA_DM_SEARCH data;
4165 APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb");
4167 data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
4168 if (bta_dm_search_cb.p_scan_cback) {
4169 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
4173 #if (SMP_INCLUDED == TRUE)
4174 /*******************************************************************************
4176 ** Function bta_dm_ble_smp_cback
4178 ** Description Callback for BLE SMP
4183 *******************************************************************************/
4184 static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data)
4186 tBTM_STATUS status = BTM_SUCCESS;
4187 tBTA_DM_SEC sec_event;
4188 char *p_name = NULL;
4190 if (!bta_dm_cb.p_sec_cback) {
4191 return BTM_NOT_AUTHORIZED;
4194 memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
4196 case BTM_LE_IO_REQ_EVT:
4197 // #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
4199 bta_dm_co_ble_io_req(bda,
4200 &p_data->io_req.io_cap,
4201 &p_data->io_req.oob_data,
4202 &p_data->io_req.auth_req,
4203 &p_data->io_req.max_key_size,
4204 &p_data->io_req.init_keys,
4205 &p_data->io_req.resp_keys);
4207 #if BTM_OOB_INCLUDED == FALSE
4208 status = BTM_SUCCESS;
4210 APPL_TRACE_EVENT("io mitm: %d oob_data:%d\n", p_data->io_req.auth_req, p_data->io_req.oob_data);
4214 case BTM_LE_SEC_REQUEST_EVT:
4215 bdcpy(sec_event.ble_req.bd_addr, bda);
4216 p_name = BTM_SecReadDevName(bda);
4217 if (p_name != NULL) {
4218 BCM_STRNCPY_S((char *)sec_event.ble_req.bd_name,
4219 sizeof(BD_NAME), p_name, (BD_NAME_LEN));
4221 sec_event.ble_req.bd_name[0] = 0;
4223 sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
4224 bta_dm_cb.p_sec_cback(BTA_DM_BLE_SEC_REQ_EVT, &sec_event);
4227 case BTM_LE_KEY_NOTIF_EVT:
4228 bdcpy(sec_event.key_notif.bd_addr, bda);
4229 p_name = BTM_SecReadDevName(bda);
4230 if (p_name != NULL) {
4231 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,
4232 sizeof(BD_NAME), p_name, (BD_NAME_LEN));
4234 sec_event.key_notif.bd_name[0] = 0;
4236 sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
4237 sec_event.key_notif.passkey = p_data->key_notif;
4238 bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_NOTIF_EVT, &sec_event);
4241 case BTM_LE_KEY_REQ_EVT:
4242 bdcpy(sec_event.ble_req.bd_addr, bda);
4243 bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_REQ_EVT, &sec_event);
4246 case BTM_LE_OOB_REQ_EVT:
4247 bdcpy(sec_event.ble_req.bd_addr, bda);
4248 bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event);
4251 case BTM_LE_NC_REQ_EVT:
4252 bdcpy(sec_event.key_notif.bd_addr, bda);
4253 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN));
4254 sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
4255 sec_event.key_notif.passkey = p_data->key_notif;
4256 bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
4259 case BTM_LE_KEY_EVT:
4260 bdcpy(sec_event.ble_key.bd_addr, bda);
4261 sec_event.ble_key.key_type = p_data->key.key_type;
4262 sec_event.ble_key.p_key_value = p_data->key.p_key_value;
4263 bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event);
4266 case BTM_LE_COMPLT_EVT:
4267 bdcpy(sec_event.auth_cmpl.bd_addr, bda);
4268 #if BLE_INCLUDED == TRUE
4269 BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
4271 p_name = BTM_SecReadDevName(bda);
4272 if (p_name != NULL) {
4273 BCM_STRNCPY_S((char *)sec_event.auth_cmpl.bd_name,
4274 sizeof(BD_NAME), p_name, (BD_NAME_LEN));
4276 sec_event.auth_cmpl.bd_name[0] = 0;
4278 if (p_data->complt.reason != 0) {
4279 sec_event.auth_cmpl.fail_reason = BTA_DM_AUTH_CONVERT_SMP_CODE(((UINT8)p_data->complt.reason));
4280 /* delete this device entry from Sec Dev DB */
4281 bta_dm_remove_sec_dev_entry (bda);
4283 sec_event.auth_cmpl.success = TRUE;
4284 if (!p_data->complt.smp_over_br) {
4289 if (bta_dm_cb.p_sec_cback) {
4290 //bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
4291 bta_dm_cb.p_sec_cback(BTA_DM_BLE_AUTH_CMPL_EVT, &sec_event);
4297 status = BTM_NOT_AUTHORIZED;
4303 /*******************************************************************************
4305 ** Function bta_dm_ble_id_key_cback
4307 ** Description Callback for BLE local ID keys
4312 *******************************************************************************/
4313 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key)
4319 case BTM_BLE_KEY_TYPE_ID:
4320 case BTM_BLE_KEY_TYPE_ER:
4321 if (bta_dm_cb.p_sec_cback) {
4322 memcpy(&dm_key.ble_id_keys, p_key, sizeof(tBTM_BLE_LOCAL_KEYS));
4324 evt = (key_type == BTM_BLE_KEY_TYPE_ID) ? BTA_DM_BLE_LOCAL_IR_EVT : \
4325 BTA_DM_BLE_LOCAL_ER_EVT;
4326 bta_dm_cb.p_sec_cback(evt, &dm_key);
4331 APPL_TRACE_DEBUG("Unknown key type %d", key_type);
4338 /*******************************************************************************
4340 ** Function bta_dm_add_blekey
4342 ** Description This function adds an BLE Key to an security database entry.
4343 ** This function shall only be called AFTER BTA_DmAddBleDevice has been called.
4344 ** It is normally called during host startup to restore all required information
4345 ** stored in the NVRAM.
4349 *******************************************************************************/
4350 void bta_dm_add_blekey (tBTA_DM_MSG *p_data)
4352 if (!BTM_SecAddBleKey (p_data->add_ble_key.bd_addr,
4353 (tBTM_LE_KEY_VALUE *)&p_data->add_ble_key.blekey,
4354 p_data->add_ble_key.key_type)) {
4355 APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Key for device %08x%04x",
4356 (p_data->add_ble_key.bd_addr[0] << 24) + (p_data->add_ble_key.bd_addr[1] << 16) + \
4357 (p_data->add_ble_key.bd_addr[2] << 8) + p_data->add_ble_key.bd_addr[3],
4358 (p_data->add_ble_key.bd_addr[4] << 8) + p_data->add_ble_key.bd_addr[5]);
4362 /*******************************************************************************
4364 ** Function bta_dm_add_ble_device
4366 ** Description This function adds an BLE device to an security database entry.
4367 ** It is normally called during host startup to restore all required information
4368 ** stored in the NVRAM.
4372 *******************************************************************************/
4373 void bta_dm_add_ble_device (tBTA_DM_MSG *p_data)
4375 if (!BTM_SecAddBleDevice (p_data->add_ble_device.bd_addr, NULL,
4376 p_data->add_ble_device.dev_type ,
4377 p_data->add_ble_device.addr_type)) {
4378 APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Device for device %08x%04x",
4379 (p_data->add_ble_device.bd_addr[0] << 24) + (p_data->add_ble_device.bd_addr[1] << 16) + \
4380 (p_data->add_ble_device.bd_addr[2] << 8) + p_data->add_ble_device.bd_addr[3],
4381 (p_data->add_ble_device.bd_addr[4] << 8) + p_data->add_ble_device.bd_addr[5]);
4385 /*******************************************************************************
4387 ** Function bta_dm_add_ble_device
4389 ** Description This function adds an BLE device to an security database entry.
4390 ** It is normally called during host startup to restore all required information
4391 ** stored in the NVRAM.
4395 *******************************************************************************/
4396 void bta_dm_ble_passkey_reply (tBTA_DM_MSG *p_data)
4398 if (p_data->pin_reply.accept) {
4399 BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_SUCCESS, p_data->ble_passkey_reply.passkey);
4401 BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED, p_data->ble_passkey_reply.passkey);
4406 /*******************************************************************************
4408 ** Function bta_dm_ble_confirm_reply
4410 ** Description This is response to SM numeric comparison request submitted
4415 *******************************************************************************/
4416 void bta_dm_ble_confirm_reply (tBTA_DM_MSG *p_data)
4418 if (p_data->confirm.accept) {
4419 BTM_BleConfirmReply(p_data->confirm.bd_addr, BTM_SUCCESS);
4421 BTM_BleConfirmReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED);
4425 /*******************************************************************************
4427 ** Function bta_dm_security_grant
4429 ** Description This function grant SMP security request access.
4433 *******************************************************************************/
4434 void bta_dm_security_grant (tBTA_DM_MSG *p_data)
4436 BTM_SecurityGrant(p_data->ble_sec_grant.bd_addr, p_data->ble_sec_grant.res);
4438 #endif ///SMP_INCLUDED == TRUE
4440 /*******************************************************************************
4442 ** Function bta_dm_ble_set_bg_conn_type
4444 ** Description This function set the BLE background connection type
4448 *******************************************************************************/
4449 void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data)
4451 BTM_BleSetBgConnType(p_data->ble_set_bd_conn_type.bg_conn_type,
4452 p_data->ble_set_bd_conn_type.p_select_cback);
4455 /*******************************************************************************
4457 ** Function bta_dm_ble_set_conn_params
4459 ** Description This function set the preferred connection parameters.
4463 *******************************************************************************/
4464 void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data)
4466 BTM_BleSetPrefConnParams(p_data->ble_set_conn_params.peer_bda,
4467 p_data->ble_set_conn_params.conn_int_min,
4468 p_data->ble_set_conn_params.conn_int_max,
4469 p_data->ble_set_conn_params.slave_latency,
4470 p_data->ble_set_conn_params.supervision_tout);
4473 /*******************************************************************************
4475 ** Function bta_dm_ble_set_conn_scan_params
4477 ** Description This function sets BLE scan parameters.
4481 *******************************************************************************/
4482 void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data)
4484 BTM_BleSetScanParams(p_data->ble_set_scan_params.client_if,
4485 p_data->ble_set_scan_params.scan_int,
4486 p_data->ble_set_scan_params.scan_window,
4487 p_data->ble_set_scan_params.scan_mode,
4488 p_data->ble_set_scan_params.scan_param_setup_cback);
4491 /*******************************************************************************
4493 ** Function bta_dm_ble_set_scan_fil_params
4495 ** Description This function sets BLE scan filter & parameters.
4499 *******************************************************************************/
4500 void bta_dm_ble_set_scan_fil_params(tBTA_DM_MSG *p_data)
4502 BTM_BleSetScanFilterParams (p_data->ble_set_scan_fil_params.client_if,
4503 p_data->ble_set_scan_fil_params.scan_int,
4504 p_data->ble_set_scan_fil_params.scan_window,
4505 p_data->ble_set_scan_fil_params.scan_mode,
4506 p_data->ble_set_scan_fil_params.addr_type_own,
4507 p_data->ble_set_scan_fil_params.scan_filter_policy,
4508 p_data->ble_set_scan_fil_params.scan_param_setup_cback);
4512 /*******************************************************************************
4514 ** Function bta_dm_ble_set_conn_scan_params
4516 ** Description This function set the preferred connection scan parameters.
4520 *******************************************************************************/
4521 void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data)
4523 BTM_BleSetConnScanParams(p_data->ble_set_conn_scan_params.scan_int,
4524 p_data->ble_set_conn_scan_params.scan_window);
4526 /*******************************************************************************
4528 ** Function bta_dm_ble_update_conn_params
4530 ** Description This function update LE connection parameters.
4534 *******************************************************************************/
4535 void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
4537 if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr,
4538 p_data->ble_update_conn_params.min_int,
4539 p_data->ble_update_conn_params.max_int,
4540 p_data->ble_update_conn_params.latency,
4541 p_data->ble_update_conn_params.timeout)) {
4542 APPL_TRACE_ERROR("Update connection parameters failed!");
4545 /*******************************************************************************
4547 ** Function bta_dm_ble_disconnect
4549 ** Description This function disconnect the ble connection.
4553 *******************************************************************************/
4554 void bta_dm_ble_disconnect (tBTA_DM_MSG *p_data)
4556 L2CA_RemoveFixedChnl(L2CAP_ATT_CID, p_data->ble_disconnect.remote_bda);
4559 /*******************************************************************************
4561 ** Function bta_dm_ble_set_rand_address
4563 ** Description This function set the LE random address for the device.
4565 ** Parameters: rand_addr:the random address whitch should be setting
4566 ** Explanation: This function added by Yulong at 2016/9/9
4567 *******************************************************************************/
4568 void bta_dm_ble_set_rand_address(tBTA_DM_MSG *p_data)
4570 BOOLEAN set_flag = false;
4571 if (p_data->set_addr.addr_type != BLE_ADDR_RANDOM) {
4572 APPL_TRACE_ERROR("Invalid random adress type = %d\n", p_data->set_addr.addr_type);
4575 //send the setting random address to BTM layer
4576 if ((set_flag = BTM_BleSetRandAddress(p_data->set_addr.address) != TRUE)){
4577 APPL_TRACE_ERROR("%s,set random address fail.", __func__);
4582 /*******************************************************************************
4584 ** Function bta_dm_ble_stop_advertising
4586 ** Description This function stop the BLE avdertising for the device.
4589 ** Explanation: This function added by Yulong at 2016/10/19
4590 *******************************************************************************/
4591 void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data)
4593 if (p_data->hdr.event != BTA_DM_API_BLE_STOP_ADV_EVT) {
4594 APPL_TRACE_ERROR("Invalid BTA event,cann't stop the BLE adverting\n");
4602 #if BLE_PRIVACY_SPT == TRUE
4603 /*******************************************************************************
4605 ** Function bta_dm_ble_config_local_privacy
4607 ** Description This function set the local device LE privacy settings.
4611 *******************************************************************************/
4612 void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data)
4614 BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable, p_data->ble_local_privacy.set_local_privacy_cback);
4618 /*******************************************************************************
4620 ** Function bta_dm_ble_observe
4622 ** Description This function set the preferred connection scan parameters.
4626 *******************************************************************************/
4627 void bta_dm_ble_observe (tBTA_DM_MSG *p_data)
4630 if (p_data->ble_observe.start) {
4631 /*Save the callback to be called when a scan results are available */
4632 bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback;
4634 if ((status = BTM_BleObserve(TRUE, p_data->ble_observe.duration,
4635 bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) {
4636 APPL_TRACE_WARNING(" %s start observe failed. status=0x%x\n", __FUNCTION__, status);
4639 if (p_data->ble_observe.p_start_scan_cback) {
4640 status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4641 p_data->ble_observe.p_start_scan_cback(status);
4644 bta_dm_search_cb.p_scan_cback = NULL;
4645 status = BTM_BleObserve(FALSE, 0, NULL, NULL);
4647 if (status != BTM_CMD_STARTED){
4648 APPL_TRACE_WARNING(" %s stop observe failed, status=0x%x\n", __FUNCTION__, status);
4651 if (p_data->ble_observe.p_stop_scan_cback) {
4652 status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4653 p_data->ble_observe.p_stop_scan_cback(status);
4658 /*******************************************************************************
4660 ** Function bta_dm_ble_scan
4662 ** Description This function set the preferred connection scan parameters.
4666 *******************************************************************************/
4667 void bta_dm_ble_scan (tBTA_DM_MSG *p_data)
4670 if (p_data->ble_scan.start) {
4671 /*Save the callback to be called when a scan results are available */
4672 bta_dm_search_cb.p_scan_cback = p_data->ble_scan.p_cback;
4674 if ((status = BTM_BleScan(TRUE, p_data->ble_scan.duration,
4675 bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) {
4676 APPL_TRACE_WARNING(" %s start scan failed. status=0x%x\n", __FUNCTION__, status);
4679 if (p_data->ble_scan.p_start_scan_cback) {
4680 status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4681 p_data->ble_scan.p_start_scan_cback(status);
4684 bta_dm_search_cb.p_scan_cback = NULL;
4685 status = BTM_BleScan(FALSE, 0, NULL, NULL);
4687 if (status != BTM_CMD_STARTED){
4688 APPL_TRACE_WARNING(" %s stop scan failed, status=0x%x\n", __FUNCTION__, status);
4691 if (p_data->ble_scan.p_stop_scan_cback) {
4692 status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4693 p_data->ble_scan.p_stop_scan_cback(status);
4698 /*******************************************************************************
4700 ** Function bta_dm_ble_set_adv_params
4702 ** Description This function set the adv parameters.
4706 *******************************************************************************/
4707 void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data)
4709 BTM_BleSetAdvParams(p_data->ble_set_adv_params.adv_int_min,
4710 p_data->ble_set_adv_params.adv_int_max,
4711 p_data->ble_set_adv_params.p_dir_bda,
4712 BTA_DM_BLE_ADV_CHNL_MAP);
4715 /*******************************************************************************
4717 ** Function bta_dm_ble_set_adv_params_all
4719 ** Description This function is called to set all of the advertising parameters.
4721 ** Parameters: None.
4725 *******************************************************************************/
4726 void bta_dm_ble_set_adv_params_all (tBTA_DM_MSG *p_data)
4728 if (BTM_BleSetAdvParamsStartAdv(p_data->ble_set_adv_params_all.adv_int_min,
4729 p_data->ble_set_adv_params_all.adv_int_max,
4730 p_data->ble_set_adv_params_all.adv_type,
4731 p_data->ble_set_adv_params_all.addr_type_own,
4732 p_data->ble_set_adv_params_all.p_dir_bda,
4733 p_data->ble_set_adv_params_all.channel_map,
4734 p_data->ble_set_adv_params_all.adv_filter_policy,
4735 p_data->ble_set_adv_params_all.p_start_adv_cback) == BTM_SUCCESS) {
4736 APPL_TRACE_DEBUG("%s(), success to start ble adv.", __func__);
4738 APPL_TRACE_ERROR("%s(), fail to start ble adv.", __func__);
4742 /*******************************************************************************
4744 ** Function bta_dm_ble_set_adv_config
4746 ** Description This function set the customized ADV data configuration
4750 *******************************************************************************/
4751 void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data)
4753 tBTA_STATUS status = BTA_FAILURE;
4755 if (BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask,
4756 (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS) {
4757 status = BTA_SUCCESS;
4760 if (p_data->ble_set_adv_data.p_adv_data_cback) {
4761 (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
4765 /*******************************************************************************
4767 ** Function bta_dm_ble_set_adv_config_raw
4769 ** Description This function set the customized ADV data configuration
4773 *******************************************************************************/
4774 void bta_dm_ble_set_adv_config_raw (tBTA_DM_MSG *p_data)
4776 tBTA_STATUS status = BTA_FAILURE;
4778 if (BTM_BleWriteAdvDataRaw(p_data->ble_set_adv_data_raw.p_raw_adv,
4779 p_data->ble_set_adv_data_raw.raw_adv_len) == BTM_SUCCESS) {
4780 status = BTA_SUCCESS;
4783 if (p_data->ble_set_adv_data_raw.p_adv_data_cback) {
4784 (*p_data->ble_set_adv_data_raw.p_adv_data_cback)(status);
4789 /*******************************************************************************
4791 ** Function bta_dm_ble_set_scan_rsp
4793 ** Description This function set the customized ADV scan resp. configuration
4797 *******************************************************************************/
4798 void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data)
4800 tBTA_STATUS status = BTA_FAILURE;
4802 if (BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
4803 (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS) {
4804 status = BTA_SUCCESS;
4807 if (p_data->ble_set_adv_data.p_adv_data_cback) {
4808 (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
4812 /*******************************************************************************
4814 ** Function bta_dm_ble_set_scan_rsp_raw
4816 ** Description This function set the raw scan response data
4820 *******************************************************************************/
4821 void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data)
4823 tBTA_STATUS status = BTA_FAILURE;
4825 if (BTM_BleWriteScanRspRaw(p_data->ble_set_adv_data_raw.p_raw_adv,
4826 p_data->ble_set_adv_data_raw.raw_adv_len) == BTM_SUCCESS) {
4827 status = BTA_SUCCESS;
4830 if (p_data->ble_set_adv_data_raw.p_adv_data_cback) {
4831 (*p_data->ble_set_adv_data_raw.p_adv_data_cback)(status);
4835 /*******************************************************************************
4837 ** Function bta_dm_ble_set_data_length
4839 ** Description This function set the maximum transmission packet size
4843 *******************************************************************************/
4844 void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data)
4846 tACL_CONN *p_acl_cb = btm_bda_to_acl(p_data->ble_set_data_length.remote_bda, BT_TRANSPORT_LE);
4847 if (p_acl_cb == NULL) {
4848 APPL_TRACE_ERROR("%s error: Invalid connection remote_bda.", __func__);
4851 p_acl_cb->p_set_pkt_data_cback = p_data->ble_set_data_length.p_set_pkt_data_cback;
4853 UINT8 status = BTM_SetBleDataLength(p_data->ble_set_data_length.remote_bda,
4854 p_data->ble_set_data_length.tx_data_length);
4855 if (status != BTM_SUCCESS) {
4856 APPL_TRACE_ERROR("%s failed\n", __FUNCTION__);
4857 if (p_data->ble_set_data_length.p_set_pkt_data_cback) {
4858 if (p_acl_cb->data_length_params.tx_len == 0){
4859 uint16_t length = controller_get_interface()->get_acl_data_size_ble();
4860 p_acl_cb->data_length_params.rx_len = length;
4861 p_acl_cb->data_length_params.tx_len = length;
4863 (*p_data->ble_set_data_length.p_set_pkt_data_cback)(status, &p_acl_cb->data_length_params);
4868 /*******************************************************************************
4870 ** Function bta_dm_ble_broadcast
4872 ** Description Starts or stops LE broadcasts
4876 *******************************************************************************/
4877 void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data)
4879 tBTM_STATUS status = 0;
4880 BOOLEAN start = p_data->ble_observe.start;
4882 status = BTM_BleBroadcast(start, p_data->ble_observe.p_stop_adv_cback);
4884 if (p_data->ble_observe.p_stop_adv_cback){
4885 if (status != BTM_SUCCESS){
4886 APPL_TRACE_WARNING("%s, %s, status=0x%x\n", __func__,\
4887 (start == TRUE) ? "start adv failed" : "stop adv failed", status);
4893 /*******************************************************************************
4895 ** Function bta_dm_ble_multi_adv_enb
4897 ** Description This function enables a single advertising instance
4901 *******************************************************************************/
4902 void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data)
4904 tBTM_STATUS btm_status = 0;
4906 bta_dm_cb.p_multi_adv_cback = p_data->ble_multi_adv_enb.p_cback;
4907 if (BTM_BleMaxMultiAdvInstanceCount() > 0 && NULL != p_data->ble_multi_adv_enb.p_ref) {
4908 btm_status = BTM_BleEnableAdvInstance((tBTM_BLE_ADV_PARAMS *)
4909 p_data->ble_multi_adv_enb.p_params,
4910 p_data->ble_multi_adv_enb.p_cback,
4911 p_data->ble_multi_adv_enb.p_ref);
4914 if (BTM_CMD_STARTED != btm_status) {
4915 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_ENB_EVT, 0xFF,
4916 p_data->ble_multi_adv_enb.p_ref, BTA_FAILURE);
4919 /*******************************************************************************
4921 ** Function bta_dm_ble_multi_adv_param_upd
4923 ** Description This function updates multiple advertising instance parameters
4927 *******************************************************************************/
4928 void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data)
4930 tBTM_STATUS btm_status = 0;
4933 if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_param.inst_id > 0
4934 && p_data->ble_multi_adv_param.inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
4935 btm_status = BTM_BleUpdateAdvInstParam(p_data->ble_multi_adv_param.inst_id,
4936 (tBTM_BLE_ADV_PARAMS *)p_data->ble_multi_adv_param.p_params);
4939 if (BTM_CMD_STARTED != btm_status) {
4940 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_param.inst_id);
4941 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_PARAM_EVT,
4942 p_data->ble_multi_adv_param.inst_id, p_ref, BTA_FAILURE);
4945 /*******************************************************************************
4947 ** Function bta_dm_ble_multi_adv_data
4949 ** Description This function write multiple advertising instance adv data
4950 ** or scan response data
4954 *******************************************************************************/
4955 void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data)
4957 tBTM_STATUS btm_status = 0;
4960 if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_data.inst_id > 0
4961 && p_data->ble_multi_adv_data.inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
4962 btm_status = BTM_BleCfgAdvInstData(p_data->ble_multi_adv_data.inst_id,
4963 p_data->ble_multi_adv_data.is_scan_rsp,
4964 p_data->ble_multi_adv_data.data_mask,
4965 (tBTM_BLE_ADV_DATA *)p_data->ble_multi_adv_data.p_data);
4968 if (BTM_CMD_STARTED != btm_status) {
4969 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_data.inst_id);
4970 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DATA_EVT,
4971 p_data->ble_multi_adv_data.inst_id, p_ref, BTA_FAILURE);
4975 /*******************************************************************************
4977 ** Function btm_dm_ble_multi_adv_disable
4979 ** Description This function disable a single adv instance
4983 *******************************************************************************/
4984 void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data)
4986 tBTM_STATUS btm_status = 0;
4989 if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_disable.inst_id > 0
4990 && p_data->ble_multi_adv_disable.inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
4991 btm_status = BTM_BleDisableAdvInstance(p_data->ble_multi_adv_disable.inst_id);
4994 if (BTM_CMD_STARTED != btm_status) {
4995 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_disable.inst_id);
4996 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DISABLE_EVT,
4997 p_data->ble_multi_adv_disable.inst_id, p_ref, BTA_FAILURE);
5001 /*******************************************************************************
5003 ** Function bta_dm_ble_setup_storage
5005 ** Description This function configures up the storage parameters for ADV batch scanning
5009 *******************************************************************************/
5010 void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data)
5012 tBTM_STATUS btm_status = 0;
5013 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5015 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5017 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5018 btm_status = BTM_BleSetStorageConfig(p_data->ble_set_storage.batch_scan_full_max,
5019 p_data->ble_set_storage.batch_scan_trunc_max,
5020 p_data->ble_set_storage.batch_scan_notify_threshold,
5021 p_data->ble_set_storage.p_setup_cback,
5022 p_data->ble_set_storage.p_thres_cback,
5023 p_data->ble_set_storage.p_read_rep_cback,
5024 p_data->ble_set_storage.ref_value);
5027 if (BTM_CMD_STARTED != btm_status)
5028 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, p_data->ble_set_storage.ref_value,
5032 /*******************************************************************************
5034 ** Function bta_dm_ble_enable_batch_scan
5036 ** Description This function sets up the parameters and enables batch scan
5040 *******************************************************************************/
5041 void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data)
5043 tBTM_STATUS btm_status = 0;
5044 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5046 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5048 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5049 btm_status = BTM_BleEnableBatchScan(p_data->ble_enable_scan.scan_mode,
5050 p_data->ble_enable_scan.scan_int,
5051 p_data->ble_enable_scan.scan_window,
5052 p_data->ble_enable_scan.discard_rule,
5053 p_data->ble_enable_scan.addr_type,
5054 p_data->ble_enable_scan.ref_value);
5057 if (BTM_CMD_STARTED != btm_status)
5058 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_ENABLE_EVT, p_data->ble_enable_scan.ref_value,
5062 /*******************************************************************************
5064 ** Function bta_dm_ble_disable_batch_scan
5066 ** Description This function disables the batch scan
5070 *******************************************************************************/
5071 void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data)
5074 tBTM_STATUS btm_status = 0;
5075 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5077 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5079 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5080 btm_status = BTM_BleDisableBatchScan(p_data->ble_disable_scan.ref_value);
5083 if (BTM_CMD_STARTED != btm_status)
5084 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_DISABLE_EVT, p_data->ble_enable_scan.ref_value,
5088 /*******************************************************************************
5090 ** Function bta_dm_ble_read_scan_reports
5092 ** Description This function reads the batch scan reports
5096 *******************************************************************************/
5097 void bta_dm_ble_read_scan_reports(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_BleReadScanReports(p_data->ble_read_reports.scan_type,
5106 p_data->ble_read_reports.ref_value);
5109 if (BTM_CMD_STARTED != btm_status)
5110 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, p_data->ble_enable_scan.ref_value,
5114 /*******************************************************************************
5116 ** Function bta_dm_ble_track_advertiser
5118 ** Description This function tracks the specific advertiser
5122 *******************************************************************************/
5123 void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data)
5125 tBTM_STATUS btm_status = 0;
5127 memset(&bda, 0 , sizeof(BD_ADDR));
5128 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5129 tBTA_DM_BLE_TRACK_ADV_DATA track_adv_data;
5131 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5133 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5134 btm_status = BTM_BleTrackAdvertiser((tBTM_BLE_TRACK_ADV_CBACK *)
5135 p_data->ble_track_advert.p_track_adv_cback,
5136 p_data->ble_track_advert.ref_value);
5139 if (BTM_CMD_STARTED != btm_status) {
5140 memset(&track_adv_data, 0, sizeof(tBTA_DM_BLE_TRACK_ADV_DATA));
5141 track_adv_data.advertiser_info_present = NO_ADV_INFO_PRESENT; /* Indicates failure */
5142 track_adv_data.client_if = (UINT8)p_data->ble_track_advert.ref_value;
5143 p_data->ble_track_advert.p_track_adv_cback(&track_adv_data);
5147 /*******************************************************************************
5149 ** Function bta_ble_scan_setup_cb
5151 ** Description Handle the setup callback from BTM layer and forward it to app layer
5155 *******************************************************************************/
5156 void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_value,
5159 tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0;
5161 APPL_TRACE_DEBUG("bta_ble_scan_setup_cb : evt: %d, ref_value: %d, status:%d", evt,
5165 case BTM_BLE_BATCH_SCAN_ENABLE_EVT:
5166 bta_evt = BTA_BLE_BATCH_SCAN_ENB_EVT;
5168 case BTM_BLE_BATCH_SCAN_CFG_STRG_EVT:
5169 bta_evt = BTA_BLE_BATCH_SCAN_CFG_STRG_EVT;
5171 case BTM_BLE_BATCH_SCAN_DISABLE_EVT:
5172 bta_evt = BTA_BLE_BATCH_SCAN_DIS_EVT;
5174 case BTM_BLE_BATCH_SCAN_PARAM_EVT:
5175 bta_evt = BTA_BLE_BATCH_SCAN_PARAM_EVT;
5181 if (NULL != bta_dm_cb.p_setup_cback) {
5182 bta_dm_cb.p_setup_cback(bta_evt, ref_value, status);
5187 #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
5188 /*******************************************************************************
5190 ** Function bta_ble_scan_pf_cmpl
5192 ** Description ADV payload filtering operation complete callback
5195 ** Returns TRUE if handled, otherwise FALSE.
5197 *******************************************************************************/
5198 static void bta_ble_scan_cfg_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op,
5199 tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status,
5200 tBTM_BLE_REF_VALUE ref_value)
5202 tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
5204 APPL_TRACE_DEBUG("bta_ble_scan_cfg_cmpl: %d, %d, %d, %d", action, cfg_op, avbl_space, status);
5206 if (bta_dm_cb.p_scan_filt_cfg_cback) {
5207 bta_dm_cb.p_scan_filt_cfg_cback(action, cfg_op, avbl_space, st, ref_value);
5211 /*******************************************************************************
5213 ** Function bta_dm_cfg_filter_cond
5215 ** Description This function configure adv payload filtering condition
5219 *******************************************************************************/
5220 void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data)
5222 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5223 tBTA_STATUS status = BTA_FAILURE;
5225 tBTM_BLE_VSC_CB cmn_vsc_cb;
5227 APPL_TRACE_DEBUG("bta_dm_cfg_filter_cond");
5228 BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5229 if (0 != cmn_vsc_cb.filter_support) {
5230 if ((st = BTM_BleCfgFilterCondition(p_data->ble_cfg_filter_cond.action,
5231 p_data->ble_cfg_filter_cond.cond_type,
5232 (tBTM_BLE_PF_FILT_INDEX)p_data->ble_cfg_filter_cond.filt_index,
5233 (tBTM_BLE_PF_COND_PARAM *)p_data->ble_cfg_filter_cond.p_cond_param,
5234 bta_ble_scan_cfg_cmpl, p_data->ble_cfg_filter_cond.ref_value))
5235 == BTM_CMD_STARTED) {
5236 bta_dm_cb.p_scan_filt_cfg_cback = p_data->ble_cfg_filter_cond.p_filt_cfg_cback;
5241 if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback)
5242 p_data->ble_cfg_filter_cond.p_filt_cfg_cback(BTA_DM_BLE_PF_CONFIG_EVT,
5243 p_data->ble_cfg_filter_cond.cond_type, 0, status,
5244 p_data->ble_cfg_filter_cond.ref_value);
5248 /*******************************************************************************
5250 ** Function bta_dm_enable_scan_filter
5252 ** Description This function enable/disable adv payload filtering condition
5256 *******************************************************************************/
5257 void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data)
5259 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5260 tBTA_STATUS status = BTA_FAILURE;
5262 tBTM_BLE_VSC_CB cmn_vsc_cb;
5263 APPL_TRACE_DEBUG("bta_dm_enable_scan_filter");
5264 BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5266 if (0 != cmn_vsc_cb.filter_support) {
5267 if ((st = BTM_BleEnableDisableFilterFeature(p_data->ble_enable_scan_filt.action,
5268 p_data->ble_enable_scan_filt.p_filt_status_cback,
5269 (tBTM_BLE_REF_VALUE)p_data->ble_enable_scan_filt.ref_value)) == BTM_CMD_STARTED) {
5270 bta_dm_cb.p_scan_filt_status_cback = p_data->ble_enable_scan_filt.p_filt_status_cback;
5275 if (p_data->ble_enable_scan_filt.p_filt_status_cback)
5276 p_data->ble_enable_scan_filt.p_filt_status_cback (BTA_DM_BLE_PF_ENABLE_EVT,
5277 p_data->ble_enable_scan_filt.ref_value, status);
5281 /*******************************************************************************
5283 ** Function bta_dm_scan_filter_param_setup
5285 ** Description This function sets up scan filter params
5289 *******************************************************************************/
5290 void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data)
5292 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5293 tBTA_STATUS status = BTA_FAILURE;
5295 tBTM_BLE_VSC_CB cmn_vsc_cb;
5297 APPL_TRACE_DEBUG("bta_dm_scan_filter_param_setup");
5298 BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5299 if (0 != cmn_vsc_cb.filter_support) {
5300 if ((st = BTM_BleAdvFilterParamSetup(p_data->ble_scan_filt_param_setup.action,
5301 p_data->ble_scan_filt_param_setup.filt_index,
5302 (tBTM_BLE_PF_FILT_PARAMS *)&p_data->ble_scan_filt_param_setup.filt_params,
5303 p_data->ble_scan_filt_param_setup.p_target,
5304 p_data->ble_scan_filt_param_setup.p_filt_param_cback,
5305 p_data->ble_scan_filt_param_setup.ref_value)) == BTM_CMD_STARTED) {
5306 bta_dm_cb.p_scan_filt_param_cback = p_data->ble_scan_filt_param_setup.p_filt_param_cback;
5311 if (p_data->ble_scan_filt_param_setup.p_filt_param_cback)
5312 p_data->ble_scan_filt_param_setup.p_filt_param_cback (BTA_DM_BLE_PF_ENABLE_EVT, 0,
5313 p_data->ble_scan_filt_param_setup.ref_value, status);
5319 /*******************************************************************************
5321 ** Function bta_ble_enable_scan_cmpl
5323 ** Description ADV payload filtering enable / disable complete callback
5328 *******************************************************************************/
5329 static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time,
5330 tBTM_BLE_RX_TIME_MS rx_time,
5331 tBTM_BLE_IDLE_TIME_MS idle_time,
5332 tBTM_BLE_ENERGY_USED energy_used,
5335 tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
5336 tBTA_DM_CONTRL_STATE ctrl_state = 0;
5337 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
5338 if (BTA_SUCCESS == st) {
5339 ctrl_state = bta_dm_pm_obtain_controller_state();
5342 if (bta_dm_cb.p_energy_info_cback) {
5343 bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, ctrl_state, st);
5347 /*******************************************************************************
5349 ** Function bta_dm_ble_get_energy_info
5351 ** Description This function obtains the energy info
5355 *******************************************************************************/
5356 void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data)
5358 tBTM_STATUS btm_status = 0;
5360 bta_dm_cb.p_energy_info_cback = p_data->ble_energy_info.p_energy_info_cback;
5361 btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl);
5362 if (BTM_CMD_STARTED != btm_status) {
5363 bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status);
5367 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
5368 #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
5369 #define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000
5372 /*******************************************************************************
5374 ** Function bta_dm_gattc_register
5376 ** Description Register with GATTC in DM if BLE is needed.
5381 *******************************************************************************/
5382 #if (GATTC_INCLUDED == TRUE)
5383 static void bta_dm_gattc_register(void)
5385 tBT_UUID app_uuid = {LEN_UUID_128, {0}};
5387 if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF) {
5388 memset (&app_uuid.uu.uuid128, 0x87, LEN_UUID_128);
5389 BTA_GATTC_AppRegister(&app_uuid, bta_dm_gattc_callback);
5392 #endif /* GATTC_INCLUDED == TRUE */
5393 /*******************************************************************************
5395 ** Function btm_dm_start_disc_gatt_services
5397 ** Description This function starts a GATT service search request.
5401 *******************************************************************************/
5402 static void btm_dm_start_disc_gatt_services (UINT16 conn_id)
5404 tBT_UUID *p_uuid = bta_dm_search_cb.p_srvc_uuid +
5405 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
5407 p_uuid = bta_dm_search_cb.p_srvc_uuid +
5408 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
5410 /* always search for all services */
5411 BTA_GATTC_ServiceSearchRequest(conn_id, p_uuid);
5414 /*******************************************************************************
5416 ** Function bta_dm_gatt_disc_result
5418 ** Description This function process the GATT service search result.
5422 *******************************************************************************/
5423 #if (GATTC_INCLUDED == TRUE)
5424 static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
5426 tBTA_DM_SEARCH result;
5429 * This logic will not work for gatt case. We are checking against the bluetooth profiles here
5430 * just copy the GATTID in raw data field and send it across.
5434 if ( bta_dm_search_cb.ble_raw_used + sizeof(tBTA_GATT_ID) < bta_dm_search_cb.ble_raw_size ) {
5435 APPL_TRACE_DEBUG("ADDING BLE SERVICE uuid=0x%x, ble_ptr = %p, ble_raw_used = 0x%x",
5436 service_id.uuid.uu.uuid16, bta_dm_search_cb.p_ble_rawdata, bta_dm_search_cb.ble_raw_used);
5438 if (bta_dm_search_cb.p_ble_rawdata) {
5439 memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used), &service_id,
5440 sizeof(service_id) );
5442 bta_dm_search_cb.ble_raw_used += sizeof(service_id);
5444 APPL_TRACE_ERROR("p_ble_rawdata is NULL");
5448 APPL_TRACE_ERROR("%s out of room to accomodate more service ids ble_raw_size = %d ble_raw_used = %d", __FUNCTION__, bta_dm_search_cb.ble_raw_size, bta_dm_search_cb.ble_raw_used );
5451 LOG_INFO("%s service_id_uuid_len=%d ", __func__, service_id.uuid.len);
5452 if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
5454 /* send result back to app now, one by one */
5455 bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
5456 BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN - 1));
5457 result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
5458 memcpy(&result.disc_ble_res.service, &service_id.uuid, sizeof(tBT_UUID));
5460 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
5463 #endif /* #if (GATTC_INCLUDED == TRUE) */
5464 /*******************************************************************************
5466 ** Function bta_dm_gatt_disc_complete
5468 ** Description This function process the GATT service search complete.
5472 *******************************************************************************/
5473 static void bta_dm_gatt_disc_complete(UINT16 conn_id, tBTA_GATT_STATUS status)
5477 APPL_TRACE_DEBUG("bta_dm_gatt_disc_complete conn_id = %d", conn_id);
5479 if (bta_dm_search_cb.uuid_to_search > 0) {
5480 bta_dm_search_cb.uuid_to_search --;
5483 if (status == BTA_GATT_OK && bta_dm_search_cb.uuid_to_search > 0) {
5484 btm_dm_start_disc_gatt_services(conn_id);
5486 bta_dm_search_cb.uuid_to_search = 0;
5488 /* no more services to be discovered */
5489 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
5490 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
5491 p_msg->disc_result.result.disc_res.result = (status == BTA_GATT_OK) ? BTA_SUCCESS : BTA_FAILURE;
5492 APPL_TRACE_DEBUG("%s service found: 0x%08x", __FUNCTION__,
5493 bta_dm_search_cb.services_found);
5494 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
5495 p_msg->disc_result.result.disc_res.num_uuids = 0;
5496 p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
5497 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
5498 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
5499 bta_dm_get_remname(), (BD_NAME_LEN - 1));
5501 /* make sure the string is terminated */
5502 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
5504 p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE;
5505 if ( bta_dm_search_cb.ble_raw_used > 0 ) {
5506 p_msg->disc_result.result.disc_res.p_raw_data = osi_malloc(bta_dm_search_cb.ble_raw_used);
5508 memcpy( p_msg->disc_result.result.disc_res.p_raw_data,
5509 bta_dm_search_cb.p_ble_rawdata,
5510 bta_dm_search_cb.ble_raw_used );
5512 p_msg->disc_result.result.disc_res.raw_data_size = bta_dm_search_cb.ble_raw_used;
5514 p_msg->disc_result.result.disc_res.p_raw_data = NULL;
5515 bta_dm_search_cb.p_ble_rawdata = 0;
5518 bta_sys_sendmsg(p_msg);
5521 if (conn_id != BTA_GATT_INVALID_CONN_ID) {
5522 /* start a GATT channel close delay timer */
5523 bta_sys_start_timer(&bta_dm_search_cb.gatt_close_timer, BTA_DM_DISC_CLOSE_TOUT_EVT,
5524 BTA_DM_GATT_CLOSE_DELAY_TOUT);
5525 bdcpy(bta_dm_search_cb.pending_close_bda, bta_dm_search_cb.peer_bdaddr);
5527 bta_dm_search_cb.gatt_disc_active = FALSE;
5531 /*******************************************************************************
5533 ** Function bta_dm_close_gatt_conn
5535 ** Description This function close the GATT connection after delay timeout.
5539 *******************************************************************************/
5540 #if (GATTC_INCLUDED == TRUE)
5541 void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data)
5545 if (bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID) {
5546 BTA_GATTC_Close(bta_dm_search_cb.conn_id);
5549 memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
5550 bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
5552 #endif /* #if (GATTC_INCLUDED == TRUE) */
5553 /*******************************************************************************
5555 ** Function btm_dm_start_gatt_discovery
5557 ** Description This is GATT initiate the service search by open a GATT connection
5562 *******************************************************************************/
5563 #if (GATTC_INCLUDED == TRUE)
5564 void btm_dm_start_gatt_discovery (BD_ADDR bd_addr)
5566 bta_dm_search_cb.gatt_disc_active = TRUE;
5568 /* connection is already open */
5569 if (bdcmp(bta_dm_search_cb.pending_close_bda, bd_addr) == 0 &&
5570 bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID) {
5571 memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
5572 bta_sys_stop_timer(&bta_dm_search_cb.gatt_close_timer);
5573 btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
5575 BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE, BTA_GATT_TRANSPORT_LE);
5578 #endif /* #if (GATTC_INCLUDED == TRUE) */
5579 /*******************************************************************************
5581 ** Function bta_dm_cancel_gatt_discovery
5583 ** Description This is GATT cancel the GATT service search.
5587 *******************************************************************************/
5588 #if (GATTC_INCLUDED == TRUE)
5589 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr)
5591 if (bta_dm_search_cb.conn_id == BTA_GATT_INVALID_CONN_ID) {
5592 BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, TRUE);
5595 bta_dm_gatt_disc_complete(bta_dm_search_cb.conn_id, (tBTA_GATT_STATUS) BTA_GATT_ERROR);
5597 #endif /* #if (GATTC_INCLUDED == TRUE) */
5598 /*******************************************************************************
5600 ** Function bta_dm_proc_open_evt
5602 ** Description process BTA_GATTC_OPEN_EVT in DM.
5606 *******************************************************************************/
5607 void bta_dm_proc_open_evt(tBTA_GATTC_OPEN *p_data)
5612 p1 = bta_dm_search_cb.peer_bdaddr;
5613 p2 = p_data->remote_bda;
5615 APPL_TRACE_DEBUG("DM Search state= %d search_cb.peer_dbaddr: [%08x%04x] connected_bda= [%08x%04x] ",
5616 bta_dm_search_cb.state,
5617 ((p1[0]) << 24) + ((p1[1]) << 16) + ((p1[2]) << 8) + (p1[3]),
5618 ((p1[4]) << 8) + p1[5],
5619 ((p2[0]) << 24) + ((p2[1]) << 16) + ((p2[2]) << 8) + (p2[3]),
5620 ((p2[4]) << 8) + p2[5]);
5622 APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d" ,
5627 bta_dm_search_cb.conn_id = p_data->conn_id;
5629 if (p_data->status == BTA_GATT_OK) {
5630 btm_dm_start_disc_gatt_services(p_data->conn_id);
5632 bta_dm_gatt_disc_complete(BTA_GATT_INVALID_CONN_ID, p_data->status);
5636 /*******************************************************************************
5638 ** Function bta_dm_gattc_callback
5640 ** Description This is GATT client callback function used in DM.
5644 *******************************************************************************/
5645 #if (GATTC_INCLUDED == TRUE)
5646 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
5648 APPL_TRACE_DEBUG("bta_dm_gattc_callback event = %d", event);
5651 case BTA_GATTC_REG_EVT:
5652 APPL_TRACE_DEBUG("BTA_GATTC_REG_EVT client_if = %d", p_data->reg_oper.client_if);
5653 if (p_data->reg_oper.status == BTA_GATT_OK) {
5654 bta_dm_search_cb.client_if = p_data->reg_oper.client_if;
5656 bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF;
5660 case BTA_GATTC_OPEN_EVT:
5661 bta_dm_proc_open_evt(&p_data->open);
5664 case BTA_GATTC_SEARCH_RES_EVT:
5665 bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid);
5668 case BTA_GATTC_SEARCH_CMPL_EVT:
5669 if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
5670 bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
5674 case BTA_GATTC_CLOSE_EVT:
5675 APPL_TRACE_DEBUG("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason);
5676 /* in case of disconnect before search is completed */
5677 if ( (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) &&
5678 (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) &&
5679 !memcmp(p_data->close.remote_bda, bta_dm_search_cb.peer_bdaddr, BD_ADDR_LEN)) {
5680 bta_dm_gatt_disc_complete((UINT16)BTA_GATT_INVALID_CONN_ID, (tBTA_GATT_STATUS) BTA_GATT_ERROR);
5688 #endif /* #if (GATTC_INCLUDED == TRUE) */
5689 #endif /* BTA_GATT_INCLUDED */
5691 #if BLE_VND_INCLUDED == TRUE
5692 /*******************************************************************************
5694 ** Function bta_dm_ctrl_features_rd_cmpl_cback
5696 ** Description callback to handle controller feature read complete
5700 *******************************************************************************/
5701 static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result)
5703 APPL_TRACE_DEBUG("%s status = %d ", __FUNCTION__, result);
5704 if (result == BTM_SUCCESS) {
5705 if (bta_dm_cb.p_sec_cback) {
5706 bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
5709 APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d", __FUNCTION__, result);
5713 #endif /* BLE_VND_INCLUDED */
5715 #endif /* BLE_INCLUDED */