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 #define LOG_TAG "bt_bta_dm"
30 #include "bt_target.h"
33 #include "bta_dm_co.h"
34 #include "bta_dm_int.h"
39 #include "gap_api.h" /* For GAP_BleReadPeerPrefConnParams */
40 #include "bt_common.h"
42 #include "osi/include/log.h"
43 #include "osi/include/osi.h"
47 #if (GAP_INCLUDED == TRUE)
51 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
52 static void bta_dm_inq_cmpl_cb (void * p_result);
53 static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, BD_NAME bd_name);
54 static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name);
55 static void bta_dm_find_services ( BD_ADDR bd_addr);
56 static void bta_dm_discover_next_device(void);
57 static void bta_dm_sdp_callback (UINT16 sdp_status);
58 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);
59 static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, BOOLEAN min_16_digit);
60 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);
61 static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,BD_NAME bd_name, int result);
62 static void bta_dm_local_name_cback(BD_ADDR bd_addr);
63 static BOOLEAN bta_dm_check_av(UINT16 event);
64 static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data);
66 static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
68 /* Extended Inquiry Response */
69 static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data);
71 static void bta_dm_set_eir (char *local_name);
73 static void bta_dm_eir_search_services( tBTM_INQ_RESULTS *p_result,
74 tBTA_SERVICE_MASK *p_services_to_search,
75 tBTA_SERVICE_MASK *p_services_found);
77 static void bta_dm_search_timer_cback(void *data);
78 static void bta_dm_disable_conn_down_timer_cback(void *data);
79 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
80 static void bta_dm_adjust_roles(BOOLEAN delay_role_switch);
81 static char *bta_dm_get_remname(void);
82 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result);
84 static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport);
85 static void bta_dm_discover_device(BD_ADDR remote_bd_addr);
87 static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status );
88 static void bta_dm_disable_search_and_disc(void);
90 #if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
91 #if ((defined SMP_INCLUDED) && (SMP_INCLUDED == TRUE))
92 static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data);
94 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key);
95 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
96 static void bta_dm_gattc_register(void);
97 static void btm_dm_start_gatt_discovery(BD_ADDR bd_addr);
98 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr);
99 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data);
100 extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void);
103 #if BLE_VND_INCLUDED == TRUE
104 static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result);
107 #ifndef BTA_DM_BLE_ADV_CHNL_MAP
108 #define BTA_DM_BLE_ADV_CHNL_MAP (BTM_BLE_ADV_CHNL_37|BTM_BLE_ADV_CHNL_38|BTM_BLE_ADV_CHNL_39)
112 /* Disable timer interval (in milliseconds) */
113 #ifndef BTA_DM_DISABLE_TIMER_MS
114 #define BTA_DM_DISABLE_TIMER_MS 5000
117 /* Disable timer retrial interval (in milliseconds) */
118 #ifndef BTA_DM_DISABLE_TIMER_RETRIAL_MS
119 #define BTA_DM_DISABLE_TIMER_RETRIAL_MS 1500
122 /* Disable connection down timer (in milliseconds) */
123 #ifndef BTA_DM_DISABLE_CONN_DOWN_TIMER_MS
124 #define BTA_DM_DISABLE_CONN_DOWN_TIMER_MS 1000
127 /* Switch delay timer (in milliseconds) */
128 #ifndef BTA_DM_SWITCH_DELAY_TIMER_MS
129 #define BTA_DM_SWITCH_DELAY_TIMER_MS 500
132 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr);
133 static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir);
134 static void bta_dm_observe_cmpl_cb(void * p_result);
135 static void bta_dm_delay_role_switch_cback(void *data);
136 extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8* p_uuid128);
137 static void bta_dm_disable_timer_cback(void *data);
140 const UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID] =
142 UUID_SERVCLASS_PNP_INFORMATION, /* Reserved */
143 UUID_SERVCLASS_SERIAL_PORT, /* BTA_SPP_SERVICE_ID */
144 UUID_SERVCLASS_DIALUP_NETWORKING, /* BTA_DUN_SERVICE_ID */
145 UUID_SERVCLASS_AUDIO_SOURCE, /* BTA_A2DP_SOURCE_SERVICE_ID */
146 UUID_SERVCLASS_LAN_ACCESS_USING_PPP, /* BTA_LAP_SERVICE_ID */
147 UUID_SERVCLASS_HEADSET, /* BTA_HSP_HS_SERVICE_ID */
148 UUID_SERVCLASS_HF_HANDSFREE, /* BTA_HFP_HS_SERVICE_ID */
149 UUID_SERVCLASS_OBEX_OBJECT_PUSH, /* BTA_OPP_SERVICE_ID */
150 UUID_SERVCLASS_OBEX_FILE_TRANSFER, /* BTA_FTP_SERVICE_ID */
151 UUID_SERVCLASS_CORDLESS_TELEPHONY, /* BTA_CTP_SERVICE_ID */
152 UUID_SERVCLASS_INTERCOM, /* BTA_ICP_SERVICE_ID */
153 UUID_SERVCLASS_IRMC_SYNC, /* BTA_SYNC_SERVICE_ID */
154 UUID_SERVCLASS_DIRECT_PRINTING, /* BTA_BPP_SERVICE_ID */
155 UUID_SERVCLASS_IMAGING_RESPONDER, /* BTA_BIP_SERVICE_ID */
156 UUID_SERVCLASS_PANU, /* BTA_PANU_SERVICE_ID */
157 UUID_SERVCLASS_NAP, /* BTA_NAP_SERVICE_ID */
158 UUID_SERVCLASS_GN, /* BTA_GN_SERVICE_ID */
159 UUID_SERVCLASS_SAP, /* BTA_SAP_SERVICE_ID */
160 UUID_SERVCLASS_AUDIO_SINK, /* BTA_A2DP_SERVICE_ID */
161 UUID_SERVCLASS_AV_REMOTE_CONTROL, /* BTA_AVRCP_SERVICE_ID */
162 UUID_SERVCLASS_HUMAN_INTERFACE, /* BTA_HID_SERVICE_ID */
163 UUID_SERVCLASS_VIDEO_SINK, /* BTA_VDP_SERVICE_ID */
164 UUID_SERVCLASS_PBAP_PSE, /* BTA_PBAP_SERVICE_ID */
165 UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, /* BTA_HSP_SERVICE_ID */
166 UUID_SERVCLASS_AG_HANDSFREE, /* BTA_HFP_SERVICE_ID */
167 UUID_SERVCLASS_MESSAGE_ACCESS, /* BTA_MAP_SERVICE_ID */
168 UUID_SERVCLASS_MESSAGE_NOTIFICATION, /* BTA_MN_SERVICE_ID */
169 UUID_SERVCLASS_HDP_PROFILE, /* BTA_HDP_SERVICE_ID */
170 UUID_SERVCLASS_PBAP_PCE /* BTA_PCE_SERVICE_ID */
171 #if BLE_INCLUDED && BTA_GATT_INCLUDED
172 ,UUID_PROTOCOL_ATT /* BTA_GATT_SERVICE_ID */
177 * NOTE : The number of element in bta_service_id_to_btm_srv_id_lkup_tbl should be matching with
178 * the value BTA_MAX_SERVICE_ID in bta_api.h
180 * i.e., If you add new Service ID for BTA, the correct security ID of the new service
181 * from Security service definitions (btm_api.h) should be added to this lookup table.
183 const UINT32 bta_service_id_to_btm_srv_id_lkup_tbl [BTA_MAX_SERVICE_ID] =
186 BTM_SEC_SERVICE_SERIAL_PORT, /* BTA_SPP_SERVICE_ID */
187 BTM_SEC_SERVICE_DUN, /* BTA_DUN_SERVICE_ID */
188 BTM_SEC_SERVICE_AVDTP, /* BTA_AUDIO_SOURCE_SERVICE_ID */
189 BTM_SEC_SERVICE_LAN_ACCESS, /* BTA_LAP_SERVICE_ID */
190 BTM_SEC_SERVICE_HEADSET_AG, /* BTA_HSP_SERVICE_ID */
191 BTM_SEC_SERVICE_AG_HANDSFREE, /* BTA_HFP_SERVICE_ID */
192 BTM_SEC_SERVICE_OBEX, /* BTA_OPP_SERVICE_ID */
193 BTM_SEC_SERVICE_OBEX_FTP, /* BTA_FTP_SERVICE_ID */
194 BTM_SEC_SERVICE_CORDLESS, /* BTA_CTP_SERVICE_ID */
195 BTM_SEC_SERVICE_INTERCOM, /* BTA_ICP_SERVICE_ID */
196 BTM_SEC_SERVICE_IRMC_SYNC, /* BTA_SYNC_SERVICE_ID */
197 BTM_SEC_SERVICE_BPP_JOB, /* BTA_BPP_SERVICE_ID */
198 BTM_SEC_SERVICE_BIP, /* BTA_BIP_SERVICE_ID */
199 BTM_SEC_SERVICE_BNEP_PANU, /* BTA_PANU_SERVICE_ID */
200 BTM_SEC_SERVICE_BNEP_NAP, /* BTA_NAP_SERVICE_ID */
201 BTM_SEC_SERVICE_BNEP_GN, /* BTA_GN_SERVICE_ID */
202 BTM_SEC_SERVICE_SAP, /* BTA_SAP_SERVICE_ID */
203 BTM_SEC_SERVICE_AVDTP, /* BTA_A2DP_SERVICE_ID */
204 BTM_SEC_SERVICE_AVCTP, /* BTA_AVRCP_SERVICE_ID */
205 BTM_SEC_SERVICE_HIDH_SEC_CTRL, /* BTA_HID_SERVICE_ID */
206 BTM_SEC_SERVICE_AVDTP, /* BTA_VDP_SERVICE_ID */
207 BTM_SEC_SERVICE_PBAP, /* BTA_PBAP_SERVICE_ID */
208 BTM_SEC_SERVICE_HEADSET, /* BTA_HSP_HS_SERVICE_ID */
209 BTM_SEC_SERVICE_HF_HANDSFREE, /* BTA_HFP_HS_SERVICE_ID */
210 BTM_SEC_SERVICE_MAP, /* BTA_MAP_SERVICE_ID */
211 BTM_SEC_SERVICE_MAP, /* BTA_MN_SERVICE_ID */
212 BTM_SEC_SERVICE_HDP_SNK, /* BTA_HDP_SERVICE_ID */
213 BTM_SEC_SERVICE_PBAP /* BTA_PCE_SERVICE_ID */
214 #if BLE_INCLUDED && BTA_GATT_INCLUDED
215 ,BTM_SEC_SERVICE_ATT /* BTA_GATT_SERVICE_ID */
220 /* bta security callback */
221 const tBTM_APPL_INFO bta_security =
223 &bta_dm_authorize_cback,
225 &bta_dm_new_link_key_cback,
226 &bta_dm_authentication_complete_cback,
227 &bta_dm_bond_cancel_complete_cback,
228 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
233 #if BLE_INCLUDED == TRUE
234 #if SMP_INCLUDED == TRUE
235 ,&bta_dm_ble_smp_cback
237 ,&bta_dm_ble_id_key_cback
242 #define MAX_DISC_RAW_DATA_BUF (4096)
243 UINT8 g_disc_raw_data_buf[MAX_DISC_RAW_DATA_BUF];
245 extern DEV_CLASS local_device_default_class;
246 extern fixed_queue_t *btu_bta_alarm_queue;
248 /*******************************************************************************
250 ** Function bta_dm_enable
252 ** Description Initialises the BT device manager
257 *******************************************************************************/
258 void bta_dm_enable(tBTA_DM_MSG *p_data)
260 tBTA_DM_ENABLE enable_event;
262 /* if already in use, return an error */
263 if( bta_dm_cb.is_bta_dm_active == TRUE )
265 APPL_TRACE_WARNING("%s Device already started by another application", __func__);
266 memset(&enable_event, 0, sizeof(tBTA_DM_ENABLE));
267 enable_event.status = BTA_FAILURE;
268 if (p_data->enable.p_sec_cback != NULL)
269 p_data->enable.p_sec_cback(BTA_DM_ENABLE_EVT, (tBTA_DM_SEC *)&enable_event);
273 /* first, register our callback to SYS HW manager */
274 bta_sys_hw_register( BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback );
276 /* make sure security callback is saved - if no callback, do not erase the previous one,
277 it could be an error recovery mechanism */
278 if( p_data->enable.p_sec_cback != NULL )
279 bta_dm_cb.p_sec_cback = p_data->enable.p_sec_cback;
280 /* notify BTA DM is now active */
281 bta_dm_cb.is_bta_dm_active = TRUE;
283 /* send a message to BTA SYS */
284 tBTA_SYS_HW_MSG *sys_enable_event =
285 (tBTA_SYS_HW_MSG *)osi_malloc(sizeof(tBTA_SYS_HW_MSG));
286 sys_enable_event->hdr.event = BTA_SYS_API_ENABLE_EVT;
287 sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;
289 bta_sys_sendmsg(sys_enable_event);
292 /*******************************************************************************
294 ** Function bta_dm_init_cb
296 ** Description Initializes or re-initializes the bta_dm_cb control block
301 *******************************************************************************/
302 void bta_dm_init_cb(void)
305 * TODO: Should alarm_free() the bta_dm_cb timers during graceful
308 alarm_free(bta_dm_cb.disable_timer);
309 alarm_free(bta_dm_cb.switch_delay_timer);
310 for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
311 for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
312 alarm_free(bta_dm_cb.pm_timer[i].timer[j]);
315 memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
316 bta_dm_cb.disable_timer = alarm_new("bta_dm.disable_timer");
317 bta_dm_cb.switch_delay_timer = alarm_new("bta_dm.switch_delay_timer");
318 for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
319 for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
320 bta_dm_cb.pm_timer[i].timer[j] = alarm_new("bta_dm.pm_timer");
325 /*******************************************************************************
327 ** Function bta_dm_sys_hw_cback
329 ** Description callback register to SYS to get HW status updates
334 *******************************************************************************/
335 static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
338 tBTA_DM_SEC_CBACK *temp_cback;
339 #if BLE_INCLUDED == TRUE
342 tBTA_BLE_LOCAL_ID_KEYS id_key;
345 APPL_TRACE_DEBUG("%s with event: %i", __func__, status);
347 /* On H/W error evt, report to the registered DM application callback */
348 if (status == BTA_SYS_HW_ERROR_EVT) {
349 if( bta_dm_cb.p_sec_cback != NULL )
350 bta_dm_cb.p_sec_cback(BTA_DM_HW_ERROR_EVT, NULL);
354 if( status == BTA_SYS_HW_OFF_EVT )
356 if( bta_dm_cb.p_sec_cback != NULL )
357 bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL);
359 /* reinitialize the control block */
362 /* unregister from SYS */
363 bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH );
364 /* notify BTA DM is now unactive */
365 bta_dm_cb.is_bta_dm_active = FALSE;
368 if( status == BTA_SYS_HW_ON_EVT )
370 /* FIXME: We should not unregister as the SYS shall invoke this callback on a H/W error.
371 * We need to revisit when this platform has more than one BLuetooth H/W chip */
372 //bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH);
374 /* save security callback */
375 temp_cback = bta_dm_cb.p_sec_cback;
376 /* make sure the control block is properly initialized */
378 /* and retrieve the callback */
379 bta_dm_cb.p_sec_cback=temp_cback;
380 bta_dm_cb.is_bta_dm_active = TRUE;
382 /* hw is ready, go on with BTA DM initialization */
383 alarm_free(bta_dm_search_cb.search_timer);
384 alarm_free(bta_dm_search_cb.gatt_close_timer);
385 memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb));
387 * TODO: Should alarm_free() the bta_dm_search_cb timers during
390 bta_dm_search_cb.search_timer =
391 alarm_new("bta_dm_search.search_timer");
392 bta_dm_search_cb.gatt_close_timer =
393 alarm_new("bta_dm_search.gatt_close_timer");
395 memset(&bta_dm_conn_srvcs, 0, sizeof(bta_dm_conn_srvcs));
396 memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB));
398 memcpy(dev_class, p_bta_dm_cfg->dev_class, sizeof(dev_class));
399 BTM_SetDeviceClass (dev_class);
401 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
402 /* load BLE local information: ID keys, ER if available */
403 bta_dm_co_ble_load_local_keys(&key_mask, er, &id_key);
405 if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ER)
407 BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ER, (tBTM_BLE_LOCAL_KEYS *)&er);
409 if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ID)
411 BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ID, (tBTM_BLE_LOCAL_KEYS *)&id_key);
413 #if (defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
414 bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
415 #endif // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
416 #endif // (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
418 BTM_SecRegister((tBTM_APPL_INFO*)&bta_security);
419 BTM_SetDefaultLinkSuperTout(p_bta_dm_cfg->link_timeout);
420 BTM_WritePageTimeout(p_bta_dm_cfg->page_timeout);
421 bta_dm_cb.cur_policy = p_bta_dm_cfg->policy_settings;
422 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
423 BTM_RegBusyLevelNotif (bta_dm_bl_change_cback, NULL, BTM_BL_UPDATE_MASK|BTM_BL_ROLE_CHG_MASK);
425 #if BLE_VND_INCLUDED == TRUE
426 BTM_BleReadControllerFeatures (bta_dm_ctrl_features_rd_cmpl_cback);
429 /* Earlier, we used to invoke BTM_ReadLocalAddr which was just copying the bd_addr
430 from the control block and invoking the callback which was sending the DM_ENABLE_EVT.
431 But then we have a few HCI commands being invoked above which were still in progress
432 when the ENABLE_EVT was sent. So modified this to fetch the local name which forces
433 the DM_ENABLE_EVT to be sent only after all the init steps are complete */
434 BTM_ReadLocalDeviceNameFromController((tBTM_CMPL_CB *)bta_dm_local_name_cback);
436 bta_sys_rm_register((tBTA_SYS_CONN_CBACK*)bta_dm_rm_cback);
438 /* initialize bluetooth low power manager */
441 bta_sys_policy_register((tBTA_SYS_CONN_CBACK*)bta_dm_policy_cback);
443 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
444 bta_dm_gattc_register();
449 APPL_TRACE_DEBUG(" --- ignored event");
454 /*******************************************************************************
456 ** Function bta_dm_disable
458 ** Description Disables the BT device manager
463 *******************************************************************************/
464 void bta_dm_disable (tBTA_DM_MSG *p_data)
468 /* Set l2cap idle timeout to 0 (so BTE immediately disconnects ACL link after last channel is closed) */
469 L2CA_SetIdleTimeoutByBdAddr((UINT8 *)BT_BD_ANY, 0, BT_TRANSPORT_BR_EDR);
470 L2CA_SetIdleTimeoutByBdAddr((UINT8 *)BT_BD_ANY, 0, BT_TRANSPORT_LE);
472 /* disable all active subsystems */
473 bta_sys_disable(BTA_SYS_HW_BLUETOOTH);
475 BTM_SetDiscoverability(BTM_NON_DISCOVERABLE, 0, 0);
476 BTM_SetConnectability(BTM_NON_CONNECTABLE, 0, 0);
479 bta_dm_disable_search_and_disc();
480 bta_dm_cb.disabling = TRUE;
482 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
483 BTM_BleClearBgConnDev();
486 if(BTM_GetNumAclLinks()==0)
488 #if (defined(BTA_DISABLE_DELAY) && BTA_DISABLE_DELAY > 0)
489 /* If BTA_DISABLE_DELAY is defined and greater than zero, then delay the shutdown by
490 * BTA_DISABLE_DELAY milliseconds
492 APPL_TRACE_WARNING("%s BTA_DISABLE_DELAY set to %d ms",
493 __FUNCTION__, BTA_DISABLE_DELAY);
494 alarm_set_on_queue(bta_dm_cb.disable_timer, BTA_DISABLE_DELAY,
495 bta_dm_disable_conn_down_timer_cback, NULL,
496 btu_bta_alarm_queue);
498 bta_dm_disable_conn_down_timer_cback(NULL);
503 alarm_set_on_queue(bta_dm_cb.disable_timer, BTA_DM_DISABLE_TIMER_MS,
504 bta_dm_disable_timer_cback, UINT_TO_PTR(0),
505 btu_bta_alarm_queue);
509 /*******************************************************************************
511 ** Function bta_dm_disable_timer_cback
513 ** Description Called if the disable timer expires
514 ** Used to close ACL connections which are still active
520 *******************************************************************************/
521 static void bta_dm_disable_timer_cback(void *data)
524 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
525 BOOLEAN trigger_disc = FALSE;
526 uint32_t param = PTR_TO_UINT(data);
528 APPL_TRACE_EVENT("%s trial %u", __func__, param);
530 if ((BTM_GetNumAclLinks() && param) == 0)
532 for(i=0; i<bta_dm_cb.device_list.count; i++)
534 #if (BLE_INCLUDED == TRUE)
535 transport = bta_dm_cb.device_list.peer_device[i].transport;
537 btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, transport);
541 /* Retrigger disable timer in case ACL disconnect failed, DISABLE_EVT still need
542 to be sent out to avoid jave layer disable timeout */
545 alarm_set_on_queue(bta_dm_cb.disable_timer,
546 BTA_DM_DISABLE_TIMER_RETRIAL_MS,
547 bta_dm_disable_timer_cback, UINT_TO_PTR(1),
548 btu_bta_alarm_queue);
553 bta_dm_cb.disabling = FALSE;
555 bta_sys_remove_uuid(UUID_SERVCLASS_PNP_INFORMATION);
556 bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL);
563 /*******************************************************************************
565 ** Function bta_dm_set_dev_name
567 ** Description Sets local device name
572 *******************************************************************************/
573 void bta_dm_set_dev_name (tBTA_DM_MSG *p_data)
576 BTM_SetLocalDeviceName((char*)p_data->set_name.name);
577 bta_dm_set_eir ((char*)p_data->set_name.name);
580 /*******************************************************************************
582 ** Function bta_dm_set_visibility
584 ** Description Sets discoverability, connectability and pairability
589 *******************************************************************************/
590 void bta_dm_set_visibility(tBTA_DM_MSG *p_data)
592 UINT16 window, interval;
593 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
594 UINT16 le_disc_mode = BTM_BleReadDiscoverability();
595 UINT16 le_conn_mode = BTM_BleReadConnectability();
596 #endif // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
597 UINT16 disc_mode = BTM_ReadDiscoverability(&window, &interval);
598 UINT16 conn_mode = BTM_ReadConnectability(&window, &interval);
600 /* set modes for Discoverability and connectability if not ignore */
601 if (p_data->set_visibility.disc_mode != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE))
603 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
604 if ((p_data->set_visibility.disc_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE)
605 p_data->set_visibility.disc_mode =
606 ((p_data->set_visibility.disc_mode & ~BTA_DM_LE_IGNORE) | le_disc_mode);
607 #endif // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
608 if ((p_data->set_visibility.disc_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE)
609 p_data->set_visibility.disc_mode =
610 ((p_data->set_visibility.disc_mode & ~BTA_DM_IGNORE) | disc_mode);
612 BTM_SetDiscoverability(p_data->set_visibility.disc_mode,
613 bta_dm_cb.inquiry_scan_window,
614 bta_dm_cb.inquiry_scan_interval);
617 if (p_data->set_visibility.conn_mode != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE))
619 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
620 if ((p_data->set_visibility.conn_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE)
621 p_data->set_visibility.conn_mode =
622 ((p_data->set_visibility.conn_mode & ~BTA_DM_LE_IGNORE) | le_conn_mode);
623 #endif // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
624 if ((p_data->set_visibility.conn_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE)
625 p_data->set_visibility.conn_mode =
626 ((p_data->set_visibility.conn_mode & ~BTA_DM_IGNORE) | conn_mode);
628 BTM_SetConnectability(p_data->set_visibility.conn_mode,
629 bta_dm_cb.page_scan_window,
630 bta_dm_cb.page_scan_interval);
633 /* Send False or True if not ignore */
634 if (p_data->set_visibility.pair_mode != BTA_DM_IGNORE )
637 if (p_data->set_visibility.pair_mode == BTA_DM_NON_PAIRABLE)
638 bta_dm_cb.disable_pair_mode = TRUE;
640 bta_dm_cb.disable_pair_mode = FALSE;
644 /* Send False or True if not ignore */
645 if (p_data->set_visibility.conn_paired_only != BTA_DM_IGNORE)
648 if (p_data->set_visibility.conn_paired_only == BTA_DM_CONN_ALL)
649 bta_dm_cb.conn_paired_only = FALSE;
651 bta_dm_cb.conn_paired_only = TRUE;
655 /* Change mode if either mode is not ignore */
656 if (p_data->set_visibility.pair_mode != BTA_DM_IGNORE || p_data->set_visibility.conn_paired_only != BTA_DM_IGNORE)
657 BTM_SetPairableMode((BOOLEAN)(!(bta_dm_cb.disable_pair_mode)),bta_dm_cb.conn_paired_only);
661 /*******************************************************************************
663 ** Function bta_dm_process_remove_device
665 ** Description Removes device, Disconnects ACL link if required.
667 *******************************************************************************/
668 void bta_dm_process_remove_device(BD_ADDR bd_addr)
670 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
671 /* need to remove all pending background connection before unpair */
672 BTA_GATTC_CancelOpen(0, bd_addr, FALSE);
675 BTM_SecDeleteDevice(bd_addr);
677 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
678 /* remove all cached GATT information */
679 BTA_GATTC_Refresh(bd_addr);
682 if (bta_dm_cb.p_sec_cback)
684 tBTA_DM_SEC sec_event;
685 bdcpy(sec_event.link_down.bd_addr, bd_addr);
686 /* No connection, set status to success (acl disc code not valid) */
687 sec_event.link_down.status = HCI_SUCCESS;
688 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event);
692 /*******************************************************************************
694 ** Function bta_dm_remove_device
696 ** Description Removes device, disconnects ACL link if required.
698 *******************************************************************************/
699 void bta_dm_remove_device(tBTA_DM_MSG *p_data)
701 tBTA_DM_API_REMOVE_DEVICE *p_dev = &p_data->remove_dev;
702 BOOLEAN continue_delete_other_dev = FALSE;
706 BD_ADDR other_address;
707 bdcpy(other_address, p_dev->bd_addr);
709 /* If ACL exists for the device in the remove_bond message*/
710 BOOLEAN continue_delete_dev = FALSE;
711 UINT8 other_transport = BT_TRANSPORT_INVALID;
713 if (BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_LE) ||
714 BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_BR_EDR))
716 APPL_TRACE_DEBUG("%s: ACL Up count %d", __func__, bta_dm_cb.device_list.count);
717 continue_delete_dev = FALSE;
719 /* Take the link down first, and mark the device for removal when disconnected */
720 for(int i=0; i < bta_dm_cb.device_list.count; i++)
722 if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_dev->bd_addr))
724 UINT8 transport = BT_TRANSPORT_BR_EDR;
726 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
727 transport = bta_dm_cb.device_list.peer_device[i].transport;
728 #endif // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
729 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
730 btm_remove_acl(p_dev->bd_addr, transport);
731 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
732 APPL_TRACE_DEBUG("%s:transport = %d", __func__,
733 bta_dm_cb.device_list.peer_device[i].transport);
735 /* save the other transport to check if device is connected on other_transport */
736 if(bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_LE)
737 other_transport = BT_TRANSPORT_BR_EDR;
739 other_transport = BT_TRANSPORT_LE;
740 #endif // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
748 continue_delete_dev = TRUE;
750 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED)
751 // If it is DUMO device and device is paired as different address, unpair that device
752 // if different address
753 if ((other_transport && (BTM_ReadConnectedTransportAddress(other_address, other_transport))) ||
754 (!other_transport && (BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_BR_EDR) ||
755 BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_LE))))
757 continue_delete_other_dev = FALSE;
758 /* Take the link down first, and mark the device for removal when disconnected */
759 for(int i=0; i < bta_dm_cb.device_list.count; i++)
761 if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, other_address))
763 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING;
764 btm_remove_acl(other_address,bta_dm_cb.device_list.peer_device[i].transport);
771 APPL_TRACE_DEBUG("%s: continue to delete the other dev ", __func__);
772 continue_delete_other_dev = TRUE;
775 /* Delete the device mentioned in the msg */
776 if (continue_delete_dev)
777 bta_dm_process_remove_device(p_dev->bd_addr);
779 /* Delete the other paired device too */
780 BD_ADDR dummy_bda = {0};
781 if (continue_delete_other_dev && (bdcmp(other_address, dummy_bda) != 0))
782 bta_dm_process_remove_device(other_address);
785 /*******************************************************************************
787 ** Function bta_dm_add_device
789 ** Description This function adds a Link Key to an security database entry.
790 ** It is normally called during host startup to restore all required information
791 ** stored in the NVRAM.
793 *******************************************************************************/
794 void bta_dm_add_device (tBTA_DM_MSG *p_data)
796 tBTA_DM_API_ADD_DEVICE *p_dev = &p_data->add_dev;
799 UINT32 trusted_services_mask[BTM_SEC_SERVICE_ARRAY_SIZE];
801 UINT8 btm_mask_index = 0;
803 memset (trusted_services_mask, 0, sizeof(trusted_services_mask));
805 /* If not all zeros, the device class has been specified */
807 p_dc = (UINT8 *)p_dev->dc;
809 if (p_dev->link_key_known)
810 p_lc = (UINT8 *)p_dev->link_key;
812 if (p_dev->is_trusted)
814 /* covert BTA service mask to BTM mask */
815 while (p_dev->tm && (index < BTA_MAX_SERVICE_ID))
817 if (p_dev->tm & (UINT32)(1<<index))
820 btm_mask_index = bta_service_id_to_btm_srv_id_lkup_tbl[index] / BTM_SEC_ARRAY_BITS;
821 trusted_services_mask[btm_mask_index] |= (UINT32)(1 << (bta_service_id_to_btm_srv_id_lkup_tbl[index] - (UINT32)(btm_mask_index * 32)));
823 p_dev->tm &= (UINT32)(~(1<<index));
830 if (!BTM_SecAddDevice (p_dev->bd_addr, p_dc, p_dev->bd_name, p_dev->features,
831 trusted_services_mask, p_lc, p_dev->key_type, p_dev->io_cap,
834 APPL_TRACE_ERROR ("BTA_DM: Error adding device %08x%04x",
835 (p_dev->bd_addr[0]<<24)+(p_dev->bd_addr[1]<<16)+(p_dev->bd_addr[2]<<8)+p_dev->bd_addr[3],
836 (p_dev->bd_addr[4]<<8)+p_dev->bd_addr[5]);
840 /*******************************************************************************
842 ** Function bta_dm_close_acl
844 ** Description This function forces to close the connection to a remote device
845 ** and optionaly remove the device from security database if
848 *******************************************************************************/
849 void bta_dm_close_acl(tBTA_DM_MSG *p_data)
851 tBTA_DM_API_REMOVE_ACL *p_remove_acl = &p_data->remove_acl;
854 APPL_TRACE_DEBUG("bta_dm_close_acl");
856 if (BTM_IsAclConnectionUp(p_remove_acl->bd_addr, p_remove_acl->transport))
858 for (index = 0; index < bta_dm_cb.device_list.count; index ++)
860 if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, p_remove_acl->bd_addr))
863 if (index != bta_dm_cb.device_list.count)
865 if (p_remove_acl->remove_dev)
866 bta_dm_cb.device_list.peer_device[index].remove_dev_pending = TRUE;
870 APPL_TRACE_ERROR("unknown device, remove ACL failed");
872 /* Disconnect the ACL link */
873 btm_remove_acl(p_remove_acl->bd_addr, p_remove_acl->transport);
875 /* if to remove the device from security database ? do it now */
876 else if (p_remove_acl->remove_dev)
878 if (!BTM_SecDeleteDevice(p_remove_acl->bd_addr))
880 APPL_TRACE_ERROR("delete device from security database failed.");
882 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
883 /* need to remove all pending background connection if any */
884 BTA_GATTC_CancelOpen(0, p_remove_acl->bd_addr, FALSE);
885 /* remove all cached GATT information */
886 BTA_GATTC_Refresh(p_remove_acl->bd_addr);
889 /* otherwise, no action needed */
893 /*******************************************************************************
895 ** Function bta_dm_remove_all_acl
897 ** Description This function forces to close all the ACL links specified by link type
899 *******************************************************************************/
900 void bta_dm_remove_all_acl(tBTA_DM_MSG *p_data)
902 const tBTA_DM_LINK_TYPE link_type = p_data->remove_all_acl.link_type;
903 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
905 APPL_TRACE_DEBUG("%s link type = %d", __func__, link_type);
907 for (UINT8 i=0; i < bta_dm_cb.device_list.count; i++)
910 bdcpy(addr, bta_dm_cb.device_list.peer_device[i].peer_bdaddr);
911 #if defined (BLE_INCLUDED) && (BLE_INCLUDED == TRUE)
912 transport = bta_dm_cb.device_list.peer_device[i].transport;
914 if ((link_type == BTA_DM_LINK_TYPE_ALL) ||
915 ((link_type == BTA_DM_LINK_TYPE_LE) && (transport == BT_TRANSPORT_LE)) ||
916 ((link_type == BTA_DM_LINK_TYPE_BR_EDR) && (transport == BT_TRANSPORT_BR_EDR)))
918 /* Disconnect the ACL link */
919 btm_remove_acl(addr, transport);
925 /*******************************************************************************
927 ** Function bta_dm_bond
929 ** Description Bonds with peer device
934 *******************************************************************************/
935 void bta_dm_bond (tBTA_DM_MSG *p_data)
938 tBTA_DM_SEC sec_event;
941 if (p_data->bond.transport == BTA_TRANSPORT_UNKNOWN)
942 status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 );
944 status = BTM_SecBondByTransport ( p_data->bond.bd_addr, p_data->bond.transport, 0, NULL, 0 );
947 if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED))
950 memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
951 bdcpy(sec_event.auth_cmpl.bd_addr, p_data->bond.bd_addr);
952 p_name = BTM_SecReadDevName(p_data->bond.bd_addr);
955 memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN-1));
956 sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0;
959 /* taken care of by memset [above]
960 sec_event.auth_cmpl.key_present = FALSE;
961 sec_event.auth_cmpl.success = FALSE;
963 sec_event.auth_cmpl.fail_reason = HCI_ERR_ILLEGAL_COMMAND;
964 if (status == BTM_SUCCESS)
966 sec_event.auth_cmpl.success = TRUE;
970 /* delete this device entry from Sec Dev DB */
971 bta_dm_remove_sec_dev_entry(p_data->bond.bd_addr);
973 bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
978 /*******************************************************************************
980 ** Function bta_dm_bond_cancel
982 ** Description Cancels bonding with a peer device
987 *******************************************************************************/
988 void bta_dm_bond_cancel (tBTA_DM_MSG *p_data)
991 tBTA_DM_SEC sec_event;
993 APPL_TRACE_EVENT(" bta_dm_bond_cancel ");
994 status = BTM_SecBondCancel ( p_data->bond_cancel.bd_addr );
996 if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED && status != BTM_SUCCESS))
998 sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
1000 bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
1005 /*******************************************************************************
1007 ** Function bta_dm_pin_reply
1009 ** Description Send the pin_reply to a request from BTM
1014 *******************************************************************************/
1015 void bta_dm_pin_reply (tBTA_DM_MSG *p_data)
1017 UINT32 trusted_mask[BTM_SEC_SERVICE_ARRAY_SIZE];
1018 UINT32 * current_trusted_mask;
1020 current_trusted_mask = BTM_ReadTrustedMask(p_data->pin_reply.bd_addr);
1022 if(current_trusted_mask)
1024 memcpy(trusted_mask, current_trusted_mask, sizeof(trusted_mask));
1028 memset(trusted_mask, 0, sizeof(trusted_mask));
1031 if(p_data->pin_reply.accept)
1034 BTM_PINCodeReply(p_data->pin_reply.bd_addr, BTM_SUCCESS, p_data->pin_reply.pin_len, p_data->pin_reply.p_pin, trusted_mask );
1038 BTM_PINCodeReply(p_data->pin_reply.bd_addr, BTM_NOT_AUTHORIZED, 0, NULL, trusted_mask );
1043 /*******************************************************************************
1045 ** Function bta_dm_policy_cback
1047 ** Description process the link policy changes
1051 *******************************************************************************/
1052 static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
1054 tBTA_DM_PEER_DEVICE *p_dev = NULL;
1055 UINT16 policy = app_id;
1056 UINT32 mask = (UINT32)(1 << id);
1059 p_dev = bta_dm_find_peer_device(peer_addr);
1061 APPL_TRACE_DEBUG(" bta_dm_policy_cback cmd:%d, policy:0x%x",
1065 case BTA_SYS_PLCY_SET:
1068 /* restore the default link policy */
1069 p_dev->link_policy |= policy;
1070 BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy));
1073 case BTA_SYS_PLCY_CLR:
1076 /* clear the policy from the default link policy */
1077 p_dev->link_policy &= (~policy);
1078 BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy));
1080 if(policy & (HCI_ENABLE_SNIFF_MODE | HCI_ENABLE_PARK_MODE))
1082 /* if clearing sniff/park, wake the link */
1083 bta_dm_pm_active(p_dev->peer_bdaddr);
1087 case BTA_SYS_PLCY_DEF_SET:
1088 /* want to restore/set the role switch policy */
1089 bta_dm_cb.role_policy_mask &= ~mask;
1090 if(0 == bta_dm_cb.role_policy_mask)
1092 /* if nobody wants to insist on the role */
1093 bta_dm_cb.cur_policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH;
1094 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
1098 case BTA_SYS_PLCY_DEF_CLR:
1099 /* want to remove the role switch policy */
1100 bta_dm_cb.role_policy_mask |= mask;
1101 bta_dm_cb.cur_policy &= ~HCI_ENABLE_MASTER_SLAVE_SWITCH;
1102 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy);
1107 /*******************************************************************************
1109 ** Function bta_dm_confirm
1111 ** Description Send the user confirm request reply in response to a
1116 *******************************************************************************/
1117 void bta_dm_confirm(tBTA_DM_MSG *p_data)
1119 tBTM_STATUS res = BTM_NOT_AUTHORIZED;
1121 if(p_data->confirm.accept == TRUE)
1123 BTM_ConfirmReqReply(res, p_data->confirm.bd_addr);
1126 /*******************************************************************************
1128 ** Function bta_dm_loc_oob
1130 ** Description Retrieve the OOB data from the local LM
1134 *******************************************************************************/
1135 void bta_dm_loc_oob(tBTA_DM_MSG *p_data)
1138 BTM_ReadLocalOobData();
1141 /*******************************************************************************
1143 ** Function bta_dm_ci_io_req_act
1145 ** Description respond to the IO capabilities request from BTM
1149 *******************************************************************************/
1150 void bta_dm_ci_io_req_act(tBTA_DM_MSG *p_data)
1152 tBTM_AUTH_REQ auth_req = BTM_AUTH_AP_NO;
1153 if(p_data->ci_io_req.auth_req)
1154 auth_req = BTM_AUTH_AP_YES;
1155 BTM_IoCapRsp(p_data->ci_io_req.bd_addr, p_data->ci_io_req.io_cap,
1156 p_data->ci_io_req.oob_data, auth_req);
1159 /*******************************************************************************
1161 ** Function bta_dm_ci_rmt_oob_act
1163 ** Description respond to the OOB data request for the remote device from BTM
1168 *******************************************************************************/
1169 void bta_dm_ci_rmt_oob_act(tBTA_DM_MSG *p_data)
1171 tBTM_STATUS res = BTM_NOT_AUTHORIZED;
1173 if(p_data->ci_rmt_oob.accept == TRUE)
1175 BTM_RemoteOobDataReply(res, p_data->ci_rmt_oob.bd_addr,
1176 p_data->ci_rmt_oob.c, p_data->ci_rmt_oob.r );
1179 /*******************************************************************************
1181 ** Function bta_dm_search_start
1183 ** Description Starts an inquiry
1188 *******************************************************************************/
1189 void bta_dm_search_start (tBTA_DM_MSG *p_data)
1191 tBTM_INQUIRY_CMPL result;
1193 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
1194 size_t len = sizeof(tBT_UUID) * p_data->search.num_uuid;
1195 bta_dm_gattc_register();
1198 APPL_TRACE_DEBUG("%s avoid_scatter=%d", __func__, p_bta_dm_cfg->avoid_scatter);
1200 if (p_bta_dm_cfg->avoid_scatter &&
1201 (p_data->search.rs_res == BTA_DM_RS_NONE) && bta_dm_check_av(BTA_DM_API_SEARCH_EVT))
1203 memcpy(&bta_dm_cb.search_msg, &p_data->search, sizeof(tBTA_DM_API_SEARCH));
1207 BTM_ClearInqDb(NULL);
1208 /* save search params */
1209 bta_dm_search_cb.p_search_cback = p_data->search.p_cback;
1210 bta_dm_search_cb.services = p_data->search.services;
1212 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
1213 osi_free_and_reset((void **)&bta_dm_search_cb.p_srvc_uuid);
1215 if ((bta_dm_search_cb.num_uuid = p_data->search.num_uuid) != 0 &&
1216 p_data->search.p_uuid != NULL) {
1217 bta_dm_search_cb.p_srvc_uuid = (tBT_UUID *)osi_malloc(len);
1218 memcpy(bta_dm_search_cb.p_srvc_uuid, p_data->search.p_uuid, len);
1221 result.status = BTM_StartInquiry( (tBTM_INQ_PARMS*)&p_data->search.inq_params,
1222 bta_dm_inq_results_cb,
1223 (tBTM_CMPL_CB*) bta_dm_inq_cmpl_cb);
1225 APPL_TRACE_EVENT("%s status=%d", __func__, result.status);
1226 if (result.status != BTM_CMD_STARTED)
1228 result.num_resp = 0;
1229 bta_dm_inq_cmpl_cb ((void *)&result);
1233 /*******************************************************************************
1235 ** Function bta_dm_search_cancel
1237 ** Description Cancels an ongoing search for devices
1242 *******************************************************************************/
1243 void bta_dm_search_cancel (tBTA_DM_MSG *p_data)
1248 if (BTM_IsInquiryActive())
1250 if (BTM_CancelInquiry() == BTM_SUCCESS)
1252 bta_dm_search_cancel_notify(NULL);
1253 p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
1254 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1255 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1256 bta_sys_sendmsg(p_msg);
1258 /* flag a search cancel is pending */
1259 bta_dm_search_cb.cancel_pending = TRUE;
1262 /* If no Service Search going on then issue cancel remote name in case it is active */
1263 else if (!bta_dm_search_cb.name_discover_done)
1265 BTM_CancelRemoteDeviceName();
1267 p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
1268 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1269 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1270 bta_sys_sendmsg(p_msg);
1272 p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
1273 p_msg->hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
1274 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1275 bta_sys_sendmsg(p_msg);
1278 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1279 if (bta_dm_search_cb.gatt_disc_active)
1281 bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
1286 /*******************************************************************************
1288 ** Function bta_dm_discover
1290 ** Description Discovers services on a remote device
1295 *******************************************************************************/
1296 void bta_dm_discover (tBTA_DM_MSG *p_data)
1298 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1299 size_t len = sizeof(tBT_UUID) * p_data->discover.num_uuid;
1301 APPL_TRACE_EVENT("%s services_to_search=0x%04X, sdp_search=%d", __func__,
1302 p_data->discover.services, p_data->discover.sdp_search);
1304 /* save the search condition */
1305 bta_dm_search_cb.services = p_data->discover.services;
1307 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1308 bta_dm_gattc_register();
1309 osi_free_and_reset((void **)&bta_dm_search_cb.p_srvc_uuid);
1310 if ((bta_dm_search_cb.num_uuid = p_data->discover.num_uuid) != 0 &&
1311 p_data->discover.p_uuid != NULL) {
1312 bta_dm_search_cb.p_srvc_uuid = (tBT_UUID *)osi_malloc(len);
1313 memcpy(bta_dm_search_cb.p_srvc_uuid, p_data->discover.p_uuid, len);
1315 bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid;
1318 bta_dm_search_cb.p_search_cback = p_data->discover.p_cback;
1319 bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
1320 bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
1321 bta_dm_search_cb.service_index = 0;
1322 bta_dm_search_cb.services_found = 0;
1323 bta_dm_search_cb.peer_name[0] = 0;
1324 bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
1325 bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead (p_data->discover.bd_addr);
1326 bta_dm_search_cb.transport = p_data->discover.transport;
1328 bta_dm_search_cb.name_discover_done = FALSE;
1329 memcpy(&bta_dm_search_cb.uuid, &p_data->discover.uuid, sizeof(tSDP_UUID));
1330 bta_dm_discover_device(p_data->discover.bd_addr);
1333 /*******************************************************************************
1335 ** Function bta_dm_di_disc_cmpl
1337 ** Description Sends event to application when DI discovery complete
1341 *******************************************************************************/
1342 void bta_dm_di_disc_cmpl(tBTA_DM_MSG *p_data)
1344 tBTA_DM_DI_DISC_CMPL di_disc;
1346 memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL));
1347 bdcpy(di_disc.bd_addr, bta_dm_search_cb.peer_bdaddr);
1349 if((p_data->hdr.offset == SDP_SUCCESS)
1350 || (p_data->hdr.offset == SDP_DB_FULL))
1352 di_disc.num_record = SDP_GetNumDiRecords(bta_dm_di_cb.p_di_db);
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, (tBTA_DM_SEARCH *) &di_disc);
1361 /*******************************************************************************
1363 ** Function bta_dm_di_disc_callback
1365 ** Description This function queries a remote device for DI information.
1370 *******************************************************************************/
1371 static void bta_dm_di_disc_callback(UINT16 result)
1373 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
1375 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1376 p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT;
1377 p_msg->hdr.offset = result;
1379 bta_sys_sendmsg(p_msg);
1382 /*******************************************************************************
1384 ** Function bta_dm_disable_search_and_disc
1386 ** Description Cancels an ongoing search or discovery for devices in case of
1387 ** a Bluetooth disable
1392 *******************************************************************************/
1393 static void bta_dm_disable_search_and_disc (void)
1395 tBTA_DM_DI_DISC_CMPL di_disc;
1397 if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE)
1398 bta_dm_search_cancel(NULL);
1400 if (bta_dm_di_cb.p_di_db != NULL)
1402 memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL));
1403 bdcpy(di_disc.bd_addr, bta_dm_search_cb.peer_bdaddr);
1404 di_disc.result = BTA_FAILURE;
1406 bta_dm_di_cb.p_di_db = NULL;
1407 bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT, NULL);
1411 /*******************************************************************************
1413 ** Function bta_dm_di_disc
1415 ** Description This function queries a remote device for DI information.
1420 *******************************************************************************/
1421 void bta_dm_di_disc (tBTA_DM_MSG *p_data)
1423 UINT16 result = BTA_FAILURE;
1425 bta_dm_search_cb.p_search_cback = p_data->di_disc.p_cback;
1426 bdcpy(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.bd_addr);
1427 bta_dm_di_cb.p_di_db = p_data->di_disc.p_sdp_db;
1429 bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(BTA_DM_SDP_DB_SIZE);
1430 if (SDP_DiDiscover(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.p_sdp_db,
1431 p_data->di_disc.len,
1432 bta_dm_di_disc_callback) == SDP_SUCCESS) {
1433 result = BTA_SUCCESS;
1436 if (result == BTA_FAILURE) {
1437 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
1439 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1440 p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT;
1441 p_data->hdr.offset = result;
1442 bta_sys_sendmsg(p_msg);
1446 /*******************************************************************************
1448 ** Function bta_dm_read_remote_device_name
1450 ** Description Initiate to get remote device name
1452 ** Returns TRUE if started to get remote name
1454 *******************************************************************************/
1455 static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport)
1457 tBTM_STATUS btm_status;
1459 APPL_TRACE_DEBUG("bta_dm_read_remote_device_name");
1461 bdcpy(bta_dm_search_cb.peer_bdaddr, bd_addr);
1462 bta_dm_search_cb.peer_name[0] = 0;
1464 btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
1465 (tBTM_CMPL_CB *) bta_dm_remname_cback,
1468 if ( btm_status == BTM_CMD_STARTED )
1470 APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is started");
1474 else if ( btm_status == BTM_BUSY )
1476 APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is busy");
1478 /* Remote name discovery is on going now so BTM cannot notify through "bta_dm_remname_cback" */
1479 /* adding callback to get notified that current reading remore name done */
1480 BTM_SecAddRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1486 APPL_TRACE_WARNING("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
1492 /*******************************************************************************
1494 ** Function bta_dm_inq_cmpl
1496 ** Description Process the inquiry complete event from BTM
1500 *******************************************************************************/
1501 void bta_dm_inq_cmpl (tBTA_DM_MSG *p_data)
1503 tBTA_DM_SEARCH data;
1505 APPL_TRACE_DEBUG("bta_dm_inq_cmpl");
1507 data.inq_cmpl.num_resps = p_data->inq_cmpl.num;
1508 bta_dm_search_cb.p_search_cback(BTA_DM_INQ_CMPL_EVT, &data);
1510 if((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbFirst()) != NULL)
1512 /* start name and service discovery from the first device on inquiry result */
1513 bta_dm_search_cb.name_discover_done = FALSE;
1514 bta_dm_search_cb.peer_name[0] = 0;
1515 bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
1517 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
1519 /* no devices, search complete */
1520 bta_dm_search_cb.services = 0;
1522 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1523 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1524 bta_sys_sendmsg(p_msg);
1528 /*******************************************************************************
1530 ** Function bta_dm_rmt_name
1532 ** Description Process the remote name result from BTM
1536 *******************************************************************************/
1537 void bta_dm_rmt_name (tBTA_DM_MSG *p_data)
1539 APPL_TRACE_DEBUG("bta_dm_rmt_name");
1541 if( p_data->rem_name.result.disc_res.bd_name[0] && bta_dm_search_cb.p_btm_inq_info)
1543 bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name = TRUE;
1546 bta_dm_discover_device(bta_dm_search_cb.peer_bdaddr);
1549 /*******************************************************************************
1551 ** Function bta_dm_disc_rmt_name
1553 ** Description Process the remote name result from BTM when application
1554 ** wants to find the name for a bdaddr
1558 *******************************************************************************/
1559 void bta_dm_disc_rmt_name (tBTA_DM_MSG *p_data)
1561 tBTM_INQ_INFO *p_btm_inq_info;
1563 APPL_TRACE_DEBUG("bta_dm_disc_rmt_name");
1565 p_btm_inq_info = BTM_InqDbRead (p_data->rem_name.result.disc_res.bd_addr);
1566 if( p_btm_inq_info )
1568 if( p_data->rem_name.result.disc_res.bd_name[0] )
1570 p_btm_inq_info->appl_knows_rem_name = TRUE;
1574 bta_dm_discover_device(p_data->rem_name.result.disc_res.bd_addr);
1577 /*******************************************************************************
1579 ** Function bta_dm_sdp_result
1581 ** Description Process the discovery result from sdp
1585 *******************************************************************************/
1586 void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
1589 tSDP_DISC_REC *p_sdp_rec = NULL;
1591 BOOLEAN scn_found = FALSE;
1592 UINT16 service = 0xFFFF;
1593 tSDP_PROTOCOL_ELEM pe;
1595 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1596 tBT_UUID *p_uuid = bta_dm_search_cb.p_srvc_uuid;
1597 tBTA_DM_SEARCH result;
1598 tBT_UUID service_uuid;
1601 UINT32 num_uuids = 0;
1602 UINT8 uuid_list[32][MAX_UUID_SIZE]; // assuming a max of 32 services
1604 if((p_data->sdp_event.sdp_result == SDP_SUCCESS)
1605 || (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH)
1606 || (p_data->sdp_event.sdp_result == SDP_DB_FULL))
1608 APPL_TRACE_DEBUG("sdp_result::0x%x", p_data->sdp_event.sdp_result);
1613 if( bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID+1) )
1615 p_sdp_rec = SDP_FindServiceUUIDInDb(bta_dm_search_cb.p_sdp_db, &bta_dm_search_cb.uuid, p_sdp_rec);
1617 if (p_sdp_rec && SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe))
1619 bta_dm_search_cb.peer_scn = (UINT8) pe.params[0];
1625 service = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index-1];
1626 p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, service, p_sdp_rec);
1628 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1629 /* finished with BR/EDR services, now we check the result for GATT based service UUID */
1630 if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID)
1632 if (bta_dm_search_cb.uuid_to_search != 0 && p_uuid != NULL)
1634 p_uuid += (bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search);
1635 /* only support 16 bits UUID for now */
1636 service = p_uuid->uu.uuid16;
1639 /* all GATT based services */
1642 /* find a service record, report it */
1643 p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db,
1647 if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid))
1649 /* send result back to app now, one by one */
1650 bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
1651 strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN);
1652 result.disc_ble_res.service.len = service_uuid.len;
1653 result.disc_ble_res.service.uu.uuid16 = service_uuid.uu.uuid16;
1655 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
1659 if (bta_dm_search_cb.uuid_to_search > 0)
1662 } while (p_sdp_rec);
1667 /* SDP_DB_FULL means some records with the
1668 required attributes were received */
1669 if (((p_data->sdp_event.sdp_result == SDP_DB_FULL) &&
1670 bta_dm_search_cb.services != BTA_ALL_SERVICE_MASK) ||
1671 (p_sdp_rec != NULL))
1673 if (service != UUID_SERVCLASS_PNP_INFORMATION)
1675 UINT16 tmp_svc = 0xFFFF;
1676 bta_dm_search_cb.services_found |=
1677 (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index-1));
1678 tmp_svc = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index-1];
1679 /* Add to the list of UUIDs */
1680 sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]);
1686 if(bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK &&
1687 bta_dm_search_cb.services_to_search == 0)
1689 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1690 if ( bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID &&
1691 bta_dm_search_cb.uuid_to_search > 0)
1692 bta_dm_search_cb.uuid_to_search --;
1694 if (bta_dm_search_cb.uuid_to_search == 0 ||
1695 bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID)
1697 bta_dm_search_cb.service_index++;
1699 else /* regular one service per search or PNP search */
1702 } while (bta_dm_search_cb.service_index <= BTA_MAX_SERVICE_ID);
1704 APPL_TRACE_DEBUG("%s services_found = %04x", __FUNCTION__,
1705 bta_dm_search_cb.services_found);
1707 /* Collect the 128-bit services here and put them into the list */
1708 if(bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK)
1714 /* find a service record, report it */
1715 p_sdp_rec = SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec);
1718 if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid))
1720 memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE);
1724 } while (p_sdp_rec);
1726 /* if there are more services to search for */
1727 if(bta_dm_search_cb.services_to_search)
1729 /* Free up the p_sdp_db before checking the next one */
1730 bta_dm_free_sdp_db(NULL);
1731 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
1736 /* start next bd_addr if necessary */
1738 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1740 p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
1741 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1742 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
1743 p_msg->disc_result.result.disc_res.p_raw_data = NULL;
1744 p_msg->disc_result.result.disc_res.raw_data_size = 0;
1745 p_msg->disc_result.result.disc_res.num_uuids = num_uuids;
1746 p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
1747 if (num_uuids > 0) {
1748 p_msg->disc_result.result.disc_res.p_uuid_list =
1749 (UINT8 *)osi_malloc(num_uuids * MAX_UUID_SIZE);
1750 memcpy(p_msg->disc_result.result.disc_res.p_uuid_list,
1751 uuid_list, num_uuids * MAX_UUID_SIZE);
1753 // Copy the raw_data to the discovery result structure
1754 if (bta_dm_search_cb.p_sdp_db != NULL &&
1755 bta_dm_search_cb.p_sdp_db->raw_used != 0 &&
1756 bta_dm_search_cb.p_sdp_db->raw_data != NULL) {
1757 APPL_TRACE_DEBUG("%s raw_data used = 0x%x raw_data_ptr = 0x%x",
1759 bta_dm_search_cb.p_sdp_db->raw_used,
1760 bta_dm_search_cb.p_sdp_db->raw_data);
1762 p_msg->disc_result.result.disc_res.p_raw_data =
1763 osi_malloc(bta_dm_search_cb.p_sdp_db->raw_used);
1764 memcpy(p_msg->disc_result.result.disc_res.p_raw_data,
1765 bta_dm_search_cb.p_sdp_db->raw_data,
1766 bta_dm_search_cb.p_sdp_db->raw_used);
1768 p_msg->disc_result.result.disc_res.raw_data_size =
1769 bta_dm_search_cb.p_sdp_db->raw_used;
1771 bta_dm_search_cb.p_sdp_db->raw_data = NULL; //no need to free this - it is a global assigned.
1772 bta_dm_search_cb.p_sdp_db->raw_used = 0;
1773 bta_dm_search_cb.p_sdp_db->raw_size = 0;
1775 APPL_TRACE_DEBUG("%s raw data size is 0 or raw_data is null!!",
1778 /* Done with p_sdp_db. Free it */
1779 bta_dm_free_sdp_db(NULL);
1780 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
1782 // Piggy back the SCN over result field
1784 p_msg->disc_result.result.disc_res.result = (3 + bta_dm_search_cb.peer_scn);
1785 p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK;
1787 APPL_TRACE_EVENT(" Piggy back the SCN over result field SCN=%d", bta_dm_search_cb.peer_scn);
1790 bdcpy(p_msg->disc_result.result.disc_res.bd_addr,
1791 bta_dm_search_cb.peer_bdaddr);
1792 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
1793 bta_dm_get_remname(), BD_NAME_LEN);
1795 bta_sys_sendmsg(p_msg);
1798 /* conn failed. No need for timer */
1799 if(p_data->sdp_event.sdp_result == SDP_CONN_FAILED || p_data->sdp_event.sdp_result == SDP_CONN_REJECTED
1800 || p_data->sdp_event.sdp_result == SDP_SECURITY_ERR)
1801 bta_dm_search_cb.wait_disc = FALSE;
1803 /* not able to connect go to next device */
1804 if (bta_dm_search_cb.p_sdp_db)
1805 osi_free_and_reset((void **)&bta_dm_search_cb.p_sdp_db);
1807 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
1809 p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
1810 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
1811 p_msg->disc_result.result.disc_res.result = BTA_FAILURE;
1812 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
1813 bdcpy(p_msg->disc_result.result.disc_res.bd_addr,
1814 bta_dm_search_cb.peer_bdaddr);
1815 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
1816 bta_dm_get_remname(), BD_NAME_LEN);
1818 bta_sys_sendmsg(p_msg);
1822 /*******************************************************************************
1824 ** Function bta_dm_search_cmpl
1826 ** Description Sends event to application
1830 *******************************************************************************/
1831 void bta_dm_search_cmpl(tBTA_DM_MSG *p_data)
1833 APPL_TRACE_EVENT("%s", __func__);
1835 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
1836 osi_free_and_reset((void **)&bta_dm_search_cb.p_srvc_uuid);
1839 if (p_data->hdr.layer_specific == BTA_DM_API_DI_DISCOVER_EVT)
1840 bta_dm_di_disc_cmpl(p_data);
1842 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, NULL);
1845 /*******************************************************************************
1847 ** Function bta_dm_disc_result
1849 ** Description Service discovery result when discovering services on a device
1853 *******************************************************************************/
1854 void bta_dm_disc_result (tBTA_DM_MSG *p_data)
1856 APPL_TRACE_EVENT("%s", __func__);
1858 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
1859 /* if any BR/EDR service discovery has been done, report the event */
1860 if ((bta_dm_search_cb.services & ((BTA_ALL_SERVICE_MASK | BTA_USER_SERVICE_MASK ) & ~BTA_BLE_SERVICE_MASK)))
1862 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
1864 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
1866 /* send a message to change state */
1867 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
1868 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
1869 bta_sys_sendmsg(p_msg);
1872 /*******************************************************************************
1874 ** Function bta_dm_search_result
1876 ** Description Service discovery result while searching for devices
1880 *******************************************************************************/
1881 void bta_dm_search_result (tBTA_DM_MSG *p_data)
1883 APPL_TRACE_DEBUG("%s searching:0x%04x, result:0x%04x", __func__,
1884 bta_dm_search_cb.services,
1885 p_data->disc_result.result.disc_res.services);
1887 /* call back if application wants name discovery or found services that application is searching */
1888 if (( !bta_dm_search_cb.services )
1889 ||(( bta_dm_search_cb.services ) && ( p_data->disc_result.result.disc_res.services )))
1891 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result);
1894 /* if searching did not initiate to create link */
1895 if(!bta_dm_search_cb.wait_disc )
1897 /* if service searching is done with EIR, don't search next device */
1898 if( bta_dm_search_cb.p_btm_inq_info )
1899 bta_dm_discover_next_device();
1903 /* wait until link is disconnected or timeout */
1904 bta_dm_search_cb.sdp_results = TRUE;
1905 alarm_set_on_queue(bta_dm_search_cb.search_timer,
1906 1000 * (L2CAP_LINK_INACTIVITY_TOUT + 1),
1907 bta_dm_search_timer_cback, NULL,
1908 btu_bta_alarm_queue);
1912 /*******************************************************************************
1914 ** Function bta_dm_search_timer_cback
1916 ** Description Called when ACL disconnect time is over
1921 *******************************************************************************/
1922 static void bta_dm_search_timer_cback(UNUSED_ATTR void *data)
1924 APPL_TRACE_EVENT("%s", __func__);
1925 bta_dm_search_cb.wait_disc = FALSE;
1927 /* proceed with next device */
1928 bta_dm_discover_next_device();
1933 /*******************************************************************************
1935 ** Function bta_dm_free_sdp_db
1937 ** Description Frees SDP data base
1941 *******************************************************************************/
1942 void bta_dm_free_sdp_db (tBTA_DM_MSG *p_data)
1945 osi_free_and_reset((void **)&bta_dm_search_cb.p_sdp_db);
1948 /*******************************************************************************
1950 ** Function bta_dm_queue_search
1952 ** Description Queues search command while search is being cancelled
1956 *******************************************************************************/
1957 void bta_dm_queue_search(tBTA_DM_MSG *p_data)
1959 osi_free(bta_dm_search_cb.p_search_queue);
1960 bta_dm_search_cb.p_search_queue =
1961 (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_SEARCH));
1962 memcpy(bta_dm_search_cb.p_search_queue, p_data,
1963 sizeof(tBTA_DM_API_SEARCH));
1966 /*******************************************************************************
1968 ** Function bta_dm_queue_disc
1970 ** Description Queues discovery command while search is being cancelled
1974 *******************************************************************************/
1975 void bta_dm_queue_disc(tBTA_DM_MSG *p_data)
1977 osi_free(bta_dm_search_cb.p_search_queue);
1978 bta_dm_search_cb.p_search_queue =
1979 (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_DISCOVER));
1980 memcpy(bta_dm_search_cb.p_search_queue, p_data,
1981 sizeof(tBTA_DM_API_DISCOVER));
1984 /*******************************************************************************
1986 ** Function bta_dm_search_clear_queue
1988 ** Description Clears the queue if API search cancel is called
1992 *******************************************************************************/
1993 void bta_dm_search_clear_queue(tBTA_DM_MSG *p_data)
1996 osi_free_and_reset((void **)&bta_dm_search_cb.p_search_queue);
1999 /*******************************************************************************
2001 ** Function bta_dm_search_cancel_cmpl
2003 ** Description Search cancel is complete
2007 *******************************************************************************/
2008 void bta_dm_search_cancel_cmpl (tBTA_DM_MSG *p_data)
2011 if(bta_dm_search_cb.p_search_queue)
2013 bta_sys_sendmsg(bta_dm_search_cb.p_search_queue);
2014 bta_dm_search_cb.p_search_queue = NULL;
2019 /*******************************************************************************
2021 ** Function bta_dm_search_cancel_transac_cmpl
2023 ** Description Current Service Discovery or remote name procedure is
2024 ** completed after search cancellation
2028 *******************************************************************************/
2029 void bta_dm_search_cancel_transac_cmpl(tBTA_DM_MSG *p_data)
2033 osi_free_and_reset((void **)&bta_dm_search_cb.p_sdp_db);
2034 bta_dm_search_cancel_notify(NULL);
2038 /*******************************************************************************
2040 ** Function bta_dm_search_cancel_notify
2042 ** Description Notify application that search has been cancelled
2046 *******************************************************************************/
2047 void bta_dm_search_cancel_notify (tBTA_DM_MSG *p_data)
2050 if (bta_dm_search_cb.p_search_cback)
2052 bta_dm_search_cb.p_search_cback(BTA_DM_SEARCH_CANCEL_CMPL_EVT, NULL);
2054 if (!bta_dm_search_cb.name_discover_done)
2056 BTM_CancelRemoteDeviceName();
2058 #if (BLE_INCLUDED == TRUE) && (BTA_GATT_INCLUDED == TRUE)
2059 if (bta_dm_search_cb.gatt_disc_active)
2061 bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
2067 /*******************************************************************************
2069 ** Function bta_dm_find_services
2071 ** Description Starts discovery on a device
2075 *******************************************************************************/
2076 static void bta_dm_find_services ( BD_ADDR bd_addr)
2081 memset(&uuid, 0, sizeof(tSDP_UUID));
2083 while(bta_dm_search_cb.service_index < BTA_MAX_SERVICE_ID)
2085 if( bta_dm_search_cb.services_to_search
2086 & (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)))
2088 bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(BTA_DM_SDP_DB_SIZE);
2089 APPL_TRACE_DEBUG("bta_dm_search_cb.services = %04x***********", bta_dm_search_cb.services);
2090 /* try to search all services by search based on L2CAP UUID */
2091 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) {
2092 LOG_INFO(LOG_TAG, "%s services_to_search=%08x", __func__,
2093 bta_dm_search_cb.services_to_search);
2094 if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK) {
2095 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[0];
2096 bta_dm_search_cb.services_to_search &= ~BTA_RES_SERVICE_MASK;
2098 uuid.uu.uuid16 = UUID_PROTOCOL_L2CAP;
2099 bta_dm_search_cb.services_to_search = 0;
2102 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
2103 /* for LE only profile */
2104 if (bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID) {
2105 if (bta_dm_search_cb.uuid_to_search > 0 &&
2106 bta_dm_search_cb.p_srvc_uuid) {
2108 (const void *)(bta_dm_search_cb.p_srvc_uuid +
2109 bta_dm_search_cb.num_uuid -
2110 bta_dm_search_cb.uuid_to_search),
2113 bta_dm_search_cb.uuid_to_search--;
2115 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index];
2118 /* last one? clear the BLE service bit if all discovery has been done */
2119 if (bta_dm_search_cb.uuid_to_search == 0)
2120 bta_dm_search_cb.services_to_search &=
2121 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
2126 /* remove the service from services to be searched */
2127 bta_dm_search_cb.services_to_search &=
2128 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index)));
2129 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index];
2134 uuid.len = LEN_UUID_16;
2136 if (bta_dm_search_cb.service_index == BTA_USER_SERVICE_ID) {
2137 memcpy(&uuid, &bta_dm_search_cb.uuid, sizeof(tSDP_UUID));
2140 LOG_INFO(LOG_TAG, "%s search UUID = %04x", __func__,
2142 SDP_InitDiscoveryDb(bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE,
2145 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
2146 bta_dm_search_cb.p_sdp_db->raw_data = g_disc_raw_data_buf;
2148 bta_dm_search_cb.p_sdp_db->raw_size = MAX_DISC_RAW_DATA_BUF;
2150 if (!SDP_ServiceSearchAttributeRequest(bd_addr, bta_dm_search_cb.p_sdp_db, &bta_dm_sdp_callback)) {
2152 * If discovery is not successful with this device, then
2153 * proceed with the next one.
2155 osi_free_and_reset((void **)&bta_dm_search_cb.p_sdp_db);
2156 bta_dm_search_cb.service_index = BTA_MAX_SERVICE_ID;
2159 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
2160 if ((bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID &&
2161 bta_dm_search_cb.uuid_to_search == 0) ||
2162 bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID)
2164 bta_dm_search_cb.service_index++;
2169 bta_dm_search_cb.service_index++;
2172 /* no more services to be discovered */
2173 if (bta_dm_search_cb.service_index >= BTA_MAX_SERVICE_ID) {
2174 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
2175 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
2176 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
2177 bdcpy(p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2178 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
2179 bta_dm_get_remname(), BD_NAME_LEN);
2181 bta_sys_sendmsg(p_msg);
2185 /*******************************************************************************
2187 ** Function bta_dm_discover_next_device
2189 ** Description Starts discovery on the next device in Inquiry data base
2193 *******************************************************************************/
2194 static void bta_dm_discover_next_device(void)
2196 APPL_TRACE_DEBUG("bta_dm_discover_next_device");
2198 /* searching next device on inquiry result */
2199 if((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbNext(bta_dm_search_cb.p_btm_inq_info)) != NULL) {
2200 bta_dm_search_cb.name_discover_done = FALSE;
2201 bta_dm_search_cb.peer_name[0] = 0;
2202 bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr);
2204 tBTA_DM_MSG *p_msg =
2205 (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
2207 /* no devices, search complete */
2208 bta_dm_search_cb.services = 0;
2210 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
2211 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
2213 bta_sys_sendmsg(p_msg);
2217 /*******************************************************************************
2219 ** Function bta_dm_discover_device
2221 ** Description Starts name and service discovery on the device
2225 *******************************************************************************/
2226 static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
2228 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
2230 #if BLE_INCLUDED == TRUE
2231 if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN)
2233 tBT_DEVICE_TYPE dev_type;
2234 tBLE_ADDR_TYPE addr_type;
2236 BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type);
2237 if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM)
2238 transport = BT_TRANSPORT_LE;
2240 transport = bta_dm_search_cb.transport;
2244 /* Reset transport state for next discovery */
2245 bta_dm_search_cb.transport = BTA_TRANSPORT_UNKNOWN;
2247 APPL_TRACE_DEBUG("%s BDA:0x%02X%02X%02X%02X%02X%02X", __func__,
2248 remote_bd_addr[0],remote_bd_addr[1],
2249 remote_bd_addr[2],remote_bd_addr[3],
2250 remote_bd_addr[4],remote_bd_addr[5]);
2252 bdcpy(bta_dm_search_cb.peer_bdaddr, remote_bd_addr);
2254 APPL_TRACE_DEBUG("%s name_discover_done = %d p_btm_inq_info 0x%x state = %d, transport=%d",
2256 bta_dm_search_cb.name_discover_done,
2257 bta_dm_search_cb.p_btm_inq_info,
2258 bta_dm_search_cb.state,
2261 if (bta_dm_search_cb.p_btm_inq_info)
2263 APPL_TRACE_DEBUG("%s appl_knows_rem_name %d", __func__,
2264 bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name);
2266 #if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE)
2267 if((bta_dm_search_cb.p_btm_inq_info)
2268 && (bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE)
2269 && (bta_dm_search_cb.state == BTA_DM_SEARCH_ACTIVE))
2271 /* Do not perform RNR for LE devices at inquiry complete*/
2272 bta_dm_search_cb.name_discover_done = TRUE;
2275 /* if name discovery is not done and application needs remote name */
2276 if ((!bta_dm_search_cb.name_discover_done)
2277 && (( bta_dm_search_cb.p_btm_inq_info == NULL )
2278 ||(bta_dm_search_cb.p_btm_inq_info && (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name))))
2280 if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport) == TRUE)
2283 /* starting name discovery failed */
2284 bta_dm_search_cb.name_discover_done = TRUE;
2287 /* if application wants to discover service */
2288 if ( bta_dm_search_cb.services )
2290 /* initialize variables */
2291 bta_dm_search_cb.service_index = 0;
2292 bta_dm_search_cb.services_found = 0;
2293 bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
2294 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
2295 bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid;
2297 if ((bta_dm_search_cb.p_btm_inq_info != NULL) &&
2298 bta_dm_search_cb.services != BTA_USER_SERVICE_MASK
2299 &&(bta_dm_search_cb.sdp_search == FALSE))
2301 /* check if EIR provides the information of supported services */
2302 bta_dm_eir_search_services( &bta_dm_search_cb.p_btm_inq_info->results,
2303 &bta_dm_search_cb.services_to_search,
2304 &bta_dm_search_cb.services_found );
2307 /* if seaching with EIR is not completed */
2308 if(bta_dm_search_cb.services_to_search)
2310 /* check whether connection already exists to the device
2311 if connection exists, we don't have to wait for ACL
2312 link to go down to start search on next device */
2313 if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR))
2314 bta_dm_search_cb.wait_disc = FALSE;
2316 bta_dm_search_cb.wait_disc = TRUE;
2318 #if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
2319 if ( bta_dm_search_cb.p_btm_inq_info )
2321 APPL_TRACE_DEBUG("%s p_btm_inq_info 0x%x results.device_type 0x%x services_to_search 0x%x",
2323 bta_dm_search_cb.p_btm_inq_info,
2324 bta_dm_search_cb.p_btm_inq_info->results.device_type,
2325 bta_dm_search_cb.services_to_search);
2328 if (transport == BT_TRANSPORT_LE)
2330 if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK)
2332 //set the raw data buffer here
2333 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf));
2334 bta_dm_search_cb.p_ble_rawdata = g_disc_raw_data_buf;
2336 bta_dm_search_cb.ble_raw_size = MAX_DISC_RAW_DATA_BUF;
2337 bta_dm_search_cb.ble_raw_used = 0;
2339 /* start GATT for service discovery */
2340 btm_dm_start_gatt_discovery(bta_dm_search_cb.peer_bdaddr);
2347 bta_dm_search_cb.sdp_results = FALSE;
2348 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr);
2354 /* name discovery and service discovery are done for this device */
2355 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
2356 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
2357 /* initialize the data structure - includes p_raw_data and raw_data_size */
2358 memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES));
2359 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
2360 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
2361 bdcpy(p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2362 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
2363 (char*)bta_dm_search_cb.peer_name, BD_NAME_LEN);
2365 bta_sys_sendmsg(p_msg);
2368 /*******************************************************************************
2370 ** Function bta_dm_sdp_callback
2372 ** Description Callback from sdp with discovery status
2376 *******************************************************************************/
2377 static void bta_dm_sdp_callback (UINT16 sdp_status)
2380 tBTA_DM_SDP_RESULT *p_msg =
2381 (tBTA_DM_SDP_RESULT *)osi_malloc(sizeof(tBTA_DM_SDP_RESULT));
2383 p_msg->hdr.event = BTA_DM_SDP_RESULT_EVT;
2384 p_msg->sdp_result = sdp_status;
2386 bta_sys_sendmsg(p_msg);
2389 /*******************************************************************************
2391 ** Function bta_dm_inq_results_cb
2393 ** Description Inquiry results callback from BTM
2397 *******************************************************************************/
2398 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
2401 tBTA_DM_SEARCH result;
2402 tBTM_INQ_INFO *p_inq_info;
2403 UINT16 service_class;
2405 bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
2406 memcpy(result.inq_res.dev_class, p_inq->dev_class, DEV_CLASS_LEN);
2407 BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class);
2408 result.inq_res.is_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER)?TRUE:FALSE;
2409 result.inq_res.rssi = p_inq->rssi;
2411 #if (BLE_INCLUDED == TRUE)
2412 result.inq_res.ble_addr_type = p_inq->ble_addr_type;
2413 result.inq_res.inq_result_type = p_inq->inq_result_type;
2414 result.inq_res.device_type = p_inq->device_type;
2415 result.inq_res.flag = p_inq->flag;
2418 /* application will parse EIR to find out remote device name */
2419 result.inq_res.p_eir = p_eir;
2421 if((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL)
2423 /* initialize remt_name_not_required to FALSE so that we get the name by default */
2424 result.inq_res.remt_name_not_required = FALSE;
2428 if(bta_dm_search_cb.p_search_cback)
2429 bta_dm_search_cb.p_search_cback(BTA_DM_INQ_RES_EVT, &result);
2433 /* application indicates if it knows the remote name, inside the callback
2434 copy that to the inquiry data base*/
2435 if(result.inq_res.remt_name_not_required)
2436 p_inq_info->appl_knows_rem_name = TRUE;
2444 /*******************************************************************************
2446 ** Function bta_dm_inq_cmpl_cb
2448 ** Description Inquiry complete callback from BTM
2452 *******************************************************************************/
2453 static void bta_dm_inq_cmpl_cb (void * p_result)
2455 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
2457 APPL_TRACE_DEBUG("%s", __func__);
2459 if (bta_dm_search_cb.cancel_pending == FALSE) {
2460 p_msg->inq_cmpl.hdr.event = BTA_DM_INQUIRY_CMPL_EVT;
2461 p_msg->inq_cmpl.num = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
2463 bta_dm_search_cb.cancel_pending = FALSE;
2464 bta_dm_search_cancel_notify(NULL);
2465 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT;
2466 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT;
2469 bta_sys_sendmsg(p_msg);
2472 /*******************************************************************************
2474 ** Function bta_dm_service_search_remname_cback
2476 ** Description Remote name call back from BTM during service discovery
2480 *******************************************************************************/
2481 static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, BD_NAME bd_name)
2483 tBTM_REMOTE_DEV_NAME rem_name;
2484 tBTM_STATUS btm_status;
2487 APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback name=<%s>", bd_name);
2489 /* if this is what we are looking for */
2490 if (!bdcmp( bta_dm_search_cb.peer_bdaddr, bd_addr))
2492 rem_name.length = strlen((char*)bd_name);
2493 if (rem_name.length > (BD_NAME_LEN-1))
2495 rem_name.length = (BD_NAME_LEN-1);
2496 rem_name.remote_bd_name[(BD_NAME_LEN-1)] = 0;
2498 strlcpy((char*)rem_name.remote_bd_name, (char*)bd_name, BD_NAME_LEN);
2499 rem_name.status = BTM_SUCCESS;
2501 bta_dm_remname_cback(&rem_name);
2505 /* get name of device */
2506 btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
2507 (tBTM_CMPL_CB *) bta_dm_remname_cback,
2508 BT_TRANSPORT_BR_EDR);
2509 if ( btm_status == BTM_BUSY )
2511 /* wait for next chance(notification of remote name discovery done) */
2512 APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName is busy");
2514 else if ( btm_status != BTM_CMD_STARTED )
2516 /* if failed to start getting remote name then continue */
2517 APPL_TRACE_WARNING("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
2519 rem_name.length = 0;
2520 rem_name.remote_bd_name[0] = 0;
2521 rem_name.status = btm_status;
2522 bta_dm_remname_cback(&rem_name);
2528 /*******************************************************************************
2530 ** Function bta_dm_remname_cback
2532 ** Description Remote name complete call back from BTM
2536 *******************************************************************************/
2537 static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
2539 APPL_TRACE_DEBUG("bta_dm_remname_cback len = %d name=<%s>", p_remote_name->length,
2540 p_remote_name->remote_bd_name);
2542 /* remote name discovery is done but it could be failed */
2543 bta_dm_search_cb.name_discover_done = TRUE;
2544 strlcpy((char*)bta_dm_search_cb.peer_name,
2545 (char*)p_remote_name->remote_bd_name, BD_NAME_LEN);
2547 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
2549 #if BLE_INCLUDED == TRUE
2550 if (bta_dm_search_cb.transport == BT_TRANSPORT_LE )
2552 GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr);
2556 tBTA_DM_REM_NAME *p_msg =
2557 (tBTA_DM_REM_NAME *)osi_malloc(sizeof(tBTA_DM_REM_NAME));
2558 bdcpy(p_msg->result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
2559 strlcpy((char*)p_msg->result.disc_res.bd_name,
2560 (char*)p_remote_name->remote_bd_name, BD_NAME_LEN);
2561 p_msg->hdr.event = BTA_DM_REMT_NAME_EVT;
2563 bta_sys_sendmsg(p_msg);
2566 /*******************************************************************************
2568 ** Function bta_dm_authorize_cback
2570 ** Description cback requesting authorization
2574 *******************************************************************************/
2575 static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
2576 UINT8 *service_name, UINT8 service_id, BOOLEAN is_originator)
2578 tBTA_DM_SEC sec_event;
2580 UNUSED(service_name);
2581 UNUSED(is_originator);
2583 bdcpy(sec_event.authorize.bd_addr, bd_addr);
2584 memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN);
2585 strlcpy((char*)sec_event.authorize.bd_name, (char*)bd_name, BD_NAME_LEN);
2587 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
2588 sec_event.authorize.service = service_id;
2591 while(index < BTA_MAX_SERVICE_ID)
2593 /* get the BTA service id corresponding to BTM id */
2594 if(bta_service_id_to_btm_srv_id_lkup_tbl[index] == service_id)
2596 sec_event.authorize.service = index;
2603 /* if supported service callback otherwise not authorized */
2604 if(bta_dm_cb.p_sec_cback && (index < BTA_MAX_SERVICE_ID
2605 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
2606 /* pass through JV service ID */
2607 || (service_id >= BTA_FIRST_JV_SERVICE_ID && service_id <= BTA_LAST_JV_SERVICE_ID)
2611 bta_dm_cb.p_sec_cback(BTA_DM_AUTHORIZE_EVT, &sec_event);
2612 return BTM_CMD_STARTED;
2616 return BTM_NOT_AUTHORIZED;
2624 /*******************************************************************************
2626 ** Function bta_dm_pinname_cback
2628 ** Description Callback requesting pin_key
2632 *******************************************************************************/
2633 static void bta_dm_pinname_cback (void *p_data)
2635 tBTM_REMOTE_DEV_NAME *p_result = (tBTM_REMOTE_DEV_NAME *)p_data;
2636 tBTA_DM_SEC sec_event;
2637 UINT32 bytes_to_copy;
2638 tBTA_DM_SEC_EVT event = bta_dm_cb.pin_evt;
2640 if (BTA_DM_SP_CFM_REQ_EVT == event)
2642 /* Retrieved saved device class and bd_addr */
2643 bdcpy(sec_event.cfm_req.bd_addr, bta_dm_cb.pin_bd_addr);
2644 BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_cb.pin_dev_class);
2646 if (p_result && p_result->status == BTM_SUCCESS)
2648 bytes_to_copy = (p_result->length < (BD_NAME_LEN-1))
2649 ? p_result->length : (BD_NAME_LEN-1);
2650 memcpy(sec_event.cfm_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
2651 sec_event.pin_req.bd_name[BD_NAME_LEN-1] = 0;
2653 else /* No name found */
2654 sec_event.cfm_req.bd_name[0] = 0;
2656 sec_event.key_notif.passkey = bta_dm_cb.num_val; /* get PIN code numeric number */
2658 /* 1 additional event data fields for this event */
2659 sec_event.cfm_req.just_works = bta_dm_cb.just_works;
2663 /* Retrieved saved device class and bd_addr */
2664 bdcpy(sec_event.pin_req.bd_addr, bta_dm_cb.pin_bd_addr);
2665 BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_cb.pin_dev_class);
2667 if (p_result && p_result->status == BTM_SUCCESS)
2669 bytes_to_copy = (p_result->length < (BD_NAME_LEN-1))
2670 ? p_result->length : (BD_NAME_LEN-1);
2671 memcpy(sec_event.pin_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
2672 sec_event.pin_req.bd_name[BD_NAME_LEN-1] = 0;
2674 else /* No name found */
2675 sec_event.pin_req.bd_name[0] = 0;
2677 event = bta_dm_cb.pin_evt;
2678 sec_event.key_notif.passkey = bta_dm_cb.num_val; /* get PIN code numeric number */
2681 if( bta_dm_cb.p_sec_cback )
2682 bta_dm_cb.p_sec_cback(event, &sec_event);
2685 /*******************************************************************************
2687 ** Function bta_dm_pin_cback
2689 ** Description Callback requesting pin_key
2693 *******************************************************************************/
2694 static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
2695 BOOLEAN min_16_digit)
2697 tBTA_DM_SEC sec_event;
2699 if (!bta_dm_cb.p_sec_cback)
2700 return BTM_NOT_AUTHORIZED;
2702 /* If the device name is not known, save bdaddr and devclass and initiate a name request */
2703 if (bd_name[0] == 0)
2705 bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT;
2706 bdcpy(bta_dm_cb.pin_bd_addr, bd_addr);
2707 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class);
2708 if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
2709 return BTM_CMD_STARTED;
2711 APPL_TRACE_WARNING(" bta_dm_pin_cback() -> Failed to start Remote Name Request ");
2714 bdcpy(sec_event.pin_req.bd_addr, bd_addr);
2715 BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
2716 strlcpy((char*)sec_event.pin_req.bd_name, (char*)bd_name, BD_NAME_LEN);
2717 sec_event.pin_req.min_16_digit = min_16_digit;
2719 bta_dm_cb.p_sec_cback(BTA_DM_PIN_REQ_EVT, &sec_event);
2720 return BTM_CMD_STARTED;
2723 /*******************************************************************************
2725 ** Function bta_dm_new_link_key_cback
2727 ** Description Callback from BTM to notify new link key
2731 *******************************************************************************/
2732 static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
2733 BD_NAME bd_name, LINK_KEY key, UINT8 key_type)
2735 tBTA_DM_SEC sec_event;
2736 tBTA_DM_AUTH_CMPL *p_auth_cmpl;
2740 memset (&sec_event, 0, sizeof(tBTA_DM_SEC));
2742 /* Not AMP Key type */
2743 if (key_type != HCI_LKEY_TYPE_AMP_WIFI && key_type != HCI_LKEY_TYPE_AMP_UWB)
2745 event = BTA_DM_AUTH_CMPL_EVT;
2746 p_auth_cmpl = &sec_event.auth_cmpl;
2748 bdcpy(p_auth_cmpl->bd_addr, bd_addr);
2750 memcpy(p_auth_cmpl->bd_name, bd_name, (BD_NAME_LEN-1));
2751 p_auth_cmpl->bd_name[BD_NAME_LEN-1] = 0;
2753 p_auth_cmpl->key_present = TRUE;
2754 p_auth_cmpl->key_type = key_type;
2755 p_auth_cmpl->success = TRUE;
2757 memcpy(p_auth_cmpl->key, key, LINK_KEY_LEN);
2758 sec_event.auth_cmpl.fail_reason = HCI_SUCCESS;
2760 #if BLE_INCLUDED == TRUE
2761 // Report the BR link key based on the BR/EDR address and type
2762 BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
2764 if(bta_dm_cb.p_sec_cback)
2765 bta_dm_cb.p_sec_cback(event, &sec_event);
2769 APPL_TRACE_WARNING("%s() Received AMP Key", __func__);
2772 return BTM_CMD_STARTED;
2776 /*******************************************************************************
2778 ** Function bta_dm_authentication_complete_cback
2780 ** Description Authentication complete callback from BTM
2784 *******************************************************************************/
2785 static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,BD_NAME bd_name, int result)
2787 tBTA_DM_SEC sec_event;
2790 if(result != BTM_SUCCESS)
2792 memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
2793 bdcpy(sec_event.auth_cmpl.bd_addr, bd_addr);
2795 memcpy(sec_event.auth_cmpl.bd_name, bd_name, (BD_NAME_LEN-1));
2796 sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0;
2798 #if BLE_INCLUDED == TRUE
2799 // Report the BR link key based on the BR/EDR address and type
2800 BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
2802 sec_event.auth_cmpl.fail_reason = (UINT8)result;
2804 if(bta_dm_cb.p_sec_cback)
2805 bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
2807 bta_dm_remove_sec_dev_entry(bd_addr);
2813 /*******************************************************************************
2815 ** Function bta_dm_sp_cback
2817 ** Description simple pairing callback from BTM
2821 *******************************************************************************/
2822 static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
2824 tBTM_STATUS status = BTM_CMD_STARTED;
2825 tBTA_DM_SEC sec_event;
2826 tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT;
2828 APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event);
2829 if (!bta_dm_cb.p_sec_cback)
2830 return BTM_NOT_AUTHORIZED;
2835 case BTM_SP_IO_REQ_EVT:
2836 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2837 /* translate auth_req */
2838 bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap,
2839 &p_data->io_req.oob_data, &p_data->io_req.auth_req, p_data->io_req.is_orig);
2841 APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
2843 case BTM_SP_IO_RSP_EVT:
2844 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2845 bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap,
2846 p_data->io_rsp.oob_data, p_data->io_rsp.auth_req );
2850 case BTM_SP_CFM_REQ_EVT:
2851 pin_evt = BTA_DM_SP_CFM_REQ_EVT;
2852 bta_dm_cb.just_works = sec_event.cfm_req.just_works = p_data->cfm_req.just_works;
2853 sec_event.cfm_req.loc_auth_req = p_data->cfm_req.loc_auth_req;
2854 sec_event.cfm_req.rmt_auth_req = p_data->cfm_req.rmt_auth_req;
2855 sec_event.cfm_req.loc_io_caps = p_data->cfm_req.loc_io_caps;
2856 sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps;
2858 /* continue to next case */
2859 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
2860 /* Passkey entry mode, mobile device with output capability is very
2861 unlikely to receive key request, so skip this event */
2862 /*case BTM_SP_KEY_REQ_EVT: */
2863 case BTM_SP_KEY_NOTIF_EVT:
2865 if(BTM_SP_CFM_REQ_EVT == event)
2867 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
2868 call remote name request using values from cfm_req */
2869 if(p_data->cfm_req.bd_name[0] == 0)
2871 bta_dm_cb.pin_evt = pin_evt;
2872 bdcpy(bta_dm_cb.pin_bd_addr, p_data->cfm_req.bd_addr);
2873 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class);
2874 if ((BTM_ReadRemoteDeviceName(p_data->cfm_req.bd_addr, bta_dm_pinname_cback,
2875 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
2876 return BTM_CMD_STARTED;
2877 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
2881 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT,
2882 copy these values into key_notif from cfm_req */
2883 bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
2884 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class);
2885 strlcpy((char*)sec_event.key_notif.bd_name,
2886 (char*)p_data->cfm_req.bd_name, BD_NAME_LEN);
2890 bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey;
2891 if (BTM_SP_KEY_NOTIF_EVT == event)
2893 /* If the device name is not known, save bdaddr and devclass
2894 and initiate a name request with values from key_notif */
2895 if(p_data->key_notif.bd_name[0] == 0)
2897 bta_dm_cb.pin_evt = pin_evt;
2898 bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr);
2899 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class);
2900 if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback,
2901 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
2902 return BTM_CMD_STARTED;
2903 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
2907 bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
2908 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
2909 strlcpy((char*)sec_event.key_notif.bd_name,
2910 (char*)p_data->key_notif.bd_name, BD_NAME_LEN);
2911 sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0;
2915 bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
2919 case BTM_SP_LOC_OOB_EVT:
2920 bta_dm_co_loc_oob((BOOLEAN)(p_data->loc_oob.status == BTM_SUCCESS),
2921 p_data->loc_oob.c, p_data->loc_oob.r);
2924 case BTM_SP_RMT_OOB_EVT:
2925 /* If the device name is not known, save bdaddr and devclass and initiate a name request */
2926 if (p_data->rmt_oob.bd_name[0] == 0)
2928 bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT;
2929 bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr);
2930 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class);
2931 if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback,
2932 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED)
2933 return BTM_CMD_STARTED;
2934 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request ");
2937 bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
2938 BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
2939 strlcpy((char*)sec_event.rmt_oob.bd_name, (char*)p_data->rmt_oob.bd_name, BD_NAME_LEN);
2941 bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
2943 bta_dm_co_rmt_oob(p_data->rmt_oob.bd_addr);
2946 case BTM_SP_COMPLT_EVT:
2947 /* do not report this event - handled by link_key_callback or auth_complete_callback */
2950 case BTM_SP_KEYPRESS_EVT:
2951 memcpy(&sec_event.key_press, &p_data->key_press, sizeof(tBTM_SP_KEYPRESS));
2952 bta_dm_cb.p_sec_cback(BTA_DM_SP_KEYPRESS_EVT, &sec_event);
2955 case BTM_SP_UPGRADE_EVT:
2956 bta_dm_co_lk_upgrade(p_data->upgrade.bd_addr, &p_data->upgrade.upgrade );
2960 status = BTM_NOT_AUTHORIZED;
2963 APPL_TRACE_EVENT("dm status: %d", status);
2967 /*******************************************************************************
2969 ** Function bta_dm_local_name_cback
2971 ** Description Callback from btm after local name is read
2976 *******************************************************************************/
2977 static void bta_dm_local_name_cback(UINT8 *p_name)
2979 tBTA_DM_SEC sec_event;
2982 sec_event.enable.status = BTA_SUCCESS;
2984 if(bta_dm_cb.p_sec_cback)
2985 bta_dm_cb.p_sec_cback(BTA_DM_ENABLE_EVT, &sec_event);
2989 /*******************************************************************************
2991 ** Function bta_dm_bl_change_cback
2993 ** Description Callback from btm when acl connection goes up or down
2998 *******************************************************************************/
2999 static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
3001 tBTA_DM_ACL_CHANGE *p_msg =
3002 (tBTA_DM_ACL_CHANGE *)osi_malloc(sizeof(tBTA_DM_ACL_CHANGE));
3004 p_msg->event = p_data->event;
3005 p_msg->is_new = FALSE;
3007 switch (p_msg->event) {
3008 case BTM_BL_CONN_EVT:
3009 p_msg->is_new = TRUE;
3010 bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
3011 #if BLE_INCLUDED == TRUE
3012 p_msg->transport = p_data->conn.transport;
3013 p_msg->handle = p_data->conn.handle;
3016 case BTM_BL_DISCN_EVT:
3017 bdcpy(p_msg->bd_addr, p_data->discn.p_bda);
3018 #if BLE_INCLUDED == TRUE
3019 p_msg->transport = p_data->discn.transport;
3020 p_msg->handle = p_data->discn.handle;
3023 case BTM_BL_UPDATE_EVT:
3024 p_msg->busy_level = p_data->update.busy_level;
3025 p_msg->busy_level_flags = p_data->update.busy_level_flags;
3027 case BTM_BL_ROLE_CHG_EVT:
3028 p_msg->new_role = p_data->role_chg.new_role;
3029 p_msg->hci_status = p_data->role_chg.hci_status;
3030 bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda);
3032 case BTM_BL_COLLISION_EVT:
3033 bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
3037 p_msg->hdr.event = BTA_DM_ACL_CHANGE_EVT;
3038 bta_sys_sendmsg(p_msg);
3041 /*******************************************************************************
3043 ** Function bta_dm_rs_cback
3045 ** Description Receives the role switch complete event
3049 *******************************************************************************/
3050 static void bta_dm_rs_cback (tBTM_ROLE_SWITCH_CMPL *p1)
3053 APPL_TRACE_WARNING("bta_dm_rs_cback:%d", bta_dm_cb.rs_event);
3054 if(bta_dm_cb.rs_event == BTA_DM_API_SEARCH_EVT)
3056 bta_dm_cb.search_msg.rs_res = BTA_DM_RS_OK; /* do not care about the result for now */
3057 bta_dm_cb.rs_event = 0;
3058 bta_dm_search_start((tBTA_DM_MSG *)&bta_dm_cb.search_msg);
3062 /*******************************************************************************
3064 ** Function bta_dm_check_av
3066 ** Description This function checks if AV is active
3067 ** if yes, make sure the AV link is master
3069 ** Returns BOOLEAN - TRUE, if switch is in progress
3071 *******************************************************************************/
3072 static BOOLEAN bta_dm_check_av(UINT16 event)
3074 BOOLEAN avoid_roleswitch = FALSE;
3075 BOOLEAN switching = FALSE;
3077 tBTA_DM_PEER_DEVICE *p_dev;
3079 #if defined(BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY) && (BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY == TRUE)
3081 /* avoid role switch upon inquiry if a2dp is actively streaming as it
3082 introduces an audioglitch due to FW scheduling delays (unavoidable) */
3083 if (event == BTA_DM_API_SEARCH_EVT)
3085 avoid_roleswitch = TRUE;
3089 APPL_TRACE_WARNING("bta_dm_check_av:%d", bta_dm_cb.cur_av_count);
3090 if(bta_dm_cb.cur_av_count)
3092 for(i=0; i<bta_dm_cb.device_list.count; i++)
3094 p_dev = &bta_dm_cb.device_list.peer_device[i];
3095 APPL_TRACE_WARNING("[%d]: state:%d, info:x%x, avoid_rs %d",
3096 i, p_dev->conn_state, p_dev->info, avoid_roleswitch);
3097 if((p_dev->conn_state == BTA_DM_CONNECTED) && (p_dev->info & BTA_DM_DI_AV_ACTIVE) &&
3098 (avoid_roleswitch == FALSE))
3100 /* make master and take away the role switch policy */
3101 if(BTM_CMD_STARTED == BTM_SwitchRole (p_dev->peer_bdaddr, HCI_ROLE_MASTER, (tBTM_CMPL_CB *)bta_dm_rs_cback))
3103 /* the role switch command is actually sent */
3104 bta_dm_cb.rs_event = event;
3107 /* else either already master or can not switch for some reasons */
3108 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr);
3116 /*******************************************************************************
3118 ** Function bta_dm_acl_change
3120 ** Description Process BTA_DM_ACL_CHANGE_EVT
3125 *******************************************************************************/
3126 void bta_dm_acl_change(tBTA_DM_MSG *p_data)
3132 BOOLEAN is_new = p_data->acl_change.is_new;
3133 BD_ADDR_PTR p_bda = p_data->acl_change.bd_addr;
3134 BOOLEAN need_policy_change = FALSE;
3135 BOOLEAN issue_unpair_cb = FALSE;
3137 tBTA_DM_PEER_DEVICE *p_dev;
3138 memset(&conn, 0, sizeof(tBTA_DM_SEC));
3140 switch(p_data->acl_change.event)
3142 case BTM_BL_UPDATE_EVT: /* busy level update */
3143 if( bta_dm_cb.p_sec_cback )
3145 conn.busy_level.level = p_data->acl_change.busy_level;
3146 conn.busy_level.level_flags = p_data->acl_change.busy_level_flags;
3147 bta_dm_cb.p_sec_cback(BTA_DM_BUSY_LEVEL_EVT, &conn);
3151 case BTM_BL_ROLE_CHG_EVT: /* role change event */
3152 p_dev = bta_dm_find_peer_device(p_bda);
3155 APPL_TRACE_DEBUG("bta_dm_acl_change role chg info:x%x new_role:%d dev count:%d",
3156 p_dev->info, p_data->acl_change.new_role, bta_dm_cb.device_list.count);
3157 if(p_dev->info & BTA_DM_DI_AV_ACTIVE)
3159 /* there's AV activity on this link */
3160 if(p_data->acl_change.new_role == HCI_ROLE_SLAVE && bta_dm_cb.device_list.count > 1
3161 && p_data->acl_change.hci_status == HCI_SUCCESS)
3163 /* more than one connections and the AV connection is role switched to slave
3164 * switch it back to master and remove the switch policy */
3165 BTM_SwitchRole(p_bda, BTM_ROLE_MASTER, NULL);
3166 need_policy_change = TRUE;
3168 else if (p_bta_dm_cfg->avoid_scatter && (p_data->acl_change.new_role == HCI_ROLE_MASTER))
3170 /* if the link updated to be master include AV activities, remove the switch policy */
3171 need_policy_change = TRUE;
3174 if(need_policy_change)
3176 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr);
3181 /* there's AV no activity on this link and role switch happened
3182 * check if AV is active
3183 * if so, make sure the AV link is master */
3186 bta_sys_notify_role_chg(p_data->acl_change.bd_addr, p_data->acl_change.new_role, p_data->acl_change.hci_status);
3187 bdcpy(conn.role_chg.bd_addr, p_bda);
3188 conn.role_chg.new_role = (UINT8) p_data->acl_change.new_role;
3189 if( bta_dm_cb.p_sec_cback )
3190 bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, (tBTA_DM_SEC *)&conn);
3195 /* Collision report from Stack: Notify profiles */
3196 if (p_data->acl_change.event == BTM_BL_COLLISION_EVT)
3198 bta_sys_notify_collision (p_bda);
3204 for(i=0; i<bta_dm_cb.device_list.count; i++)
3206 if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
3207 #if BLE_INCLUDED == TRUE
3208 && bta_dm_cb.device_list.peer_device[i].conn_handle == p_data->acl_change.handle
3215 if(i == bta_dm_cb.device_list.count)
3217 if (bta_dm_cb.device_list.count < BTA_DM_NUM_PEER_DEVICE)
3219 bdcpy(bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].peer_bdaddr, p_bda);
3220 bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].link_policy = bta_dm_cb.cur_policy;
3221 bta_dm_cb.device_list.count++;
3222 #if BLE_INCLUDED == TRUE
3223 bta_dm_cb.device_list.peer_device[i].conn_handle = p_data->acl_change.handle;
3224 if (p_data->acl_change.transport == BT_TRANSPORT_LE)
3225 bta_dm_cb.device_list.le_count++;
3228 APPL_TRACE_ERROR("%s max active connection reached, no resources", __func__);
3233 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED;
3234 bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE;
3235 bdcpy(conn.link_up.bd_addr, p_bda);
3236 bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE;
3237 #if BLE_INCLUDED == TRUE
3238 conn.link_up.link_type = p_data->acl_change.transport;
3239 bta_dm_cb.device_list.peer_device[i].transport = p_data->acl_change.transport;
3242 if (((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) &&
3243 ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)))
3245 /* both local and remote devices support SSR */
3246 bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR;
3248 APPL_TRACE_WARNING("%s info: 0x%x", __func__, bta_dm_cb.device_list.peer_device[i].info);
3250 if (bta_dm_cb.p_sec_cback)
3251 bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, (tBTA_DM_SEC *)&conn);
3253 for(i=0; i<bta_dm_cb.device_list.count; i++)
3255 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda)
3256 #if BLE_INCLUDED == TRUE
3257 ||bta_dm_cb.device_list.peer_device[i].transport != p_data->acl_change.transport
3262 if( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING )
3264 if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr))
3265 issue_unpair_cb = TRUE;
3267 APPL_TRACE_DEBUG("%s: Unpairing: issue unpair CB = %d ",__FUNCTION__, issue_unpair_cb);
3270 conn.link_down.is_removed = bta_dm_cb.device_list.peer_device[i].remove_dev_pending;
3272 for(; i<bta_dm_cb.device_list.count ; i++)
3274 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]));
3278 if(bta_dm_cb.device_list.count)
3279 bta_dm_cb.device_list.count--;
3280 #if BLE_INCLUDED == TRUE
3281 if ((p_data->acl_change.transport == BT_TRANSPORT_LE) &&
3282 (bta_dm_cb.device_list.le_count))
3283 bta_dm_cb.device_list.le_count--;
3284 conn.link_down.link_type = p_data->acl_change.transport;
3287 if(bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda))
3289 bta_dm_search_cb.wait_disc = FALSE;
3291 if(bta_dm_search_cb.sdp_results)
3293 APPL_TRACE_EVENT(" timer stopped ");
3294 alarm_cancel(bta_dm_search_cb.search_timer);
3295 bta_dm_discover_next_device();
3300 if(bta_dm_cb.disabling)
3302 if(!BTM_GetNumAclLinks())
3305 * Start a timer to make sure that the profiles
3306 * get the disconnect event.
3308 alarm_set_on_queue(bta_dm_cb.disable_timer,
3309 BTA_DM_DISABLE_CONN_DOWN_TIMER_MS,
3310 bta_dm_disable_conn_down_timer_cback, NULL,
3311 btu_bta_alarm_queue);
3314 if (conn.link_down.is_removed)
3316 BTM_SecDeleteDevice(p_bda);
3317 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
3318 /* need to remove all pending background connection */
3319 BTA_GATTC_CancelOpen(0, p_bda, FALSE);
3320 /* remove all cached GATT information */
3321 BTA_GATTC_Refresh(p_bda);
3325 bdcpy(conn.link_down.bd_addr, p_bda);
3326 conn.link_down.status = (UINT8) btm_get_acl_disc_reason_code();
3327 if( bta_dm_cb.p_sec_cback )
3329 bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn);
3330 if( issue_unpair_cb )
3331 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn);
3335 bta_dm_adjust_roles(TRUE);
3338 /*******************************************************************************
3340 ** Function bta_dm_disable_conn_down_timer_cback
3342 ** Description Sends disable event to application
3347 *******************************************************************************/
3348 static void bta_dm_disable_conn_down_timer_cback(UNUSED_ATTR void *data)
3350 tBTA_SYS_HW_MSG *sys_enable_event =
3351 (tBTA_SYS_HW_MSG *)osi_malloc(sizeof(tBTA_SYS_HW_MSG));
3353 /* disable the power managment module */
3354 bta_dm_disable_pm();
3356 /* register our callback to SYS HW manager */
3357 bta_sys_hw_register(BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback );
3359 /* send a message to BTA SYS */
3360 sys_enable_event->hdr.event = BTA_SYS_API_DISABLE_EVT;
3361 sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH;
3362 bta_sys_sendmsg(sys_enable_event);
3364 bta_dm_cb.disabling = FALSE;
3367 /*******************************************************************************
3369 ** Function bta_dm_rm_cback
3371 ** Description Role management callback from sys
3376 *******************************************************************************/
3377 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
3380 tBTA_PREF_ROLES role;
3381 tBTA_DM_PEER_DEVICE *p_dev;
3383 p_dev = bta_dm_find_peer_device(peer_addr);
3384 if( status == BTA_SYS_CONN_OPEN)
3388 /* Do not set to connected if we are in the middle of unpairing. When AV stream is
3389 * started it fakes out a SYS_CONN_OPEN to potentially trigger a role switch command.
3390 * But this should not be done if we are in the middle of unpairing.
3392 if (p_dev->conn_state != BTA_DM_UNPAIRING)
3393 p_dev->conn_state = BTA_DM_CONNECTED;
3395 for(j=1; j<= p_bta_dm_rm_cfg[0].app_id; j++)
3397 if(((p_bta_dm_rm_cfg[j].app_id == app_id) || (p_bta_dm_rm_cfg[j].app_id == BTA_ALL_APP_ID))
3398 && (p_bta_dm_rm_cfg[j].id == id))
3400 role = p_bta_dm_rm_cfg[j].cfg;
3402 if(role > p_dev->pref_role )
3403 p_dev->pref_role = role;
3410 if((BTA_ID_AV == id)||(BTA_ID_AVK ==id))
3412 if( status == BTA_SYS_CONN_BUSY)
3415 p_dev->info |= BTA_DM_DI_AV_ACTIVE;
3416 /* AV calls bta_sys_conn_open with the A2DP stream count as app_id */
3418 bta_dm_cb.cur_av_count = bta_dm_get_av_count();
3420 else if( status == BTA_SYS_CONN_IDLE)
3423 p_dev->info &= ~BTA_DM_DI_AV_ACTIVE;
3425 /* get cur_av_count from connected services */
3427 bta_dm_cb.cur_av_count = bta_dm_get_av_count();
3429 APPL_TRACE_WARNING("bta_dm_rm_cback:%d, status:%d", bta_dm_cb.cur_av_count, status);
3432 /* Don't adjust roles for each busy/idle state transition to avoid
3433 excessive switch requests when individual profile busy/idle status
3435 if ((status != BTA_SYS_CONN_BUSY) && (status != BTA_SYS_CONN_IDLE))
3436 bta_dm_adjust_roles(FALSE);
3439 /*******************************************************************************
3441 ** Function bta_dm_delay_role_switch_cback
3443 ** Description Callback from btm to delay a role switch
3447 *******************************************************************************/
3448 static void bta_dm_delay_role_switch_cback(UNUSED_ATTR void *data)
3450 APPL_TRACE_EVENT("%s: initiating Delayed RS", __func__);
3451 bta_dm_adjust_roles(FALSE);
3454 /*******************************************************************************
3456 ** Function bta_dm_remove_sec_dev_entry
3458 ** Description Removes device entry from Security device DB if ACL connection with
3459 ** remtoe device does not exist, else schedule for dev entry removal upon
3464 *******************************************************************************/
3465 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr)
3468 if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) ||
3469 BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR))
3471 APPL_TRACE_DEBUG("%s ACL is not down. Schedule for Dev Removal when ACL closes",
3473 for (index = 0; index < bta_dm_cb.device_list.count; index ++)
3475 if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, remote_bd_addr))
3478 if (index != bta_dm_cb.device_list.count)
3480 bta_dm_cb.device_list.peer_device[index].remove_dev_pending = TRUE;
3484 APPL_TRACE_ERROR(" %s Device does not exist in DB", __FUNCTION__);
3489 BTM_SecDeleteDevice (remote_bd_addr);
3490 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE)
3491 /* need to remove all pending background connection */
3492 BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE);
3493 /* remove all cached GATT information */
3494 BTA_GATTC_Refresh(remote_bd_addr);
3500 /*******************************************************************************
3502 ** Function bta_dm_adjust_roles
3504 ** Description Adjust roles
3509 *******************************************************************************/
3510 static void bta_dm_adjust_roles(BOOLEAN delay_role_switch)
3514 BOOLEAN set_master_role = FALSE;
3515 #if BLE_INCLUDED == TRUE
3516 UINT8 br_count = bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count;
3518 UINT8 br_count = bta_dm_cb.device_list.count;
3523 /* the configuration is no scatternet
3524 * or AV connection exists and there are more than one ACL link */
3525 if ( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) ||
3526 (bta_dm_cb.cur_av_count && br_count > 1) )
3529 L2CA_SetDesireRole (HCI_ROLE_MASTER);
3530 set_master_role = TRUE;
3534 for(i=0; i<bta_dm_cb.device_list.count; i++)
3536 if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED
3537 #if BLE_INCLUDED == TRUE
3538 && bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_BR_EDR
3542 if(!set_master_role && (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE)
3543 && (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET))
3545 L2CA_SetDesireRole (HCI_ROLE_MASTER);
3546 set_master_role = TRUE;
3549 if((bta_dm_cb.device_list.peer_device[i].pref_role == BTA_MASTER_ROLE_ONLY)
3553 /* Initiating immediate role switch with certain remote devices
3554 has caused issues due to role switch colliding with link encryption setup and
3555 causing encryption (and in turn the link) to fail . These device . Firmware
3556 versions are stored in a blacklist and role switch with these devices are
3557 delayed to avoid the collision with link encryption setup */
3559 if (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_SLAVE_ROLE_ONLY &&
3560 delay_role_switch == FALSE)
3562 BTM_SwitchRole (bta_dm_cb.device_list.peer_device[i].peer_bdaddr,
3563 HCI_ROLE_MASTER, NULL);
3567 alarm_set_on_queue(bta_dm_cb.switch_delay_timer,
3568 BTA_DM_SWITCH_DELAY_TIMER_MS,
3569 bta_dm_delay_role_switch_cback,
3570 NULL, btu_bta_alarm_queue);
3577 if(!set_master_role)
3580 L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
3587 L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE);
3593 /*******************************************************************************
3595 ** Function bta_dm_get_remname
3597 ** Description Returns a pointer to the remote name stored in the DM control
3598 ** block if it exists, or from the BTM memory.
3600 ** Returns char * - Pointer to the remote device name
3601 *******************************************************************************/
3602 static char *bta_dm_get_remname(void)
3604 char *p_name = (char *)bta_dm_search_cb.peer_name;
3607 /* If the name isn't already stored, try retrieving from BTM */
3608 if (*p_name == '\0')
3609 if ((p_temp = BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr)) != NULL)
3615 /*******************************************************************************
3617 ** Function bta_dm_bond_cancel_complete_cback
3619 ** Description Authentication complete callback from BTM
3623 *******************************************************************************/
3624 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result)
3627 tBTA_DM_SEC sec_event;
3629 if (result == BTM_SUCCESS)
3630 sec_event.bond_cancel_cmpl.result = BTA_SUCCESS;
3632 sec_event.bond_cancel_cmpl.result = BTA_FAILURE;
3634 if(bta_dm_cb.p_sec_cback)
3636 bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event);
3640 /*******************************************************************************
3642 ** Function bta_dm_set_eir
3644 ** Description This function creates EIR tagged data and writes it to controller.
3648 *******************************************************************************/
3649 static void bta_dm_set_eir (char *local_name)
3653 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3656 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3657 UINT8 custom_uuid_idx;
3658 #endif // BTA_EIR_SERVER_NUM_CUSTOM_UUID
3659 #endif // BTA_EIR_CANNED_UUID_LIST
3660 #if (BTM_EIR_DEFAULT_FEC_REQUIRED == FALSE)
3661 UINT8 free_eir_length = HCI_EXT_INQ_RESPONSE_LEN;
3662 #else // BTM_EIR_DEFAULT_FEC_REQUIRED
3663 UINT8 free_eir_length = HCI_DM5_PACKET_SIZE;
3664 #endif // BTM_EIR_DEFAULT_FEC_REQUIRED
3667 UINT8 local_name_len;
3669 /* wait until complete to disable */
3670 if (alarm_is_scheduled(bta_dm_cb.disable_timer))
3673 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )
3674 /* if local name is not provided, get it from controller */
3675 if( local_name == NULL )
3677 if( BTM_ReadLocalDeviceName( &local_name ) != BTM_SUCCESS )
3679 APPL_TRACE_ERROR("Fail to read local device name for EIR");
3682 #endif // BTA_EIR_CANNED_UUID_LIST
3684 /* Allocate a buffer to hold HCI command */
3685 BT_HDR *p_buf = (BT_HDR *)osi_malloc(BTM_CMD_BUF_SIZE);
3686 p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET;
3688 memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN );
3690 APPL_TRACE_DEBUG("BTA is generating EIR");
3693 local_name_len = strlen( local_name );
3697 data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3698 /* if local name is longer than minimum length of shortened name */
3699 /* check whether it needs to be shortened or not */
3700 if( local_name_len > p_bta_dm_eir_cfg->bta_dm_eir_min_name_len )
3702 /* get number of UUID 16-bit list */
3703 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3704 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len/LEN_UUID_16;
3705 #else // BTA_EIR_CANNED_UUID_LIST
3706 max_num_uuid = (free_eir_length - 2)/LEN_UUID_16;
3707 data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p,
3708 max_num_uuid, &num_uuid );
3709 p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET; /* reset p */
3710 #endif // BTA_EIR_CANNED_UUID_LIST
3712 /* if UUID doesn't fit remaing space, shorten local name */
3713 if ( local_name_len > (free_eir_length - 4 - num_uuid*LEN_UUID_16))
3715 APPL_TRACE_WARNING("BTA EIR: local name is shortened");
3716 local_name_len = p_bta_dm_eir_cfg->bta_dm_eir_min_name_len;
3717 data_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE;
3720 data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
3723 UINT8_TO_STREAM(p, local_name_len + 1);
3724 UINT8_TO_STREAM(p, data_type);
3726 if (local_name != NULL)
3728 memcpy(p, local_name, local_name_len);
3729 p += local_name_len;
3731 free_eir_length -= local_name_len + 2;
3733 #if (BTA_EIR_CANNED_UUID_LIST == TRUE)
3734 /* if UUID list is provided as static data in configuration */
3735 if(( p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len > 0 )
3736 &&(p_bta_dm_eir_cfg->bta_dm_eir_uuid16))
3738 if( free_eir_length > LEN_UUID_16 + 2)
3740 free_eir_length -= 2;
3742 if( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len)
3744 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / LEN_UUID_16;
3745 data_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3747 else /* not enough room for all UUIDs */
3749 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3750 num_uuid = free_eir_length / LEN_UUID_16;
3751 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3753 UINT8_TO_STREAM(p, num_uuid * LEN_UUID_16 + 1);
3754 UINT8_TO_STREAM(p, data_type);
3755 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_uuid16, num_uuid * LEN_UUID_16 );
3756 p += num_uuid * LEN_UUID_16;
3757 free_eir_length -= num_uuid * LEN_UUID_16;
3760 #else /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3761 /* if UUID list is dynamic */
3762 if ( free_eir_length >= 2)
3768 max_num_uuid = (free_eir_length - 2)/LEN_UUID_16;
3769 data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p, max_num_uuid, &num_uuid );
3771 if( data_type == BTM_EIR_MORE_16BITS_UUID_TYPE )
3773 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3775 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3778 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++)
3780 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_16)
3782 if ( num_uuid < max_num_uuid )
3784 UINT16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid16);
3789 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3790 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated");
3796 #endif /* (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3798 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_16 + 1);
3799 UINT8_TO_STREAM(p_type, data_type);
3800 free_eir_length -= num_uuid * LEN_UUID_16 + 2;
3802 #endif /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */
3804 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0)
3805 /* Adding 32-bit UUID list */
3806 if ( free_eir_length >= 2)
3811 data_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE;
3813 max_num_uuid = (free_eir_length - 2)/LEN_UUID_32;
3815 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++)
3817 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_32)
3819 if ( num_uuid < max_num_uuid )
3821 UINT32_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid32);
3826 data_type = BTM_EIR_MORE_32BITS_UUID_TYPE;
3827 APPL_TRACE_WARNING("BTA EIR: UUID 32-bit list is truncated");
3833 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_32 + 1);
3834 UINT8_TO_STREAM(p_type, data_type);
3835 free_eir_length -= num_uuid * LEN_UUID_32 + 2;
3838 /* Adding 128-bit UUID list */
3839 if ( free_eir_length >= 2)
3844 data_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE;
3846 max_num_uuid = (free_eir_length - 2)/LEN_UUID_128;
3848 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++)
3850 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_128)
3852 if ( num_uuid < max_num_uuid )
3854 ARRAY16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid128);
3859 data_type = BTM_EIR_MORE_128BITS_UUID_TYPE;
3860 APPL_TRACE_WARNING("BTA EIR: UUID 128-bit list is truncated");
3866 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_128 + 1);
3867 UINT8_TO_STREAM(p_type, data_type);
3868 free_eir_length -= num_uuid * LEN_UUID_128 + 2;
3870 #endif /* ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */
3872 /* if Flags are provided in configuration */
3873 if(( p_bta_dm_eir_cfg->bta_dm_eir_flag_len > 0 )
3874 &&( p_bta_dm_eir_cfg->bta_dm_eir_flags )
3875 &&( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2 ))
3877 UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 1);
3878 UINT8_TO_STREAM(p, BTM_EIR_FLAGS_TYPE);
3879 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_flags,
3880 p_bta_dm_eir_cfg->bta_dm_eir_flag_len);
3881 p += p_bta_dm_eir_cfg->bta_dm_eir_flag_len;
3882 free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2;
3885 /* if Manufacturer Specific are provided in configuration */
3886 if(( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len > 0 )
3887 &&( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec )
3888 &&( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2 ))
3892 UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 1);
3893 UINT8_TO_STREAM(p, BTM_EIR_MANUFACTURER_SPECIFIC_TYPE);
3894 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec,
3895 p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len);
3896 p += p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len;
3897 free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2;
3905 /* if Inquiry Tx Resp Power compiled */
3906 if ((p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power) &&
3907 (free_eir_length >= 3))
3909 UINT8_TO_STREAM(p, 2); /* Length field */
3910 UINT8_TO_STREAM(p, BTM_EIR_TX_POWER_LEVEL_TYPE);
3911 UINT8_TO_STREAM(p, *(p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power));
3912 free_eir_length -= 3;
3915 if( free_eir_length )
3916 UINT8_TO_STREAM(p, 0); /* terminator of significant part */
3918 BTM_WriteEIR( p_buf );
3922 /*******************************************************************************
3924 ** Function bta_dm_eir_search_services
3926 ** Description This function searches services in received EIR
3930 *******************************************************************************/
3931 static void bta_dm_eir_search_services( tBTM_INQ_RESULTS *p_result,
3932 tBTA_SERVICE_MASK *p_services_to_search,
3933 tBTA_SERVICE_MASK *p_services_found)
3935 tBTA_SERVICE_MASK service_index = 0;
3936 tBTM_EIR_SEARCH_RESULT result;
3938 APPL_TRACE_DEBUG("BTA searching services in EIR of BDA:0x%02X%02X%02X%02X%02X%02X",
3939 p_result->remote_bd_addr[0],p_result->remote_bd_addr[1],
3940 p_result->remote_bd_addr[2],p_result->remote_bd_addr[3],
3941 p_result->remote_bd_addr[4],p_result->remote_bd_addr[5]);
3943 APPL_TRACE_DEBUG(" with services_to_search=0x%08X", *p_services_to_search);
3945 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE
3946 /* always do GATT based service discovery by SDP instead of from EIR */
3947 /* if GATT based service is also to be put in EIR, need to modify this */
3948 while (service_index < (BTA_MAX_SERVICE_ID - 1))
3950 while(service_index < BTA_MAX_SERVICE_ID)
3953 if( *p_services_to_search
3954 & (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)))
3956 result = BTM_HasInquiryEirService( p_result,
3957 bta_service_id_to_uuid_lkup_tbl[service_index] );
3959 /* Searching for HSP v1.2 only device */
3960 if ((result != BTM_EIR_FOUND) &&
3961 (bta_service_id_to_uuid_lkup_tbl[service_index] == UUID_SERVCLASS_HEADSET))
3963 result = BTM_HasInquiryEirService (p_result, UUID_SERVCLASS_HEADSET_HS);
3966 if( result == BTM_EIR_FOUND )
3968 /* If Plug and Play service record, need to check to see if Broadcom stack */
3969 /* However, EIR data doesn't have EXT_BRCM_VERSION so just skip it */
3970 if( bta_service_id_to_uuid_lkup_tbl[service_index]
3971 != UUID_SERVCLASS_PNP_INFORMATION )
3974 *p_services_found |=
3975 (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index));
3976 /* remove the service from services to be searched */
3977 *p_services_to_search &=
3978 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
3981 else if( result == BTM_EIR_NOT_FOUND )
3983 /* remove the service from services to be searched */
3984 *p_services_to_search &=
3985 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)));
3992 APPL_TRACE_ERROR("BTA EIR search result, services_to_search=0x%08X, services_found=0x%08X",
3993 *p_services_to_search, *p_services_found);
3996 #if (BTA_EIR_CANNED_UUID_LIST != TRUE)
3997 /*******************************************************************************
3999 ** Function bta_dm_eir_update_uuid
4001 ** Description This function adds or removes service UUID in EIR database.
4005 *******************************************************************************/
4006 void bta_dm_eir_update_uuid(UINT16 uuid16, BOOLEAN adding)
4008 /* if this UUID is not advertised in EIR */
4009 if( !BTM_HasEirService( p_bta_dm_eir_cfg->uuid_mask, uuid16 ))
4014 APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid16);
4016 BTM_AddEirService( bta_dm_cb.eir_uuid, uuid16 );
4020 APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid16);
4022 BTM_RemoveEirService( bta_dm_cb.eir_uuid, uuid16 );
4025 bta_dm_set_eir (NULL);
4027 APPL_TRACE_EVENT("bta_dm_eir_update_uuid UUID bit mask=0x%08X %08X",
4028 bta_dm_cb.eir_uuid[1], bta_dm_cb.eir_uuid[0] );
4032 /*******************************************************************************
4034 ** Function bta_dm_enable_test_mode
4036 ** Description enable test mode
4041 *******************************************************************************/
4042 void bta_dm_enable_test_mode(tBTA_DM_MSG *p_data)
4045 BTM_EnableTestMode();
4048 /*******************************************************************************
4050 ** Function bta_dm_disable_test_mode
4052 ** Description disable test mode
4057 *******************************************************************************/
4058 void bta_dm_disable_test_mode(tBTA_DM_MSG *p_data)
4061 BTM_DeviceReset(NULL);
4064 /*******************************************************************************
4066 ** Function bta_dm_execute_callback
4068 ** Description Just execute a generic call back in the context of the BTU/BTA tack
4073 *******************************************************************************/
4074 void bta_dm_execute_callback(tBTA_DM_MSG *p_data)
4077 if(p_data->exec_cback.p_exec_cback == NULL)
4082 p_data->exec_cback.p_exec_cback(p_data->exec_cback.p_param);
4085 /*******************************************************************************
4087 ** Function bta_dm_encrypt_cback
4089 ** Description link encryption complete callback.
4093 *******************************************************************************/
4094 void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result)
4096 tBTA_STATUS bta_status = BTA_SUCCESS;
4097 tBTA_DM_ENCRYPT_CBACK *p_callback = NULL;
4101 for (i=0; i<bta_dm_cb.device_list.count; i++)
4103 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bd_addr) == 0 &&
4104 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
4108 if (i < bta_dm_cb.device_list.count)
4110 p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback;
4111 bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL;
4118 case BTM_WRONG_MODE:
4119 bta_status = BTA_WRONG_MODE;
4121 case BTM_NO_RESOURCES:
4122 bta_status = BTA_NO_RESOURCES;
4125 bta_status = BTA_BUSY;
4128 bta_status = BTA_FAILURE;
4132 APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=0x%x", bta_status, p_callback);
4136 (*p_callback)(bd_addr, transport, bta_status);
4140 /*******************************************************************************
4142 ** Function bta_dm_set_encryption
4144 ** Description This function to encrypt the link
4148 *******************************************************************************/
4149 void bta_dm_set_encryption (tBTA_DM_MSG *p_data)
4153 APPL_TRACE_DEBUG("bta_dm_set_encryption"); //todo
4154 if (!p_data->set_encryption.p_callback)
4156 APPL_TRACE_ERROR("bta_dm_set_encryption callback is not provided");
4159 for (i=0; i<bta_dm_cb.device_list.count; i++)
4161 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_data->set_encryption.bd_addr) == 0 &&
4162 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED)
4165 if (i < bta_dm_cb.device_list.count)
4167 if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback)
4169 APPL_TRACE_ERROR("earlier enc was not done for same device");
4170 (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr,
4171 p_data->set_encryption.transport,
4176 if (BTM_SetEncryption(p_data->set_encryption.bd_addr, p_data->set_encryption.transport,
4177 bta_dm_encrypt_cback, NULL, p_data->set_encryption.sec_act)
4180 bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_data->set_encryption.p_callback;
4185 #if (BLE_INCLUDED == TRUE)
4186 /*******************************************************************************
4188 ** Function bta_dm_observe_results_cb
4190 ** Description Callback for BLE Observe result
4195 *******************************************************************************/
4196 static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
4199 tBTA_DM_SEARCH result;
4200 tBTM_INQ_INFO *p_inq_info;
4201 APPL_TRACE_DEBUG("bta_dm_observe_results_cb")
4203 bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr);
4204 result.inq_res.rssi = p_inq->rssi;
4205 result.inq_res.ble_addr_type = p_inq->ble_addr_type;
4206 result.inq_res.inq_result_type = p_inq->inq_result_type;
4207 result.inq_res.device_type = p_inq->device_type;
4208 result.inq_res.flag = p_inq->flag;
4210 /* application will parse EIR to find out remote device name */
4211 result.inq_res.p_eir = p_eir;
4213 if((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL)
4215 /* initialize remt_name_not_required to FALSE so that we get the name by default */
4216 result.inq_res.remt_name_not_required = FALSE;
4219 if(bta_dm_search_cb.p_scan_cback)
4220 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result);
4224 /* application indicates if it knows the remote name, inside the callback
4225 copy that to the inquiry data base*/
4226 if(result.inq_res.remt_name_not_required)
4227 p_inq_info->appl_knows_rem_name = TRUE;
4231 /*******************************************************************************
4233 ** Function bta_dm_observe_cmpl_cb
4235 ** Description Callback for BLE Observe complete
4240 *******************************************************************************/
4241 static void bta_dm_observe_cmpl_cb (void * p_result)
4243 tBTA_DM_SEARCH data;
4245 APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb");
4247 data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp;
4248 if (bta_dm_search_cb.p_scan_cback)
4250 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
4254 #if (SMP_INCLUDED == TRUE)
4255 /*******************************************************************************
4257 ** Function bta_dm_ble_smp_cback
4259 ** Description Callback for BLE SMP
4264 *******************************************************************************/
4265 static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data)
4267 tBTM_STATUS status = BTM_SUCCESS;
4268 tBTA_DM_SEC sec_event;
4269 char *p_name = NULL;
4271 if (!bta_dm_cb.p_sec_cback)
4272 return BTM_NOT_AUTHORIZED;
4274 memset(&sec_event, 0, sizeof(tBTA_DM_SEC));
4277 case BTM_LE_IO_REQ_EVT:
4278 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
4280 bta_dm_co_ble_io_req(bda,
4281 &p_data->io_req.io_cap,
4282 &p_data->io_req.oob_data,
4283 &p_data->io_req.auth_req,
4284 &p_data->io_req.max_key_size,
4285 &p_data->io_req.init_keys,
4286 &p_data->io_req.resp_keys);
4288 APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data);
4292 case BTM_LE_SEC_REQUEST_EVT:
4293 bdcpy(sec_event.ble_req.bd_addr, bda);
4294 p_name = BTM_SecReadDevName(bda);
4296 strlcpy((char*)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN);
4298 sec_event.ble_req.bd_name[0] = 0;
4299 bta_dm_cb.p_sec_cback(BTA_DM_BLE_SEC_REQ_EVT, &sec_event);
4302 case BTM_LE_KEY_NOTIF_EVT:
4303 bdcpy(sec_event.key_notif.bd_addr, bda);
4304 p_name = BTM_SecReadDevName(bda);
4306 strlcpy((char*)sec_event.key_notif.bd_name, p_name, BD_NAME_LEN);
4308 sec_event.key_notif.bd_name[0] = 0;
4309 sec_event.key_notif.passkey = p_data->key_notif;
4310 bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_NOTIF_EVT, &sec_event);
4313 case BTM_LE_KEY_REQ_EVT:
4314 bdcpy(sec_event.ble_req.bd_addr, bda);
4315 bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_REQ_EVT, &sec_event);
4318 case BTM_LE_OOB_REQ_EVT:
4319 bdcpy(sec_event.ble_req.bd_addr, bda);
4320 bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event);
4323 case BTM_LE_NC_REQ_EVT:
4324 bdcpy(sec_event.key_notif.bd_addr, bda);
4325 strlcpy((char*)sec_event.key_notif.bd_name, bta_dm_get_remname(), (BD_NAME_LEN));
4326 sec_event.key_notif.passkey = p_data->key_notif;
4327 bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
4330 case BTM_LE_KEY_EVT:
4331 bdcpy(sec_event.ble_key.bd_addr, bda);
4332 sec_event.ble_key.key_type = p_data->key.key_type;
4333 sec_event.ble_key.p_key_value = p_data->key.p_key_value;
4334 bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event);
4337 case BTM_LE_COMPLT_EVT:
4338 bdcpy(sec_event.auth_cmpl.bd_addr, bda);
4339 #if BLE_INCLUDED == TRUE
4340 BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type);
4342 p_name = BTM_SecReadDevName(bda);
4344 strlcpy((char*)sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN));
4346 sec_event.auth_cmpl.bd_name[0] = 0;
4348 if (p_data->complt.reason != 0)
4350 sec_event.auth_cmpl.fail_reason = BTA_DM_AUTH_CONVERT_SMP_CODE(((UINT8)p_data->complt.reason));
4351 /* delete this device entry from Sec Dev DB */
4352 bta_dm_remove_sec_dev_entry (bda);
4356 sec_event.auth_cmpl.success = TRUE;
4357 /* We also register for Service Changed right after connect. */
4358 if (!p_data->complt.smp_over_br)
4359 GATT_ConfigServiceChangeCCC(bda, TRUE, BT_TRANSPORT_LE);
4362 if (bta_dm_cb.p_sec_cback)
4364 //bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event);
4365 bta_dm_cb.p_sec_cback(BTA_DM_BLE_AUTH_CMPL_EVT, &sec_event);
4370 status = BTM_NOT_AUTHORIZED;
4375 #endif /* SMP_INCLUDED == TRUE */
4377 /*******************************************************************************
4379 ** Function bta_dm_ble_id_key_cback
4381 ** Description Callback for BLE local ID keys
4386 *******************************************************************************/
4387 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key)
4394 case BTM_BLE_KEY_TYPE_ID:
4395 case BTM_BLE_KEY_TYPE_ER:
4396 if (bta_dm_cb.p_sec_cback)
4398 memcpy(&dm_key.ble_id_keys, p_key, sizeof(tBTM_BLE_LOCAL_KEYS));
4400 evt = (key_type == BTM_BLE_KEY_TYPE_ID) ? BTA_DM_BLE_LOCAL_IR_EVT :\
4401 BTA_DM_BLE_LOCAL_ER_EVT;
4402 bta_dm_cb.p_sec_cback(evt, &dm_key);
4407 APPL_TRACE_DEBUG("Unknown key type %d", key_type);
4414 /*******************************************************************************
4416 ** Function bta_dm_add_blekey
4418 ** Description This function adds an BLE Key to an security database entry.
4419 ** This function shall only be called AFTER BTA_DmAddBleDevice has been called.
4420 ** It is normally called during host startup to restore all required information
4421 ** stored in the NVRAM.
4425 *******************************************************************************/
4426 void bta_dm_add_blekey (tBTA_DM_MSG *p_data)
4428 if (!BTM_SecAddBleKey (p_data->add_ble_key.bd_addr,
4429 (tBTM_LE_KEY_VALUE *)&p_data->add_ble_key.blekey,
4430 p_data->add_ble_key.key_type))
4432 APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Key for device %08x%04x",
4433 (p_data->add_ble_key.bd_addr[0]<<24)+(p_data->add_ble_key.bd_addr[1]<<16)+\
4434 (p_data->add_ble_key.bd_addr[2]<<8)+p_data->add_ble_key.bd_addr[3],
4435 (p_data->add_ble_key.bd_addr[4]<<8)+p_data->add_ble_key.bd_addr[5]);
4439 /*******************************************************************************
4441 ** Function bta_dm_add_ble_device
4443 ** Description This function adds an BLE device to an security database entry.
4444 ** It is normally called during host startup to restore all required information
4445 ** stored in the NVRAM.
4449 *******************************************************************************/
4450 void bta_dm_add_ble_device (tBTA_DM_MSG *p_data)
4452 if (!BTM_SecAddBleDevice (p_data->add_ble_device.bd_addr, NULL,
4453 p_data->add_ble_device.dev_type ,
4454 p_data->add_ble_device.addr_type))
4456 APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Device for device %08x%04x",
4457 (p_data->add_ble_device.bd_addr[0]<<24)+(p_data->add_ble_device.bd_addr[1]<<16)+ \
4458 (p_data->add_ble_device.bd_addr[2]<<8)+p_data->add_ble_device.bd_addr[3],
4459 (p_data->add_ble_device.bd_addr[4]<<8)+p_data->add_ble_device.bd_addr[5]);
4463 /*******************************************************************************
4465 ** Function bta_dm_add_ble_device
4467 ** Description This function adds an BLE device to an security database entry.
4468 ** It is normally called during host startup to restore all required information
4469 ** stored in the NVRAM.
4473 *******************************************************************************/
4474 void bta_dm_ble_passkey_reply (tBTA_DM_MSG *p_data)
4476 if (p_data->pin_reply.accept)
4478 BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_SUCCESS, p_data->ble_passkey_reply.passkey);
4482 BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED, p_data->ble_passkey_reply.passkey);
4487 /*******************************************************************************
4489 ** Function bta_dm_ble_confirm_reply
4491 ** Description This is response to SM numeric comparison request submitted
4496 *******************************************************************************/
4497 void bta_dm_ble_confirm_reply (tBTA_DM_MSG *p_data)
4499 if (p_data->confirm.accept)
4501 BTM_BleConfirmReply(p_data->confirm.bd_addr, BTM_SUCCESS);
4505 BTM_BleConfirmReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED);
4509 /*******************************************************************************
4511 ** Function bta_dm_security_grant
4513 ** Description This function grant SMP security request access.
4517 *******************************************************************************/
4518 void bta_dm_security_grant (tBTA_DM_MSG *p_data)
4520 BTM_SecurityGrant(p_data->ble_sec_grant.bd_addr, p_data->ble_sec_grant.res);
4523 /*******************************************************************************
4525 ** Function bta_dm_ble_set_bg_conn_type
4527 ** Description This function set the BLE background connection type
4531 *******************************************************************************/
4532 void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data)
4534 BTM_BleSetBgConnType(p_data->ble_set_bd_conn_type.bg_conn_type,
4535 p_data->ble_set_bd_conn_type.p_select_cback);
4538 /*******************************************************************************
4540 ** Function bta_dm_ble_set_conn_params
4542 ** Description This function set the preferred connection parameters.
4546 *******************************************************************************/
4547 void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data)
4549 BTM_BleSetPrefConnParams(p_data->ble_set_conn_params.peer_bda,
4550 p_data->ble_set_conn_params.conn_int_min,
4551 p_data->ble_set_conn_params.conn_int_max,
4552 p_data->ble_set_conn_params.slave_latency,
4553 p_data->ble_set_conn_params.supervision_tout);
4556 /*******************************************************************************
4558 ** Function bta_dm_ble_set_conn_scan_params
4560 ** Description This function sets BLE scan parameters.
4564 *******************************************************************************/
4565 void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data)
4567 BTM_BleSetScanParams(p_data->ble_set_scan_params.client_if,
4568 p_data->ble_set_scan_params.scan_int,
4569 p_data->ble_set_scan_params.scan_window,
4570 p_data->ble_set_scan_params.scan_mode,
4571 p_data->ble_set_scan_params.scan_param_setup_cback);
4574 /*******************************************************************************
4576 ** Function bta_dm_ble_set_conn_scan_params
4578 ** Description This function set the preferred connection scan parameters.
4582 *******************************************************************************/
4583 void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data)
4585 BTM_BleSetConnScanParams(p_data->ble_set_conn_scan_params.scan_int,
4586 p_data->ble_set_conn_scan_params.scan_window);
4588 /*******************************************************************************
4590 ** Function bta_dm_ble_update_conn_params
4592 ** Description This function update LE connection parameters.
4596 *******************************************************************************/
4597 void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data)
4599 if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr,
4600 p_data->ble_update_conn_params.min_int,
4601 p_data->ble_update_conn_params.max_int,
4602 p_data->ble_update_conn_params.latency,
4603 p_data->ble_update_conn_params.timeout))
4605 APPL_TRACE_ERROR("Update connection parameters failed!");
4609 #if BLE_PRIVACY_SPT == TRUE
4610 /*******************************************************************************
4612 ** Function bta_dm_ble_config_local_privacy
4614 ** Description This function set the local device LE privacy settings.
4618 *******************************************************************************/
4619 void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data)
4621 BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable);
4625 /*******************************************************************************
4627 ** Function bta_dm_ble_observe
4629 ** Description This function set the preferred connection scan parameters.
4633 *******************************************************************************/
4634 void bta_dm_ble_observe (tBTA_DM_MSG *p_data)
4637 if (p_data->ble_observe.start)
4639 /*Save the callback to be called when a scan results are available */
4640 bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback;
4641 if ((status = BTM_BleObserve(TRUE, p_data->ble_observe.duration,
4642 bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb))!= BTM_CMD_STARTED)
4644 tBTA_DM_SEARCH data;
4645 APPL_TRACE_WARNING(" %s BTM_BleObserve failed. status %d",__FUNCTION__,status);
4646 data.inq_cmpl.num_resps = 0;
4647 if (bta_dm_search_cb.p_scan_cback)
4649 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
4655 bta_dm_search_cb.p_scan_cback = NULL;
4656 BTM_BleObserve(FALSE, 0, NULL,NULL );
4659 /*******************************************************************************
4661 ** Function bta_dm_ble_set_adv_params
4663 ** Description This function set the adv parameters.
4667 *******************************************************************************/
4668 void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data)
4670 BTM_BleSetAdvParams(p_data->ble_set_adv_params.adv_int_min,
4671 p_data->ble_set_adv_params.adv_int_max,
4672 p_data->ble_set_adv_params.p_dir_bda,
4673 BTA_DM_BLE_ADV_CHNL_MAP);
4676 /*******************************************************************************
4678 ** Function bta_dm_ble_set_adv_config
4680 ** Description This function set the customized ADV data configuration
4684 *******************************************************************************/
4685 void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data)
4687 tBTA_STATUS status = BTA_FAILURE;
4689 if (BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask,
4690 (tBTM_BLE_ADV_DATA *)&p_data->ble_set_adv_data.adv_cfg) == BTM_SUCCESS)
4692 status = BTA_SUCCESS;
4695 if (p_data->ble_set_adv_data.p_adv_data_cback)
4696 (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
4699 /*******************************************************************************
4701 ** Function bta_dm_ble_set_scan_rsp
4703 ** Description This function set the customized ADV scan resp. configuration
4707 *******************************************************************************/
4708 void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data)
4710 tBTA_STATUS status = BTA_FAILURE;
4712 if(BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask,
4713 (tBTM_BLE_ADV_DATA *)&p_data->ble_set_adv_data.adv_cfg) == BTM_SUCCESS)
4715 status = BTA_SUCCESS;
4718 if (p_data->ble_set_adv_data.p_adv_data_cback)
4719 (*p_data->ble_set_adv_data.p_adv_data_cback)(status);
4722 /*******************************************************************************
4724 ** Function bta_dm_ble_set_data_length
4726 ** Description This function set the maximum transmission packet size
4730 *******************************************************************************/
4731 void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data)
4733 if (BTM_SetBleDataLength(p_data->ble_set_data_length.remote_bda,
4734 p_data->ble_set_data_length.tx_data_length) != BTM_SUCCESS)
4736 APPL_TRACE_ERROR("%s failed", __FUNCTION__);
4740 /*******************************************************************************
4742 ** Function bta_dm_ble_broadcast
4744 ** Description Starts or stops LE broadcasts
4748 *******************************************************************************/
4749 void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data)
4751 BTM_BleBroadcast(p_data->ble_observe.start);
4754 /*******************************************************************************
4756 ** Function bta_dm_ble_multi_adv_enb
4758 ** Description This function enables a single advertising instance
4762 *******************************************************************************/
4763 void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data)
4765 tBTM_STATUS btm_status = 0;
4767 bta_dm_cb.p_multi_adv_cback = p_data->ble_multi_adv_enb.p_cback;
4768 if(BTM_BleMaxMultiAdvInstanceCount() > 0 && NULL != p_data->ble_multi_adv_enb.p_ref)
4770 btm_status = BTM_BleEnableAdvInstance((tBTM_BLE_ADV_PARAMS*)
4771 p_data->ble_multi_adv_enb.p_params,
4772 p_data->ble_multi_adv_enb.p_cback,
4773 p_data->ble_multi_adv_enb.p_ref);
4776 if(BTM_CMD_STARTED != btm_status)
4778 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_ENB_EVT, 0xFF,
4779 p_data->ble_multi_adv_enb.p_ref, BTA_FAILURE);
4782 /*******************************************************************************
4784 ** Function bta_dm_ble_multi_adv_param_upd
4786 ** Description This function updates multiple advertising instance parameters
4790 *******************************************************************************/
4791 void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data)
4793 tBTM_STATUS btm_status = 0;
4796 if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_param.inst_id > 0
4797 && p_data->ble_multi_adv_param.inst_id < BTM_BleMaxMultiAdvInstanceCount())
4799 btm_status = BTM_BleUpdateAdvInstParam(p_data->ble_multi_adv_param.inst_id,
4800 (tBTM_BLE_ADV_PARAMS*)p_data->ble_multi_adv_param.p_params);
4803 if(BTM_CMD_STARTED != btm_status)
4805 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_param.inst_id);
4806 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_PARAM_EVT,
4807 p_data->ble_multi_adv_param.inst_id, p_ref, BTA_FAILURE);
4810 /*******************************************************************************
4812 ** Function bta_dm_ble_multi_adv_data
4814 ** Description This function write multiple advertising instance adv data
4815 ** or scan response data
4819 *******************************************************************************/
4820 void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data)
4822 tBTM_STATUS btm_status = 0;
4825 if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_data.inst_id > 0
4826 && p_data->ble_multi_adv_data.inst_id < BTM_BleMaxMultiAdvInstanceCount())
4828 btm_status = BTM_BleCfgAdvInstData(p_data->ble_multi_adv_data.inst_id,
4829 p_data->ble_multi_adv_data.is_scan_rsp,
4830 p_data->ble_multi_adv_data.data_mask,
4831 (tBTM_BLE_ADV_DATA*)&p_data->ble_multi_adv_data.data);
4834 if(BTM_CMD_STARTED != btm_status)
4836 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_data.inst_id);
4837 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DATA_EVT,
4838 p_data->ble_multi_adv_data.inst_id, p_ref, BTA_FAILURE);
4842 /*******************************************************************************
4844 ** Function btm_dm_ble_multi_adv_disable
4846 ** Description This function disable a single adv instance
4850 *******************************************************************************/
4851 void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data)
4853 tBTM_STATUS btm_status = 0;
4856 if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_disable.inst_id > 0
4857 && p_data->ble_multi_adv_disable.inst_id < BTM_BleMaxMultiAdvInstanceCount())
4859 btm_status = BTM_BleDisableAdvInstance(p_data->ble_multi_adv_disable.inst_id);
4862 if(BTM_CMD_STARTED != btm_status)
4864 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_disable.inst_id);
4865 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DISABLE_EVT,
4866 p_data->ble_multi_adv_disable.inst_id, p_ref, BTA_FAILURE);
4870 /*******************************************************************************
4872 ** Function bta_dm_ble_setup_storage
4874 ** Description This function configures up the storage parameters for ADV batch scanning
4878 *******************************************************************************/
4879 void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data)
4881 tBTM_STATUS btm_status = 0;
4882 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
4884 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
4886 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
4888 btm_status = BTM_BleSetStorageConfig(p_data->ble_set_storage.batch_scan_full_max,
4889 p_data->ble_set_storage.batch_scan_trunc_max,
4890 p_data->ble_set_storage.batch_scan_notify_threshold,
4891 p_data->ble_set_storage.p_setup_cback,
4892 p_data->ble_set_storage.p_thres_cback,
4893 p_data->ble_set_storage.p_read_rep_cback,
4894 p_data->ble_set_storage.ref_value);
4897 if(BTM_CMD_STARTED != btm_status)
4898 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, p_data->ble_set_storage.ref_value,
4902 /*******************************************************************************
4904 ** Function bta_dm_ble_enable_batch_scan
4906 ** Description This function sets up the parameters and enables batch scan
4910 *******************************************************************************/
4911 void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data)
4913 tBTM_STATUS btm_status = 0;
4914 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
4916 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
4918 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
4920 btm_status = BTM_BleEnableBatchScan(p_data->ble_enable_scan.scan_mode,
4921 p_data->ble_enable_scan.scan_int,
4922 p_data->ble_enable_scan.scan_window,
4923 p_data->ble_enable_scan.discard_rule,
4924 p_data->ble_enable_scan.addr_type,
4925 p_data->ble_enable_scan.ref_value);
4928 if(BTM_CMD_STARTED != btm_status)
4929 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_ENABLE_EVT, p_data->ble_enable_scan.ref_value,
4933 /*******************************************************************************
4935 ** Function bta_dm_ble_disable_batch_scan
4937 ** Description This function disables the batch scan
4941 *******************************************************************************/
4942 void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data)
4945 tBTM_STATUS btm_status = 0;
4946 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
4948 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
4950 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
4952 btm_status = BTM_BleDisableBatchScan(p_data->ble_disable_scan.ref_value);
4955 if(BTM_CMD_STARTED != btm_status)
4956 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_DISABLE_EVT, p_data->ble_enable_scan.ref_value,
4960 /*******************************************************************************
4962 ** Function bta_dm_ble_read_scan_reports
4964 ** Description This function reads the batch scan reports
4968 *******************************************************************************/
4969 void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data)
4971 tBTM_STATUS btm_status = 0;
4972 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
4974 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
4976 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
4978 btm_status = BTM_BleReadScanReports(p_data->ble_read_reports.scan_type,
4979 p_data->ble_read_reports.ref_value);
4982 if(BTM_CMD_STARTED != btm_status)
4983 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, p_data->ble_enable_scan.ref_value,
4987 /*******************************************************************************
4989 ** Function bta_dm_ble_track_advertiser
4991 ** Description This function tracks the specific advertiser
4995 *******************************************************************************/
4996 void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data)
4998 tBTM_STATUS btm_status = 0;
5000 memset(&bda, 0 , sizeof(BD_ADDR));
5001 tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
5002 tBTA_DM_BLE_TRACK_ADV_DATA track_adv_data;
5004 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
5006 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg)
5008 btm_status = BTM_BleTrackAdvertiser((tBTM_BLE_TRACK_ADV_CBACK *)
5009 p_data->ble_track_advert.p_track_adv_cback,
5010 p_data->ble_track_advert.ref_value);
5013 if(BTM_CMD_STARTED != btm_status)
5015 memset(&track_adv_data, 0, sizeof(tBTA_DM_BLE_TRACK_ADV_DATA));
5016 track_adv_data.advertiser_info_present = NO_ADV_INFO_PRESENT; /* Indicates failure */
5017 track_adv_data.client_if = (UINT8)p_data->ble_track_advert.ref_value;
5018 p_data->ble_track_advert.p_track_adv_cback(&track_adv_data);
5022 /*******************************************************************************
5024 ** Function bta_ble_scan_setup_cb
5026 ** Description Handle the setup callback from BTM layer and forward it to app layer
5030 *******************************************************************************/
5031 void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_value,
5034 tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0;
5036 APPL_TRACE_DEBUG("bta_ble_scan_setup_cb : evt: %d, ref_value: %d, status:%d", evt,
5041 case BTM_BLE_BATCH_SCAN_ENABLE_EVT:
5042 bta_evt = BTA_BLE_BATCH_SCAN_ENB_EVT;
5044 case BTM_BLE_BATCH_SCAN_CFG_STRG_EVT:
5045 bta_evt = BTA_BLE_BATCH_SCAN_CFG_STRG_EVT;
5047 case BTM_BLE_BATCH_SCAN_DISABLE_EVT:
5048 bta_evt = BTA_BLE_BATCH_SCAN_DIS_EVT;
5050 case BTM_BLE_BATCH_SCAN_PARAM_EVT:
5051 bta_evt = BTA_BLE_BATCH_SCAN_PARAM_EVT;
5057 if(NULL != bta_dm_cb.p_setup_cback)
5058 bta_dm_cb.p_setup_cback(bta_evt, ref_value, status);
5062 #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
5063 /*******************************************************************************
5065 ** Function bta_ble_scan_pf_cmpl
5067 ** Description ADV payload filtering operation complete callback
5070 ** Returns TRUE if handled, otherwise FALSE.
5072 *******************************************************************************/
5073 static void bta_ble_scan_cfg_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op,
5074 tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status,
5075 tBTM_BLE_REF_VALUE ref_value)
5077 tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE;
5079 APPL_TRACE_DEBUG("bta_ble_scan_cfg_cmpl: %d, %d, %d, %d", action, cfg_op, avbl_space, status);
5081 if(bta_dm_cb.p_scan_filt_cfg_cback)
5082 bta_dm_cb.p_scan_filt_cfg_cback(action, cfg_op, avbl_space, st, ref_value);
5085 /*******************************************************************************
5087 ** Function bta_dm_cfg_filter_cond
5089 ** Description This function configure adv payload filtering condition
5093 *******************************************************************************/
5094 void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data)
5096 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5097 tBTA_STATUS status = BTA_FAILURE;
5099 tBTM_BLE_VSC_CB cmn_vsc_cb;
5101 APPL_TRACE_DEBUG("bta_dm_cfg_filter_cond");
5102 BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5103 if(0 != cmn_vsc_cb.filter_support)
5105 if ((st = BTM_BleCfgFilterCondition(p_data->ble_cfg_filter_cond.action,
5106 p_data->ble_cfg_filter_cond.cond_type,
5107 (tBTM_BLE_PF_FILT_INDEX)p_data->ble_cfg_filter_cond.filt_index,
5108 (tBTM_BLE_PF_COND_PARAM *)p_data->ble_cfg_filter_cond.p_cond_param,
5109 bta_ble_scan_cfg_cmpl, p_data->ble_cfg_filter_cond.ref_value))
5112 bta_dm_cb.p_scan_filt_cfg_cback = p_data->ble_cfg_filter_cond.p_filt_cfg_cback;
5117 if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback)
5118 p_data->ble_cfg_filter_cond.p_filt_cfg_cback(BTA_DM_BLE_PF_CONFIG_EVT,
5119 p_data->ble_cfg_filter_cond.cond_type, 0, status,
5120 p_data->ble_cfg_filter_cond.ref_value);
5124 /*******************************************************************************
5126 ** Function bta_dm_enable_scan_filter
5128 ** Description This function enable/disable adv payload filtering condition
5132 *******************************************************************************/
5133 void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data)
5135 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5136 tBTA_STATUS status = BTA_FAILURE;
5138 tBTM_BLE_VSC_CB cmn_vsc_cb;
5139 APPL_TRACE_DEBUG("bta_dm_enable_scan_filter");
5140 BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5142 if(0 != cmn_vsc_cb.filter_support)
5144 if((st = BTM_BleEnableDisableFilterFeature(p_data->ble_enable_scan_filt.action,
5145 p_data->ble_enable_scan_filt.p_filt_status_cback,
5146 (tBTM_BLE_REF_VALUE)p_data->ble_enable_scan_filt.ref_value)) == BTM_CMD_STARTED)
5147 bta_dm_cb.p_scan_filt_status_cback = p_data->ble_enable_scan_filt.p_filt_status_cback;
5151 if (p_data->ble_enable_scan_filt.p_filt_status_cback)
5152 p_data->ble_enable_scan_filt.p_filt_status_cback (BTA_DM_BLE_PF_ENABLE_EVT,
5153 p_data->ble_enable_scan_filt.ref_value, status);
5157 /*******************************************************************************
5159 ** Function bta_dm_scan_filter_param_setup
5161 ** Description This function sets up scan filter params
5165 *******************************************************************************/
5166 void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data)
5168 tBTM_STATUS st = BTM_MODE_UNSUPPORTED;
5169 tBTA_STATUS status = BTA_FAILURE;
5171 tBTM_BLE_VSC_CB cmn_vsc_cb;
5173 APPL_TRACE_DEBUG("bta_dm_scan_filter_param_setup");
5174 BTM_BleGetVendorCapabilities(&cmn_vsc_cb);
5175 if(0 != cmn_vsc_cb.filter_support)
5177 if ((st = BTM_BleAdvFilterParamSetup(p_data->ble_scan_filt_param_setup.action,
5178 p_data->ble_scan_filt_param_setup.filt_index,
5179 (tBTM_BLE_PF_FILT_PARAMS *)&p_data->ble_scan_filt_param_setup.filt_params,
5180 p_data->ble_scan_filt_param_setup.p_target,
5181 p_data->ble_scan_filt_param_setup.p_filt_param_cback,
5182 p_data->ble_scan_filt_param_setup.ref_value)) == BTM_CMD_STARTED)
5184 bta_dm_cb.p_scan_filt_param_cback = p_data->ble_scan_filt_param_setup.p_filt_param_cback;
5189 if (p_data->ble_scan_filt_param_setup.p_filt_param_cback)
5190 p_data->ble_scan_filt_param_setup.p_filt_param_cback (BTA_DM_BLE_PF_ENABLE_EVT, 0,
5191 p_data->ble_scan_filt_param_setup.ref_value, status);
5197 /*******************************************************************************
5199 ** Function bta_ble_enable_scan_cmpl
5201 ** Description ADV payload filtering enable / disable complete callback
5206 *******************************************************************************/
5207 static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time,
5208 tBTM_BLE_RX_TIME_MS rx_time,
5209 tBTM_BLE_IDLE_TIME_MS idle_time,
5210 tBTM_BLE_ENERGY_USED energy_used,
5213 tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE;
5214 tBTA_DM_CONTRL_STATE ctrl_state = 0;
5216 if (BTA_SUCCESS == st)
5217 ctrl_state = bta_dm_pm_obtain_controller_state();
5219 if (bta_dm_cb.p_energy_info_cback)
5220 bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, ctrl_state, st);
5223 /*******************************************************************************
5225 ** Function bta_dm_ble_get_energy_info
5227 ** Description This function obtains the energy info
5231 *******************************************************************************/
5232 void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data)
5234 tBTM_STATUS btm_status = 0;
5236 bta_dm_cb.p_energy_info_cback = p_data->ble_energy_info.p_energy_info_cback;
5237 btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl);
5238 if (BTM_CMD_STARTED != btm_status)
5239 bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status);
5242 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
5243 #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT
5244 #define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000
5247 /*******************************************************************************
5249 ** Function bta_dm_gattc_register
5251 ** Description Register with GATTC in DM if BLE is needed.
5256 *******************************************************************************/
5257 static void bta_dm_gattc_register(void)
5259 tBT_UUID app_uuid = {LEN_UUID_128,{0}};
5261 if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF)
5263 memset (&app_uuid.uu.uuid128, 0x87, LEN_UUID_128);
5264 BTA_GATTC_AppRegister(&app_uuid, bta_dm_gattc_callback);
5268 /*******************************************************************************
5270 ** Function btm_dm_start_disc_gatt_services
5272 ** Description This function starts a GATT service search request.
5276 *******************************************************************************/
5277 static void btm_dm_start_disc_gatt_services (UINT16 conn_id)
5279 tBT_UUID *p_uuid = bta_dm_search_cb.p_srvc_uuid +
5280 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
5282 p_uuid = bta_dm_search_cb.p_srvc_uuid +
5283 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search;
5285 /* always search for all services */
5286 BTA_GATTC_ServiceSearchRequest(conn_id, p_uuid);
5289 /*******************************************************************************
5291 ** Function bta_dm_gatt_disc_result
5293 ** Description This function process the GATT service search result.
5297 *******************************************************************************/
5298 static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
5300 tBTA_DM_SEARCH result;
5303 * This logic will not work for gatt case. We are checking against the bluetooth profiles here
5304 * just copy the GATTID in raw data field and send it across.
5308 if ( bta_dm_search_cb.ble_raw_used + sizeof(tBTA_GATT_ID) < bta_dm_search_cb.ble_raw_size )
5310 APPL_TRACE_DEBUG("ADDING BLE SERVICE uuid=0x%x, ble_ptr = 0x%x, ble_raw_used = 0x%x",
5311 service_id.uuid.uu.uuid16,bta_dm_search_cb.p_ble_rawdata,bta_dm_search_cb.ble_raw_used);
5313 if(bta_dm_search_cb.p_ble_rawdata)
5315 memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used), &service_id,
5316 sizeof(service_id) );
5318 bta_dm_search_cb.ble_raw_used += sizeof(service_id);
5322 APPL_TRACE_ERROR("p_ble_rawdata is NULL");
5328 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 );
5331 LOG_INFO(LOG_TAG, "%s service_id_uuid_len=%d ", __func__, service_id.uuid.len);
5332 if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE)
5335 /* send result back to app now, one by one */
5336 bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
5337 strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN);
5338 memcpy(&result.disc_ble_res.service, &service_id.uuid, sizeof(tBT_UUID));
5340 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
5344 /*******************************************************************************
5346 ** Function bta_dm_gatt_disc_complete
5348 ** Description This function process the GATT service search complete.
5352 *******************************************************************************/
5353 static void bta_dm_gatt_disc_complete(UINT16 conn_id, tBTA_GATT_STATUS status)
5355 APPL_TRACE_DEBUG("%s conn_id = %d", __func__, conn_id);
5357 if (bta_dm_search_cb.uuid_to_search > 0)
5358 bta_dm_search_cb.uuid_to_search --;
5360 if (status == BTA_GATT_OK && bta_dm_search_cb.uuid_to_search > 0) {
5361 btm_dm_start_disc_gatt_services(conn_id);
5363 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG));
5365 bta_dm_search_cb.uuid_to_search = 0;
5367 /* no more services to be discovered */
5368 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
5369 p_msg->disc_result.result.disc_res.result = (status == BTA_GATT_OK) ? BTA_SUCCESS :BTA_FAILURE;
5370 APPL_TRACE_DEBUG("%s service found: 0x%08x", __func__,
5371 bta_dm_search_cb.services_found);
5372 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
5373 p_msg->disc_result.result.disc_res.num_uuids = 0;
5374 p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
5375 bdcpy(p_msg->disc_result.result.disc_res.bd_addr,
5376 bta_dm_search_cb.peer_bdaddr);
5377 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name,
5378 bta_dm_get_remname(), BD_NAME_LEN);
5380 p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE;
5381 if (bta_dm_search_cb.ble_raw_used > 0) {
5382 p_msg->disc_result.result.disc_res.p_raw_data =
5383 osi_malloc(bta_dm_search_cb.ble_raw_used);
5385 memcpy(p_msg->disc_result.result.disc_res.p_raw_data,
5386 bta_dm_search_cb.p_ble_rawdata,
5387 bta_dm_search_cb.ble_raw_used);
5389 p_msg->disc_result.result.disc_res.raw_data_size =
5390 bta_dm_search_cb.ble_raw_used;
5392 p_msg->disc_result.result.disc_res.p_raw_data = NULL;
5393 bta_dm_search_cb.p_ble_rawdata = 0;
5396 bta_sys_sendmsg(p_msg);
5398 if (conn_id != BTA_GATT_INVALID_CONN_ID)
5400 /* start a GATT channel close delay timer */
5401 bta_sys_start_timer(bta_dm_search_cb.gatt_close_timer,
5402 BTA_DM_GATT_CLOSE_DELAY_TOUT,
5403 BTA_DM_DISC_CLOSE_TOUT_EVT, 0);
5404 bdcpy(bta_dm_search_cb.pending_close_bda,
5405 bta_dm_search_cb.peer_bdaddr);
5407 bta_dm_search_cb.gatt_disc_active = FALSE;
5411 /*******************************************************************************
5413 ** Function bta_dm_close_gatt_conn
5415 ** Description This function close the GATT connection after delay timeout.
5419 *******************************************************************************/
5420 void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data)
5424 if (bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID)
5425 BTA_GATTC_Close(bta_dm_search_cb.conn_id);
5427 memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
5428 bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID;
5430 /*******************************************************************************
5432 ** Function btm_dm_start_gatt_discovery
5434 ** Description This is GATT initiate the service search by open a GATT connection
5439 *******************************************************************************/
5440 void btm_dm_start_gatt_discovery (BD_ADDR bd_addr)
5442 bta_dm_search_cb.gatt_disc_active = TRUE;
5444 /* connection is already open */
5445 if (bdcmp(bta_dm_search_cb.pending_close_bda, bd_addr) == 0 &&
5446 bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID)
5448 memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN);
5449 alarm_cancel(bta_dm_search_cb.gatt_close_timer);
5450 btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id);
5453 BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE, BTA_GATT_TRANSPORT_LE);
5456 /*******************************************************************************
5458 ** Function bta_dm_cancel_gatt_discovery
5460 ** Description This is GATT cancel the GATT service search.
5464 *******************************************************************************/
5465 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr)
5467 if (bta_dm_search_cb.conn_id == BTA_GATT_INVALID_CONN_ID)
5469 BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, TRUE);
5472 bta_dm_gatt_disc_complete(bta_dm_search_cb.conn_id, (tBTA_GATT_STATUS) BTA_GATT_ERROR);
5475 /*******************************************************************************
5477 ** Function bta_dm_proc_open_evt
5479 ** Description process BTA_GATTC_OPEN_EVT in DM.
5483 *******************************************************************************/
5484 void bta_dm_proc_open_evt(tBTA_GATTC_OPEN *p_data)
5489 p1 = bta_dm_search_cb.peer_bdaddr;
5490 p2 = p_data->remote_bda;
5492 APPL_TRACE_DEBUG("DM Search state= %d search_cb.peer_dbaddr: [%08x%04x] connected_bda= [%08x%04x] ",
5493 bta_dm_search_cb.state,
5494 ((p1[0])<<24)+((p1[1])<<16)+((p1[2])<<8)+(p1[3]),
5495 ((p1[4])<<8)+ p1[5],
5496 ((p2[0])<<24)+((p2[1])<<16)+((p2[2])<<8)+(p2[3]),
5497 ((p2[4])<<8)+ p2[5]);
5499 APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d" ,
5504 bta_dm_search_cb.conn_id = p_data->conn_id;
5506 if (p_data->status == BTA_GATT_OK)
5508 btm_dm_start_disc_gatt_services(p_data->conn_id);
5512 bta_dm_gatt_disc_complete(BTA_GATT_INVALID_CONN_ID, p_data->status);
5516 /*******************************************************************************
5518 ** Function bta_dm_gattc_callback
5520 ** Description This is GATT client callback function used in DM.
5524 *******************************************************************************/
5525 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data)
5527 APPL_TRACE_DEBUG("bta_dm_gattc_callback event = %d", event);
5531 case BTA_GATTC_REG_EVT:
5532 APPL_TRACE_DEBUG("BTA_GATTC_REG_EVT client_if = %d", p_data->reg_oper.client_if);
5533 if (p_data->reg_oper.status == BTA_GATT_OK)
5534 bta_dm_search_cb.client_if = p_data->reg_oper.client_if;
5536 bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF;
5539 case BTA_GATTC_OPEN_EVT:
5540 bta_dm_proc_open_evt(&p_data->open);
5543 case BTA_GATTC_SEARCH_RES_EVT:
5544 bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid);
5547 case BTA_GATTC_SEARCH_CMPL_EVT:
5548 if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE)
5549 bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
5552 case BTA_GATTC_CLOSE_EVT:
5553 APPL_TRACE_DEBUG("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason);
5554 /* in case of disconnect before search is completed */
5555 if ( (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) &&
5556 (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) &&
5557 !memcmp(p_data->close.remote_bda, bta_dm_search_cb.peer_bdaddr, BD_ADDR_LEN))
5559 bta_dm_gatt_disc_complete((UINT16)BTA_GATT_INVALID_CONN_ID, (tBTA_GATT_STATUS) BTA_GATT_ERROR);
5568 #endif /* BTA_GATT_INCLUDED */
5570 #if BLE_VND_INCLUDED == TRUE
5571 /*******************************************************************************
5573 ** Function bta_dm_ctrl_features_rd_cmpl_cback
5575 ** Description callback to handle controller feature read complete
5579 *******************************************************************************/
5580 static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result)
5582 APPL_TRACE_DEBUG("%s status = %d ", __FUNCTION__, result);
5583 if (result == BTM_SUCCESS)
5585 if(bta_dm_cb.p_sec_cback)
5586 bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL);
5590 APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d",__FUNCTION__, result);
5594 #endif /* BLE_VND_INCLUDED */
5596 #endif /* BLE_INCLUDED */