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);
1565 if ( bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID + 1) ) {
1566 p_sdp_rec = SDP_FindServiceUUIDInDb(bta_dm_search_cb.p_sdp_db, &bta_dm_search_cb.uuid, p_sdp_rec);
1568 if (p_sdp_rec && SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
1569 bta_dm_search_cb.peer_scn = (UINT8) pe.params[0];
1573 service = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1];
1574 p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, service, p_sdp_rec);
1576 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1577 /* finished with BR/EDR services, now we check the result for GATT based service UUID */
1578 if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID) {
1579 if (bta_dm_search_cb.uuid_to_search != 0 && p_uuid != NULL) {
1580 p_uuid += (bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search);
1581 /* only support 16 bits UUID for now */
1582 service = p_uuid->uu.uuid16;
1585 /* all GATT based services */
1587 /* find a service record, report it */
1588 p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db,
1591 if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) {
1592 /* send result back to app now, one by one */
1593 bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1594 BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN));
1595 result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
1596 result.disc_ble_res.service.len = service_uuid.len;
1597 result.disc_ble_res.service.uu.uuid16 = service_uuid.uu.uuid16;
1599 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
1603 if (bta_dm_search_cb.uuid_to_search > 0) {
1607 } while (p_sdp_rec);
1611 /* SDP_DB_FULL means some records with the
1612 required attributes were received */
1613 if (((p_data->sdp_event.sdp_result == SDP_DB_FULL) &&
1614 bta_dm_search_cb.services != BTA_ALL_SERVICE_MASK) ||
1615 (p_sdp_rec != NULL)) {
1616 if (service != UUID_SERVCLASS_PNP_INFORMATION) {
1617 UINT16 tmp_svc = 0xFFFF;
1618 bta_dm_search_cb.services_found |=
1619 (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index - 1));
1620 tmp_svc = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1];
1621 /* Add to the list of UUIDs */
1622 sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]);
1628 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK &&
1629 bta_dm_search_cb.services_to_search == 0) {
1630 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1631 if ( bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID &&
1632 bta_dm_search_cb.uuid_to_search > 0) {
1633 bta_dm_search_cb.uuid_to_search --;
1636 if (bta_dm_search_cb.uuid_to_search == 0 ||
1637 bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID)
1639 bta_dm_search_cb.service_index++;
1640 } else { /* regular one service per search or PNP search */
1644 } while (bta_dm_search_cb.service_index <= BTA_MAX_SERVICE_ID);
1646 // osi_free(bta_dm_search_cb.p_sdp_db);
1647 // bta_dm_search_cb.p_sdp_db = NULL;
1648 APPL_TRACE_DEBUG("%s services_found = %04x", __FUNCTION__,
1649 bta_dm_search_cb.services_found);
1651 /* Collect the 128-bit services here and put them into the list */
1652 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) {
1656 /* find a service record, report it */
1657 p_sdp_rec = SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec);
1659 if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid)) {
1660 memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE);
1664 } while (p_sdp_rec);
1666 /* if there are more services to search for */
1667 if (bta_dm_search_cb.services_to_search) {
1668 /* Free up the p_sdp_db before checking the next one */
1669 bta_dm_free_sdp_db(NULL);
1670 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
1673 /* start next bd_addr if necessary */
1675 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1678 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1679 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1680 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
1681 p_msg->disc_result.result.disc_res.p_raw_data = NULL;
1682 p_msg->disc_result.result.disc_res.raw_data_size = 0;
1683 p_msg->disc_result.result.disc_res.num_uuids = num_uuids;
1684 p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
1685 if (num_uuids > 0) {
1686 p_msg->disc_result.result.disc_res.p_uuid_list = (UINT8 *)osi_malloc(num_uuids * MAX_UUID_SIZE);
1687 if (p_msg->disc_result.result.disc_res.p_uuid_list) {
1688 memcpy(p_msg->disc_result.result.disc_res.p_uuid_list, uuid_list,
1689 num_uuids * MAX_UUID_SIZE);
1691 p_msg->disc_result.result.disc_res.num_uuids = 0;
1692 APPL_TRACE_ERROR("%s: Unable to allocate memory for uuid_list", __func__);
1695 //copy the raw_data to the discovery result structure
1698 if ( bta_dm_search_cb.p_sdp_db != NULL && bta_dm_search_cb.p_sdp_db->raw_used != 0 &&
1699 bta_dm_search_cb.p_sdp_db->raw_data != NULL) {
1701 "%s raw_data used = 0x%x raw_data_ptr = %p", __func__,
1702 bta_dm_search_cb.p_sdp_db->raw_used,
1703 bta_dm_search_cb.p_sdp_db->raw_data);
1705 p_msg->disc_result.result.disc_res.p_raw_data = osi_malloc(bta_dm_search_cb.p_sdp_db->raw_used);
1706 if ( NULL != p_msg->disc_result.result.disc_res.p_raw_data ) {
1707 memcpy( p_msg->disc_result.result.disc_res.p_raw_data,
1708 bta_dm_search_cb.p_sdp_db->raw_data,
1709 bta_dm_search_cb.p_sdp_db->raw_used );
1711 p_msg->disc_result.result.disc_res.raw_data_size =
1712 bta_dm_search_cb.p_sdp_db->raw_used;
1715 APPL_TRACE_DEBUG("%s Alloc failed to allocate %d bytes !!", __func__,
1716 bta_dm_search_cb.p_sdp_db->raw_used);
1719 bta_dm_search_cb.p_sdp_db->raw_data = NULL; //no need to free this - it is a global assigned.
1720 bta_dm_search_cb.p_sdp_db->raw_used = 0;
1721 bta_dm_search_cb.p_sdp_db->raw_size = 0;
1723 APPL_TRACE_DEBUG("%s raw data size is 0 or raw_data is null!!", __func__);
1725 /* Done with p_sdp_db. Free it */
1726 bta_dm_free_sdp_db(NULL);
1727 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
1729 //Piggy back the SCN over result field
1731 p_msg->disc_result.result.disc_res.result = (3 + bta_dm_search_cb.peer_scn);
1732 p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK;
1734 APPL_TRACE_EVENT(" Piggy back the SCN over result field SCN=%d", bta_dm_search_cb.peer_scn);
1737 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1738 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
1739 bta_dm_get_remname(), (BD_NAME_LEN - 1));
1741 /* make sure the string is null terminated */
1742 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
1744 bta_sys_sendmsg(p_msg);
1748 /* conn failed. No need for timer */
1749 if (p_data->sdp_event.sdp_result == SDP_CONN_FAILED || p_data->sdp_event.sdp_result == SDP_CONN_REJECTED
1750 || p_data->sdp_event.sdp_result == SDP_SECURITY_ERR) {
1751 bta_dm_search_cb.wait_disc = FALSE;
1754 /* not able to connect go to next device */
1755 osi_free(bta_dm_search_cb.p_sdp_db);
1756 bta_dm_search_cb.p_sdp_db = NULL;
1758 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1760 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
1761 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1762 p_msg->disc_result.result.disc_res.result = BTA_FAILURE;
1763 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
1764 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1765 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
1766 bta_dm_get_remname(), (BD_NAME_LEN - 1));
1768 /* make sure the string is null terminated */
1769 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
1771 bta_sys_sendmsg(p_msg);
1775 #endif ///SDP_INCLUDE == TRUE
1777 /*******************************************************************************
1779 ** Function bta_dm_search_cmpl
1781 ** Description Sends event to application
1785 *******************************************************************************/
1786 void bta_dm_search_cmpl (tBTA_DM_MSG *p_data)
1788 APPL_TRACE_EVENT("%s", __func__);
1790 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE)
1791 utl_freebuf((void **)&bta_dm_search_cb.p_srvc_uuid);
1794 if (p_data->hdr.layer_specific == BTA_DM_API_DI_DISCOVER_EVT) {
1795 #if (SDP_INCLUDED == TRUE)
1796 bta_dm_di_disc_cmpl(p_data);
1797 #endif ///SDP_INCLUDED == TRUE
1799 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, NULL);
1803 /*******************************************************************************
1805 ** Function bta_dm_disc_result
1807 ** Description Service discovery result when discovering services on a device
1811 *******************************************************************************/
1812 void bta_dm_disc_result (tBTA_DM_MSG *p_data)
1814 APPL_TRACE_EVENT("%s", __func__);
1816 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1817 /* if any BR/EDR service discovery has been done, report the event */
1818 if ((bta_dm_search_cb.services & ((BTA_ALL_SERVICE_MASK | BTA_USER_SERVICE_MASK ) & ~BTA_BLE_SERVICE_MASK)))
1820 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
1822 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
1824 /* send a message to change state */
1825 if (p_msg != NULL) {
1826 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1827 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1828 bta_sys_sendmsg(p_msg);
1832 /*******************************************************************************
1834 ** Function bta_dm_search_result
1836 ** Description Service discovery result while searching for devices
1840 *******************************************************************************/
1841 void bta_dm_search_result (tBTA_DM_MSG *p_data)
1843 APPL_TRACE_DEBUG("%s searching:0x%04x, result:0x%04x", __func__,
1844 bta_dm_search_cb.services,
1845 p_data->disc_result.result.disc_res.services);
1847 /* call back if application wants name discovery or found services that application is searching */
1848 if (( !bta_dm_search_cb.services )
1849 || (( bta_dm_search_cb.services ) && ( p_data->disc_result.result.disc_res.services ))) {
1850 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
1853 /* if searching did not initiate to create link */
1854 if (!bta_dm_search_cb.wait_disc ) {
1855 /* if service searching is done with EIR, don't search next device */
1856 if ( bta_dm_search_cb.p_btm_inq_info ) {
1857 bta_dm_discover_next_device();
1860 /* wait until link is disconnected or timeout */
1861 bta_dm_search_cb.sdp_results = TRUE;
1862 bta_dm_search_cb.search_timer.p_cback = (TIMER_CBACK *)&bta_dm_search_timer_cback;
1863 bta_sys_start_timer(&bta_dm_search_cb.search_timer, 0, 1000 * (L2CAP_LINK_INACTIVITY_TOUT + 1) );
1868 /*******************************************************************************
1870 ** Function bta_dm_search_timer_cback
1872 ** Description Called when ACL disconnect time is over
1877 *******************************************************************************/
1878 static void bta_dm_search_timer_cback (TIMER_LIST_ENT *p_tle)
1882 APPL_TRACE_EVENT("%s", __func__);
1883 bta_dm_search_cb.wait_disc = FALSE;
1885 /* proceed with next device */
1886 bta_dm_discover_next_device();
1891 /*******************************************************************************
1893 ** Function bta_dm_free_sdp_db
1895 ** Description Frees SDP data base
1899 *******************************************************************************/
1900 #if (SDP_INCLUDED == TRUE)
1901 void bta_dm_free_sdp_db (tBTA_DM_MSG *p_data)
1904 if (bta_dm_search_cb.p_sdp_db) {
1905 osi_free(bta_dm_search_cb.p_sdp_db);
1906 bta_dm_search_cb.p_sdp_db = NULL;
1909 #endif ///SDP_INCLUDED == TRUE
1911 /*******************************************************************************
1913 ** Function bta_dm_queue_search
1915 ** Description Queues search command while search is being cancelled
1919 *******************************************************************************/
1920 void bta_dm_queue_search (tBTA_DM_MSG *p_data)
1922 if (bta_dm_search_cb.p_search_queue) {
1923 osi_free(bta_dm_search_cb.p_search_queue);
1926 bta_dm_search_cb.p_search_queue = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_SEARCH));
1927 memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_SEARCH));
1931 /*******************************************************************************
1933 ** Function bta_dm_queue_disc
1935 ** Description Queues discovery command while search is being cancelled
1939 *******************************************************************************/
1940 #if (SDP_INCLUDED == TRUE)
1941 void bta_dm_queue_disc (tBTA_DM_MSG *p_data)
1943 if (bta_dm_search_cb.p_search_queue) {
1944 osi_free(bta_dm_search_cb.p_search_queue);
1947 bta_dm_search_cb.p_search_queue = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_DISCOVER));
1948 memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_DISCOVER));
1950 #endif ///SDP_INCLUDED == TRUE
1952 /*******************************************************************************
1954 ** Function bta_dm_search_clear_queue
1956 ** Description Clears the queue if API search cancel is called
1960 *******************************************************************************/
1961 void bta_dm_search_clear_queue (tBTA_DM_MSG *p_data)
1964 if (bta_dm_search_cb.p_search_queue) {
1965 osi_free(bta_dm_search_cb.p_search_queue);
1966 bta_dm_search_cb.p_search_queue = NULL;
1970 /*******************************************************************************
1972 ** Function bta_dm_search_cancel_cmpl
1974 ** Description Search cancel is complete
1978 *******************************************************************************/
1979 void bta_dm_search_cancel_cmpl (tBTA_DM_MSG *p_data)
1982 if (bta_dm_search_cb.p_search_queue) {
1983 bta_sys_sendmsg(bta_dm_search_cb.p_search_queue);
1984 bta_dm_search_cb.p_search_queue = NULL;
1989 /*******************************************************************************
1991 ** Function bta_dm_search_cancel_transac_cmpl
1993 ** Description Current Service Discovery or remote name procedure is
1994 ** completed after search cancellation
1998 *******************************************************************************/
1999 #if (SDP_INCLUDED == TRUE)
2000 void bta_dm_search_cancel_transac_cmpl(tBTA_DM_MSG *p_data)
2003 if (bta_dm_search_cb.p_sdp_db) {
2004 osi_free(bta_dm_search_cb.p_sdp_db);
2005 bta_dm_search_cb.p_sdp_db = NULL;
2008 bta_dm_search_cancel_notify(NULL);
2010 #endif ///SDP_INCLUDED == TRUE
2013 /*******************************************************************************
2015 ** Function bta_dm_search_cancel_notify
2017 ** Description Notify application that search has been cancelled
2021 *******************************************************************************/
2022 void bta_dm_search_cancel_notify (tBTA_DM_MSG *p_data)
2025 if (bta_dm_search_cb.p_search_cback) {
2026 bta_dm_search_cb.p_search_cback(BTA_DM_SEARCH_CANCEL_CMPL_EVT, NULL);
2028 if (!bta_dm_search_cb.name_discover_done) {
2029 BTM_CancelRemoteDeviceName();
2031 #if (BLE_INCLUDED == TRUE) && (BTA_GATT_INCLUDED == TRUE) && (SDP_INCLUDED == TRUE) && (GATTC_INCLUDED) == TRUE
2032 if (bta_dm_search_cb.gatt_disc_active) {
2033 bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
2039 /*******************************************************************************
2041 ** Function bta_dm_find_services
2043 ** Description Starts discovery on a device
2047 *******************************************************************************/
2048 #if (SDP_INCLUDED == TRUE)
2049 static void bta_dm_find_services ( BD_ADDR bd_addr)
2054 memset (&uuid, 0, sizeof(tSDP_UUID));
2056 while (bta_dm_search_cb.service_index < BTA_MAX_SERVICE_ID) {
2057 if ( bta_dm_search_cb.services_to_search
2058 & (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index))) {
2059 if ((bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(BTA_DM_SDP_DB_SIZE)) != NULL) {
2060 APPL_TRACE_DEBUG("bta_dm_search_cb.services = %04x***********", bta_dm_search_cb.services);
2061 /* try to search all services by search based on L2CAP UUID */
2062 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK ) {
2063 LOG_INFO("%s services_to_search=%08x", __func__, bta_dm_search_cb.services_to_search);
2064 if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK) {
2065 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[0];
2066 bta_dm_search_cb.services_to_search &= ~BTA_RES_SERVICE_MASK;
2068 uuid.uu.uuid16 = UUID_PROTOCOL_L2CAP;
2069 bta_dm_search_cb.services_to_search = 0;
2072 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
2073 /* for LE only profile */
2074 if (bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID) {
2075 if (bta_dm_search_cb.uuid_to_search > 0 && bta_dm_search_cb.p_srvc_uuid) {
2077 (const void *)(bta_dm_search_cb.p_srvc_uuid + \
2078 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search),
2081 bta_dm_search_cb.uuid_to_search -- ;
2083 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index];
2086 /* last one? clear the BLE service bit if all discovery has been done */
2087 if (bta_dm_search_cb.uuid_to_search == 0)
2088 bta_dm_search_cb.services_to_search &=
2089 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
2094 /* remove the service from services to be searched */
2095 bta_dm_search_cb.services_to_search &=
2096 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
2097 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index];
2101 if (uuid.len == 0) {
2102 uuid.len = LEN_UUID_16;
2105 if (bta_dm_search_cb.service_index == BTA_USER_SERVICE_ID) {
2106 memcpy(&uuid, &bta_dm_search_cb.uuid, sizeof(tSDP_UUID));
2109 LOG_INFO("%s search UUID = %04x", __func__, uuid.uu.uuid16);
2110 SDP_InitDiscoveryDb (bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1, &uuid, 0, NULL);
2112 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
2113 bta_dm_search_cb.p_sdp_db->raw_data = g_disc_raw_data_buf;
2115 bta_dm_search_cb.p_sdp_db->raw_size = MAX_DISC_RAW_DATA_BUF;
2117 if (!SDP_ServiceSearchAttributeRequest (bd_addr, bta_dm_search_cb.p_sdp_db, &bta_dm_sdp_callback)) {
2118 /* if discovery not successful with this device
2119 proceed to next one */
2120 osi_free(bta_dm_search_cb.p_sdp_db);
2121 bta_dm_search_cb.p_sdp_db = NULL;
2122 bta_dm_search_cb.service_index = BTA_MAX_SERVICE_ID;
2125 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
2126 if ((bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID &&
2127 bta_dm_search_cb.uuid_to_search == 0) ||
2128 bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID)
2130 bta_dm_search_cb.service_index++;
2134 APPL_TRACE_ERROR("#### Failed to allocate SDP DB buffer! ####");
2138 bta_dm_search_cb.service_index++;
2141 /* no more services to be discovered */
2142 if (bta_dm_search_cb.service_index >= BTA_MAX_SERVICE_ID) {
2143 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
2144 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
2145 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
2146 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2147 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
2148 bta_dm_get_remname(), (BD_NAME_LEN - 1));
2150 /* make sure the string is terminated */
2151 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
2153 bta_sys_sendmsg(p_msg);
2157 #endif ///SDP_INCLUDED == TRUE
2159 /*******************************************************************************
2161 ** Function bta_dm_discover_next_device
2163 ** Description Starts discovery on the next device in Inquiry data base
2167 *******************************************************************************/
2168 static void bta_dm_discover_next_device(void)
2173 APPL_TRACE_DEBUG("bta_dm_discover_next_device");
2175 /* searching next device on inquiry result */
2176 if ((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbNext(bta_dm_search_cb.p_btm_inq_info)) != NULL) {
2177 bta_dm_search_cb.name_discover_done = FALSE;
2178 bta_dm_search_cb.peer_name[0] = 0;
2179 #if (SDP_INCLUDED == TRUE)
2180 bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
2181 #endif ///SDP_INCLUDED == TRUE
2183 /* no devices, search complete */
2184 bta_dm_search_cb.services = 0;
2186 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
2187 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
2188 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
2189 bta_sys_sendmsg(p_msg);
2194 /*******************************************************************************
2196 ** Function bta_dm_discover_device
2198 ** Description Starts name and service discovery on the device
2202 *******************************************************************************/
2203 #if (SDP_INCLUDED == TRUE)
2204 static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
2207 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
2209 #if BLE_INCLUDED == TRUE
2210 if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN) {
2211 tBT_DEVICE_TYPE dev_type;
2212 tBLE_ADDR_TYPE addr_type;
2214 BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
2215 if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM) {
2216 transport = BT_TRANSPORT_LE;
2219 transport = bta_dm_search_cb.transport;
2223 /* Reset transport state for next discovery */
2224 bta_dm_search_cb.transport = BTA_TRANSPORT_UNKNOWN;
2226 APPL_TRACE_DEBUG("%s BDA:0x%02X%02X%02X%02X%02X%02X", __func__,
2227 remote_bd_addr[0], remote_bd_addr[1],
2228 remote_bd_addr[2], remote_bd_addr[3],
2229 remote_bd_addr[4], remote_bd_addr[5]);
2231 bdcpy(bta_dm_search_cb.peer_bdaddr, remote_bd_addr);
2233 APPL_TRACE_DEBUG("%s name_discover_done = %d p_btm_inq_info %p state = %d, transport=%d",
2235 bta_dm_search_cb.name_discover_done,
2236 bta_dm_search_cb.p_btm_inq_info,
2237 bta_dm_search_cb.state,
2240 if (bta_dm_search_cb.p_btm_inq_info) {
2241 APPL_TRACE_DEBUG("%s appl_knows_rem_name %d", __func__,
2242 bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name);
2245 if ((bta_dm_search_cb.p_btm_inq_info)
2246 && (bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE)
2247 && (bta_dm_search_cb.state == BTA_DM_SEARCH_ACTIVE)) {
2248 /* Do not perform RNR for LE devices at inquiry complete*/
2249 bta_dm_search_cb.name_discover_done = TRUE;
2252 /* if name discovery is not done and application needs remote name */
2253 if ((!bta_dm_search_cb.name_discover_done)
2254 && (( bta_dm_search_cb.p_btm_inq_info == NULL )
2255 || (bta_dm_search_cb.p_btm_inq_info && (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name)))) {
2256 if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport) == TRUE) {
2260 /* starting name discovery failed */
2261 bta_dm_search_cb.name_discover_done = TRUE;
2264 /* if application wants to discover service */
2265 if ( bta_dm_search_cb.services ) {
2266 /* initialize variables */
2267 bta_dm_search_cb.service_index = 0;
2268 bta_dm_search_cb.services_found = 0;
2269 bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
2270 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && SDP_INCLUDED == TRUE
2271 bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid;
2273 if ((bta_dm_search_cb.p_btm_inq_info != NULL) &&
2274 bta_dm_search_cb.services != BTA_USER_SERVICE_MASK
2275 && (bta_dm_search_cb.sdp_search == FALSE)) {
2276 /* check if EIR provides the information of supported services */
2277 bta_dm_eir_search_services( &bta_dm_search_cb.p_btm_inq_info->results,
2278 &bta_dm_search_cb.services_to_search,
2279 &bta_dm_search_cb.services_found );
2282 /* if seaching with EIR is not completed */
2283 if (bta_dm_search_cb.services_to_search) {
2284 /* check whether connection already exists to the device
2285 if connection exists, we don't have to wait for ACL
2286 link to go down to start search on next device */
2287 if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR)) {
2288 bta_dm_search_cb.wait_disc = FALSE;
2290 bta_dm_search_cb.wait_disc = TRUE;
2293 #if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE) && (GATTC_INCLUDED == TRUE)
2294 if ( bta_dm_search_cb.p_btm_inq_info ) {
2295 APPL_TRACE_DEBUG("%s p_btm_inq_info %p results.device_type 0x%x services_to_search 0x%x",
2297 bta_dm_search_cb.p_btm_inq_info,
2298 bta_dm_search_cb.p_btm_inq_info->results.device_type,
2299 bta_dm_search_cb.services_to_search);
2302 if (transport == BT_TRANSPORT_LE) {
2303 if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK) {
2304 //set the raw data buffer here
2305 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
2306 bta_dm_search_cb.p_ble_rawdata = g_disc_raw_data_buf;
2308 bta_dm_search_cb.ble_raw_size = MAX_DISC_RAW_DATA_BUF;
2309 bta_dm_search_cb.ble_raw_used = 0;
2311 /* start GATT for service discovery */
2312 btm_dm_start_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
2318 bta_dm_search_cb.sdp_results = FALSE;
2319 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
2325 /* name discovery and service discovery are done for this device */
2326 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
2327 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
2328 /* initialize the data structure - includes p_raw_data and raw_data_size */
2329 memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES));
2330 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
2331 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
2332 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2333 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
2334 (char *)bta_dm_search_cb.peer_name, (BD_NAME_LEN - 1));
2336 /* make sure the string is terminated */
2337 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
2339 bta_sys_sendmsg(p_msg);
2343 /*******************************************************************************
2345 ** Function bta_dm_sdp_callback
2347 ** Description Callback from sdp with discovery status
2351 *******************************************************************************/
2352 static void bta_dm_sdp_callback (UINT16 sdp_status)
2355 tBTA_DM_SDP_RESULT *p_msg;
2357 if ((p_msg = (tBTA_DM_SDP_RESULT *) osi_malloc(sizeof(tBTA_DM_SDP_RESULT))) != NULL) {
2358 p_msg->hdr.event = BTA_DM_SDP_RESULT_EVT;
2359 p_msg->sdp_result = sdp_status;
2360 bta_sys_sendmsg(p_msg);
2364 #endif ///SDP_INCLUDED == TRUE
2365 /*******************************************************************************
2367 ** Function bta_dm_inq_results_cb
2369 ** Description Inquiry results callback from BTM
2373 *******************************************************************************/
2374 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
2377 tBTA_DM_SEARCH result;
2378 tBTM_INQ_INFO *p_inq_info;
2379 UINT16 service_class;
2381 bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
2382 memcpy(result.inq_res.dev_class, p_inq->dev_class, DEV_CLASS_LEN);
2383 BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class);
2384 result.inq_res.is_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? TRUE : FALSE;
2385 result.inq_res.rssi = p_inq->rssi;
2387 #if (BLE_INCLUDED == TRUE)
2388 result.inq_res.ble_addr_type = p_inq->ble_addr_type;
2389 result.inq_res.inq_result_type = p_inq->inq_result_type;
2390 result.inq_res.device_type = p_inq->device_type;
2391 result.inq_res.flag = p_inq->flag;
2394 /* application will parse EIR to find out remote device name */
2395 result.inq_res.p_eir = p_eir;
2397 if ((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL) {
2398 /* initialize remt_name_not_required to FALSE so that we get the name by default */
2399 result.inq_res.remt_name_not_required = FALSE;
2403 if (bta_dm_search_cb.p_search_cback) {
2404 bta_dm_search_cb.p_search_cback(BTA_DM_INQ_RES_EVT, &result);
2408 /* application indicates if it knows the remote name, inside the callback
2409 copy that to the inquiry data base*/
2410 if (result.inq_res.remt_name_not_required) {
2411 p_inq_info->appl_knows_rem_name = TRUE;
2420 /*******************************************************************************
2422 ** Function bta_dm_inq_cmpl_cb
2424 ** Description Inquiry complete callback from BTM
2428 *******************************************************************************/
2429 static void bta_dm_inq_cmpl_cb (void *p_result)
2433 if (bta_dm_search_cb.cancel_pending == FALSE) {
2434 APPL_TRACE_DEBUG("%s", __FUNCTION__);
2435 p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
2436 if (p_msg != NULL) {
2437 p_msg->inq_cmpl.hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
2438 p_msg->inq_cmpl.num = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
2439 bta_sys_sendmsg(p_msg);
2442 bta_dm_search_cb.cancel_pending = FALSE;
2443 bta_dm_search_cancel_notify(NULL);
2445 p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG));
2446 if (p_msg != NULL) {
2447 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
2448 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
2449 bta_sys_sendmsg(p_msg);
2454 /*******************************************************************************
2456 ** Function bta_dm_service_search_remname_cback
2458 ** Description Remote name call back from BTM during service discovery
2462 *******************************************************************************/
2463 static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, BD_NAME bd_name)
2465 tBTM_REMOTE_DEV_NAME rem_name;
2466 tBTM_STATUS btm_status;
2469 APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback name=<%s>", bd_name);
2471 /* if this is what we are looking for */
2472 if (!bdcmp( bta_dm_search_cb.peer_bdaddr, bd_addr)) {
2473 rem_name.length = strlen((char *)bd_name);
2474 if (rem_name.length > (BD_NAME_LEN - 1)) {
2475 rem_name.length = (BD_NAME_LEN - 1);
2476 rem_name.remote_bd_name[(BD_NAME_LEN - 1)] = 0;
2478 BCM_STRNCPY_S((char *)rem_name.remote_bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
2479 rem_name.status = BTM_SUCCESS;
2481 bta_dm_remname_cback(&rem_name);
2483 /* get name of device */
2484 btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
2485 (tBTM_CMPL_CB *) bta_dm_remname_cback,
2486 BT_TRANSPORT_BR_EDR);
2487 if ( btm_status == BTM_BUSY ) {
2488 /* wait for next chance(notification of remote name discovery done) */
2489 APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName is busy");
2490 } else if ( btm_status != BTM_CMD_STARTED ) {
2491 /* if failed to start getting remote name then continue */
2492 APPL_TRACE_WARNING("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
2494 rem_name.length = 0;
2495 rem_name.remote_bd_name[0] = 0;
2496 rem_name.status = btm_status;
2497 bta_dm_remname_cback(&rem_name);
2503 /*******************************************************************************
2505 ** Function bta_dm_remname_cback
2507 ** Description Remote name complete call back from BTM
2511 *******************************************************************************/
2512 static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
2514 tBTA_DM_REM_NAME *p_msg;
2516 APPL_TRACE_DEBUG("bta_dm_remname_cback len = %d name=<%s>", p_remote_name->length,
2517 p_remote_name->remote_bd_name);
2519 /* remote name discovery is done but it could be failed */
2520 bta_dm_search_cb.name_discover_done = TRUE;
2521 BCM_STRNCPY_S((char *)bta_dm_search_cb.peer_name, sizeof(BD_NAME), (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
2522 bta_dm_search_cb.peer_name[BD_NAME_LEN] = 0;
2524 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
2526 #if BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE
2527 if (bta_dm_search_cb.transport == BT_TRANSPORT_LE ) {
2528 GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
2532 if ((p_msg = (tBTA_DM_REM_NAME *) osi_malloc(sizeof(tBTA_DM_REM_NAME))) != NULL) {
2533 bdcpy (p_msg->result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2534 BCM_STRNCPY_S((char *)p_msg->result.disc_res.bd_name, sizeof(BD_NAME), (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
2536 /* make sure the string is null terminated */
2537 p_msg->result.disc_res.bd_name[BD_NAME_LEN] = 0;
2539 p_msg->hdr.event = BTA_DM_REMT_NAME_EVT;
2540 bta_sys_sendmsg(p_msg);
2545 /*******************************************************************************
2547 ** Function bta_dm_authorize_cback
2549 ** Description cback requesting authorization
2553 *******************************************************************************/
2554 #if (SMP_INCLUDED == TRUE)
2555 static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
2556 UINT8 *service_name, UINT8 service_id, BOOLEAN is_originator)
2558 tBTA_DM_SEC sec_event;
2560 UNUSED(service_name);
2561 UNUSED(is_originator);
2563 bdcpy(sec_event.authorize.bd_addr, bd_addr);
2564 memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN);
2566 BCM_STRNCPY_S((char *)sec_event.authorize.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
2568 /* make sure the string is null terminated */
2569 sec_event.authorize.bd_name[BD_NAME_LEN - 1] = 0;
2571 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
2572 sec_event.authorize.service = service_id;
2575 while (index < BTA_MAX_SERVICE_ID) {
2576 /* get the BTA service id corresponding to BTM id */
2577 if (bta_service_id_to_btm_srv_id_lkup_tbl[index] == service_id) {
2578 sec_event.authorize.service = index;
2585 /* if supported service callback otherwise not authorized */
2586 if (bta_dm_cb.p_sec_cback && (index < BTA_MAX_SERVICE_ID
2587 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
2588 /* pass through JV service ID */
2589 || (service_id >= BTA_FIRST_JV_SERVICE_ID && service_id <= BTA_LAST_JV_SERVICE_ID)
2592 bta_dm_cb.p_sec_cback(BTA_DM_AUTHORIZE_EVT, &sec_event);
2593 return BTM_CMD_STARTED;
2595 return BTM_NOT_AUTHORIZED;
2602 /*******************************************************************************
2604 ** Function bta_dm_pinname_cback
2606 ** Description Callback requesting pin_key
2610 *******************************************************************************/
2611 static void bta_dm_pinname_cback (void *p_data)
2613 tBTM_REMOTE_DEV_NAME *p_result = (tBTM_REMOTE_DEV_NAME *)p_data;
2614 tBTA_DM_SEC sec_event;
2615 UINT32 bytes_to_copy;
2616 tBTA_DM_SEC_EVT event = bta_dm_cb.pin_evt;
2618 if (BTA_DM_SP_CFM_REQ_EVT == event) {
2619 /* Retrieved saved device class and bd_addr */
2620 bdcpy(sec_event.cfm_req.bd_addr, bta_dm_cb.pin_bd_addr);
2621 BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_cb.pin_dev_class);
2623 if (p_result && p_result->status == BTM_SUCCESS) {
2624 bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1))
2625 ? p_result->length : (BD_NAME_LEN - 1);
2626 memcpy(sec_event.cfm_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
2627 sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2628 } else { /* No name found */
2629 sec_event.cfm_req.bd_name[0] = 0;
2632 sec_event.key_notif.passkey = bta_dm_cb.num_val; /* get PIN code numeric number */
2634 /* 1 additional event data fields for this event */
2635 sec_event.cfm_req.just_works = bta_dm_cb.just_works;
2637 /* Retrieved saved device class and bd_addr */
2638 bdcpy(sec_event.pin_req.bd_addr, bta_dm_cb.pin_bd_addr);
2639 BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_cb.pin_dev_class);
2641 if (p_result && p_result->status == BTM_SUCCESS) {
2642 bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1))
2643 ? p_result->length : (BD_NAME_LEN - 1);
2644 memcpy(sec_event.pin_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
2645 sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2646 } else { /* No name found */
2647 sec_event.pin_req.bd_name[0] = 0;
2650 event = bta_dm_cb.pin_evt;
2651 sec_event.key_notif.passkey = bta_dm_cb.num_val; /* get PIN code numeric number */
2654 if ( bta_dm_cb.p_sec_cback ) {
2655 bta_dm_cb.p_sec_cback(event, &sec_event);
2659 /*******************************************************************************
2661 ** Function bta_dm_pin_cback
2663 ** Description Callback requesting pin_key
2667 *******************************************************************************/
2668 static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
2669 BOOLEAN min_16_digit)
2671 tBTA_DM_SEC sec_event;
2673 if (!bta_dm_cb.p_sec_cback) {
2674 return BTM_NOT_AUTHORIZED;
2677 /* If the device name is not known, save bdaddr and devclass and initiate a name request */
2678 if (bd_name[0] == 0) {
2679 bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
2680 bdcpy(bta_dm_cb.pin_bd_addr, bd_addr);
2681 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
2682 if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2683 return BTM_CMD_STARTED;
2686 APPL_TRACE_WARNING(" bta_dm_pin_cback() -> Failed to start Remote Name Request ");
2689 bdcpy(sec_event.pin_req.bd_addr, bd_addr);
2690 BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
2691 BCM_STRNCPY_S((char *)sec_event.pin_req.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
2692 sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
2693 sec_event.pin_req.min_16_digit = min_16_digit;
2695 bta_dm_cb.p_sec_cback(BTA_DM_PIN_REQ_EVT, &sec_event);
2696 return BTM_CMD_STARTED;
2699 /*******************************************************************************
2701 ** Function bta_dm_new_link_key_cback
2703 ** Description Callback from BTM to notify new link key
2707 *******************************************************************************/
2708 static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
2709 BD_NAME bd_name, LINK_KEY key, UINT8 key_type)
2711 tBTA_DM_SEC sec_event;
2712 tBTA_DM_AUTH_CMPL *p_auth_cmpl;
2716 memset (&sec_event, 0, sizeof(tBTA_DM_SEC));
2718 /* Not AMP Key type */
2719 if (key_type != HCI_LKEY_TYPE_AMP_WIFI && key_type != HCI_LKEY_TYPE_AMP_UWB) {
2720 event = BTA_DM_AUTH_CMPL_EVT;
2721 p_auth_cmpl = &sec_event.auth_cmpl;
2723 bdcpy(p_auth_cmpl->bd_addr, bd_addr);
2725 memcpy(p_auth_cmpl->bd_name, bd_name, (BD_NAME_LEN - 1));
2726 p_auth_cmpl->bd_name[BD_NAME_LEN - 1] = 0;
2728 p_auth_cmpl->key_present = TRUE;
2729 p_auth_cmpl->key_type = key_type;
2730 p_auth_cmpl->success = TRUE;
2732 memcpy(p_auth_cmpl->key, key, LINK_KEY_LEN);
2733 sec_event.auth_cmpl.fail_reason = HCI_SUCCESS;
2735 #if BLE_INCLUDED == TRUE
2736 // Report the BR link key based on the BR/EDR address and type
2737 BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
2739 if (bta_dm_cb.p_sec_cback) {
2740 bta_dm_cb.p_sec_cback(event, &sec_event);
2743 APPL_TRACE_WARNING("%s() Received AMP Key", __func__);
2746 return BTM_CMD_STARTED;
2750 /*******************************************************************************
2752 ** Function bta_dm_authentication_complete_cback
2754 ** Description Authentication complete callback from BTM
2758 *******************************************************************************/
2759 static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, int result)
2761 tBTA_DM_SEC sec_event;
2764 if (result != BTM_SUCCESS) {
2765 memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
2766 bdcpy(sec_event.auth_cmpl.bd_addr, bd_addr);
2768 memcpy(sec_event.auth_cmpl.bd_name, bd_name, (BD_NAME_LEN - 1));
2769 sec_event.auth_cmpl.bd_name[BD_NAME_LEN - 1] = 0;
2771 #if BLE_INCLUDED == TRUE
2772 // Report the BR link key based on the BR/EDR address and type
2773 BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
2775 sec_event.auth_cmpl.fail_reason = (UINT8)result;
2777 if (bta_dm_cb.p_sec_cback) {
2778 bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
2781 bta_dm_remove_sec_dev_entry(bd_addr);
2787 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2788 /*******************************************************************************
2790 ** Function bta_dm_sp_cback
2792 ** Description simple pairing callback from BTM
2796 *******************************************************************************/
2797 static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
2799 tBTM_STATUS status = BTM_CMD_STARTED;
2800 tBTA_DM_SEC sec_event;
2801 tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT;
2803 APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event);
2804 if (!bta_dm_cb.p_sec_cback) {
2805 return BTM_NOT_AUTHORIZED;
2810 case BTM_SP_IO_REQ_EVT:
2811 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2812 /* translate auth_req */
2813 bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap,
2814 &p_data->io_req.oob_data, &p_data->io_req.auth_req, p_data->io_req.is_orig);
2816 #if BTM_OOB_INCLUDED == FALSE
2817 status = BTM_SUCCESS;
2820 APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
2822 case BTM_SP_IO_RSP_EVT:
2823 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2824 bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap,
2825 p_data->io_rsp.oob_data, p_data->io_rsp.auth_req );
2829 case BTM_SP_CFM_REQ_EVT:
2830 pin_evt = BTA_DM_SP_CFM_REQ_EVT;
2831 bta_dm_cb.just_works = sec_event.cfm_req.just_works = p_data->cfm_req.just_works;
2832 sec_event.cfm_req.loc_auth_req = p_data->cfm_req.loc_auth_req;
2833 sec_event.cfm_req.rmt_auth_req = p_data->cfm_req.rmt_auth_req;
2834 sec_event.cfm_req.loc_io_caps = p_data->cfm_req.loc_io_caps;
2835 sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps;
2837 /* continue to next case */
2838 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2839 /* Passkey entry mode, mobile device with output capability is very
2840 unlikely to receive key request, so skip this event */
2841 /*case BTM_SP_KEY_REQ_EVT: */
2842 case BTM_SP_KEY_NOTIF_EVT:
2844 if (BTM_SP_CFM_REQ_EVT == event) {
2845 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
2846 call remote name request using values from cfm_req */
2847 if (p_data->cfm_req.bd_name[0] == 0) {
2848 bta_dm_cb.pin_evt = pin_evt;
2849 bdcpy(bta_dm_cb.pin_bd_addr, p_data->cfm_req.bd_addr);
2850 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class);
2851 if ((BTM_ReadRemoteDeviceName(p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
2852 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2853 return BTM_CMD_STARTED;
2855 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
2857 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
2858 copy these values into key_notif from cfm_req */
2859 bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
2860 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class);
2861 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
2862 (char *)p_data->cfm_req.bd_name, (BD_NAME_LEN - 1));
2863 sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
2867 bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
2868 if (BTM_SP_KEY_NOTIF_EVT == event) {
2869 /* If the device name is not known, save bdaddr and devclass
2870 and initiate a name request with values from key_notif */
2871 if (p_data->key_notif.bd_name[0] == 0) {
2872 bta_dm_cb.pin_evt = pin_evt;
2873 bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
2874 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
2875 if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback,
2876 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2877 return BTM_CMD_STARTED;
2879 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
2881 bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
2882 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
2883 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
2884 (char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
2885 sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
2889 bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
2893 #if BTM_OOB_INCLUDED == TRUE
2894 case BTM_SP_LOC_OOB_EVT:
2895 bta_dm_co_loc_oob((BOOLEAN)(p_data->loc_oob.status == BTM_SUCCESS),
2896 p_data->loc_oob.c, p_data->loc_oob.r);
2899 case BTM_SP_RMT_OOB_EVT:
2900 /* If the device name is not known, save bdaddr and devclass and initiate a name request */
2901 if (p_data->rmt_oob.bd_name[0] == 0) {
2902 bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
2903 bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
2904 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class);
2905 if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback,
2906 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) {
2907 return BTM_CMD_STARTED;
2909 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
2912 bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
2913 BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
2914 BCM_STRNCPY_S((char *)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char *)p_data->rmt_oob.bd_name, (BD_NAME_LEN - 1));
2915 sec_event.rmt_oob.bd_name[BD_NAME_LEN - 1] = 0;
2917 bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
2919 bta_dm_co_rmt_oob(p_data->rmt_oob.bd_addr);
2922 case BTM_SP_COMPLT_EVT:
2923 /* do not report this event - handled by link_key_callback or auth_complete_callback */
2926 case BTM_SP_KEYPRESS_EVT:
2927 memcpy(&sec_event.key_press, &p_data->key_press, sizeof(tBTM_SP_KEYPRESS));
2928 bta_dm_cb.p_sec_cback(BTA_DM_SP_KEYPRESS_EVT, &sec_event);
2931 case BTM_SP_UPGRADE_EVT:
2932 bta_dm_co_lk_upgrade(p_data->upgrade.bd_addr, &p_data->upgrade.upgrade );
2936 status = BTM_NOT_AUTHORIZED;
2939 APPL_TRACE_EVENT("dm status: %d", status);
2942 #endif /* (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) */
2944 #endif ///SMP_INCLUDED == TRUE
2947 /*******************************************************************************
2949 ** Function bta_dm_local_name_cback
2951 ** Description Callback from btm after local name is read
2956 *******************************************************************************/
2957 static void bta_dm_local_name_cback(UINT8 *p_name)
2959 tBTA_DM_SEC sec_event;
2962 sec_event.enable.status = BTA_SUCCESS;
2964 if (bta_dm_cb.p_sec_cback) {
2965 bta_dm_cb.p_sec_cback(BTA_DM_ENABLE_EVT, &sec_event);
2970 /*******************************************************************************
2972 ** Function bta_dm_bl_change_cback
2974 ** Description Callback from btm when acl connection goes up or down
2979 *******************************************************************************/
2980 static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
2982 tBTA_DM_ACL_CHANGE *p_msg;
2984 if ((p_msg = (tBTA_DM_ACL_CHANGE *) osi_malloc(sizeof(tBTA_DM_ACL_CHANGE))) != NULL) {
2985 p_msg->event = p_data->event;
2986 p_msg->is_new = FALSE;
2988 switch (p_msg->event) {
2989 case BTM_BL_CONN_EVT:
2990 p_msg->is_new = TRUE;
2991 bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
2992 #if BLE_INCLUDED == TRUE
2993 p_msg->transport = p_data->conn.transport;
2994 p_msg->handle = p_data->conn.handle;
2997 case BTM_BL_DISCN_EVT:
2998 bdcpy(p_msg->bd_addr, p_data->discn.p_bda);
2999 #if BLE_INCLUDED == TRUE
3000 p_msg->transport = p_data->discn.transport;
3001 p_msg->handle = p_data->discn.handle;
3004 case BTM_BL_UPDATE_EVT:
3005 p_msg->busy_level = p_data->update.busy_level;
3006 p_msg->busy_level_flags = p_data->update.busy_level_flags;
3008 case BTM_BL_ROLE_CHG_EVT:
3009 p_msg->new_role = p_data->role_chg.new_role;
3010 p_msg->hci_status = p_data->role_chg.hci_status;
3011 bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda);
3013 case BTM_BL_COLLISION_EVT:
3014 bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
3018 p_msg->hdr.event = BTA_DM_ACL_CHANGE_EVT;
3019 bta_sys_sendmsg(p_msg);
3025 /*******************************************************************************
3027 ** Function bta_dm_rs_cback
3029 ** Description Receives the role switch complete event
3033 *******************************************************************************/
3034 static void bta_dm_rs_cback (tBTM_ROLE_SWITCH_CMPL *p1)
3037 APPL_TRACE_WARNING("bta_dm_rs_cback:%d", bta_dm_cb.rs_event);
3038 if (bta_dm_cb.rs_event == BTA_DM_API_SEARCH_EVT) {
3039 bta_dm_cb.search_msg.rs_res = BTA_DM_RS_OK; /* do not care about the result for now */
3040 bta_dm_cb.rs_event = 0;
3041 bta_dm_search_start((tBTA_DM_MSG *)&bta_dm_cb.search_msg);
3045 /*******************************************************************************
3047 ** Function bta_dm_check_av
3049 ** Description This function checks if AV is active
3050 ** if yes, make sure the AV link is master
3052 ** Returns BOOLEAN - TRUE, if switch is in progress
3054 *******************************************************************************/
3055 static BOOLEAN bta_dm_check_av(UINT16 event)
3057 BOOLEAN avoid_roleswitch = FALSE;
3058 BOOLEAN switching = FALSE;
3060 tBTA_DM_PEER_DEVICE *p_dev;
3062 #if defined(BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY) && (BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY == TRUE)
3064 /* avoid role switch upon inquiry if a2dp is actively streaming as it
3065 introduces an audioglitch due to FW scheduling delays (unavoidable) */
3066 if (event == BTA_DM_API_SEARCH_EVT) {
3067 avoid_roleswitch = TRUE;
3071 APPL_TRACE_WARNING("bta_dm_check_av:%d", bta_dm_cb.cur_av_count);
3072 if (bta_dm_cb.cur_av_count) {
3073 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3074 p_dev = &bta_dm_cb.device_list.peer_device[i];
3075 APPL_TRACE_WARNING("[%d]: state:%d, info:x%x, avoid_rs %d",
3076 i, p_dev->conn_state, p_dev->info, avoid_roleswitch);
3077 if ((p_dev->conn_state == BTA_DM_CONNECTED) && (p_dev->info & BTA_DM_DI_AV_ACTIVE) &&
3078 (avoid_roleswitch == FALSE)) {
3079 /* make master and take away the role switch policy */
3080 if (BTM_CMD_STARTED == BTM_SwitchRole (p_dev->peer_bdaddr, HCI_ROLE_MASTER, (tBTM_CMPL_CB *)bta_dm_rs_cback)) {
3081 /* the role switch command is actually sent */
3082 bta_dm_cb.rs_event = event;
3085 /* else either already master or can not switch for some reasons */
3086 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr);
3094 /*******************************************************************************
3096 ** Function bta_dm_acl_change
3098 ** Description Process BTA_DM_ACL_CHANGE_EVT
3103 *******************************************************************************/
3104 void bta_dm_acl_change(tBTA_DM_MSG *p_data)
3110 BOOLEAN is_new = p_data->acl_change.is_new;
3111 BD_ADDR_PTR p_bda = p_data->acl_change.bd_addr;
3112 BOOLEAN need_policy_change = FALSE;
3113 BOOLEAN issue_unpair_cb = FALSE;
3115 tBTA_DM_PEER_DEVICE *p_dev;
3116 memset(&conn, 0, sizeof(tBTA_DM_SEC));
3118 switch (p_data->acl_change.event) {
3119 case BTM_BL_UPDATE_EVT: /* busy level update */
3120 if ( bta_dm_cb.p_sec_cback ) {
3121 conn.busy_level.level = p_data->acl_change.busy_level;
3122 conn.busy_level.level_flags = p_data->acl_change.busy_level_flags;
3123 bta_dm_cb.p_sec_cback(BTA_DM_BUSY_LEVEL_EVT, &conn);
3127 case BTM_BL_ROLE_CHG_EVT: /* role change event */
3128 p_dev = bta_dm_find_peer_device(p_bda);
3130 APPL_TRACE_DEBUG("bta_dm_acl_change role chg info:x%x new_role:%d dev count:%d",
3131 p_dev->info, p_data->acl_change.new_role, bta_dm_cb.device_list.count);
3132 if (p_dev->info & BTA_DM_DI_AV_ACTIVE) {
3133 /* there's AV activity on this link */
3134 if (p_data->acl_change.new_role == HCI_ROLE_SLAVE && bta_dm_cb.device_list.count > 1
3135 && p_data->acl_change.hci_status == HCI_SUCCESS) {
3136 /* more than one connections and the AV connection is role switched to slave
3137 * switch it back to master and remove the switch policy */
3138 BTM_SwitchRole(p_bda, BTM_ROLE_MASTER, NULL);
3139 need_policy_change = TRUE;
3140 } else if (p_bta_dm_cfg->avoid_scatter && (p_data->acl_change.new_role == HCI_ROLE_MASTER)) {
3141 /* if the link updated to be master include AV activities, remove the switch policy */
3142 need_policy_change = TRUE;
3145 if (need_policy_change) {
3146 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr);
3149 /* there's AV no activity on this link and role switch happened
3150 * check if AV is active
3151 * if so, make sure the AV link is master */
3154 bta_sys_notify_role_chg(p_data->acl_change.bd_addr, p_data->acl_change.new_role, p_data->acl_change.hci_status);
3155 bdcpy(conn.role_chg.bd_addr, p_bda);
3156 conn.role_chg.new_role = (UINT8) p_data->acl_change.new_role;
3157 if ( bta_dm_cb.p_sec_cback ) {
3158 bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, (tBTA_DM_SEC *)&conn);
3164 /* Collision report from Stack: Notify profiles */
3165 if (p_data->acl_change.event == BTM_BL_COLLISION_EVT) {
3166 bta_sys_notify_collision (p_bda);
3171 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3172 if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
3173 #if BLE_INCLUDED == TRUE
3174 && bta_dm_cb.device_list.peer_device[i].conn_handle == p_data->acl_change.handle
3182 if (i == bta_dm_cb.device_list.count) {
3183 if (bta_dm_cb.device_list.count < BTA_DM_NUM_PEER_DEVICE) {
3184 bdcpy(bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].peer_bdaddr, p_bda);
3185 bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].link_policy = bta_dm_cb.cur_policy;
3186 bta_dm_cb.device_list.count++;
3187 #if BLE_INCLUDED == TRUE
3188 bta_dm_cb.device_list.peer_device[i].conn_handle = p_data->acl_change.handle;
3189 if (p_data->acl_change.transport == BT_TRANSPORT_LE) {
3190 bta_dm_cb.device_list.le_count++;
3194 APPL_TRACE_ERROR("%s max active connection reached, no resources", __func__);
3199 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED;
3200 bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE;
3201 bdcpy(conn.link_up.bd_addr, p_bda);
3202 bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE;
3203 #if BLE_INCLUDED == TRUE
3204 conn.link_up.link_type = p_data->acl_change.transport;
3205 bta_dm_cb.device_list.peer_device[i].transport = p_data->acl_change.transport;
3208 if (((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
3209 ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p))) {
3210 /* both local and remote devices support SSR */
3211 bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR;
3213 APPL_TRACE_DEBUG("%s info: 0x%x", __func__, bta_dm_cb.device_list.peer_device[i].info);
3215 if (bta_dm_cb.p_sec_cback) {
3216 bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, (tBTA_DM_SEC *)&conn);
3219 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3220 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
3221 #if BLE_INCLUDED == TRUE
3222 || bta_dm_cb.device_list.peer_device[i].transport != p_data->acl_change.transport
3228 if ( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING ) {
3229 if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr)) {
3230 issue_unpair_cb = TRUE;
3233 APPL_TRACE_DEBUG("%s: Unpairing: issue unpair CB = %d ", __FUNCTION__, issue_unpair_cb);
3236 conn.link_down.is_removed = bta_dm_cb.device_list.peer_device[i].remove_dev_pending;
3238 for (; i < bta_dm_cb.device_list.count ; i++) {
3239 memcpy(&bta_dm_cb.device_list.peer_device[i], &bta_dm_cb.device_list.peer_device[i + 1], sizeof(bta_dm_cb.device_list.peer_device[i]));
3243 if (bta_dm_cb.device_list.count) {
3244 bta_dm_cb.device_list.count--;
3246 #if BLE_INCLUDED == TRUE
3247 if ((p_data->acl_change.transport == BT_TRANSPORT_LE) &&
3248 (bta_dm_cb.device_list.le_count)) {
3249 bta_dm_cb.device_list.le_count--;
3251 conn.link_down.link_type = p_data->acl_change.transport;
3254 if (bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda)) {
3255 bta_dm_search_cb.wait_disc = FALSE;
3257 if (bta_dm_search_cb.sdp_results) {
3258 APPL_TRACE_EVENT(" timer stopped ");
3259 bta_sys_stop_timer(&bta_dm_search_cb.search_timer);
3260 bta_dm_discover_next_device();
3265 if (bta_dm_cb.disabling) {
3266 if (!BTM_GetNumAclLinks()) {
3267 bta_sys_stop_timer(&bta_dm_cb.disable_timer);
3268 bta_dm_cb.disable_timer.p_cback = (TIMER_CBACK *)&bta_dm_disable_conn_down_timer_cback;
3270 * Start a timer to make sure that the profiles
3271 * get the disconnect event.
3273 bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 1000);
3276 if (conn.link_down.is_removed) {
3277 BTM_SecDeleteDevice(p_bda);
3278 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
3279 /* need to remove all pending background connection */
3280 BTA_GATTC_CancelOpen(0, p_bda, FALSE);
3281 /* remove all cached GATT information */
3282 BTA_GATTC_Refresh(p_bda);
3286 bdcpy(conn.link_down.bd_addr, p_bda);
3287 conn.link_down.status = (UINT8) btm_get_acl_disc_reason_code();
3288 if ( bta_dm_cb.p_sec_cback ) {
3289 bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn);
3290 if ( issue_unpair_cb ) {
3291 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn);
3296 bta_dm_adjust_roles(TRUE);
3299 /*******************************************************************************
3301 ** Function bta_dm_disable_conn_down_timer_cback
3303 ** Description Sends disable event to application
3308 *******************************************************************************/
3309 static void bta_dm_disable_conn_down_timer_cback (TIMER_LIST_ENT *p_tle)
3312 tBTA_SYS_HW_MSG *sys_enable_event;
3313 #if (BTM_SSR_INCLUDED == TRUE)
3314 /* disable the power managment module */
3315 bta_dm_disable_pm();
3316 #endif ///BTM_SSR_INCLUDED == TRUE
3317 /* register our callback to SYS HW manager */
3318 bta_sys_hw_register( BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback );
3320 /* send a message to BTA SYS */
3321 if ((sys_enable_event = (tBTA_SYS_HW_MSG *) osi_malloc(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
3322 sys_enable_event->hdr.event = BTA_SYS_API_DISABLE_EVT;
3323 sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;
3324 bta_sys_sendmsg(sys_enable_event);
3327 bta_dm_cb.disabling = FALSE;
3331 /*******************************************************************************
3333 ** Function bta_dm_rm_cback
3335 ** Description Role management callback from sys
3340 *******************************************************************************/
3341 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
3344 tBTA_PREF_ROLES role;
3345 tBTA_DM_PEER_DEVICE *p_dev;
3347 p_dev = bta_dm_find_peer_device(peer_addr);
3348 if ( status == BTA_SYS_CONN_OPEN) {
3350 /* Do not set to connected if we are in the middle of unpairing. When AV stream is
3351 * started it fakes out a SYS_CONN_OPEN to potentially trigger a role switch command.
3352 * But this should not be done if we are in the middle of unpairing.
3354 if (p_dev->conn_state != BTA_DM_UNPAIRING) {
3355 p_dev->conn_state = BTA_DM_CONNECTED;
3358 for (j = 1; j <= p_bta_dm_rm_cfg[0].app_id; j++) {
3359 if (((p_bta_dm_rm_cfg[j].app_id == app_id) || (p_bta_dm_rm_cfg[j].app_id == BTA_ALL_APP_ID))
3360 && (p_bta_dm_rm_cfg[j].id == id)) {
3361 role = p_bta_dm_rm_cfg[j].cfg;
3363 if (role > p_dev->pref_role ) {
3364 p_dev->pref_role = role;
3372 if ((BTA_ID_AV == id) || (BTA_ID_AVK == id)) {
3373 if ( status == BTA_SYS_CONN_BUSY) {
3375 p_dev->info |= BTA_DM_DI_AV_ACTIVE;
3377 /* AV calls bta_sys_conn_open with the A2DP stream count as app_id */
3378 if (BTA_ID_AV == id) {
3379 #if (BTM_SSR_INCLUDED == TRUE)
3380 bta_dm_cb.cur_av_count = bta_dm_get_av_count();
3381 #endif ///BTM_SSR_INCLUDED == TRUE
3383 } else if ( status == BTA_SYS_CONN_IDLE) {
3385 p_dev->info &= ~BTA_DM_DI_AV_ACTIVE;
3388 /* get cur_av_count from connected services */
3389 if (BTA_ID_AV == id) {
3390 #if (BTM_SSR_INCLUDED == TRUE)
3391 bta_dm_cb.cur_av_count = bta_dm_get_av_count();
3392 #endif ///BTM_SSR_INCLUDED == TRUE
3395 APPL_TRACE_WARNING("bta_dm_rm_cback:%d, status:%d", bta_dm_cb.cur_av_count, status);
3398 /* Don't adjust roles for each busy/idle state transition to avoid
3399 excessive switch requests when individual profile busy/idle status
3401 if ((status != BTA_SYS_CONN_BUSY) && (status != BTA_SYS_CONN_IDLE)) {
3402 bta_dm_adjust_roles(FALSE);
3406 /*******************************************************************************
3408 ** Function bta_dm_delay_role_switch_cback
3410 ** Description Callback from btm to delay a role switch
3414 *******************************************************************************/
3415 static void bta_dm_delay_role_switch_cback(TIMER_LIST_ENT *p_tle)
3418 APPL_TRACE_EVENT("bta_dm_delay_role_switch_cback: initiating Delayed RS");
3419 bta_dm_adjust_roles (FALSE);
3422 /*******************************************************************************
3424 ** Function bta_dm_remove_sec_dev_entry
3426 ** Description Removes device entry from Security device DB if ACL connection with
3427 ** remtoe device does not exist, else schedule for dev entry removal upon
3432 *******************************************************************************/
3433 #if (SMP_INCLUDED == TRUE)
3434 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
3437 if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
3438 BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR)) {
3439 APPL_TRACE_DEBUG("%s ACL is not down. Schedule for Dev Removal when ACL closes",
3441 BTM_SecClearSecurityFlags (remote_bd_addr);
3442 for (index = 0; index < bta_dm_cb.device_list.count; index ++) {
3443 if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, remote_bd_addr)) {
3447 if (index != bta_dm_cb.device_list.count) {
3448 bta_dm_cb.device_list.peer_device[index].remove_dev_pending = TRUE;
3450 APPL_TRACE_ERROR(" %s Device does not exist in DB", __FUNCTION__);
3453 BTM_SecDeleteDevice (remote_bd_addr);
3454 #if (BLE_INCLUDED == TRUE && GATTC_INCLUDED == TRUE)
3455 /* need to remove all pending background connection */
3456 BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
3457 /* remove all cached GATT information */
3458 BTA_GATTC_Refresh(remote_bd_addr);
3462 #endif ///SMP_INCLUDED == TRUE
3465 /*******************************************************************************
3467 ** Function bta_dm_adjust_roles
3469 ** Description Adjust roles
3474 *******************************************************************************/
3475 static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
3479 BOOLEAN set_master_role = FALSE;
3480 #if BLE_INCLUDED == TRUE
3481 UINT8 br_count = bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count;
3483 UINT8 br_count = bta_dm_cb.device_list.count;
3487 /* the configuration is no scatternet
3488 * or AV connection exists and there are more than one ACL link */
3489 if ( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
3490 (bta_dm_cb.cur_av_count && br_count > 1) ) {
3492 L2CA_SetDesireRole (HCI_ROLE_MASTER);
3493 set_master_role = TRUE;
3497 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
3498 if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED
3499 #if BLE_INCLUDED == TRUE
3500 && bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_BR_EDR
3503 if (!set_master_role && (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE)
3504 && (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET)) {
3505 L2CA_SetDesireRole (HCI_ROLE_MASTER);
3506 set_master_role = TRUE;
3509 if ((bta_dm_cb.device_list.peer_device[i].pref_role == BTA_MASTER_ROLE_ONLY)
3510 || (br_count > 1)) {
3512 /* Initiating immediate role switch with certain remote devices
3513 has caused issues due to role switch colliding with link encryption setup and
3514 causing encryption (and in turn the link) to fail . These device . Firmware
3515 versions are stored in a blacklist and role switch with these devices are
3516 delayed to avoid the collision with link encryption setup */
3518 if (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_SLAVE_ROLE_ONLY &&
3519 delay_role_switch == FALSE) {
3520 BTM_SwitchRole (bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
3521 HCI_ROLE_MASTER, NULL);
3523 bta_dm_cb.switch_delay_timer.p_cback =
3524 (TIMER_CBACK *)&bta_dm_delay_role_switch_cback;
3525 bta_sys_start_timer(&bta_dm_cb.switch_delay_timer, 0, 500);
3533 if (!set_master_role) {
3535 L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
3540 L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
3546 /*******************************************************************************
3548 ** Function bta_dm_get_remname
3550 ** Description Returns a pointer to the remote name stored in the DM control
3551 ** block if it exists, or from the BTM memory.
3553 ** Returns char * - Pointer to the remote device name
3554 *******************************************************************************/
3555 #if (SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE)
3556 static char *bta_dm_get_remname(void)
3558 char *p_name = (char *)bta_dm_search_cb.peer_name;
3561 /* If the name isn't already stored, try retrieving from BTM */
3562 if (*p_name == '\0')
3563 if ((p_temp = BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr)) != NULL) {
3569 #endif ///SDP_INCLUDED == TRUE || SMP_INCLUDED == TRUE
3571 /*******************************************************************************
3573 ** Function bta_dm_bond_cancel_complete_cback
3575 ** Description Authentication complete callback from BTM
3579 *******************************************************************************/
3580 #if (SMP_INCLUDED == TRUE)
3581 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result)
3584 tBTA_DM_SEC sec_event;
3586 if (result == BTM_SUCCESS) {
3587 sec_event.bond_cancel_cmpl.result = BTA_SUCCESS;
3589 sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
3592 if (bta_dm_cb.p_sec_cback) {
3593 bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
3596 #endif ///SMP_INCLUDED == TRUE
3598 /*******************************************************************************
3600 ** Function bta_dm_set_eir
3602 ** Description This function creates EIR tagged data and writes it to controller.
3606 *******************************************************************************/
3607 static void bta_dm_set_eir (char *local_name)
3612 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3615 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3616 UINT8 custom_uuid_idx;
3617 #endif // BTA_EIR_SERVER_NUM_CUSTOM_UUID
3618 #endif // BTA_EIR_CANNED_UUID_LIST
3619 #if (BTM_EIR_DEFAULT_FEC_REQUIRED == FALSE)
3620 UINT8 free_eir_length = HCI_EXT_INQ_RESPONSE_LEN;
3621 #else // BTM_EIR_DEFAULT_FEC_REQUIRED
3622 UINT8 free_eir_length = HCI_DM5_PACKET_SIZE;
3623 #endif // BTM_EIR_DEFAULT_FEC_REQUIRED
3626 UINT8 local_name_len;
3628 /* wait until complete to disable */
3629 if (bta_dm_cb.disable_timer.in_use) {
3633 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )
3634 /* wait until App is ready */
3635 if (bta_dm_cb.app_ready_timer.in_use) {
3639 /* if local name is not provided, get it from controller */
3640 if ( local_name == NULL ) {
3641 if ( BTM_ReadLocalDeviceName( &local_name ) != BTM_SUCCESS ) {
3642 APPL_TRACE_ERROR("Fail to read local device name for EIR");
3645 #endif // BTA_EIR_CANNED_UUID_LIST
3647 /* Allocate a buffer to hold HCI command */
3648 if ((p_buf = (BT_HDR *)osi_malloc(BTM_CMD_BUF_SIZE)) == NULL) {
3649 APPL_TRACE_ERROR("bta_dm_set_eir couldn't allocate buffer");
3652 p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET;
3654 memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN );
3656 APPL_TRACE_DEBUG("BTA is generating EIR");
3659 local_name_len = strlen( local_name );
3664 data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3665 /* if local name is longer than minimum length of shortened name */
3666 /* check whether it needs to be shortened or not */
3667 if ( local_name_len > p_bta_dm_eir_cfg->bta_dm_eir_min_name_len ) {
3668 /* get number of UUID 16-bit list */
3669 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3670 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / LEN_UUID_16;
3671 #else // BTA_EIR_CANNED_UUID_LIST
3672 max_num_uuid = (free_eir_length - 2) / LEN_UUID_16;
3673 data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p,
3674 max_num_uuid, &num_uuid );
3675 p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET; /* reset p */
3676 #endif // BTA_EIR_CANNED_UUID_LIST
3678 /* if UUID doesn't fit remaing space, shorten local name */
3679 if ( local_name_len > (free_eir_length - 4 - num_uuid * LEN_UUID_16)) {
3680 APPL_TRACE_WARNING("BTA EIR: local name is shortened");
3681 local_name_len = p_bta_dm_eir_cfg->bta_dm_eir_min_name_len;
3682 data_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE;
3684 data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3688 UINT8_TO_STREAM(p, local_name_len + 1);
3689 UINT8_TO_STREAM(p, data_type);
3691 if (local_name != NULL) {
3692 memcpy(p, local_name, local_name_len);
3693 p += local_name_len;
3695 free_eir_length -= local_name_len + 2;
3697 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3698 /* if UUID list is provided as static data in configuration */
3699 if (( p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len > 0 )
3700 && (p_bta_dm_eir_cfg->bta_dm_eir_uuid16)) {
3701 if ( free_eir_length > LEN_UUID_16 + 2) {
3702 free_eir_length -= 2;
3704 if ( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len) {
3705 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / LEN_UUID_16;
3706 data_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3707 } else { /* not enough room for all UUIDs */
3708 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3709 num_uuid = free_eir_length / LEN_UUID_16;
3710 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3712 UINT8_TO_STREAM(p, num_uuid * LEN_UUID_16 + 1);
3713 UINT8_TO_STREAM(p, data_type);
3714 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_uuid16, num_uuid * LEN_UUID_16 );
3715 p += num_uuid * LEN_UUID_16;
3716 free_eir_length -= num_uuid * LEN_UUID_16;
3719 #else /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3720 /* if UUID list is dynamic */
3721 if ( free_eir_length >= 2) {
3726 max_num_uuid = (free_eir_length - 2) / LEN_UUID_16;
3727 data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p, max_num_uuid, &num_uuid );
3729 if ( data_type == BTM_EIR_MORE_16BITS_UUID_TYPE ) {
3730 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3732 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3734 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) {
3735 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_16) {
3736 if ( num_uuid < max_num_uuid ) {
3737 UINT16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid16);
3740 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3741 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3747 #endif /* (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3749 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_16 + 1);
3750 UINT8_TO_STREAM(p_type, data_type);
3751 free_eir_length -= num_uuid * LEN_UUID_16 + 2;
3753 #endif /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3755 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3756 /* Adding 32-bit UUID list */
3757 if ( free_eir_length >= 2) {
3761 data_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE;
3763 max_num_uuid = (free_eir_length - 2) / LEN_UUID_32;
3765 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) {
3766 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_32) {
3767 if ( num_uuid < max_num_uuid ) {
3768 UINT32_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid32);
3771 data_type = BTM_EIR_MORE_32BITS_UUID_TYPE;
3772 APPL_TRACE_WARNING("BTA EIR: UUID 32-bit list is truncated");
3778 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_32 + 1);
3779 UINT8_TO_STREAM(p_type, data_type);
3780 free_eir_length -= num_uuid * LEN_UUID_32 + 2;
3783 /* Adding 128-bit UUID list */
3784 if ( free_eir_length >= 2) {
3788 data_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE;
3790 max_num_uuid = (free_eir_length - 2) / LEN_UUID_128;
3792 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) {
3793 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_128) {
3794 if ( num_uuid < max_num_uuid ) {
3795 ARRAY16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid128);
3798 data_type = BTM_EIR_MORE_128BITS_UUID_TYPE;
3799 APPL_TRACE_WARNING("BTA EIR: UUID 128-bit list is truncated");
3805 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_128 + 1);
3806 UINT8_TO_STREAM(p_type, data_type);
3807 free_eir_length -= num_uuid * LEN_UUID_128 + 2;
3809 #endif /* ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3811 /* if Flags are provided in configuration */
3812 if (( p_bta_dm_eir_cfg->bta_dm_eir_flag_len > 0 )
3813 && ( p_bta_dm_eir_cfg->bta_dm_eir_flags )
3814 && ( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2 )) {
3815 UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 1);
3816 UINT8_TO_STREAM(p, BTM_EIR_FLAGS_TYPE);
3817 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_flags,
3818 p_bta_dm_eir_cfg->bta_dm_eir_flag_len);
3819 p += p_bta_dm_eir_cfg->bta_dm_eir_flag_len;
3820 free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2;
3823 /* if Manufacturer Specific are provided in configuration */
3824 if (( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len > 0 )
3825 && ( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec )
3826 && ( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2 )) {
3829 UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 1);
3830 UINT8_TO_STREAM(p, BTM_EIR_MANUFACTURER_SPECIFIC_TYPE);
3831 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec,
3832 p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len);
3833 p += p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len;
3834 free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2;
3840 /* if Inquiry Tx Resp Power compiled */
3841 if ((p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power) &&
3842 (free_eir_length >= 3)) {
3843 UINT8_TO_STREAM(p, 2); /* Length field */
3844 UINT8_TO_STREAM(p, BTM_EIR_TX_POWER_LEVEL_TYPE);
3845 UINT8_TO_STREAM(p, *(p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power));
3846 free_eir_length -= 3;
3849 if ( free_eir_length ) {
3850 UINT8_TO_STREAM(p, 0); /* terminator of significant part */
3853 BTM_WriteEIR( p_buf );
3857 /*******************************************************************************
3859 ** Function bta_dm_eir_search_services
3861 ** Description This function searches services in received EIR
3865 *******************************************************************************/
3866 #if (SDP_INCLUDED == TRUE)
3867 static void bta_dm_eir_search_services( tBTM_INQ_RESULTS *p_result,
3868 tBTA_SERVICE_MASK *p_services_to_search,
3869 tBTA_SERVICE_MASK *p_services_found)
3871 tBTA_SERVICE_MASK service_index = 0;
3872 tBTM_EIR_SEARCH_RESULT result;
3874 APPL_TRACE_DEBUG("BTA searching services in EIR of BDA:0x%02X%02X%02X%02X%02X%02X",
3875 p_result->remote_bd_addr[0], p_result->remote_bd_addr[1],
3876 p_result->remote_bd_addr[2], p_result->remote_bd_addr[3],
3877 p_result->remote_bd_addr[4], p_result->remote_bd_addr[5]);
3879 APPL_TRACE_DEBUG(" with services_to_search=0x%08X", *p_services_to_search);
3881 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
3882 /* always do GATT based service discovery by SDP instead of from EIR */
3883 /* if GATT based service is also to be put in EIR, need to modify this */
3884 while (service_index < (BTA_MAX_SERVICE_ID - 1))
3886 while (service_index < BTA_MAX_SERVICE_ID)
3889 if ( *p_services_to_search
3890 & (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index))) {
3891 result = BTM_HasInquiryEirService( p_result,
3892 bta_service_id_to_uuid_lkup_tbl[service_index] );
3894 /* Searching for HSP v1.2 only device */
3895 if ((result != BTM_EIR_FOUND) &&
3896 (bta_service_id_to_uuid_lkup_tbl[service_index] == UUID_SERVCLASS_HEADSET)) {
3897 result = BTM_HasInquiryEirService (p_result, UUID_SERVCLASS_HEADSET_HS);
3900 if ( result == BTM_EIR_FOUND ) {
3901 /* If Plug and Play service record, need to check to see if Broadcom stack */
3902 /* However, EIR data doesn't have EXT_BRCM_VERSION so just skip it */
3903 if ( bta_service_id_to_uuid_lkup_tbl[service_index]
3904 != UUID_SERVCLASS_PNP_INFORMATION ) {
3906 *p_services_found |=
3907 (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index));
3908 /* remove the service from services to be searched */
3909 *p_services_to_search &=
3910 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
3912 } else if ( result == BTM_EIR_NOT_FOUND ) {
3913 /* remove the service from services to be searched */
3914 *p_services_to_search &=
3915 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
3922 APPL_TRACE_ERROR("BTA EIR search result, services_to_search=0x%08X, services_found=0x%08X",
3923 *p_services_to_search, *p_services_found);
3925 #endif ///SDP_INCLUDED == TRUE
3927 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3928 /*******************************************************************************
3930 ** Function bta_dm_eir_update_uuid
3932 ** Description This function adds or removes service UUID in EIR database.
3936 *******************************************************************************/
3937 void bta_dm_eir_update_uuid(UINT16 uuid16, BOOLEAN adding)
3939 /* if this UUID is not advertised in EIR */
3940 if ( !BTM_HasEirService( p_bta_dm_eir_cfg->uuid_mask, uuid16 )) {
3945 APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid16);
3947 BTM_AddEirService( bta_dm_cb.eir_uuid, uuid16 );
3949 APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid16);
3951 BTM_RemoveEirService( bta_dm_cb.eir_uuid, uuid16 );
3954 bta_dm_set_eir (NULL);
3956 APPL_TRACE_EVENT("bta_dm_eir_update_uuid UUID bit mask=0x%08X %08X",
3957 bta_dm_cb.eir_uuid[1], bta_dm_cb.eir_uuid[0] );
3961 /*******************************************************************************
3963 ** Function bta_dm_enable_test_mode
3965 ** Description enable test mode
3970 *******************************************************************************/
3971 void bta_dm_enable_test_mode(tBTA_DM_MSG *p_data)
3974 BTM_EnableTestMode();
3977 /*******************************************************************************
3979 ** Function bta_dm_disable_test_mode
3981 ** Description disable test mode
3986 *******************************************************************************/
3987 void bta_dm_disable_test_mode(tBTA_DM_MSG *p_data)
3990 BTM_DeviceReset(NULL);
3993 /*******************************************************************************
3995 ** Function bta_dm_execute_callback
3997 ** Description Just execute a generic call back in the context of the BTU/BTA tack
4002 *******************************************************************************/
4003 void bta_dm_execute_callback(tBTA_DM_MSG *p_data)
4006 if (p_data->exec_cback.p_exec_cback == NULL) {
4010 p_data->exec_cback.p_exec_cback(p_data->exec_cback.p_param);
4013 /*******************************************************************************
4015 ** Function bta_dm_encrypt_cback
4017 ** Description link encryption complete callback.
4021 *******************************************************************************/
4022 void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
4024 tBTA_STATUS bta_status = BTA_SUCCESS;
4025 tBTA_DM_ENCRYPT_CBACK *p_callback = NULL;
4029 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
4030 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bd_addr) == 0 &&
4031 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) {
4036 if (i < bta_dm_cb.device_list.count) {
4037 p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback;
4038 bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL;
4044 case BTM_WRONG_MODE:
4045 bta_status = BTA_WRONG_MODE;
4047 case BTM_NO_RESOURCES:
4048 bta_status = BTA_NO_RESOURCES;
4051 bta_status = BTA_BUSY;
4054 bta_status = BTA_FAILURE;
4058 APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=%p", bta_status, p_callback);
4061 (*p_callback)(bd_addr, transport, bta_status);
4065 /*******************************************************************************
4067 ** Function bta_dm_set_encryption
4069 ** Description This function to encrypt the link
4073 *******************************************************************************/
4074 #if (SMP_INCLUDED == TRUE)
4075 void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
4079 APPL_TRACE_DEBUG("bta_dm_set_encryption\n"); //todo
4080 if (!p_data->set_encryption.p_callback) {
4081 APPL_TRACE_ERROR("bta_dm_set_encryption callback is not provided\n");
4084 for (i = 0; i < bta_dm_cb.device_list.count; i++) {
4085 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_data->set_encryption.bd_addr) == 0 &&
4086 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) {
4090 if (i < bta_dm_cb.device_list.count) {
4091 if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback) {
4092 APPL_TRACE_ERROR("earlier enc was not done for same device\n");
4093 (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr,
4094 p_data->set_encryption.transport,
4099 if (BTM_SetEncryption(p_data->set_encryption.bd_addr, p_data->set_encryption.transport,
4100 bta_dm_encrypt_cback, &p_data->set_encryption.sec_act)
4101 == BTM_CMD_STARTED) {
4102 bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_data->set_encryption.p_callback;
4106 #endif ///SMP_INCLUDED == TRUE
4108 #if (BLE_INCLUDED == TRUE)
4109 /*******************************************************************************
4111 ** Function bta_dm_observe_results_cb
4113 ** Description Callback for BLE Observe result
4118 *******************************************************************************/
4119 static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
4121 tBTA_DM_SEARCH result;
4122 tBTM_INQ_INFO *p_inq_info;
4123 APPL_TRACE_DEBUG("bta_dm_observe_results_cb")
4125 bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
4126 result.inq_res.rssi = p_inq->rssi;
4127 result.inq_res.ble_addr_type = p_inq->ble_addr_type;
4128 result.inq_res.inq_result_type = p_inq->inq_result_type;
4129 result.inq_res.device_type = p_inq->device_type;
4130 result.inq_res.flag = p_inq->flag;
4131 result.inq_res.adv_data_len = p_inq->adv_data_len;
4132 result.inq_res.scan_rsp_len = p_inq->scan_rsp_len;
4134 /* application will parse EIR to find out remote device name */
4135 result.inq_res.p_eir = p_eir;
4137 if ((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL) {
4138 /* initialize remt_name_not_required to FALSE so that we get the name by default */
4139 result.inq_res.remt_name_not_required = FALSE;
4142 if (bta_dm_search_cb.p_scan_cback) {
4143 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result);
4147 /* application indicates if it knows the remote name, inside the callback
4148 copy that to the inquiry data base*/
4149 if (result.inq_res.remt_name_not_required) {
4150 p_inq_info->appl_knows_rem_name = TRUE;
4155 /*******************************************************************************
4157 ** Function bta_dm_observe_cmpl_cb
4159 ** Description Callback for BLE Observe complete
4164 *******************************************************************************/
4165 static void bta_dm_observe_cmpl_cb (void *p_result)
4167 tBTA_DM_SEARCH data;
4169 APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb");
4171 data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
4172 if (bta_dm_search_cb.p_scan_cback) {
4173 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
4177 #if (SMP_INCLUDED == TRUE)
4178 /*******************************************************************************
4180 ** Function bta_dm_ble_smp_cback
4182 ** Description Callback for BLE SMP
4187 *******************************************************************************/
4188 static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data)
4190 tBTM_STATUS status = BTM_SUCCESS;
4191 tBTA_DM_SEC sec_event;
4192 char *p_name = NULL;
4194 if (!bta_dm_cb.p_sec_cback) {
4195 return BTM_NOT_AUTHORIZED;
4198 memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
4200 case BTM_LE_IO_REQ_EVT:
4201 // #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
4203 bta_dm_co_ble_io_req(bda,
4204 &p_data->io_req.io_cap,
4205 &p_data->io_req.oob_data,
4206 &p_data->io_req.auth_req,
4207 &p_data->io_req.max_key_size,
4208 &p_data->io_req.init_keys,
4209 &p_data->io_req.resp_keys);
4211 #if BTM_OOB_INCLUDED == FALSE
4212 status = BTM_SUCCESS;
4214 APPL_TRACE_EVENT("io mitm: %d oob_data:%d\n", p_data->io_req.auth_req, p_data->io_req.oob_data);
4218 case BTM_LE_SEC_REQUEST_EVT:
4219 bdcpy(sec_event.ble_req.bd_addr, bda);
4220 p_name = BTM_SecReadDevName(bda);
4221 if (p_name != NULL) {
4222 BCM_STRNCPY_S((char *)sec_event.ble_req.bd_name,
4223 sizeof(BD_NAME), p_name, (BD_NAME_LEN));
4225 sec_event.ble_req.bd_name[0] = 0;
4227 sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
4228 bta_dm_cb.p_sec_cback(BTA_DM_BLE_SEC_REQ_EVT, &sec_event);
4231 case BTM_LE_KEY_NOTIF_EVT:
4232 bdcpy(sec_event.key_notif.bd_addr, bda);
4233 p_name = BTM_SecReadDevName(bda);
4234 if (p_name != NULL) {
4235 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,
4236 sizeof(BD_NAME), p_name, (BD_NAME_LEN));
4238 sec_event.key_notif.bd_name[0] = 0;
4240 sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
4241 sec_event.key_notif.passkey = p_data->key_notif;
4242 bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_NOTIF_EVT, &sec_event);
4245 case BTM_LE_KEY_REQ_EVT:
4246 bdcpy(sec_event.ble_req.bd_addr, bda);
4247 bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_REQ_EVT, &sec_event);
4250 case BTM_LE_OOB_REQ_EVT:
4251 bdcpy(sec_event.ble_req.bd_addr, bda);
4252 bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event);
4255 case BTM_LE_NC_REQ_EVT:
4256 bdcpy(sec_event.key_notif.bd_addr, bda);
4257 BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN));
4258 sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
4259 sec_event.key_notif.passkey = p_data->key_notif;
4260 bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
4263 case BTM_LE_KEY_EVT:
4264 bdcpy(sec_event.ble_key.bd_addr, bda);
4265 sec_event.ble_key.key_type = p_data->key.key_type;
4266 sec_event.ble_key.p_key_value = p_data->key.p_key_value;
4267 bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event);
4270 case BTM_LE_COMPLT_EVT:
4271 bdcpy(sec_event.auth_cmpl.bd_addr, bda);
4272 #if BLE_INCLUDED == TRUE
4273 BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
4275 p_name = BTM_SecReadDevName(bda);
4276 if (p_name != NULL) {
4277 BCM_STRNCPY_S((char *)sec_event.auth_cmpl.bd_name,
4278 sizeof(BD_NAME), p_name, (BD_NAME_LEN));
4280 sec_event.auth_cmpl.bd_name[0] = 0;
4282 if (p_data->complt.reason != 0) {
4283 sec_event.auth_cmpl.fail_reason = BTA_DM_AUTH_CONVERT_SMP_CODE(((UINT8)p_data->complt.reason));
4284 /* delete this device entry from Sec Dev DB */
4285 bta_dm_remove_sec_dev_entry (bda);
4287 sec_event.auth_cmpl.success = TRUE;
4288 if (!p_data->complt.smp_over_br) {
4293 if (bta_dm_cb.p_sec_cback) {
4294 //bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
4295 bta_dm_cb.p_sec_cback(BTA_DM_BLE_AUTH_CMPL_EVT, &sec_event);
4301 status = BTM_NOT_AUTHORIZED;
4307 /*******************************************************************************
4309 ** Function bta_dm_ble_id_key_cback
4311 ** Description Callback for BLE local ID keys
4316 *******************************************************************************/
4317 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key)
4323 case BTM_BLE_KEY_TYPE_ID:
4324 case BTM_BLE_KEY_TYPE_ER:
4325 if (bta_dm_cb.p_sec_cback) {
4326 memcpy(&dm_key.ble_id_keys, p_key, sizeof(tBTM_BLE_LOCAL_KEYS));
4328 evt = (key_type == BTM_BLE_KEY_TYPE_ID) ? BTA_DM_BLE_LOCAL_IR_EVT : \
4329 BTA_DM_BLE_LOCAL_ER_EVT;
4330 bta_dm_cb.p_sec_cback(evt, &dm_key);
4335 APPL_TRACE_DEBUG("Unknown key type %d", key_type);
4342 /*******************************************************************************
4344 ** Function bta_dm_add_blekey
4346 ** Description This function adds an BLE Key to an security database entry.
4347 ** This function shall only be called AFTER BTA_DmAddBleDevice has been called.
4348 ** It is normally called during host startup to restore all required information
4349 ** stored in the NVRAM.
4353 *******************************************************************************/
4354 void bta_dm_add_blekey (tBTA_DM_MSG *p_data)
4356 if (!BTM_SecAddBleKey (p_data->add_ble_key.bd_addr,
4357 (tBTM_LE_KEY_VALUE *)&p_data->add_ble_key.blekey,
4358 p_data->add_ble_key.key_type)) {
4359 APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Key for device %08x%04x",
4360 (p_data->add_ble_key.bd_addr[0] << 24) + (p_data->add_ble_key.bd_addr[1] << 16) + \
4361 (p_data->add_ble_key.bd_addr[2] << 8) + p_data->add_ble_key.bd_addr[3],
4362 (p_data->add_ble_key.bd_addr[4] << 8) + p_data->add_ble_key.bd_addr[5]);
4366 /*******************************************************************************
4368 ** Function bta_dm_add_ble_device
4370 ** Description This function adds an BLE device to an security database entry.
4371 ** It is normally called during host startup to restore all required information
4372 ** stored in the NVRAM.
4376 *******************************************************************************/
4377 void bta_dm_add_ble_device (tBTA_DM_MSG *p_data)
4379 if (!BTM_SecAddBleDevice (p_data->add_ble_device.bd_addr, NULL,
4380 p_data->add_ble_device.dev_type ,
4381 p_data->add_ble_device.addr_type)) {
4382 APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Device for device %08x%04x",
4383 (p_data->add_ble_device.bd_addr[0] << 24) + (p_data->add_ble_device.bd_addr[1] << 16) + \
4384 (p_data->add_ble_device.bd_addr[2] << 8) + p_data->add_ble_device.bd_addr[3],
4385 (p_data->add_ble_device.bd_addr[4] << 8) + p_data->add_ble_device.bd_addr[5]);
4389 /*******************************************************************************
4391 ** Function bta_dm_add_ble_device
4393 ** Description This function adds an BLE device to an security database entry.
4394 ** It is normally called during host startup to restore all required information
4395 ** stored in the NVRAM.
4399 *******************************************************************************/
4400 void bta_dm_ble_passkey_reply (tBTA_DM_MSG *p_data)
4402 if (p_data->pin_reply.accept) {
4403 BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_SUCCESS, p_data->ble_passkey_reply.passkey);
4405 BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED, p_data->ble_passkey_reply.passkey);
4410 /*******************************************************************************
4412 ** Function bta_dm_ble_confirm_reply
4414 ** Description This is response to SM numeric comparison request submitted
4419 *******************************************************************************/
4420 void bta_dm_ble_confirm_reply (tBTA_DM_MSG *p_data)
4422 if (p_data->confirm.accept) {
4423 BTM_BleConfirmReply(p_data->confirm.bd_addr, BTM_SUCCESS);
4425 BTM_BleConfirmReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED);
4429 /*******************************************************************************
4431 ** Function bta_dm_security_grant
4433 ** Description This function grant SMP security request access.
4437 *******************************************************************************/
4438 void bta_dm_security_grant (tBTA_DM_MSG *p_data)
4440 BTM_SecurityGrant(p_data->ble_sec_grant.bd_addr, p_data->ble_sec_grant.res);
4442 #endif ///SMP_INCLUDED == TRUE
4444 /*******************************************************************************
4446 ** Function bta_dm_ble_set_bg_conn_type
4448 ** Description This function set the BLE background connection type
4452 *******************************************************************************/
4453 void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data)
4455 BTM_BleSetBgConnType(p_data->ble_set_bd_conn_type.bg_conn_type,
4456 p_data->ble_set_bd_conn_type.p_select_cback);
4459 /*******************************************************************************
4461 ** Function bta_dm_ble_set_conn_params
4463 ** Description This function set the preferred connection parameters.
4467 *******************************************************************************/
4468 void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data)
4470 BTM_BleSetPrefConnParams(p_data->ble_set_conn_params.peer_bda,
4471 p_data->ble_set_conn_params.conn_int_min,
4472 p_data->ble_set_conn_params.conn_int_max,
4473 p_data->ble_set_conn_params.slave_latency,
4474 p_data->ble_set_conn_params.supervision_tout);
4477 /*******************************************************************************
4479 ** Function bta_dm_ble_set_conn_scan_params
4481 ** Description This function sets BLE scan parameters.
4485 *******************************************************************************/
4486 void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data)
4488 BTM_BleSetScanParams(p_data->ble_set_scan_params.client_if,
4489 p_data->ble_set_scan_params.scan_int,
4490 p_data->ble_set_scan_params.scan_window,
4491 p_data->ble_set_scan_params.scan_mode,
4492 p_data->ble_set_scan_params.scan_param_setup_cback);
4495 /*******************************************************************************
4497 ** Function bta_dm_ble_set_scan_fil_params
4499 ** Description This function sets BLE scan filter & parameters.
4503 *******************************************************************************/
4504 void bta_dm_ble_set_scan_fil_params(tBTA_DM_MSG *p_data)
4506 BTM_BleSetScanFilterParams (p_data->ble_set_scan_fil_params.client_if,
4507 p_data->ble_set_scan_fil_params.scan_int,
4508 p_data->ble_set_scan_fil_params.scan_window,
4509 p_data->ble_set_scan_fil_params.scan_mode,
4510 p_data->ble_set_scan_fil_params.addr_type_own,
4511 p_data->ble_set_scan_fil_params.scan_filter_policy,
4512 p_data->ble_set_scan_fil_params.scan_param_setup_cback);
4516 /*******************************************************************************
4518 ** Function bta_dm_ble_set_conn_scan_params
4520 ** Description This function set the preferred connection scan parameters.
4524 *******************************************************************************/
4525 void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data)
4527 BTM_BleSetConnScanParams(p_data->ble_set_conn_scan_params.scan_int,
4528 p_data->ble_set_conn_scan_params.scan_window);
4530 /*******************************************************************************
4532 ** Function bta_dm_ble_update_conn_params
4534 ** Description This function update LE connection parameters.
4538 *******************************************************************************/
4539 void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
4541 if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr,
4542 p_data->ble_update_conn_params.min_int,
4543 p_data->ble_update_conn_params.max_int,
4544 p_data->ble_update_conn_params.latency,
4545 p_data->ble_update_conn_params.timeout)) {
4546 APPL_TRACE_ERROR("Update connection parameters failed!");
4549 /*******************************************************************************
4551 ** Function bta_dm_ble_disconnect
4553 ** Description This function disconnect the ble connection.
4557 *******************************************************************************/
4558 void bta_dm_ble_disconnect (tBTA_DM_MSG *p_data)
4560 L2CA_RemoveFixedChnl(L2CAP_ATT_CID, p_data->ble_disconnect.remote_bda);
4563 /*******************************************************************************
4565 ** Function bta_dm_ble_set_rand_address
4567 ** Description This function set the LE random address for the device.
4569 ** Parameters: rand_addr:the random address whitch should be setting
4570 ** Explanation: This function added by Yulong at 2016/9/9
4571 *******************************************************************************/
4572 void bta_dm_ble_set_rand_address(tBTA_DM_MSG *p_data)
4574 BOOLEAN set_flag = false;
4575 if (p_data->set_addr.addr_type != BLE_ADDR_RANDOM) {
4576 APPL_TRACE_ERROR("Invalid random adress type = %d\n", p_data->set_addr.addr_type);
4579 //send the setting random address to BTM layer
4580 if ((set_flag = BTM_BleSetRandAddress(p_data->set_addr.address) != TRUE)){
4581 APPL_TRACE_ERROR("%s,set random address fail.", __func__);
4586 /*******************************************************************************
4588 ** Function bta_dm_ble_stop_advertising
4590 ** Description This function stop the BLE avdertising for the device.
4593 ** Explanation: This function added by Yulong at 2016/10/19
4594 *******************************************************************************/
4595 void bta_dm_ble_stop_advertising(tBTA_DM_MSG *p_data)
4597 if (p_data->hdr.event != BTA_DM_API_BLE_STOP_ADV_EVT) {
4598 APPL_TRACE_ERROR("Invalid BTA event,cann't stop the BLE adverting\n");
4606 #if BLE_PRIVACY_SPT == TRUE
4607 /*******************************************************************************
4609 ** Function bta_dm_ble_config_local_privacy
4611 ** Description This function set the local device LE privacy settings.
4615 *******************************************************************************/
4616 void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data)
4618 BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable, p_data->ble_local_privacy.set_local_privacy_cback);
4622 /*******************************************************************************
4624 ** Function bta_dm_ble_observe
4626 ** Description This function set the preferred connection scan parameters.
4630 *******************************************************************************/
4631 void bta_dm_ble_observe (tBTA_DM_MSG *p_data)
4634 if (p_data->ble_observe.start) {
4635 /*Save the callback to be called when a scan results are available */
4636 bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback;
4638 if ((status = BTM_BleObserve(TRUE, p_data->ble_observe.duration,
4639 bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) {
4640 APPL_TRACE_WARNING(" %s start observe failed. status=0x%x\n", __FUNCTION__, status);
4643 if (p_data->ble_observe.p_start_scan_cback) {
4644 status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4645 p_data->ble_observe.p_start_scan_cback(status);
4648 bta_dm_search_cb.p_scan_cback = NULL;
4649 status = BTM_BleObserve(FALSE, 0, NULL, NULL);
4651 if (status != BTM_CMD_STARTED){
4652 APPL_TRACE_WARNING(" %s stop observe failed, status=0x%x\n", __FUNCTION__, status);
4655 if (p_data->ble_observe.p_stop_scan_cback) {
4656 status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4657 p_data->ble_observe.p_stop_scan_cback(status);
4662 /*******************************************************************************
4664 ** Function bta_dm_ble_scan
4666 ** Description This function set the preferred connection scan parameters.
4670 *******************************************************************************/
4671 void bta_dm_ble_scan (tBTA_DM_MSG *p_data)
4674 if (p_data->ble_scan.start) {
4675 /*Save the callback to be called when a scan results are available */
4676 bta_dm_search_cb.p_scan_cback = p_data->ble_scan.p_cback;
4678 if ((status = BTM_BleScan(TRUE, p_data->ble_scan.duration,
4679 bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) {
4680 APPL_TRACE_WARNING(" %s start scan failed. status=0x%x\n", __FUNCTION__, status);
4683 if (p_data->ble_scan.p_start_scan_cback) {
4684 status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4685 p_data->ble_scan.p_start_scan_cback(status);
4688 bta_dm_search_cb.p_scan_cback = NULL;
4689 status = BTM_BleScan(FALSE, 0, NULL, NULL);
4691 if (status != BTM_CMD_STARTED){
4692 APPL_TRACE_WARNING(" %s stop scan failed, status=0x%x\n", __FUNCTION__, status);
4695 if (p_data->ble_scan.p_stop_scan_cback) {
4696 status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
4697 p_data->ble_scan.p_stop_scan_cback(status);
4702 /*******************************************************************************
4704 ** Function bta_dm_ble_set_adv_params
4706 ** Description This function set the adv parameters.
4710 *******************************************************************************/
4711 void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data)
4713 BTM_BleSetAdvParams(p_data->ble_set_adv_params.adv_int_min,
4714 p_data->ble_set_adv_params.adv_int_max,
4715 p_data->ble_set_adv_params.p_dir_bda,
4716 BTA_DM_BLE_ADV_CHNL_MAP);
4719 /*******************************************************************************
4721 ** Function bta_dm_ble_set_adv_params_all
4723 ** Description This function is called to set all of the advertising parameters.
4725 ** Parameters: None.
4729 *******************************************************************************/
4730 void bta_dm_ble_set_adv_params_all (tBTA_DM_MSG *p_data)
4732 tBTA_STATUS status = BTA_FAILURE;
4734 if (BTM_BleSetAdvParamsStartAdv(p_data->ble_set_adv_params_all.adv_int_min,
4735 p_data->ble_set_adv_params_all.adv_int_max,
4736 p_data->ble_set_adv_params_all.adv_type,
4737 p_data->ble_set_adv_params_all.addr_type_own,
4738 p_data->ble_set_adv_params_all.p_dir_bda,
4739 p_data->ble_set_adv_params_all.channel_map,
4740 p_data->ble_set_adv_params_all.adv_filter_policy) == BTM_SUCCESS) {
4741 status = BTA_SUCCESS;
4744 if (p_data->ble_set_adv_params_all.p_start_adv_cback) {
4745 (*p_data->ble_set_adv_params_all.p_start_adv_cback)(status);
4749 /*******************************************************************************
4751 ** Function bta_dm_ble_set_adv_config
4753 ** Description This function set the customized ADV data configuration
4757 *******************************************************************************/
4758 void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data)
4760 tBTA_STATUS status = BTA_FAILURE;
4762 if (BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask,
4763 (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS) {
4764 status = BTA_SUCCESS;
4767 if (p_data->ble_set_adv_data.p_adv_data_cback) {
4768 (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
4772 /*******************************************************************************
4774 ** Function bta_dm_ble_set_adv_config_raw
4776 ** Description This function set the customized ADV data configuration
4780 *******************************************************************************/
4781 void bta_dm_ble_set_adv_config_raw (tBTA_DM_MSG *p_data)
4783 tBTA_STATUS status = BTA_FAILURE;
4785 if (BTM_BleWriteAdvDataRaw(p_data->ble_set_adv_data_raw.p_raw_adv,
4786 p_data->ble_set_adv_data_raw.raw_adv_len) == BTM_SUCCESS) {
4787 status = BTA_SUCCESS;
4790 if (p_data->ble_set_adv_data_raw.p_adv_data_cback) {
4791 (*p_data->ble_set_adv_data_raw.p_adv_data_cback)(status);
4796 /*******************************************************************************
4798 ** Function bta_dm_ble_set_scan_rsp
4800 ** Description This function set the customized ADV scan resp. configuration
4804 *******************************************************************************/
4805 void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data)
4807 tBTA_STATUS status = BTA_FAILURE;
4809 if (BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
4810 (tBTM_BLE_ADV_DATA *)p_data->ble_set_adv_data.p_adv_cfg) == BTM_SUCCESS) {
4811 status = BTA_SUCCESS;
4814 if (p_data->ble_set_adv_data.p_adv_data_cback) {
4815 (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
4819 /*******************************************************************************
4821 ** Function bta_dm_ble_set_scan_rsp_raw
4823 ** Description This function set the raw scan response data
4827 *******************************************************************************/
4828 void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data)
4830 tBTA_STATUS status = BTA_FAILURE;
4832 if (BTM_BleWriteScanRspRaw(p_data->ble_set_adv_data_raw.p_raw_adv,
4833 p_data->ble_set_adv_data_raw.raw_adv_len) == BTM_SUCCESS) {
4834 status = BTA_SUCCESS;
4837 if (p_data->ble_set_adv_data_raw.p_adv_data_cback) {
4838 (*p_data->ble_set_adv_data_raw.p_adv_data_cback)(status);
4842 /*******************************************************************************
4844 ** Function bta_dm_ble_set_data_length
4846 ** Description This function set the maximum transmission packet size
4850 *******************************************************************************/
4851 void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data)
4853 tACL_CONN *p_acl_cb = btm_bda_to_acl(p_data->ble_set_data_length.remote_bda, BT_TRANSPORT_LE);
4854 if (p_acl_cb == NULL) {
4855 APPL_TRACE_ERROR("%s error: Invalid connection remote_bda.", __func__);
4858 p_acl_cb->p_set_pkt_data_cback = p_data->ble_set_data_length.p_set_pkt_data_cback;
4860 UINT8 status = BTM_SetBleDataLength(p_data->ble_set_data_length.remote_bda,
4861 p_data->ble_set_data_length.tx_data_length);
4862 if (status != BTM_SUCCESS) {
4863 APPL_TRACE_ERROR("%s failed\n", __FUNCTION__);
4864 if (p_data->ble_set_data_length.p_set_pkt_data_cback) {
4865 if (p_acl_cb->data_length_params.tx_len == 0){
4866 uint16_t length = controller_get_interface()->get_acl_data_size_ble();
4867 p_acl_cb->data_length_params.rx_len = length;
4868 p_acl_cb->data_length_params.tx_len = length;
4870 (*p_data->ble_set_data_length.p_set_pkt_data_cback)(status, &p_acl_cb->data_length_params);
4875 /*******************************************************************************
4877 ** Function bta_dm_ble_broadcast
4879 ** Description Starts or stops LE broadcasts
4883 *******************************************************************************/
4884 void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data)
4886 tBTM_STATUS status = 0;
4887 BOOLEAN start = p_data->ble_observe.start;
4889 status = BTM_BleBroadcast(start);
4891 if (p_data->ble_observe.p_stop_adv_cback){
4892 if (status != BTM_SUCCESS){
4893 APPL_TRACE_WARNING("%s, %s, status=0x%x\n", __func__,\
4894 (start == TRUE) ? "start adv failed" : "stop adv failed", status);
4896 status = (status == BTM_SUCCESS ? BTA_SUCCESS : BTA_FAILURE);
4897 p_data->ble_observe.p_stop_adv_cback(status);
4902 /*******************************************************************************
4904 ** Function bta_dm_ble_multi_adv_enb
4906 ** Description This function enables a single advertising instance
4910 *******************************************************************************/
4911 void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data)
4913 tBTM_STATUS btm_status = 0;
4915 bta_dm_cb.p_multi_adv_cback = p_data->ble_multi_adv_enb.p_cback;
4916 if (BTM_BleMaxMultiAdvInstanceCount() > 0 && NULL != p_data->ble_multi_adv_enb.p_ref) {
4917 btm_status = BTM_BleEnableAdvInstance((tBTM_BLE_ADV_PARAMS *)
4918 p_data->ble_multi_adv_enb.p_params,
4919 p_data->ble_multi_adv_enb.p_cback,
4920 p_data->ble_multi_adv_enb.p_ref);
4923 if (BTM_CMD_STARTED != btm_status) {
4924 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_ENB_EVT, 0xFF,
4925 p_data->ble_multi_adv_enb.p_ref, BTA_FAILURE);
4928 /*******************************************************************************
4930 ** Function bta_dm_ble_multi_adv_param_upd
4932 ** Description This function updates multiple advertising instance parameters
4936 *******************************************************************************/
4937 void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data)
4939 tBTM_STATUS btm_status = 0;
4942 if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_param.inst_id > 0
4943 && p_data->ble_multi_adv_param.inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
4944 btm_status = BTM_BleUpdateAdvInstParam(p_data->ble_multi_adv_param.inst_id,
4945 (tBTM_BLE_ADV_PARAMS *)p_data->ble_multi_adv_param.p_params);
4948 if (BTM_CMD_STARTED != btm_status) {
4949 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_param.inst_id);
4950 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_PARAM_EVT,
4951 p_data->ble_multi_adv_param.inst_id, p_ref, BTA_FAILURE);
4954 /*******************************************************************************
4956 ** Function bta_dm_ble_multi_adv_data
4958 ** Description This function write multiple advertising instance adv data
4959 ** or scan response data
4963 *******************************************************************************/
4964 void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data)
4966 tBTM_STATUS btm_status = 0;
4969 if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_data.inst_id > 0
4970 && p_data->ble_multi_adv_data.inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
4971 btm_status = BTM_BleCfgAdvInstData(p_data->ble_multi_adv_data.inst_id,
4972 p_data->ble_multi_adv_data.is_scan_rsp,
4973 p_data->ble_multi_adv_data.data_mask,
4974 (tBTM_BLE_ADV_DATA *)p_data->ble_multi_adv_data.p_data);
4977 if (BTM_CMD_STARTED != btm_status) {
4978 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_data.inst_id);
4979 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DATA_EVT,
4980 p_data->ble_multi_adv_data.inst_id, p_ref, BTA_FAILURE);
4984 /*******************************************************************************
4986 ** Function btm_dm_ble_multi_adv_disable
4988 ** Description This function disable a single adv instance
4992 *******************************************************************************/
4993 void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data)
4995 tBTM_STATUS btm_status = 0;
4998 if (BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_disable.inst_id > 0
4999 && p_data->ble_multi_adv_disable.inst_id < BTM_BleMaxMultiAdvInstanceCount()) {
5000 btm_status = BTM_BleDisableAdvInstance(p_data->ble_multi_adv_disable.inst_id);
5003 if (BTM_CMD_STARTED != btm_status) {
5004 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_disable.inst_id);
5005 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DISABLE_EVT,
5006 p_data->ble_multi_adv_disable.inst_id, p_ref, BTA_FAILURE);
5010 /*******************************************************************************
5012 ** Function bta_dm_ble_setup_storage
5014 ** Description This function configures up the storage parameters for ADV batch scanning
5018 *******************************************************************************/
5019 void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data)
5021 tBTM_STATUS btm_status = 0;
5022 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5024 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5026 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5027 btm_status = BTM_BleSetStorageConfig(p_data->ble_set_storage.batch_scan_full_max,
5028 p_data->ble_set_storage.batch_scan_trunc_max,
5029 p_data->ble_set_storage.batch_scan_notify_threshold,
5030 p_data->ble_set_storage.p_setup_cback,
5031 p_data->ble_set_storage.p_thres_cback,
5032 p_data->ble_set_storage.p_read_rep_cback,
5033 p_data->ble_set_storage.ref_value);
5036 if (BTM_CMD_STARTED != btm_status)
5037 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, p_data->ble_set_storage.ref_value,
5041 /*******************************************************************************
5043 ** Function bta_dm_ble_enable_batch_scan
5045 ** Description This function sets up the parameters and enables batch scan
5049 *******************************************************************************/
5050 void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data)
5052 tBTM_STATUS btm_status = 0;
5053 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5055 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5057 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5058 btm_status = BTM_BleEnableBatchScan(p_data->ble_enable_scan.scan_mode,
5059 p_data->ble_enable_scan.scan_int,
5060 p_data->ble_enable_scan.scan_window,
5061 p_data->ble_enable_scan.discard_rule,
5062 p_data->ble_enable_scan.addr_type,
5063 p_data->ble_enable_scan.ref_value);
5066 if (BTM_CMD_STARTED != btm_status)
5067 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_ENABLE_EVT, p_data->ble_enable_scan.ref_value,
5071 /*******************************************************************************
5073 ** Function bta_dm_ble_disable_batch_scan
5075 ** Description This function disables the batch scan
5079 *******************************************************************************/
5080 void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data)
5083 tBTM_STATUS btm_status = 0;
5084 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5086 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5088 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5089 btm_status = BTM_BleDisableBatchScan(p_data->ble_disable_scan.ref_value);
5092 if (BTM_CMD_STARTED != btm_status)
5093 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_DISABLE_EVT, p_data->ble_enable_scan.ref_value,
5097 /*******************************************************************************
5099 ** Function bta_dm_ble_read_scan_reports
5101 ** Description This function reads the batch scan reports
5105 *******************************************************************************/
5106 void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data)
5108 tBTM_STATUS btm_status = 0;
5109 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5111 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5113 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5114 btm_status = BTM_BleReadScanReports(p_data->ble_read_reports.scan_type,
5115 p_data->ble_read_reports.ref_value);
5118 if (BTM_CMD_STARTED != btm_status)
5119 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, p_data->ble_enable_scan.ref_value,
5123 /*******************************************************************************
5125 ** Function bta_dm_ble_track_advertiser
5127 ** Description This function tracks the specific advertiser
5131 *******************************************************************************/
5132 void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data)
5134 tBTM_STATUS btm_status = 0;
5136 memset(&bda, 0 , sizeof(BD_ADDR));
5137 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5138 tBTA_DM_BLE_TRACK_ADV_DATA track_adv_data;
5140 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5142 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) {
5143 btm_status = BTM_BleTrackAdvertiser((tBTM_BLE_TRACK_ADV_CBACK *)
5144 p_data->ble_track_advert.p_track_adv_cback,
5145 p_data->ble_track_advert.ref_value);
5148 if (BTM_CMD_STARTED != btm_status) {
5149 memset(&track_adv_data, 0, sizeof(tBTA_DM_BLE_TRACK_ADV_DATA));
5150 track_adv_data.advertiser_info_present = NO_ADV_INFO_PRESENT; /* Indicates failure */
5151 track_adv_data.client_if = (UINT8)p_data->ble_track_advert.ref_value;
5152 p_data->ble_track_advert.p_track_adv_cback(&track_adv_data);
5156 /*******************************************************************************
5158 ** Function bta_ble_scan_setup_cb
5160 ** Description Handle the setup callback from BTM layer and forward it to app layer
5164 *******************************************************************************/
5165 void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_value,
5168 tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0;
5170 APPL_TRACE_DEBUG("bta_ble_scan_setup_cb : evt: %d, ref_value: %d, status:%d", evt,
5174 case BTM_BLE_BATCH_SCAN_ENABLE_EVT:
5175 bta_evt = BTA_BLE_BATCH_SCAN_ENB_EVT;
5177 case BTM_BLE_BATCH_SCAN_CFG_STRG_EVT:
5178 bta_evt = BTA_BLE_BATCH_SCAN_CFG_STRG_EVT;
5180 case BTM_BLE_BATCH_SCAN_DISABLE_EVT:
5181 bta_evt = BTA_BLE_BATCH_SCAN_DIS_EVT;
5183 case BTM_BLE_BATCH_SCAN_PARAM_EVT:
5184 bta_evt = BTA_BLE_BATCH_SCAN_PARAM_EVT;
5190 if (NULL != bta_dm_cb.p_setup_cback) {
5191 bta_dm_cb.p_setup_cback(bta_evt, ref_value, status);
5196 #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
5197 /*******************************************************************************
5199 ** Function bta_ble_scan_pf_cmpl
5201 ** Description ADV payload filtering operation complete callback
5204 ** Returns TRUE if handled, otherwise FALSE.
5206 *******************************************************************************/
5207 static void bta_ble_scan_cfg_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op,
5208 tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status,
5209 tBTM_BLE_REF_VALUE ref_value)
5211 tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
5213 APPL_TRACE_DEBUG("bta_ble_scan_cfg_cmpl: %d, %d, %d, %d", action, cfg_op, avbl_space, status);
5215 if (bta_dm_cb.p_scan_filt_cfg_cback) {
5216 bta_dm_cb.p_scan_filt_cfg_cback(action, cfg_op, avbl_space, st, ref_value);
5220 /*******************************************************************************
5222 ** Function bta_dm_cfg_filter_cond
5224 ** Description This function configure adv payload filtering condition
5228 *******************************************************************************/
5229 void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data)
5231 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5232 tBTA_STATUS status = BTA_FAILURE;
5234 tBTM_BLE_VSC_CB cmn_vsc_cb;
5236 APPL_TRACE_DEBUG("bta_dm_cfg_filter_cond");
5237 BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5238 if (0 != cmn_vsc_cb.filter_support) {
5239 if ((st = BTM_BleCfgFilterCondition(p_data->ble_cfg_filter_cond.action,
5240 p_data->ble_cfg_filter_cond.cond_type,
5241 (tBTM_BLE_PF_FILT_INDEX)p_data->ble_cfg_filter_cond.filt_index,
5242 (tBTM_BLE_PF_COND_PARAM *)p_data->ble_cfg_filter_cond.p_cond_param,
5243 bta_ble_scan_cfg_cmpl, p_data->ble_cfg_filter_cond.ref_value))
5244 == BTM_CMD_STARTED) {
5245 bta_dm_cb.p_scan_filt_cfg_cback = p_data->ble_cfg_filter_cond.p_filt_cfg_cback;
5250 if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback)
5251 p_data->ble_cfg_filter_cond.p_filt_cfg_cback(BTA_DM_BLE_PF_CONFIG_EVT,
5252 p_data->ble_cfg_filter_cond.cond_type, 0, status,
5253 p_data->ble_cfg_filter_cond.ref_value);
5257 /*******************************************************************************
5259 ** Function bta_dm_enable_scan_filter
5261 ** Description This function enable/disable adv payload filtering condition
5265 *******************************************************************************/
5266 void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data)
5268 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5269 tBTA_STATUS status = BTA_FAILURE;
5271 tBTM_BLE_VSC_CB cmn_vsc_cb;
5272 APPL_TRACE_DEBUG("bta_dm_enable_scan_filter");
5273 BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5275 if (0 != cmn_vsc_cb.filter_support) {
5276 if ((st = BTM_BleEnableDisableFilterFeature(p_data->ble_enable_scan_filt.action,
5277 p_data->ble_enable_scan_filt.p_filt_status_cback,
5278 (tBTM_BLE_REF_VALUE)p_data->ble_enable_scan_filt.ref_value)) == BTM_CMD_STARTED) {
5279 bta_dm_cb.p_scan_filt_status_cback = p_data->ble_enable_scan_filt.p_filt_status_cback;
5284 if (p_data->ble_enable_scan_filt.p_filt_status_cback)
5285 p_data->ble_enable_scan_filt.p_filt_status_cback (BTA_DM_BLE_PF_ENABLE_EVT,
5286 p_data->ble_enable_scan_filt.ref_value, status);
5290 /*******************************************************************************
5292 ** Function bta_dm_scan_filter_param_setup
5294 ** Description This function sets up scan filter params
5298 *******************************************************************************/
5299 void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data)
5301 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5302 tBTA_STATUS status = BTA_FAILURE;
5304 tBTM_BLE_VSC_CB cmn_vsc_cb;
5306 APPL_TRACE_DEBUG("bta_dm_scan_filter_param_setup");
5307 BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5308 if (0 != cmn_vsc_cb.filter_support) {
5309 if ((st = BTM_BleAdvFilterParamSetup(p_data->ble_scan_filt_param_setup.action,
5310 p_data->ble_scan_filt_param_setup.filt_index,
5311 (tBTM_BLE_PF_FILT_PARAMS *)&p_data->ble_scan_filt_param_setup.filt_params,
5312 p_data->ble_scan_filt_param_setup.p_target,
5313 p_data->ble_scan_filt_param_setup.p_filt_param_cback,
5314 p_data->ble_scan_filt_param_setup.ref_value)) == BTM_CMD_STARTED) {
5315 bta_dm_cb.p_scan_filt_param_cback = p_data->ble_scan_filt_param_setup.p_filt_param_cback;
5320 if (p_data->ble_scan_filt_param_setup.p_filt_param_cback)
5321 p_data->ble_scan_filt_param_setup.p_filt_param_cback (BTA_DM_BLE_PF_ENABLE_EVT, 0,
5322 p_data->ble_scan_filt_param_setup.ref_value, status);
5328 /*******************************************************************************
5330 ** Function bta_ble_enable_scan_cmpl
5332 ** Description ADV payload filtering enable / disable complete callback
5337 *******************************************************************************/
5338 static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time,
5339 tBTM_BLE_RX_TIME_MS rx_time,
5340 tBTM_BLE_IDLE_TIME_MS idle_time,
5341 tBTM_BLE_ENERGY_USED energy_used,
5344 tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE;
5345 tBTA_DM_CONTRL_STATE ctrl_state = 0;
5346 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
5347 if (BTA_SUCCESS == st) {
5348 ctrl_state = bta_dm_pm_obtain_controller_state();
5351 if (bta_dm_cb.p_energy_info_cback) {
5352 bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, ctrl_state, st);
5356 /*******************************************************************************
5358 ** Function bta_dm_ble_get_energy_info
5360 ** Description This function obtains the energy info
5364 *******************************************************************************/
5365 void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data)
5367 tBTM_STATUS btm_status = 0;
5369 bta_dm_cb.p_energy_info_cback = p_data->ble_energy_info.p_energy_info_cback;
5370 btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl);
5371 if (BTM_CMD_STARTED != btm_status) {
5372 bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status);
5376 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
5377 #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
5378 #define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000
5381 /*******************************************************************************
5383 ** Function bta_dm_gattc_register
5385 ** Description Register with GATTC in DM if BLE is needed.
5390 *******************************************************************************/
5391 #if (GATTC_INCLUDED == TRUE)
5392 static void bta_dm_gattc_register(void)
5394 tBT_UUID app_uuid = {LEN_UUID_128, {0}};
5396 if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF) {
5397 memset (&app_uuid.uu.uuid128, 0x87, LEN_UUID_128);
5398 BTA_GATTC_AppRegister(&app_uuid, bta_dm_gattc_callback);
5401 #endif /* GATTC_INCLUDED == TRUE */
5402 /*******************************************************************************
5404 ** Function btm_dm_start_disc_gatt_services
5406 ** Description This function starts a GATT service search request.
5410 *******************************************************************************/
5411 static void btm_dm_start_disc_gatt_services (UINT16 conn_id)
5413 tBT_UUID *p_uuid = bta_dm_search_cb.p_srvc_uuid +
5414 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
5416 p_uuid = bta_dm_search_cb.p_srvc_uuid +
5417 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
5419 /* always search for all services */
5420 BTA_GATTC_ServiceSearchRequest(conn_id, p_uuid);
5423 /*******************************************************************************
5425 ** Function bta_dm_gatt_disc_result
5427 ** Description This function process the GATT service search result.
5431 *******************************************************************************/
5432 #if (GATTC_INCLUDED == TRUE)
5433 static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
5435 tBTA_DM_SEARCH result;
5438 * This logic will not work for gatt case. We are checking against the bluetooth profiles here
5439 * just copy the GATTID in raw data field and send it across.
5443 if ( bta_dm_search_cb.ble_raw_used + sizeof(tBTA_GATT_ID) < bta_dm_search_cb.ble_raw_size ) {
5444 APPL_TRACE_DEBUG("ADDING BLE SERVICE uuid=0x%x, ble_ptr = %p, ble_raw_used = 0x%x",
5445 service_id.uuid.uu.uuid16, bta_dm_search_cb.p_ble_rawdata, bta_dm_search_cb.ble_raw_used);
5447 if (bta_dm_search_cb.p_ble_rawdata) {
5448 memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used), &service_id,
5449 sizeof(service_id) );
5451 bta_dm_search_cb.ble_raw_used += sizeof(service_id);
5453 APPL_TRACE_ERROR("p_ble_rawdata is NULL");
5457 APPL_TRACE_ERROR("%s out of room to accomodate more service ids ble_raw_size = %d ble_raw_used = %d", __FUNCTION__, bta_dm_search_cb.ble_raw_size, bta_dm_search_cb.ble_raw_used );
5460 LOG_INFO("%s service_id_uuid_len=%d ", __func__, service_id.uuid.len);
5461 if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
5463 /* send result back to app now, one by one */
5464 bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
5465 BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN - 1));
5466 result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
5467 memcpy(&result.disc_ble_res.service, &service_id.uuid, sizeof(tBT_UUID));
5469 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
5472 #endif /* #if (GATTC_INCLUDED == TRUE) */
5473 /*******************************************************************************
5475 ** Function bta_dm_gatt_disc_complete
5477 ** Description This function process the GATT service search complete.
5481 *******************************************************************************/
5482 static void bta_dm_gatt_disc_complete(UINT16 conn_id, tBTA_GATT_STATUS status)
5486 APPL_TRACE_DEBUG("bta_dm_gatt_disc_complete conn_id = %d", conn_id);
5488 if (bta_dm_search_cb.uuid_to_search > 0) {
5489 bta_dm_search_cb.uuid_to_search --;
5492 if (status == BTA_GATT_OK && bta_dm_search_cb.uuid_to_search > 0) {
5493 btm_dm_start_disc_gatt_services(conn_id);
5495 bta_dm_search_cb.uuid_to_search = 0;
5497 /* no more services to be discovered */
5498 if ((p_msg = (tBTA_DM_MSG *) osi_malloc(sizeof(tBTA_DM_MSG))) != NULL) {
5499 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
5500 p_msg->disc_result.result.disc_res.result = (status == BTA_GATT_OK) ? BTA_SUCCESS : BTA_FAILURE;
5501 APPL_TRACE_DEBUG("%s service found: 0x%08x", __FUNCTION__,
5502 bta_dm_search_cb.services_found);
5503 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
5504 p_msg->disc_result.result.disc_res.num_uuids = 0;
5505 p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
5506 bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
5507 BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
5508 bta_dm_get_remname(), (BD_NAME_LEN - 1));
5510 /* make sure the string is terminated */
5511 p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
5513 p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE;
5514 if ( bta_dm_search_cb.ble_raw_used > 0 ) {
5515 p_msg->disc_result.result.disc_res.p_raw_data = osi_malloc(bta_dm_search_cb.ble_raw_used);
5517 memcpy( p_msg->disc_result.result.disc_res.p_raw_data,
5518 bta_dm_search_cb.p_ble_rawdata,
5519 bta_dm_search_cb.ble_raw_used );
5521 p_msg->disc_result.result.disc_res.raw_data_size = bta_dm_search_cb.ble_raw_used;
5523 p_msg->disc_result.result.disc_res.p_raw_data = NULL;
5524 bta_dm_search_cb.p_ble_rawdata = 0;
5527 bta_sys_sendmsg(p_msg);
5530 if (conn_id != BTA_GATT_INVALID_CONN_ID) {
5531 /* start a GATT channel close delay timer */
5532 bta_sys_start_timer(&bta_dm_search_cb.gatt_close_timer, BTA_DM_DISC_CLOSE_TOUT_EVT,
5533 BTA_DM_GATT_CLOSE_DELAY_TOUT);
5534 bdcpy(bta_dm_search_cb.pending_close_bda, bta_dm_search_cb.peer_bdaddr);
5536 bta_dm_search_cb.gatt_disc_active = FALSE;
5540 /*******************************************************************************
5542 ** Function bta_dm_close_gatt_conn
5544 ** Description This function close the GATT connection after delay timeout.
5548 *******************************************************************************/
5549 #if (GATTC_INCLUDED == TRUE)
5550 void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data)
5554 if (bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID) {
5555 BTA_GATTC_Close(bta_dm_search_cb.conn_id);
5558 memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
5559 bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
5561 #endif /* #if (GATTC_INCLUDED == TRUE) */
5562 /*******************************************************************************
5564 ** Function btm_dm_start_gatt_discovery
5566 ** Description This is GATT initiate the service search by open a GATT connection
5571 *******************************************************************************/
5572 #if (GATTC_INCLUDED == TRUE)
5573 void btm_dm_start_gatt_discovery (BD_ADDR bd_addr)
5575 bta_dm_search_cb.gatt_disc_active = TRUE;
5577 /* connection is already open */
5578 if (bdcmp(bta_dm_search_cb.pending_close_bda, bd_addr) == 0 &&
5579 bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID) {
5580 memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
5581 bta_sys_stop_timer(&bta_dm_search_cb.gatt_close_timer);
5582 btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
5584 BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE, BTA_GATT_TRANSPORT_LE);
5587 #endif /* #if (GATTC_INCLUDED == TRUE) */
5588 /*******************************************************************************
5590 ** Function bta_dm_cancel_gatt_discovery
5592 ** Description This is GATT cancel the GATT service search.
5596 *******************************************************************************/
5597 #if (GATTC_INCLUDED == TRUE)
5598 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr)
5600 if (bta_dm_search_cb.conn_id == BTA_GATT_INVALID_CONN_ID) {
5601 BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, TRUE);
5604 bta_dm_gatt_disc_complete(bta_dm_search_cb.conn_id, (tBTA_GATT_STATUS) BTA_GATT_ERROR);
5606 #endif /* #if (GATTC_INCLUDED == TRUE) */
5607 /*******************************************************************************
5609 ** Function bta_dm_proc_open_evt
5611 ** Description process BTA_GATTC_OPEN_EVT in DM.
5615 *******************************************************************************/
5616 void bta_dm_proc_open_evt(tBTA_GATTC_OPEN *p_data)
5621 p1 = bta_dm_search_cb.peer_bdaddr;
5622 p2 = p_data->remote_bda;
5624 APPL_TRACE_DEBUG("DM Search state= %d search_cb.peer_dbaddr: [%08x%04x] connected_bda= [%08x%04x] ",
5625 bta_dm_search_cb.state,
5626 ((p1[0]) << 24) + ((p1[1]) << 16) + ((p1[2]) << 8) + (p1[3]),
5627 ((p1[4]) << 8) + p1[5],
5628 ((p2[0]) << 24) + ((p2[1]) << 16) + ((p2[2]) << 8) + (p2[3]),
5629 ((p2[4]) << 8) + p2[5]);
5631 APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d" ,
5636 bta_dm_search_cb.conn_id = p_data->conn_id;
5638 if (p_data->status == BTA_GATT_OK) {
5639 btm_dm_start_disc_gatt_services(p_data->conn_id);
5641 bta_dm_gatt_disc_complete(BTA_GATT_INVALID_CONN_ID, p_data->status);
5645 /*******************************************************************************
5647 ** Function bta_dm_gattc_callback
5649 ** Description This is GATT client callback function used in DM.
5653 *******************************************************************************/
5654 #if (GATTC_INCLUDED == TRUE)
5655 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
5657 APPL_TRACE_DEBUG("bta_dm_gattc_callback event = %d", event);
5660 case BTA_GATTC_REG_EVT:
5661 APPL_TRACE_DEBUG("BTA_GATTC_REG_EVT client_if = %d", p_data->reg_oper.client_if);
5662 if (p_data->reg_oper.status == BTA_GATT_OK) {
5663 bta_dm_search_cb.client_if = p_data->reg_oper.client_if;
5665 bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF;
5669 case BTA_GATTC_OPEN_EVT:
5670 bta_dm_proc_open_evt(&p_data->open);
5673 case BTA_GATTC_SEARCH_RES_EVT:
5674 bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid);
5677 case BTA_GATTC_SEARCH_CMPL_EVT:
5678 if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) {
5679 bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
5683 case BTA_GATTC_CLOSE_EVT:
5684 APPL_TRACE_DEBUG("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason);
5685 /* in case of disconnect before search is completed */
5686 if ( (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) &&
5687 (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) &&
5688 !memcmp(p_data->close.remote_bda, bta_dm_search_cb.peer_bdaddr, BD_ADDR_LEN)) {
5689 bta_dm_gatt_disc_complete((UINT16)BTA_GATT_INVALID_CONN_ID, (tBTA_GATT_STATUS) BTA_GATT_ERROR);
5697 #endif /* #if (GATTC_INCLUDED == TRUE) */
5698 #endif /* BTA_GATT_INCLUDED */
5700 #if BLE_VND_INCLUDED == TRUE
5701 /*******************************************************************************
5703 ** Function bta_dm_ctrl_features_rd_cmpl_cback
5705 ** Description callback to handle controller feature read complete
5709 *******************************************************************************/
5710 static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result)
5712 APPL_TRACE_DEBUG("%s status = %d ", __FUNCTION__, result);
5713 if (result == BTM_SUCCESS) {
5714 if (bta_dm_cb.p_sec_cback) {
5715 bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
5718 APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d", __FUNCTION__, result);
5722 #endif /* BLE_VND_INCLUDED */
5724 #endif /* BLE_INCLUDED */