1/****************************************************************************** 2 * 3 * Copyright 2003-2014 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19/****************************************************************************** 20 * 21 * This file contains the action functions for device manager state 22 * machine. 23 * 24 ******************************************************************************/ 25 26#define LOG_TAG "bt_bta_dm" 27 28#include <base/bind.h> 29#include <base/callback.h> 30#include <base/logging.h> 31#include <string.h> 32 33#include "bt_common.h" 34#include "bt_target.h" 35#include "bt_types.h" 36#include "bta_api.h" 37#include "bta_dm_api.h" 38#include "bta_dm_co.h" 39#include "bta_dm_int.h" 40#include "bta_sys.h" 41#include "btm_api.h" 42#include "btm_int.h" 43#include "btu.h" 44#include "gap_api.h" /* For GAP_BleReadPeerPrefConnParams */ 45#include "l2c_api.h" 46#include "osi/include/log.h" 47#include "osi/include/osi.h" 48#include "sdp_api.h" 49#include "utl.h" 50 51#if (GAP_INCLUDED == TRUE) 52#include "gap_api.h" 53#endif 54 55using bluetooth::Uuid; 56 57static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, uint8_t* p_eir, 58 uint16_t eir_len); 59static void bta_dm_inq_cmpl_cb(void* p_result); 60static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr, 61 DEV_CLASS dc, BD_NAME bd_name); 62static void bta_dm_remname_cback(void* p); 63static void bta_dm_find_services(const RawAddress& bd_addr); 64static void bta_dm_discover_next_device(void); 65static void bta_dm_sdp_callback(uint16_t sdp_status); 66static uint8_t bta_dm_authorize_cback(const RawAddress& bd_addr, 67 DEV_CLASS dev_class, BD_NAME bd_name, 68 uint8_t* service_name, uint8_t service_id, 69 bool is_originator); 70static uint8_t bta_dm_pin_cback(const RawAddress& bd_addr, DEV_CLASS dev_class, 71 BD_NAME bd_name, bool min_16_digit); 72static uint8_t bta_dm_new_link_key_cback(const RawAddress& bd_addr, 73 DEV_CLASS dev_class, BD_NAME bd_name, 74 LINK_KEY key, uint8_t key_type); 75static uint8_t bta_dm_authentication_complete_cback(const RawAddress& bd_addr, 76 DEV_CLASS dev_class, 77 BD_NAME bd_name, 78 int result); 79static void bta_dm_local_name_cback(void* p_name); 80static bool bta_dm_check_av(uint16_t event); 81static void bta_dm_bl_change_cback(tBTM_BL_EVENT_DATA* p_data); 82 83static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, uint8_t id, 84 uint8_t app_id, const RawAddress& peer_addr); 85 86/* Extended Inquiry Response */ 87static uint8_t bta_dm_sp_cback(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data); 88 89static void bta_dm_set_eir(char* local_name); 90 91static void bta_dm_eir_search_services(tBTM_INQ_RESULTS* p_result, 92 tBTA_SERVICE_MASK* p_services_to_search, 93 tBTA_SERVICE_MASK* p_services_found); 94 95static void bta_dm_search_timer_cback(void* data); 96static void bta_dm_disable_conn_down_timer_cback(void* data); 97static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id, 98 uint8_t app_id, const RawAddress& peer_addr); 99static void bta_dm_adjust_roles(bool delay_role_switch); 100static char* bta_dm_get_remname(void); 101static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result); 102 103static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, 104 tBT_TRANSPORT transport); 105static void bta_dm_discover_device(const RawAddress& remote_bd_addr); 106 107static void bta_dm_sys_hw_cback(tBTA_SYS_HW_EVT status); 108static void bta_dm_disable_search_and_disc(void); 109 110static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda, 111 tBTM_LE_EVT_DATA* p_data); 112static void bta_dm_ble_id_key_cback(uint8_t key_type, 113 tBTM_BLE_LOCAL_KEYS* p_key); 114static void bta_dm_gattc_register(void); 115static void btm_dm_start_gatt_discovery(const RawAddress& bd_addr); 116static void bta_dm_cancel_gatt_discovery(const RawAddress& bd_addr); 117static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data); 118extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void); 119 120#if (BLE_VND_INCLUDED == TRUE) 121static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result); 122#endif 123 124#ifndef BTA_DM_BLE_ADV_CHNL_MAP 125#define BTA_DM_BLE_ADV_CHNL_MAP \ 126 (BTM_BLE_ADV_CHNL_37 | BTM_BLE_ADV_CHNL_38 | BTM_BLE_ADV_CHNL_39) 127#endif 128 129/* Disable timer interval (in milliseconds) */ 130#ifndef BTA_DM_DISABLE_TIMER_MS 131#define BTA_DM_DISABLE_TIMER_MS 5000 132#endif 133 134/* Disable timer retrial interval (in milliseconds) */ 135#ifndef BTA_DM_DISABLE_TIMER_RETRIAL_MS 136#define BTA_DM_DISABLE_TIMER_RETRIAL_MS 1500 137#endif 138 139/* Disable connection down timer (in milliseconds) */ 140#ifndef BTA_DM_DISABLE_CONN_DOWN_TIMER_MS 141#define BTA_DM_DISABLE_CONN_DOWN_TIMER_MS 1000 142#endif 143 144/* Switch delay timer (in milliseconds) */ 145#ifndef BTA_DM_SWITCH_DELAY_TIMER_MS 146#define BTA_DM_SWITCH_DELAY_TIMER_MS 500 147#endif 148 149static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr); 150static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr); 151static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq, uint8_t* p_eir, 152 uint16_t eir_len); 153static void bta_dm_observe_cmpl_cb(void* p_result); 154static void bta_dm_delay_role_switch_cback(void* data); 155static void bta_dm_disable_timer_cback(void* data); 156 157const uint16_t bta_service_id_to_uuid_lkup_tbl[BTA_MAX_SERVICE_ID] = { 158 UUID_SERVCLASS_PNP_INFORMATION, /* Reserved */ 159 UUID_SERVCLASS_SERIAL_PORT, /* BTA_SPP_SERVICE_ID */ 160 UUID_SERVCLASS_DIALUP_NETWORKING, /* BTA_DUN_SERVICE_ID */ 161 UUID_SERVCLASS_AUDIO_SOURCE, /* BTA_A2DP_SOURCE_SERVICE_ID */ 162 UUID_SERVCLASS_LAN_ACCESS_USING_PPP, /* BTA_LAP_SERVICE_ID */ 163 UUID_SERVCLASS_HEADSET, /* BTA_HSP_HS_SERVICE_ID */ 164 UUID_SERVCLASS_HF_HANDSFREE, /* BTA_HFP_HS_SERVICE_ID */ 165 UUID_SERVCLASS_OBEX_OBJECT_PUSH, /* BTA_OPP_SERVICE_ID */ 166 UUID_SERVCLASS_OBEX_FILE_TRANSFER, /* BTA_FTP_SERVICE_ID */ 167 UUID_SERVCLASS_CORDLESS_TELEPHONY, /* BTA_CTP_SERVICE_ID */ 168 UUID_SERVCLASS_INTERCOM, /* BTA_ICP_SERVICE_ID */ 169 UUID_SERVCLASS_IRMC_SYNC, /* BTA_SYNC_SERVICE_ID */ 170 UUID_SERVCLASS_DIRECT_PRINTING, /* BTA_BPP_SERVICE_ID */ 171 UUID_SERVCLASS_IMAGING_RESPONDER, /* BTA_BIP_SERVICE_ID */ 172 UUID_SERVCLASS_PANU, /* BTA_PANU_SERVICE_ID */ 173 UUID_SERVCLASS_NAP, /* BTA_NAP_SERVICE_ID */ 174 UUID_SERVCLASS_GN, /* BTA_GN_SERVICE_ID */ 175 UUID_SERVCLASS_SAP, /* BTA_SAP_SERVICE_ID */ 176 UUID_SERVCLASS_AUDIO_SINK, /* BTA_A2DP_SERVICE_ID */ 177 UUID_SERVCLASS_AV_REMOTE_CONTROL, /* BTA_AVRCP_SERVICE_ID */ 178 UUID_SERVCLASS_HUMAN_INTERFACE, /* BTA_HID_SERVICE_ID */ 179 UUID_SERVCLASS_VIDEO_SINK, /* BTA_VDP_SERVICE_ID */ 180 UUID_SERVCLASS_PBAP_PSE, /* BTA_PBAP_SERVICE_ID */ 181 UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, /* BTA_HSP_SERVICE_ID */ 182 UUID_SERVCLASS_AG_HANDSFREE, /* BTA_HFP_SERVICE_ID */ 183 UUID_SERVCLASS_MESSAGE_ACCESS, /* BTA_MAP_SERVICE_ID */ 184 UUID_SERVCLASS_MESSAGE_NOTIFICATION, /* BTA_MN_SERVICE_ID */ 185 UUID_SERVCLASS_HDP_PROFILE, /* BTA_HDP_SERVICE_ID */ 186 UUID_SERVCLASS_PBAP_PCE, /* BTA_PCE_SERVICE_ID */ 187 UUID_PROTOCOL_ATT /* BTA_GATT_SERVICE_ID */ 188}; 189 190/* 191 * NOTE : The number of element in bta_service_id_to_btm_srv_id_lkup_tbl should 192 * be matching with 193 * the value BTA_MAX_SERVICE_ID in bta_api.h 194 * 195 * i.e., If you add new Service ID for BTA, the correct security ID of 196 * the new service 197 * from Security service definitions (btm_api.h) should be added to 198 * this lookup table. 199 */ 200const uint32_t bta_service_id_to_btm_srv_id_lkup_tbl[BTA_MAX_SERVICE_ID] = { 201 0, /* Reserved */ 202 BTM_SEC_SERVICE_SERIAL_PORT, /* BTA_SPP_SERVICE_ID */ 203 BTM_SEC_SERVICE_DUN, /* BTA_DUN_SERVICE_ID */ 204 BTM_SEC_SERVICE_AVDTP, /* BTA_AUDIO_SOURCE_SERVICE_ID */ 205 BTM_SEC_SERVICE_LAN_ACCESS, /* BTA_LAP_SERVICE_ID */ 206 BTM_SEC_SERVICE_HEADSET_AG, /* BTA_HSP_SERVICE_ID */ 207 BTM_SEC_SERVICE_AG_HANDSFREE, /* BTA_HFP_SERVICE_ID */ 208 BTM_SEC_SERVICE_OBEX, /* BTA_OPP_SERVICE_ID */ 209 BTM_SEC_SERVICE_OBEX_FTP, /* BTA_FTP_SERVICE_ID */ 210 BTM_SEC_SERVICE_CORDLESS, /* BTA_CTP_SERVICE_ID */ 211 BTM_SEC_SERVICE_INTERCOM, /* BTA_ICP_SERVICE_ID */ 212 BTM_SEC_SERVICE_IRMC_SYNC, /* BTA_SYNC_SERVICE_ID */ 213 BTM_SEC_SERVICE_BPP_JOB, /* BTA_BPP_SERVICE_ID */ 214 BTM_SEC_SERVICE_BIP, /* BTA_BIP_SERVICE_ID */ 215 BTM_SEC_SERVICE_BNEP_PANU, /* BTA_PANU_SERVICE_ID */ 216 BTM_SEC_SERVICE_BNEP_NAP, /* BTA_NAP_SERVICE_ID */ 217 BTM_SEC_SERVICE_BNEP_GN, /* BTA_GN_SERVICE_ID */ 218 BTM_SEC_SERVICE_SAP, /* BTA_SAP_SERVICE_ID */ 219 BTM_SEC_SERVICE_AVDTP, /* BTA_A2DP_SERVICE_ID */ 220 BTM_SEC_SERVICE_AVCTP, /* BTA_AVRCP_SERVICE_ID */ 221 BTM_SEC_SERVICE_HIDH_SEC_CTRL, /* BTA_HID_SERVICE_ID */ 222 BTM_SEC_SERVICE_AVDTP, /* BTA_VDP_SERVICE_ID */ 223 BTM_SEC_SERVICE_PBAP, /* BTA_PBAP_SERVICE_ID */ 224 BTM_SEC_SERVICE_HEADSET, /* BTA_HSP_HS_SERVICE_ID */ 225 BTM_SEC_SERVICE_HF_HANDSFREE, /* BTA_HFP_HS_SERVICE_ID */ 226 BTM_SEC_SERVICE_MAP, /* BTA_MAP_SERVICE_ID */ 227 BTM_SEC_SERVICE_MAP, /* BTA_MN_SERVICE_ID */ 228 BTM_SEC_SERVICE_HDP_SNK, /* BTA_HDP_SERVICE_ID */ 229 BTM_SEC_SERVICE_PBAP, /* BTA_PCE_SERVICE_ID */ 230 BTM_SEC_SERVICE_ATT /* BTA_GATT_SERVICE_ID */ 231}; 232 233/* bta security callback */ 234const tBTM_APPL_INFO bta_security = {&bta_dm_authorize_cback, 235 &bta_dm_pin_cback, 236 &bta_dm_new_link_key_cback, 237 &bta_dm_authentication_complete_cback, 238 &bta_dm_bond_cancel_complete_cback, 239 &bta_dm_sp_cback, 240 &bta_dm_ble_smp_cback, 241 &bta_dm_ble_id_key_cback}; 242 243#define MAX_DISC_RAW_DATA_BUF (4096) 244uint8_t g_disc_raw_data_buf[MAX_DISC_RAW_DATA_BUF]; 245 246extern DEV_CLASS local_device_default_class; 247 248/** Initialises the BT device manager */ 249void bta_dm_enable(tBTA_DM_SEC_CBACK* p_sec_cback) { 250 /* if already in use, return an error */ 251 if (bta_dm_cb.is_bta_dm_active) { 252 tBTA_DM_SEC enable_event; 253 APPL_TRACE_WARNING("%s Device already started by another application", 254 __func__); 255 memset(&enable_event, 0, sizeof(tBTA_DM_SEC)); 256 enable_event.enable.status = BTA_FAILURE; 257 if (p_sec_cback != NULL) p_sec_cback(BTA_DM_ENABLE_EVT, &enable_event); 258 return; 259 } 260 261 /* first, register our callback to SYS HW manager */ 262 bta_sys_hw_register(BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback); 263 264 /* make sure security callback is saved - if no callback, do not erase the 265 previous one, 266 it could be an error recovery mechanism */ 267 if (p_sec_cback != NULL) bta_dm_cb.p_sec_cback = p_sec_cback; 268 /* notify BTA DM is now active */ 269 bta_dm_cb.is_bta_dm_active = true; 270 271 /* send a message to BTA SYS */ 272 tBTA_SYS_HW_MSG* sys_enable_event = 273 (tBTA_SYS_HW_MSG*)osi_malloc(sizeof(tBTA_SYS_HW_MSG)); 274 sys_enable_event->hdr.event = BTA_SYS_API_ENABLE_EVT; 275 sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH; 276 277 bta_sys_sendmsg(sys_enable_event); 278} 279 280/******************************************************************************* 281 * 282 * Function bta_dm_init_cb 283 * 284 * Description Initializes the bta_dm_cb control block 285 * 286 * 287 * Returns void 288 * 289 ******************************************************************************/ 290void bta_dm_init_cb(void) { 291 memset(&bta_dm_cb, 0, sizeof(bta_dm_cb)); 292 bta_dm_cb.disable_timer = alarm_new("bta_dm.disable_timer"); 293 bta_dm_cb.switch_delay_timer = alarm_new("bta_dm.switch_delay_timer"); 294 for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) { 295 for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) { 296 bta_dm_cb.pm_timer[i].timer[j] = alarm_new("bta_dm.pm_timer"); 297 } 298 } 299} 300 301/******************************************************************************* 302 * 303 * Function bta_dm_deinit_cb 304 * 305 * Description De-initializes the bta_dm_cb control block 306 * 307 * 308 * Returns void 309 * 310 ******************************************************************************/ 311void bta_dm_deinit_cb(void) { 312 /* 313 * TODO: Should alarm_free() the bta_dm_cb timers during graceful 314 * shutdown. 315 */ 316 alarm_free(bta_dm_cb.disable_timer); 317 alarm_free(bta_dm_cb.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 alarm_free(bta_dm_cb.pm_timer[i].timer[j]); 321 } 322 } 323 memset(&bta_dm_cb, 0, sizeof(bta_dm_cb)); 324} 325 326/******************************************************************************* 327 * 328 * Function bta_dm_sys_hw_cback 329 * 330 * Description callback register to SYS to get HW status updates 331 * 332 * 333 * Returns void 334 * 335 ******************************************************************************/ 336static void bta_dm_sys_hw_cback(tBTA_SYS_HW_EVT status) { 337 DEV_CLASS dev_class; 338 tBTA_DM_SEC_CBACK* temp_cback; 339 uint8_t key_mask = 0; 340 BT_OCTET16 er; 341 tBTA_BLE_LOCAL_ID_KEYS id_key; 342 343 APPL_TRACE_DEBUG("%s with event: %i", __func__, status); 344 345 /* On H/W error evt, report to the registered DM application callback */ 346 if (status == BTA_SYS_HW_ERROR_EVT) { 347 if (bta_dm_cb.p_sec_cback != NULL) 348 bta_dm_cb.p_sec_cback(BTA_DM_HW_ERROR_EVT, NULL); 349 return; 350 } 351 352 if (status == BTA_SYS_HW_OFF_EVT) { 353 if (bta_dm_cb.p_sec_cback != NULL) 354 bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL); 355 356 /* reinitialize the control block */ 357 bta_dm_deinit_cb(); 358 359 /* hw is ready, go on with BTA DM initialization */ 360 alarm_free(bta_dm_search_cb.search_timer); 361 alarm_free(bta_dm_search_cb.gatt_close_timer); 362 memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb)); 363 364 /* unregister from SYS */ 365 bta_sys_hw_unregister(BTA_SYS_HW_BLUETOOTH); 366 /* notify BTA DM is now unactive */ 367 bta_dm_cb.is_bta_dm_active = false; 368 } else if (status == BTA_SYS_HW_ON_EVT) { 369 /* FIXME: We should not unregister as the SYS shall invoke this callback on 370 * a H/W error. 371 * We need to revisit when this platform has more than one BLuetooth H/W 372 * chip 373 */ 374 // bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH); 375 376 /* save security callback */ 377 temp_cback = bta_dm_cb.p_sec_cback; 378 /* make sure the control block is properly initialized */ 379 bta_dm_init_cb(); 380 /* and retrieve the callback */ 381 bta_dm_cb.p_sec_cback = temp_cback; 382 bta_dm_cb.is_bta_dm_active = true; 383 384 /* hw is ready, go on with BTA DM initialization */ 385 alarm_free(bta_dm_search_cb.search_timer); 386 alarm_free(bta_dm_search_cb.gatt_close_timer); 387 memset(&bta_dm_search_cb, 0, sizeof(bta_dm_search_cb)); 388 /* 389 * TODO: Should alarm_free() the bta_dm_search_cb timers during 390 * graceful shutdown. 391 */ 392 bta_dm_search_cb.search_timer = alarm_new("bta_dm_search.search_timer"); 393 bta_dm_search_cb.gatt_close_timer = 394 alarm_new("bta_dm_search.gatt_close_timer"); 395 396 memset(&bta_dm_conn_srvcs, 0, sizeof(bta_dm_conn_srvcs)); 397 memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB)); 398 399 memcpy(dev_class, p_bta_dm_cfg->dev_class, sizeof(dev_class)); 400 BTM_SetDeviceClass(dev_class); 401 402 /* load BLE local information: ID keys, ER if available */ 403 bta_dm_co_ble_load_local_keys(&key_mask, er, &id_key); 404 405 if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ER) { 406 BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ER, 407 (tBTM_BLE_LOCAL_KEYS*)&er); 408 } 409 if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ID) { 410 BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ID, 411 (tBTM_BLE_LOCAL_KEYS*)&id_key); 412 } 413 bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID; 414 415 BTM_SecRegister(&bta_security); 416 BTM_SetDefaultLinkSuperTout(p_bta_dm_cfg->link_timeout); 417 BTM_WritePageTimeout(p_bta_dm_cfg->page_timeout); 418 bta_dm_cb.cur_policy = p_bta_dm_cfg->policy_settings; 419 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy); 420 BTM_RegBusyLevelNotif(bta_dm_bl_change_cback, NULL, 421 BTM_BL_UPDATE_MASK | BTM_BL_ROLE_CHG_MASK); 422 423#if (BLE_VND_INCLUDED == TRUE) 424 BTM_BleReadControllerFeatures(bta_dm_ctrl_features_rd_cmpl_cback); 425#else 426 /* If VSC multi adv commands are available, advertising will be initialized 427 * when capabilities are read. If they are not avaliable, initialize 428 * advertising here */ 429 btm_ble_adv_init(); 430#endif 431 432 /* Earlier, we used to invoke BTM_ReadLocalAddr which was just copying the 433 bd_addr 434 from the control block and invoking the callback which was sending the 435 DM_ENABLE_EVT. 436 But then we have a few HCI commands being invoked above which were still 437 in progress 438 when the ENABLE_EVT was sent. So modified this to fetch the local name 439 which forces 440 the DM_ENABLE_EVT to be sent only after all the init steps are complete 441 */ 442 BTM_ReadLocalDeviceNameFromController(bta_dm_local_name_cback); 443 444 bta_sys_rm_register(bta_dm_rm_cback); 445 446 /* initialize bluetooth low power manager */ 447 bta_dm_init_pm(); 448 449 bta_sys_policy_register(bta_dm_policy_cback); 450 451 bta_dm_gattc_register(); 452 453 } else 454 APPL_TRACE_DEBUG(" --- ignored event"); 455} 456 457/** Disables the BT device manager */ 458void bta_dm_disable() { 459 /* Set l2cap idle timeout to 0 (so BTE immediately disconnects ACL link after 460 * last channel is closed) */ 461 L2CA_SetIdleTimeoutByBdAddr(RawAddress::kAny, 0, BT_TRANSPORT_BR_EDR); 462 L2CA_SetIdleTimeoutByBdAddr(RawAddress::kAny, 0, BT_TRANSPORT_LE); 463 464 /* disable all active subsystems */ 465 bta_sys_disable(BTA_SYS_HW_BLUETOOTH); 466 467 BTM_SetDiscoverability(BTM_NON_DISCOVERABLE, 0, 0); 468 BTM_SetConnectability(BTM_NON_CONNECTABLE, 0, 0); 469 470 bta_dm_disable_pm(); 471 bta_dm_disable_search_and_disc(); 472 bta_dm_cb.disabling = true; 473 474 BTM_BleClearBgConnDev(); 475 476 if (BTM_GetNumAclLinks() == 0) { 477#if (BTA_DISABLE_DELAY > 0) 478 /* If BTA_DISABLE_DELAY is defined and greater than zero, then delay the 479 * shutdown by 480 * BTA_DISABLE_DELAY milliseconds 481 */ 482 APPL_TRACE_WARNING("%s BTA_DISABLE_DELAY set to %d ms", __func__, 483 BTA_DISABLE_DELAY); 484 alarm_set_on_mloop(bta_dm_cb.disable_timer, BTA_DISABLE_DELAY, 485 bta_dm_disable_conn_down_timer_cback, NULL); 486#else 487 bta_dm_disable_conn_down_timer_cback(NULL); 488#endif 489 } else { 490 alarm_set_on_mloop(bta_dm_cb.disable_timer, BTA_DM_DISABLE_TIMER_MS, 491 bta_dm_disable_timer_cback, UINT_TO_PTR(0)); 492 } 493} 494 495/******************************************************************************* 496 * 497 * Function bta_dm_disable_timer_cback 498 * 499 * Description Called if the disable timer expires 500 * Used to close ACL connections which are still active 501 * 502 * 503 * 504 * Returns void 505 * 506 ******************************************************************************/ 507static void bta_dm_disable_timer_cback(void* data) { 508 uint8_t i; 509 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; 510 bool trigger_disc = false; 511 uint32_t param = PTR_TO_UINT(data); 512 513 APPL_TRACE_EVENT("%s trial %u", __func__, param); 514 515 if (BTM_GetNumAclLinks() && (param == 0)) { 516 for (i = 0; i < bta_dm_cb.device_list.count; i++) { 517 transport = bta_dm_cb.device_list.peer_device[i].transport; 518 btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, 519 transport); 520 trigger_disc = true; 521 } 522 523 /* Retrigger disable timer in case ACL disconnect failed, DISABLE_EVT still 524 need 525 to be sent out to avoid jave layer disable timeout */ 526 if (trigger_disc) { 527 alarm_set_on_mloop(bta_dm_cb.disable_timer, 528 BTA_DM_DISABLE_TIMER_RETRIAL_MS, 529 bta_dm_disable_timer_cback, UINT_TO_PTR(1)); 530 } 531 } else { 532 bta_dm_cb.disabling = false; 533 534 bta_sys_remove_uuid(UUID_SERVCLASS_PNP_INFORMATION); 535 bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL); 536 } 537} 538 539/** Sets local device name */ 540void bta_dm_set_dev_name(const std::vector<uint8_t>& name) { 541 BTM_SetLocalDeviceName((char*)name.data()); 542 bta_dm_set_eir((char*)name.data()); 543} 544 545/** Sets discoverability, connectability and pairability */ 546void bta_dm_set_visibility(tBTA_DM_DISC disc_mode_param, 547 tBTA_DM_CONN conn_mode_param, uint8_t pairable_mode, 548 uint8_t conn_paired_only) { 549 uint16_t window, interval; 550 uint16_t le_disc_mode = BTM_BleReadDiscoverability(); 551 uint16_t le_conn_mode = BTM_BleReadConnectability(); 552 uint16_t disc_mode = BTM_ReadDiscoverability(&window, &interval); 553 uint16_t conn_mode = BTM_ReadConnectability(&window, &interval); 554 555 /* set modes for Discoverability and connectability if not ignore */ 556 if (disc_mode_param != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE)) { 557 if ((disc_mode_param & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE) 558 disc_mode_param = ((disc_mode_param & ~BTA_DM_LE_IGNORE) | le_disc_mode); 559 if ((disc_mode_param & BTA_DM_IGNORE) == BTA_DM_IGNORE) 560 disc_mode_param = ((disc_mode_param & ~BTA_DM_IGNORE) | disc_mode); 561 562 BTM_SetDiscoverability(disc_mode_param, bta_dm_cb.inquiry_scan_window, 563 bta_dm_cb.inquiry_scan_interval); 564 } 565 566 if (conn_mode_param != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE)) { 567 if ((conn_mode_param & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE) 568 conn_mode_param = ((conn_mode_param & ~BTA_DM_LE_IGNORE) | le_conn_mode); 569 if ((conn_mode_param & BTA_DM_IGNORE) == BTA_DM_IGNORE) 570 conn_mode_param = ((conn_mode_param & ~BTA_DM_IGNORE) | conn_mode); 571 572 BTM_SetConnectability(conn_mode_param, bta_dm_cb.page_scan_window, 573 bta_dm_cb.page_scan_interval); 574 } 575 576 /* Send False or True if not ignore */ 577 if (pairable_mode != BTA_DM_IGNORE) { 578 if (pairable_mode == BTA_DM_NON_PAIRABLE) 579 bta_dm_cb.disable_pair_mode = true; 580 else 581 bta_dm_cb.disable_pair_mode = false; 582 } 583 584 /* Send False or True if not ignore */ 585 if (conn_paired_only != BTA_DM_IGNORE) { 586 if (conn_paired_only == BTA_DM_CONN_ALL) 587 bta_dm_cb.conn_paired_only = false; 588 else 589 bta_dm_cb.conn_paired_only = true; 590 } 591 592 /* Change mode if either mode is not ignore */ 593 if (pairable_mode != BTA_DM_IGNORE || conn_paired_only != BTA_DM_IGNORE) 594 BTM_SetPairableMode((bool)(!(bta_dm_cb.disable_pair_mode)), 595 bta_dm_cb.conn_paired_only); 596} 597 598/******************************************************************************* 599 * 600 * Function bta_dm_process_remove_device 601 * 602 * Description Removes device, Disconnects ACL link if required. 603 *** 604 ******************************************************************************/ 605void bta_dm_process_remove_device(const RawAddress& bd_addr) { 606 /* need to remove all pending background connection before unpair */ 607 BTA_GATTC_CancelOpen(0, bd_addr, false); 608 609 BTM_SecDeleteDevice(bd_addr); 610 611 /* remove all cached GATT information */ 612 BTA_GATTC_Refresh(bd_addr); 613 614 if (bta_dm_cb.p_sec_cback) { 615 tBTA_DM_SEC sec_event; 616 sec_event.link_down.bd_addr = bd_addr; 617 ; 618 /* No connection, set status to success (acl disc code not valid) */ 619 sec_event.link_down.status = HCI_SUCCESS; 620 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event); 621 } 622} 623 624/** Removes device, disconnects ACL link if required */ 625void bta_dm_remove_device(const RawAddress& bd_addr) { 626 /* If ACL exists for the device in the remove_bond message*/ 627 bool is_bd_addr_connected = 628 BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) || 629 BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR); 630 631 uint8_t other_transport = BT_TRANSPORT_INVALID; 632 if (is_bd_addr_connected) { 633 APPL_TRACE_DEBUG("%s: ACL Up count: %d", __func__, 634 bta_dm_cb.device_list.count); 635 636 /* Take the link down first, and mark the device for removal when 637 * disconnected */ 638 for (int i = 0; i < bta_dm_cb.device_list.count; i++) { 639 auto& peer_device = bta_dm_cb.device_list.peer_device[i]; 640 if (peer_device.peer_bdaddr == bd_addr) { 641 peer_device.conn_state = BTA_DM_UNPAIRING; 642 btm_remove_acl(bd_addr, peer_device.transport); 643 APPL_TRACE_DEBUG("%s: transport: %d", __func__, peer_device.transport); 644 645 /* save the other transport to check if device is connected on 646 * other_transport */ 647 if (peer_device.transport == BT_TRANSPORT_LE) 648 other_transport = BT_TRANSPORT_BR_EDR; 649 else 650 other_transport = BT_TRANSPORT_LE; 651 652 break; 653 } 654 } 655 } 656 657 RawAddress other_address = bd_addr; 658 RawAddress other_address2 = bd_addr; 659 660 // If it is DUMO device and device is paired as different address, unpair that 661 // device 662 bool other_address_connected = 663 (other_transport) 664 ? BTM_ReadConnectedTransportAddress(&other_address, other_transport) 665 : (BTM_ReadConnectedTransportAddress(&other_address, 666 BT_TRANSPORT_BR_EDR) || 667 BTM_ReadConnectedTransportAddress(&other_address2, 668 BT_TRANSPORT_LE)); 669 if (other_address == bd_addr) other_address = other_address2; 670 671 if (other_address_connected) { 672 /* Take the link down first, and mark the device for removal when 673 * disconnected */ 674 for (int i = 0; i < bta_dm_cb.device_list.count; i++) { 675 auto& peer_device = bta_dm_cb.device_list.peer_device[i]; 676 if (peer_device.peer_bdaddr == other_address) { 677 peer_device.conn_state = BTA_DM_UNPAIRING; 678 btm_remove_acl(other_address, peer_device.transport); 679 break; 680 } 681 } 682 } 683 684 /* Delete the device mentioned in the msg */ 685 if (!is_bd_addr_connected) { 686 bta_dm_process_remove_device(bd_addr); 687 } 688 689 /* Delete the other paired device too */ 690 if (!other_address_connected && !other_address.IsEmpty()) { 691 bta_dm_process_remove_device(other_address); 692 } 693} 694 695/******************************************************************************* 696 * 697 * Function bta_dm_add_device 698 * 699 * Description This function adds a Link Key to an security database entry. 700 * It is normally called during host startup to restore all 701 * required information stored in the NVRAM. 702 *** 703 ******************************************************************************/ 704void bta_dm_add_device(std::unique_ptr<tBTA_DM_API_ADD_DEVICE> msg) { 705 uint8_t* p_dc = NULL; 706 uint8_t* p_lc = NULL; 707 uint32_t trusted_services_mask[BTM_SEC_SERVICE_ARRAY_SIZE]; 708 uint8_t index = 0; 709 uint8_t btm_mask_index = 0; 710 711 memset(trusted_services_mask, 0, sizeof(trusted_services_mask)); 712 713 /* If not all zeros, the device class has been specified */ 714 if (msg->dc_known) p_dc = (uint8_t*)msg->dc; 715 716 if (msg->link_key_known) p_lc = (uint8_t*)msg->link_key; 717 718 if (msg->is_trusted) { 719 /* covert BTA service mask to BTM mask */ 720 while (msg->tm && (index < BTA_MAX_SERVICE_ID)) { 721 if (msg->tm & (uint32_t)(1 << index)) { 722 btm_mask_index = 723 bta_service_id_to_btm_srv_id_lkup_tbl[index] / BTM_SEC_ARRAY_BITS; 724 trusted_services_mask[btm_mask_index] |= 725 (uint32_t)(1 << (bta_service_id_to_btm_srv_id_lkup_tbl[index] - 726 (uint32_t)(btm_mask_index * 32))); 727 728 msg->tm &= (uint32_t)(~(1 << index)); 729 } 730 index++; 731 } 732 } 733 734 if (!BTM_SecAddDevice(msg->bd_addr, p_dc, msg->bd_name, msg->features, 735 trusted_services_mask, p_lc, msg->key_type, msg->io_cap, 736 msg->pin_length)) { 737 LOG(ERROR) << "BTA_DM: Error adding device " << msg->bd_addr; 738 } 739} 740 741/** This function forces to close the connection to a remote device and 742 * optionaly remove the device from security database if required. */ 743void bta_dm_close_acl(const RawAddress& bd_addr, bool remove_dev, 744 tBTA_TRANSPORT transport) { 745 uint8_t index; 746 747 APPL_TRACE_DEBUG("bta_dm_close_acl"); 748 749 if (BTM_IsAclConnectionUp(bd_addr, transport)) { 750 for (index = 0; index < bta_dm_cb.device_list.count; index++) { 751 if (bta_dm_cb.device_list.peer_device[index].peer_bdaddr == bd_addr) 752 break; 753 } 754 if (index != bta_dm_cb.device_list.count) { 755 if (remove_dev) 756 bta_dm_cb.device_list.peer_device[index].remove_dev_pending = true; 757 } else { 758 APPL_TRACE_ERROR("unknown device, remove ACL failed"); 759 } 760 /* Disconnect the ACL link */ 761 btm_remove_acl(bd_addr, transport); 762 } 763 /* if to remove the device from security database ? do it now */ 764 else if (remove_dev) { 765 if (!BTM_SecDeleteDevice(bd_addr)) { 766 APPL_TRACE_ERROR("delete device from security database failed."); 767 } 768 /* need to remove all pending background connection if any */ 769 BTA_GATTC_CancelOpen(0, bd_addr, false); 770 /* remove all cached GATT information */ 771 BTA_GATTC_Refresh(bd_addr); 772 } 773 /* otherwise, no action needed */ 774} 775 776// TODO: this is unused. remove? 777/** This function forces to close all the ACL links specified by link type */ 778void bta_dm_remove_all_acl(const tBTA_DM_LINK_TYPE link_type) { 779 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; 780 781 APPL_TRACE_DEBUG("%s link type = %d", __func__, link_type); 782 783 for (uint8_t i = 0; i < bta_dm_cb.device_list.count; i++) { 784 transport = bta_dm_cb.device_list.peer_device[i].transport; 785 if ((link_type == BTA_DM_LINK_TYPE_ALL) || 786 ((link_type == BTA_DM_LINK_TYPE_LE) && 787 (transport == BT_TRANSPORT_LE)) || 788 ((link_type == BTA_DM_LINK_TYPE_BR_EDR) && 789 (transport == BT_TRANSPORT_BR_EDR))) { 790 /* Disconnect the ACL link */ 791 btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, 792 transport); 793 } 794 } 795} 796 797/** Bonds with peer device */ 798void bta_dm_bond(const RawAddress& bd_addr, tBTA_TRANSPORT transport) { 799 tBTM_STATUS status; 800 tBTA_DM_SEC sec_event; 801 char* p_name; 802 803 if (transport == BTA_TRANSPORT_UNKNOWN) 804 status = BTM_SecBond(bd_addr, 0, NULL, 0); 805 else 806 status = BTM_SecBondByTransport(bd_addr, transport, 0, NULL, 0); 807 808 if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED)) { 809 memset(&sec_event, 0, sizeof(tBTA_DM_SEC)); 810 sec_event.auth_cmpl.bd_addr = bd_addr; 811 p_name = BTM_SecReadDevName(bd_addr); 812 if (p_name != NULL) { 813 memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN - 1)); 814 sec_event.auth_cmpl.bd_name[BD_NAME_LEN - 1] = 0; 815 } 816 817 /* taken care of by memset [above] 818 sec_event.auth_cmpl.key_present = false; 819 sec_event.auth_cmpl.success = false; 820 */ 821 sec_event.auth_cmpl.fail_reason = HCI_ERR_ILLEGAL_COMMAND; 822 if (status == BTM_SUCCESS) { 823 sec_event.auth_cmpl.success = true; 824 } else { 825 /* delete this device entry from Sec Dev DB */ 826 bta_dm_remove_sec_dev_entry(bd_addr); 827 } 828 bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event); 829 } 830} 831 832/** Cancels bonding with a peer device */ 833void bta_dm_bond_cancel(const RawAddress& bd_addr) { 834 tBTM_STATUS status; 835 tBTA_DM_SEC sec_event; 836 837 APPL_TRACE_EVENT(" bta_dm_bond_cancel "); 838 status = BTM_SecBondCancel(bd_addr); 839 840 if (bta_dm_cb.p_sec_cback && 841 (status != BTM_CMD_STARTED && status != BTM_SUCCESS)) { 842 sec_event.bond_cancel_cmpl.result = BTA_FAILURE; 843 844 bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event); 845 } 846} 847 848/** Send the pin_reply to a request from BTM */ 849void bta_dm_pin_reply(std::unique_ptr<tBTA_DM_API_PIN_REPLY> msg) { 850 uint32_t trusted_mask[BTM_SEC_SERVICE_ARRAY_SIZE]; 851 852 uint32_t* current_trusted_mask = BTM_ReadTrustedMask(msg->bd_addr); 853 if (current_trusted_mask) { 854 memcpy(trusted_mask, current_trusted_mask, sizeof(trusted_mask)); 855 } else { 856 memset(trusted_mask, 0, sizeof(trusted_mask)); 857 } 858 859 if (msg->accept) { 860 BTM_PINCodeReply(msg->bd_addr, BTM_SUCCESS, msg->pin_len, msg->p_pin, 861 trusted_mask); 862 } else { 863 BTM_PINCodeReply(msg->bd_addr, BTM_NOT_AUTHORIZED, 0, NULL, trusted_mask); 864 } 865} 866 867/******************************************************************************* 868 * 869 * Function bta_dm_policy_cback 870 * 871 * Description process the link policy changes 872 * 873 * Returns void 874 * 875 ******************************************************************************/ 876static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, uint8_t id, 877 uint8_t app_id, const RawAddress& peer_addr) { 878 tBTA_DM_PEER_DEVICE* p_dev = NULL; 879 uint16_t policy = app_id; 880 uint32_t mask = (uint32_t)(1 << id); 881 882 if (peer_addr != RawAddress::kEmpty) { 883 p_dev = bta_dm_find_peer_device(peer_addr); 884 } 885 886 APPL_TRACE_DEBUG(" bta_dm_policy_cback cmd:%d, policy:0x%x", status, policy); 887 switch (status) { 888 case BTA_SYS_PLCY_SET: 889 if (!p_dev) return; 890 /* restore the default link policy */ 891 p_dev->link_policy |= policy; 892 BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy)); 893 break; 894 895 case BTA_SYS_PLCY_CLR: 896 if (!p_dev) return; 897 /* clear the policy from the default link policy */ 898 p_dev->link_policy &= (~policy); 899 BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy)); 900 901 if (policy & (HCI_ENABLE_SNIFF_MODE | HCI_ENABLE_PARK_MODE)) { 902 /* if clearing sniff/park, wake the link */ 903 bta_dm_pm_active(p_dev->peer_bdaddr); 904 } 905 break; 906 907 case BTA_SYS_PLCY_DEF_SET: 908 /* want to restore/set the role switch policy */ 909 bta_dm_cb.role_policy_mask &= ~mask; 910 if (0 == bta_dm_cb.role_policy_mask) { 911 /* if nobody wants to insist on the role */ 912 bta_dm_cb.cur_policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH; 913 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy); 914 } 915 break; 916 917 case BTA_SYS_PLCY_DEF_CLR: 918 /* want to remove the role switch policy */ 919 bta_dm_cb.role_policy_mask |= mask; 920 bta_dm_cb.cur_policy &= ~HCI_ENABLE_MASTER_SLAVE_SWITCH; 921 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy); 922 break; 923 } 924} 925 926/** Send the user confirm request reply in response to a request from BTM */ 927void bta_dm_confirm(const RawAddress& bd_addr, bool accept) { 928 BTM_ConfirmReqReply(accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED, bd_addr); 929} 930 931/** respond to the IO capabilities request from BTM */ 932void bta_dm_ci_io_req_act(const RawAddress& bd_addr, tBTA_IO_CAP io_cap, 933 tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req) { 934 BTM_IoCapRsp(bd_addr, io_cap, oob_data, 935 auth_req ? BTM_AUTH_AP_YES : BTM_AUTH_AP_NO); 936} 937 938/** respond to the OOB data request for the remote device from BTM */ 939void bta_dm_ci_rmt_oob_act(std::unique_ptr<tBTA_DM_CI_RMT_OOB> msg) { 940 BTM_RemoteOobDataReply(msg->accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED, 941 msg->bd_addr, msg->c, msg->r); 942} 943 944/******************************************************************************* 945 * 946 * Function bta_dm_search_start 947 * 948 * Description Starts an inquiry 949 * 950 * 951 * Returns void 952 * 953 ******************************************************************************/ 954void bta_dm_search_start(tBTA_DM_MSG* p_data) { 955 tBTM_INQUIRY_CMPL result = {}; 956 957 size_t len = sizeof(Uuid) * p_data->search.num_uuid; 958 bta_dm_gattc_register(); 959 960 APPL_TRACE_DEBUG("%s avoid_scatter=%d", __func__, 961 p_bta_dm_cfg->avoid_scatter); 962 963 if (p_bta_dm_cfg->avoid_scatter && 964 (p_data->search.rs_res == BTA_DM_RS_NONE) && 965 bta_dm_check_av(BTA_DM_API_SEARCH_EVT)) { 966 LOG(INFO) << __func__ << ": delay search to avoid scatter"; 967 memcpy(&bta_dm_cb.search_msg, &p_data->search, sizeof(tBTA_DM_API_SEARCH)); 968 return; 969 } 970 971 BTM_ClearInqDb(nullptr); 972 /* save search params */ 973 bta_dm_search_cb.p_search_cback = p_data->search.p_cback; 974 bta_dm_search_cb.services = p_data->search.services; 975 976 osi_free_and_reset((void**)&bta_dm_search_cb.p_srvc_uuid); 977 978 if ((bta_dm_search_cb.num_uuid = p_data->search.num_uuid) != 0 && 979 p_data->search.p_uuid != nullptr) { 980 bta_dm_search_cb.p_srvc_uuid = (Uuid*)osi_malloc(len); 981 *bta_dm_search_cb.p_srvc_uuid = *p_data->search.p_uuid; 982 } 983 result.status = BTM_StartInquiry((tBTM_INQ_PARMS*)&p_data->search.inq_params, 984 bta_dm_inq_results_cb, bta_dm_inq_cmpl_cb); 985 986 APPL_TRACE_EVENT("%s status=%d", __func__, result.status); 987 if (result.status != BTM_CMD_STARTED) { 988 LOG(ERROR) << __func__ << ": BTM_StartInquiry returned " 989 << std::to_string(result.status); 990 result.num_resp = 0; 991 bta_dm_inq_cmpl_cb((void*)&result); 992 } 993} 994 995/******************************************************************************* 996 * 997 * Function bta_dm_search_cancel 998 * 999 * Description Cancels an ongoing search for devices 1000 * 1001 * 1002 * Returns void 1003 * 1004 ******************************************************************************/ 1005void bta_dm_search_cancel(UNUSED_ATTR tBTA_DM_MSG* p_data) { 1006 tBTA_DM_MSG* p_msg; 1007 1008 if (BTM_IsInquiryActive()) { 1009 if (BTM_CancelInquiry() == BTM_SUCCESS) { 1010 bta_dm_search_cancel_notify(NULL); 1011 p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 1012 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1013 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 1014 bta_sys_sendmsg(p_msg); 1015 } else { 1016 /* flag a search cancel is pending */ 1017 bta_dm_search_cb.cancel_pending = true; 1018 } 1019 } 1020 /* If no Service Search going on then issue cancel remote name in case it is 1021 active */ 1022 else if (!bta_dm_search_cb.name_discover_done) { 1023 BTM_CancelRemoteDeviceName(); 1024 1025 p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 1026 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1027 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 1028 bta_sys_sendmsg(p_msg); 1029 } else { 1030 p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 1031 p_msg->hdr.event = BTA_DM_INQUIRY_CMPL_EVT; 1032 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 1033 bta_sys_sendmsg(p_msg); 1034 } 1035 1036 if (bta_dm_search_cb.gatt_disc_active) { 1037 bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr); 1038 } 1039} 1040 1041/******************************************************************************* 1042 * 1043 * Function bta_dm_discover 1044 * 1045 * Description Discovers services on a remote device 1046 * 1047 * 1048 * Returns void 1049 * 1050 ******************************************************************************/ 1051void bta_dm_discover(tBTA_DM_MSG* p_data) { 1052 size_t len = sizeof(Uuid) * p_data->discover.num_uuid; 1053 APPL_TRACE_EVENT("%s services_to_search=0x%04X, sdp_search=%d", __func__, 1054 p_data->discover.services, p_data->discover.sdp_search); 1055 1056 /* save the search condition */ 1057 bta_dm_search_cb.services = p_data->discover.services; 1058 1059 bta_dm_gattc_register(); 1060 osi_free_and_reset((void**)&bta_dm_search_cb.p_srvc_uuid); 1061 if ((bta_dm_search_cb.num_uuid = p_data->discover.num_uuid) != 0 && 1062 p_data->discover.p_uuid != NULL) { 1063 bta_dm_search_cb.p_srvc_uuid = (Uuid*)osi_malloc(len); 1064 *bta_dm_search_cb.p_srvc_uuid = *p_data->discover.p_uuid; 1065 } 1066 bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid; 1067 1068 bta_dm_search_cb.p_search_cback = p_data->discover.p_cback; 1069 bta_dm_search_cb.sdp_search = p_data->discover.sdp_search; 1070 bta_dm_search_cb.services_to_search = bta_dm_search_cb.services; 1071 bta_dm_search_cb.service_index = 0; 1072 bta_dm_search_cb.services_found = 0; 1073 bta_dm_search_cb.peer_name[0] = 0; 1074 bta_dm_search_cb.sdp_search = p_data->discover.sdp_search; 1075 bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead(p_data->discover.bd_addr); 1076 bta_dm_search_cb.transport = p_data->discover.transport; 1077 1078 bta_dm_search_cb.name_discover_done = false; 1079 bta_dm_search_cb.uuid = p_data->discover.uuid; 1080 bta_dm_discover_device(p_data->discover.bd_addr); 1081} 1082 1083/******************************************************************************* 1084 * 1085 * Function bta_dm_di_disc_cmpl 1086 * 1087 * Description Sends event to application when DI discovery complete 1088 * 1089 * Returns void 1090 * 1091 ******************************************************************************/ 1092void bta_dm_di_disc_cmpl(tBTA_DM_MSG* p_data) { 1093 tBTA_DM_DI_DISC_CMPL di_disc; 1094 1095 memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL)); 1096 di_disc.bd_addr = bta_dm_search_cb.peer_bdaddr; 1097 1098 if ((p_data->hdr.offset == SDP_SUCCESS) || 1099 (p_data->hdr.offset == SDP_DB_FULL)) { 1100 di_disc.num_record = SDP_GetNumDiRecords(bta_dm_di_cb.p_di_db); 1101 } else 1102 di_disc.result = BTA_FAILURE; 1103 1104 bta_dm_di_cb.p_di_db = NULL; 1105 bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT, 1106 (tBTA_DM_SEARCH*)&di_disc); 1107} 1108 1109/******************************************************************************* 1110 * 1111 * Function bta_dm_di_disc_callback 1112 * 1113 * Description This function queries a remote device for DI information. 1114 * 1115 * 1116 * Returns void 1117 * 1118 ******************************************************************************/ 1119static void bta_dm_di_disc_callback(uint16_t result) { 1120 tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 1121 1122 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1123 p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT; 1124 p_msg->hdr.offset = result; 1125 1126 bta_sys_sendmsg(p_msg); 1127} 1128 1129/******************************************************************************* 1130 * 1131 * Function bta_dm_disable_search_and_disc 1132 * 1133 * Description Cancels an ongoing search or discovery for devices in case 1134 * of a Bluetooth disable 1135 * 1136 * 1137 * Returns void 1138 * 1139 ******************************************************************************/ 1140static void bta_dm_disable_search_and_disc(void) { 1141 tBTA_DM_DI_DISC_CMPL di_disc; 1142 1143 if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) bta_dm_search_cancel(NULL); 1144 1145 if (bta_dm_di_cb.p_di_db != NULL) { 1146 memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL)); 1147 di_disc.bd_addr = bta_dm_search_cb.peer_bdaddr; 1148 di_disc.result = BTA_FAILURE; 1149 1150 bta_dm_di_cb.p_di_db = NULL; 1151 bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT, NULL); 1152 } 1153} 1154 1155/******************************************************************************* 1156 * 1157 * Function bta_dm_di_disc 1158 * 1159 * Description This function queries a remote device for DI information. 1160 * 1161 * 1162 * Returns void 1163 * 1164 ******************************************************************************/ 1165void bta_dm_di_disc(tBTA_DM_MSG* p_data) { 1166 uint16_t result = BTA_FAILURE; 1167 1168 bta_dm_search_cb.p_search_cback = p_data->di_disc.p_cback; 1169 bta_dm_search_cb.peer_bdaddr = p_data->di_disc.bd_addr; 1170 bta_dm_di_cb.p_di_db = p_data->di_disc.p_sdp_db; 1171 1172 bta_dm_search_cb.p_sdp_db = 1173 (tSDP_DISCOVERY_DB*)osi_malloc(BTA_DM_SDP_DB_SIZE); 1174 if (SDP_DiDiscover(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.p_sdp_db, 1175 p_data->di_disc.len, 1176 bta_dm_di_disc_callback) == SDP_SUCCESS) { 1177 result = BTA_SUCCESS; 1178 } 1179 1180 if (result == BTA_FAILURE) { 1181 tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 1182 1183 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1184 p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT; 1185 p_data->hdr.offset = result; 1186 bta_sys_sendmsg(p_msg); 1187 } 1188} 1189 1190/******************************************************************************* 1191 * 1192 * Function bta_dm_read_remote_device_name 1193 * 1194 * Description Initiate to get remote device name 1195 * 1196 * Returns true if started to get remote name 1197 * 1198 ******************************************************************************/ 1199static bool bta_dm_read_remote_device_name(const RawAddress& bd_addr, 1200 tBT_TRANSPORT transport) { 1201 tBTM_STATUS btm_status; 1202 1203 APPL_TRACE_DEBUG("%s", __func__); 1204 1205 bta_dm_search_cb.peer_bdaddr = bd_addr; 1206 bta_dm_search_cb.peer_name[0] = 0; 1207 1208 btm_status = BTM_ReadRemoteDeviceName(bta_dm_search_cb.peer_bdaddr, 1209 bta_dm_remname_cback, transport); 1210 1211 if (btm_status == BTM_CMD_STARTED) { 1212 APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is started", __func__); 1213 1214 return (true); 1215 } else if (btm_status == BTM_BUSY) { 1216 APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is busy", __func__); 1217 1218 /* Remote name discovery is on going now so BTM cannot notify through 1219 * "bta_dm_remname_cback" */ 1220 /* adding callback to get notified that current reading remore name done */ 1221 BTM_SecAddRmtNameNotifyCallback(&bta_dm_service_search_remname_cback); 1222 1223 return (true); 1224 } else { 1225 APPL_TRACE_WARNING("%s: BTM_ReadRemoteDeviceName returns 0x%02X", __func__, 1226 btm_status); 1227 1228 return (false); 1229 } 1230} 1231 1232/******************************************************************************* 1233 * 1234 * Function bta_dm_inq_cmpl 1235 * 1236 * Description Process the inquiry complete event from BTM 1237 * 1238 * Returns void 1239 * 1240 ******************************************************************************/ 1241void bta_dm_inq_cmpl(tBTA_DM_MSG* p_data) { 1242 tBTA_DM_SEARCH data; 1243 1244 APPL_TRACE_DEBUG("bta_dm_inq_cmpl"); 1245 1246 data.inq_cmpl.num_resps = p_data->inq_cmpl.num; 1247 bta_dm_search_cb.p_search_cback(BTA_DM_INQ_CMPL_EVT, &data); 1248 1249 bta_dm_search_cb.p_btm_inq_info = BTM_InqDbFirst(); 1250 if (bta_dm_search_cb.p_btm_inq_info != NULL) { 1251 /* start name and service discovery from the first device on inquiry result 1252 */ 1253 bta_dm_search_cb.name_discover_done = false; 1254 bta_dm_search_cb.peer_name[0] = 0; 1255 bta_dm_discover_device( 1256 bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr); 1257 } else { 1258 tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 1259 1260 /* no devices, search complete */ 1261 bta_dm_search_cb.services = 0; 1262 1263 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1264 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 1265 bta_sys_sendmsg(p_msg); 1266 } 1267} 1268 1269/******************************************************************************* 1270 * 1271 * Function bta_dm_rmt_name 1272 * 1273 * Description Process the remote name result from BTM 1274 * 1275 * Returns void 1276 * 1277 ******************************************************************************/ 1278void bta_dm_rmt_name(tBTA_DM_MSG* p_data) { 1279 APPL_TRACE_DEBUG("bta_dm_rmt_name"); 1280 1281 if (p_data->rem_name.result.disc_res.bd_name[0] && 1282 bta_dm_search_cb.p_btm_inq_info) { 1283 bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name = true; 1284 } 1285 1286 bta_dm_discover_device(bta_dm_search_cb.peer_bdaddr); 1287} 1288 1289/******************************************************************************* 1290 * 1291 * Function bta_dm_disc_rmt_name 1292 * 1293 * Description Process the remote name result from BTM when application 1294 * wants to find the name for a bdaddr 1295 * 1296 * Returns void 1297 * 1298 ******************************************************************************/ 1299void bta_dm_disc_rmt_name(tBTA_DM_MSG* p_data) { 1300 tBTM_INQ_INFO* p_btm_inq_info; 1301 1302 APPL_TRACE_DEBUG("bta_dm_disc_rmt_name"); 1303 1304 p_btm_inq_info = BTM_InqDbRead(p_data->rem_name.result.disc_res.bd_addr); 1305 if (p_btm_inq_info) { 1306 if (p_data->rem_name.result.disc_res.bd_name[0]) { 1307 p_btm_inq_info->appl_knows_rem_name = true; 1308 } 1309 } 1310 1311 bta_dm_discover_device(p_data->rem_name.result.disc_res.bd_addr); 1312} 1313 1314/******************************************************************************* 1315 * 1316 * Function bta_dm_sdp_result 1317 * 1318 * Description Process the discovery result from sdp 1319 * 1320 * Returns void 1321 * 1322 ******************************************************************************/ 1323void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { 1324 tSDP_DISC_REC* p_sdp_rec = NULL; 1325 tBTA_DM_MSG* p_msg; 1326 bool scn_found = false; 1327 uint16_t service = 0xFFFF; 1328 tSDP_PROTOCOL_ELEM pe; 1329 1330 Uuid* p_uuid = bta_dm_search_cb.p_srvc_uuid; 1331 tBTA_DM_SEARCH result; 1332 1333 std::vector<Uuid> uuid_list; 1334 1335 if ((p_data->sdp_event.sdp_result == SDP_SUCCESS) || 1336 (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH) || 1337 (p_data->sdp_event.sdp_result == SDP_DB_FULL)) { 1338 APPL_TRACE_DEBUG("sdp_result::0x%x", p_data->sdp_event.sdp_result); 1339 do { 1340 p_sdp_rec = NULL; 1341 if (bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID + 1)) { 1342 p_sdp_rec = SDP_FindServiceUUIDInDb(bta_dm_search_cb.p_sdp_db, 1343 bta_dm_search_cb.uuid, p_sdp_rec); 1344 1345 if (p_sdp_rec && SDP_FindProtocolListElemInRec( 1346 p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) { 1347 bta_dm_search_cb.peer_scn = (uint8_t)pe.params[0]; 1348 scn_found = true; 1349 } 1350 } else { 1351 service = 1352 bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1]; 1353 p_sdp_rec = 1354 SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, service, p_sdp_rec); 1355 } 1356 /* finished with BR/EDR services, now we check the result for GATT based 1357 * service UUID */ 1358 if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID) { 1359 if (bta_dm_search_cb.uuid_to_search != 0 && p_uuid != NULL) { 1360 p_uuid += 1361 (bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search); 1362 /* only support 16 bits UUID for now */ 1363 service = p_uuid->As16Bit(); 1364 } 1365 /* all GATT based services */ 1366 do { 1367 /* find a service record, report it */ 1368 p_sdp_rec = 1369 SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, 0, p_sdp_rec); 1370 if (p_sdp_rec) { 1371 Uuid service_uuid; 1372 if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) { 1373 /* send result back to app now, one by one */ 1374 result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr; 1375 strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(), 1376 BD_NAME_LEN); 1377 1378 result.disc_ble_res.service = service_uuid; 1379 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result); 1380 } 1381 } 1382 1383 if (bta_dm_search_cb.uuid_to_search > 0) break; 1384 1385 } while (p_sdp_rec); 1386 } else { 1387 /* SDP_DB_FULL means some records with the 1388 required attributes were received */ 1389 if (((p_data->sdp_event.sdp_result == SDP_DB_FULL) && 1390 bta_dm_search_cb.services != BTA_ALL_SERVICE_MASK) || 1391 (p_sdp_rec != NULL)) { 1392 if (service != UUID_SERVCLASS_PNP_INFORMATION) { 1393 bta_dm_search_cb.services_found |= 1394 (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK( 1395 bta_dm_search_cb.service_index - 1)); 1396 uint16_t tmp_svc = 1397 bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1398 1]; 1399 /* Add to the list of UUIDs */ 1400 uuid_list.push_back(Uuid::From16Bit(tmp_svc)); 1401 } 1402 } 1403 } 1404 1405 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK && 1406 bta_dm_search_cb.services_to_search == 0) { 1407 if (bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID && 1408 bta_dm_search_cb.uuid_to_search > 0) 1409 bta_dm_search_cb.uuid_to_search--; 1410 1411 if (bta_dm_search_cb.uuid_to_search == 0 || 1412 bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID) 1413 bta_dm_search_cb.service_index++; 1414 } else /* regular one service per search or PNP search */ 1415 break; 1416 1417 } while (bta_dm_search_cb.service_index <= BTA_MAX_SERVICE_ID); 1418 1419 APPL_TRACE_DEBUG("%s services_found = %04x", __func__, 1420 bta_dm_search_cb.services_found); 1421 1422 /* Collect the 128-bit services here and put them into the list */ 1423 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) { 1424 p_sdp_rec = NULL; 1425 do { 1426 /* find a service record, report it */ 1427 p_sdp_rec = 1428 SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec); 1429 if (p_sdp_rec) { 1430 // SDP_FindServiceUUIDInRec_128bit is used only once, refactor? 1431 Uuid temp_uuid; 1432 if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid)) { 1433 uuid_list.push_back(temp_uuid); 1434 } 1435 } 1436 } while (p_sdp_rec); 1437 } 1438 /* if there are more services to search for */ 1439 if (bta_dm_search_cb.services_to_search) { 1440 /* Free up the p_sdp_db before checking the next one */ 1441 bta_dm_free_sdp_db(NULL); 1442 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr); 1443 } else { 1444 /* callbacks */ 1445 /* start next bd_addr if necessary */ 1446 1447 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback); 1448 1449 p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 1450 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT; 1451 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS; 1452 p_msg->disc_result.result.disc_res.p_raw_data = NULL; 1453 p_msg->disc_result.result.disc_res.raw_data_size = 0; 1454 p_msg->disc_result.result.disc_res.num_uuids = uuid_list.size(); 1455 p_msg->disc_result.result.disc_res.p_uuid_list = NULL; 1456 if (uuid_list.size() > 0) { 1457 // TODO(jpawlowski): make p_uuid_list into vector, and just copy 1458 // vectors, but first get rid of bta_sys_sendmsg below. 1459 p_msg->disc_result.result.disc_res.p_uuid_list = 1460 (Uuid*)osi_malloc(uuid_list.size() * sizeof(Uuid)); 1461 memcpy(p_msg->disc_result.result.disc_res.p_uuid_list, uuid_list.data(), 1462 uuid_list.size() * sizeof(Uuid)); 1463 } 1464 // Copy the raw_data to the discovery result structure 1465 if (bta_dm_search_cb.p_sdp_db != NULL && 1466 bta_dm_search_cb.p_sdp_db->raw_used != 0 && 1467 bta_dm_search_cb.p_sdp_db->raw_data != NULL) { 1468 APPL_TRACE_DEBUG("%s raw_data used = 0x%x raw_data_ptr = 0x%x", 1469 __func__, bta_dm_search_cb.p_sdp_db->raw_used, 1470 bta_dm_search_cb.p_sdp_db->raw_data); 1471 1472 p_msg->disc_result.result.disc_res.p_raw_data = 1473 (uint8_t*)osi_malloc(bta_dm_search_cb.p_sdp_db->raw_used); 1474 memcpy(p_msg->disc_result.result.disc_res.p_raw_data, 1475 bta_dm_search_cb.p_sdp_db->raw_data, 1476 bta_dm_search_cb.p_sdp_db->raw_used); 1477 1478 p_msg->disc_result.result.disc_res.raw_data_size = 1479 bta_dm_search_cb.p_sdp_db->raw_used; 1480 1481 bta_dm_search_cb.p_sdp_db->raw_data = 1482 NULL; // no need to free this - it is a global assigned. 1483 bta_dm_search_cb.p_sdp_db->raw_used = 0; 1484 bta_dm_search_cb.p_sdp_db->raw_size = 0; 1485 } else { 1486 APPL_TRACE_DEBUG("%s raw data size is 0 or raw_data is null!!", 1487 __func__); 1488 } 1489 /* Done with p_sdp_db. Free it */ 1490 bta_dm_free_sdp_db(NULL); 1491 p_msg->disc_result.result.disc_res.services = 1492 bta_dm_search_cb.services_found; 1493 1494 // Piggy back the SCN over result field 1495 if (scn_found) { 1496 p_msg->disc_result.result.disc_res.result = 1497 (3 + bta_dm_search_cb.peer_scn); 1498 p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK; 1499 1500 APPL_TRACE_EVENT(" Piggy back the SCN over result field SCN=%d", 1501 bta_dm_search_cb.peer_scn); 1502 } 1503 p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr; 1504 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name, 1505 bta_dm_get_remname(), BD_NAME_LEN); 1506 1507 bta_sys_sendmsg(p_msg); 1508 } 1509 } else { 1510 /* conn failed. No need for timer */ 1511 if (p_data->sdp_event.sdp_result == SDP_CONN_FAILED || 1512 p_data->sdp_event.sdp_result == SDP_CONN_REJECTED || 1513 p_data->sdp_event.sdp_result == SDP_SECURITY_ERR) 1514 bta_dm_search_cb.wait_disc = false; 1515 1516 /* not able to connect go to next device */ 1517 if (bta_dm_search_cb.p_sdp_db) 1518 osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db); 1519 1520 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback); 1521 1522 p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 1523 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT; 1524 p_msg->disc_result.result.disc_res.result = BTA_FAILURE; 1525 p_msg->disc_result.result.disc_res.services = 1526 bta_dm_search_cb.services_found; 1527 p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr; 1528 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name, 1529 bta_dm_get_remname(), BD_NAME_LEN); 1530 1531 bta_sys_sendmsg(p_msg); 1532 } 1533} 1534 1535/******************************************************************************* 1536 * 1537 * Function bta_dm_search_cmpl 1538 * 1539 * Description Sends event to application 1540 * 1541 * Returns void 1542 * 1543 ******************************************************************************/ 1544void bta_dm_search_cmpl(tBTA_DM_MSG* p_data) { 1545 APPL_TRACE_EVENT("%s", __func__); 1546 1547 osi_free_and_reset((void**)&bta_dm_search_cb.p_srvc_uuid); 1548 1549 if (p_data->hdr.layer_specific == BTA_DM_API_DI_DISCOVER_EVT) 1550 bta_dm_di_disc_cmpl(p_data); 1551 else 1552 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, NULL); 1553} 1554 1555/******************************************************************************* 1556 * 1557 * Function bta_dm_disc_result 1558 * 1559 * Description Service discovery result when discovering services on a 1560 * device 1561 * 1562 * Returns void 1563 * 1564 ******************************************************************************/ 1565void bta_dm_disc_result(tBTA_DM_MSG* p_data) { 1566 APPL_TRACE_EVENT("%s", __func__); 1567 1568 /* if any BR/EDR service discovery has been done, report the event */ 1569 if ((bta_dm_search_cb.services & 1570 ((BTA_ALL_SERVICE_MASK | BTA_USER_SERVICE_MASK) & 1571 ~BTA_BLE_SERVICE_MASK))) 1572 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, 1573 &p_data->disc_result.result); 1574 1575 tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 1576 1577 /* send a message to change state */ 1578 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1579 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 1580 bta_sys_sendmsg(p_msg); 1581} 1582 1583/******************************************************************************* 1584 * 1585 * Function bta_dm_search_result 1586 * 1587 * Description Service discovery result while searching for devices 1588 * 1589 * Returns void 1590 * 1591 ******************************************************************************/ 1592void bta_dm_search_result(tBTA_DM_MSG* p_data) { 1593 APPL_TRACE_DEBUG("%s searching:0x%04x, result:0x%04x", __func__, 1594 bta_dm_search_cb.services, 1595 p_data->disc_result.result.disc_res.services); 1596 1597 /* call back if application wants name discovery or found services that 1598 * application is searching */ 1599 if ((!bta_dm_search_cb.services) || 1600 ((bta_dm_search_cb.services) && 1601 (p_data->disc_result.result.disc_res.services))) { 1602 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, 1603 &p_data->disc_result.result); 1604 } 1605 1606 /* if searching did not initiate to create link */ 1607 if (!bta_dm_search_cb.wait_disc) { 1608 /* if service searching is done with EIR, don't search next device */ 1609 if (bta_dm_search_cb.p_btm_inq_info) bta_dm_discover_next_device(); 1610 } else { 1611 /* wait until link is disconnected or timeout */ 1612 bta_dm_search_cb.sdp_results = true; 1613 alarm_set_on_mloop(bta_dm_search_cb.search_timer, 1614 1000 * (L2CAP_LINK_INACTIVITY_TOUT + 1), 1615 bta_dm_search_timer_cback, NULL); 1616 } 1617} 1618 1619/******************************************************************************* 1620 * 1621 * Function bta_dm_search_timer_cback 1622 * 1623 * Description Called when ACL disconnect time is over 1624 * 1625 * 1626 * Returns void 1627 * 1628 ******************************************************************************/ 1629static void bta_dm_search_timer_cback(UNUSED_ATTR void* data) { 1630 APPL_TRACE_EVENT("%s", __func__); 1631 bta_dm_search_cb.wait_disc = false; 1632 1633 /* proceed with next device */ 1634 bta_dm_discover_next_device(); 1635} 1636 1637/******************************************************************************* 1638 * 1639 * Function bta_dm_free_sdp_db 1640 * 1641 * Description Frees SDP data base 1642 * 1643 * Returns void 1644 * 1645 ******************************************************************************/ 1646void bta_dm_free_sdp_db(UNUSED_ATTR tBTA_DM_MSG* p_data) { 1647 osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db); 1648} 1649 1650/******************************************************************************* 1651 * 1652 * Function bta_dm_queue_search 1653 * 1654 * Description Queues search command while search is being cancelled 1655 * 1656 * Returns void 1657 * 1658 ******************************************************************************/ 1659void bta_dm_queue_search(tBTA_DM_MSG* p_data) { 1660 osi_free(bta_dm_search_cb.p_search_queue); 1661 bta_dm_search_cb.p_search_queue = 1662 (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_SEARCH)); 1663 memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_SEARCH)); 1664} 1665 1666/******************************************************************************* 1667 * 1668 * Function bta_dm_queue_disc 1669 * 1670 * Description Queues discovery command while search is being cancelled 1671 * 1672 * Returns void 1673 * 1674 ******************************************************************************/ 1675void bta_dm_queue_disc(tBTA_DM_MSG* p_data) { 1676 osi_free(bta_dm_search_cb.p_search_queue); 1677 bta_dm_search_cb.p_search_queue = 1678 (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_API_DISCOVER)); 1679 memcpy(bta_dm_search_cb.p_search_queue, p_data, sizeof(tBTA_DM_API_DISCOVER)); 1680} 1681 1682/******************************************************************************* 1683 * 1684 * Function bta_dm_search_clear_queue 1685 * 1686 * Description Clears the queue if API search cancel is called 1687 * 1688 * Returns void 1689 * 1690 ******************************************************************************/ 1691void bta_dm_search_clear_queue(UNUSED_ATTR tBTA_DM_MSG* p_data) { 1692 osi_free_and_reset((void**)&bta_dm_search_cb.p_search_queue); 1693} 1694 1695/******************************************************************************* 1696 * 1697 * Function bta_dm_search_cancel_cmpl 1698 * 1699 * Description Search cancel is complete 1700 * 1701 * Returns void 1702 * 1703 ******************************************************************************/ 1704void bta_dm_search_cancel_cmpl(UNUSED_ATTR tBTA_DM_MSG* p_data) { 1705 if (bta_dm_search_cb.p_search_queue) { 1706 bta_sys_sendmsg(bta_dm_search_cb.p_search_queue); 1707 bta_dm_search_cb.p_search_queue = NULL; 1708 } 1709} 1710 1711/******************************************************************************* 1712 * 1713 * Function bta_dm_search_cancel_transac_cmpl 1714 * 1715 * Description Current Service Discovery or remote name procedure is 1716 * completed after search cancellation 1717 * 1718 * Returns void 1719 * 1720 ******************************************************************************/ 1721void bta_dm_search_cancel_transac_cmpl(UNUSED_ATTR tBTA_DM_MSG* p_data) { 1722 osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db); 1723 bta_dm_search_cancel_notify(NULL); 1724} 1725 1726/******************************************************************************* 1727 * 1728 * Function bta_dm_search_cancel_notify 1729 * 1730 * Description Notify application that search has been cancelled 1731 * 1732 * Returns void 1733 * 1734 ******************************************************************************/ 1735void bta_dm_search_cancel_notify(UNUSED_ATTR tBTA_DM_MSG* p_data) { 1736 if (bta_dm_search_cb.p_search_cback) { 1737 bta_dm_search_cb.p_search_cback(BTA_DM_SEARCH_CANCEL_CMPL_EVT, NULL); 1738 } 1739 if (!bta_dm_search_cb.name_discover_done) { 1740 BTM_CancelRemoteDeviceName(); 1741 } 1742 if (bta_dm_search_cb.gatt_disc_active) { 1743 bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr); 1744 } 1745} 1746 1747/******************************************************************************* 1748 * 1749 * Function bta_dm_find_services 1750 * 1751 * Description Starts discovery on a device 1752 * 1753 * Returns void 1754 * 1755 ******************************************************************************/ 1756static void bta_dm_find_services(const RawAddress& bd_addr) { 1757 1758 while (bta_dm_search_cb.service_index < BTA_MAX_SERVICE_ID) { 1759 Uuid uuid = Uuid::kEmpty; 1760 if (bta_dm_search_cb.services_to_search & 1761 (tBTA_SERVICE_MASK)( 1762 BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index))) { 1763 bta_dm_search_cb.p_sdp_db = 1764 (tSDP_DISCOVERY_DB*)osi_malloc(BTA_DM_SDP_DB_SIZE); 1765 APPL_TRACE_DEBUG("bta_dm_search_cb.services = %04x***********", 1766 bta_dm_search_cb.services); 1767 /* try to search all services by search based on L2CAP UUID */ 1768 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) { 1769 LOG_INFO(LOG_TAG, "%s services_to_search=%08x", __func__, 1770 bta_dm_search_cb.services_to_search); 1771 if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK) { 1772 uuid = Uuid::From16Bit(bta_service_id_to_uuid_lkup_tbl[0]); 1773 bta_dm_search_cb.services_to_search &= ~BTA_RES_SERVICE_MASK; 1774 } else { 1775 uuid = Uuid::From16Bit(UUID_PROTOCOL_L2CAP); 1776 bta_dm_search_cb.services_to_search = 0; 1777 } 1778 } else { 1779 /* for LE only profile */ 1780 if (bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID) { 1781 if (bta_dm_search_cb.uuid_to_search > 0 && 1782 bta_dm_search_cb.p_srvc_uuid) { 1783 uuid = *(bta_dm_search_cb.p_srvc_uuid + bta_dm_search_cb.num_uuid - 1784 bta_dm_search_cb.uuid_to_search); 1785 1786 bta_dm_search_cb.uuid_to_search--; 1787 } else { 1788 uuid = Uuid::From16Bit( 1789 bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb 1790 .service_index]); 1791 } 1792 1793 /* last one? clear the BLE service bit if all discovery has been done 1794 */ 1795 if (bta_dm_search_cb.uuid_to_search == 0) 1796 bta_dm_search_cb.services_to_search &= 1797 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK( 1798 bta_dm_search_cb.service_index))); 1799 1800 } else { 1801 /* remove the service from services to be searched */ 1802 bta_dm_search_cb.services_to_search &= (tBTA_SERVICE_MASK)(~( 1803 BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index))); 1804 uuid = Uuid::From16Bit( 1805 bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index]); 1806 } 1807 } 1808 1809 if (bta_dm_search_cb.service_index == BTA_USER_SERVICE_ID) { 1810 uuid = bta_dm_search_cb.uuid; 1811 } 1812 1813 LOG_INFO(LOG_TAG, "%s search UUID = %s", __func__, 1814 uuid.ToString().c_str()); 1815 SDP_InitDiscoveryDb(bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 1, 1816 &uuid, 0, NULL); 1817 1818 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf)); 1819 bta_dm_search_cb.p_sdp_db->raw_data = g_disc_raw_data_buf; 1820 1821 bta_dm_search_cb.p_sdp_db->raw_size = MAX_DISC_RAW_DATA_BUF; 1822 1823 if (!SDP_ServiceSearchAttributeRequest(bd_addr, bta_dm_search_cb.p_sdp_db, 1824 &bta_dm_sdp_callback)) { 1825 /* 1826 * If discovery is not successful with this device, then 1827 * proceed with the next one. 1828 */ 1829 osi_free_and_reset((void**)&bta_dm_search_cb.p_sdp_db); 1830 bta_dm_search_cb.service_index = BTA_MAX_SERVICE_ID; 1831 1832 } else { 1833 if ((bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID && 1834 bta_dm_search_cb.uuid_to_search == 0) || 1835 bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID) 1836 bta_dm_search_cb.service_index++; 1837 return; 1838 } 1839 } 1840 1841 bta_dm_search_cb.service_index++; 1842 } 1843 1844 /* no more services to be discovered */ 1845 if (bta_dm_search_cb.service_index >= BTA_MAX_SERVICE_ID) { 1846 tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 1847 /* initialize the data structure - includes p_raw_data and raw_data_size */ 1848 memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES)); 1849 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT; 1850 p_msg->disc_result.result.disc_res.services = 1851 bta_dm_search_cb.services_found; 1852 p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr; 1853 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name, 1854 bta_dm_get_remname(), BD_NAME_LEN); 1855 1856 bta_sys_sendmsg(p_msg); 1857 } 1858} 1859 1860/******************************************************************************* 1861 * 1862 * Function bta_dm_discover_next_device 1863 * 1864 * Description Starts discovery on the next device in Inquiry data base 1865 * 1866 * Returns void 1867 * 1868 ******************************************************************************/ 1869static void bta_dm_discover_next_device(void) { 1870 APPL_TRACE_DEBUG("bta_dm_discover_next_device"); 1871 1872 /* searching next device on inquiry result */ 1873 bta_dm_search_cb.p_btm_inq_info = 1874 BTM_InqDbNext(bta_dm_search_cb.p_btm_inq_info); 1875 if (bta_dm_search_cb.p_btm_inq_info != NULL) { 1876 bta_dm_search_cb.name_discover_done = false; 1877 bta_dm_search_cb.peer_name[0] = 0; 1878 bta_dm_discover_device( 1879 bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr); 1880 } else { 1881 tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 1882 1883 /* no devices, search complete */ 1884 bta_dm_search_cb.services = 0; 1885 1886 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1887 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 1888 1889 bta_sys_sendmsg(p_msg); 1890 } 1891} 1892 1893/******************************************************************************* 1894 * 1895 * Function bta_dm_discover_device 1896 * 1897 * Description Starts name and service discovery on the device 1898 * 1899 * Returns void 1900 * 1901 ******************************************************************************/ 1902static void bta_dm_discover_device(const RawAddress& remote_bd_addr) { 1903 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; 1904 if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN) { 1905 tBT_DEVICE_TYPE dev_type; 1906 tBLE_ADDR_TYPE addr_type; 1907 1908 BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type); 1909 if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM) 1910 transport = BT_TRANSPORT_LE; 1911 } else { 1912 transport = bta_dm_search_cb.transport; 1913 } 1914 1915 /* Reset transport state for next discovery */ 1916 bta_dm_search_cb.transport = BTA_TRANSPORT_UNKNOWN; 1917 1918 VLOG(1) << __func__ << " BDA: " << remote_bd_addr; 1919 1920 bta_dm_search_cb.peer_bdaddr = remote_bd_addr; 1921 1922 APPL_TRACE_DEBUG( 1923 "%s name_discover_done = %d p_btm_inq_info 0x%x state = %d, transport=%d", 1924 __func__, bta_dm_search_cb.name_discover_done, 1925 bta_dm_search_cb.p_btm_inq_info, bta_dm_search_cb.state, transport); 1926 1927 if (bta_dm_search_cb.p_btm_inq_info) { 1928 APPL_TRACE_DEBUG("%s appl_knows_rem_name %d", __func__, 1929 bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name); 1930 } 1931 if ((bta_dm_search_cb.p_btm_inq_info) && 1932 (bta_dm_search_cb.p_btm_inq_info->results.device_type == 1933 BT_DEVICE_TYPE_BLE) && 1934 (bta_dm_search_cb.state == BTA_DM_SEARCH_ACTIVE)) { 1935 /* Do not perform RNR for LE devices at inquiry complete*/ 1936 bta_dm_search_cb.name_discover_done = true; 1937 } 1938 /* if name discovery is not done and application needs remote name */ 1939 if ((!bta_dm_search_cb.name_discover_done) && 1940 ((bta_dm_search_cb.p_btm_inq_info == NULL) || 1941 (bta_dm_search_cb.p_btm_inq_info && 1942 (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name)))) { 1943 if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport)) 1944 return; 1945 1946 /* starting name discovery failed */ 1947 bta_dm_search_cb.name_discover_done = true; 1948 } 1949 1950 /* if application wants to discover service */ 1951 if (bta_dm_search_cb.services) { 1952 /* initialize variables */ 1953 bta_dm_search_cb.service_index = 0; 1954 bta_dm_search_cb.services_found = 0; 1955 bta_dm_search_cb.services_to_search = bta_dm_search_cb.services; 1956 bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid; 1957 if ((bta_dm_search_cb.p_btm_inq_info != NULL) && 1958 bta_dm_search_cb.services != BTA_USER_SERVICE_MASK && 1959 (!bta_dm_search_cb.sdp_search)) { 1960 /* check if EIR provides the information of supported services */ 1961 bta_dm_eir_search_services(&bta_dm_search_cb.p_btm_inq_info->results, 1962 &bta_dm_search_cb.services_to_search, 1963 &bta_dm_search_cb.services_found); 1964 } 1965 1966 /* if seaching with EIR is not completed */ 1967 if (bta_dm_search_cb.services_to_search) { 1968 /* check whether connection already exists to the device 1969 if connection exists, we don't have to wait for ACL 1970 link to go down to start search on next device */ 1971 if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, 1972 BT_TRANSPORT_BR_EDR)) 1973 bta_dm_search_cb.wait_disc = false; 1974 else 1975 bta_dm_search_cb.wait_disc = true; 1976 1977 if (bta_dm_search_cb.p_btm_inq_info) { 1978 APPL_TRACE_DEBUG( 1979 "%s p_btm_inq_info 0x%x results.device_type 0x%x " 1980 "services_to_search 0x%x", 1981 __func__, bta_dm_search_cb.p_btm_inq_info, 1982 bta_dm_search_cb.p_btm_inq_info->results.device_type, 1983 bta_dm_search_cb.services_to_search); 1984 } 1985 1986 if (transport == BT_TRANSPORT_LE) { 1987 if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK) { 1988 // set the raw data buffer here 1989 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf)); 1990 bta_dm_search_cb.p_ble_rawdata = g_disc_raw_data_buf; 1991 1992 bta_dm_search_cb.ble_raw_size = MAX_DISC_RAW_DATA_BUF; 1993 bta_dm_search_cb.ble_raw_used = 0; 1994 1995 /* start GATT for service discovery */ 1996 btm_dm_start_gatt_discovery(bta_dm_search_cb.peer_bdaddr); 1997 return; 1998 } 1999 } else { 2000 bta_dm_search_cb.sdp_results = false; 2001 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr); 2002 return; 2003 } 2004 } 2005 } 2006 2007 /* name discovery and service discovery are done for this device */ 2008 tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 2009 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT; 2010 /* initialize the data structure - includes p_raw_data and raw_data_size */ 2011 memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES)); 2012 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS; 2013 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found; 2014 p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr; 2015 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name, 2016 (char*)bta_dm_search_cb.peer_name, BD_NAME_LEN); 2017 2018 bta_sys_sendmsg(p_msg); 2019} 2020 2021/******************************************************************************* 2022 * 2023 * Function bta_dm_sdp_callback 2024 * 2025 * Description Callback from sdp with discovery status 2026 * 2027 * Returns void 2028 * 2029 ******************************************************************************/ 2030static void bta_dm_sdp_callback(uint16_t sdp_status) { 2031 tBTA_DM_SDP_RESULT* p_msg = 2032 (tBTA_DM_SDP_RESULT*)osi_malloc(sizeof(tBTA_DM_SDP_RESULT)); 2033 2034 p_msg->hdr.event = BTA_DM_SDP_RESULT_EVT; 2035 p_msg->sdp_result = sdp_status; 2036 2037 bta_sys_sendmsg(p_msg); 2038} 2039 2040/******************************************************************************* 2041 * 2042 * Function bta_dm_inq_results_cb 2043 * 2044 * Description Inquiry results callback from BTM 2045 * 2046 * Returns void 2047 * 2048 ******************************************************************************/ 2049static void bta_dm_inq_results_cb(tBTM_INQ_RESULTS* p_inq, uint8_t* p_eir, 2050 uint16_t eir_len) { 2051 tBTA_DM_SEARCH result; 2052 tBTM_INQ_INFO* p_inq_info; 2053 uint16_t service_class; 2054 2055 result.inq_res.bd_addr = p_inq->remote_bd_addr; 2056 memcpy(result.inq_res.dev_class, p_inq->dev_class, DEV_CLASS_LEN); 2057 BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class); 2058 result.inq_res.is_limited = 2059 (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? true : false; 2060 result.inq_res.rssi = p_inq->rssi; 2061 2062 result.inq_res.ble_addr_type = p_inq->ble_addr_type; 2063 result.inq_res.inq_result_type = p_inq->inq_result_type; 2064 result.inq_res.device_type = p_inq->device_type; 2065 result.inq_res.flag = p_inq->flag; 2066 2067 /* application will parse EIR to find out remote device name */ 2068 result.inq_res.p_eir = p_eir; 2069 result.inq_res.eir_len = eir_len; 2070 2071 p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr); 2072 if (p_inq_info != NULL) { 2073 /* initialize remt_name_not_required to false so that we get the name by 2074 * default */ 2075 result.inq_res.remt_name_not_required = false; 2076 } 2077 2078 if (bta_dm_search_cb.p_search_cback) 2079 bta_dm_search_cb.p_search_cback(BTA_DM_INQ_RES_EVT, &result); 2080 2081 if (p_inq_info) { 2082 /* application indicates if it knows the remote name, inside the callback 2083 copy that to the inquiry data base*/ 2084 if (result.inq_res.remt_name_not_required) 2085 p_inq_info->appl_knows_rem_name = true; 2086 } 2087} 2088 2089/******************************************************************************* 2090 * 2091 * Function bta_dm_inq_cmpl_cb 2092 * 2093 * Description Inquiry complete callback from BTM 2094 * 2095 * Returns void 2096 * 2097 ******************************************************************************/ 2098static void bta_dm_inq_cmpl_cb(void* p_result) { 2099 tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 2100 2101 APPL_TRACE_DEBUG("%s", __func__); 2102 2103 if (!bta_dm_search_cb.cancel_pending) { 2104 p_msg->inq_cmpl.hdr.event = BTA_DM_INQUIRY_CMPL_EVT; 2105 p_msg->inq_cmpl.num = ((tBTM_INQUIRY_CMPL*)p_result)->num_resp; 2106 } else { 2107 bta_dm_search_cb.cancel_pending = false; 2108 bta_dm_search_cancel_notify(NULL); 2109 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 2110 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 2111 } 2112 2113 bta_sys_sendmsg(p_msg); 2114} 2115 2116/******************************************************************************* 2117 * 2118 * Function bta_dm_service_search_remname_cback 2119 * 2120 * Description Remote name call back from BTM during service discovery 2121 * 2122 * Returns void 2123 * 2124 ******************************************************************************/ 2125static void bta_dm_service_search_remname_cback(const RawAddress& bd_addr, 2126 UNUSED_ATTR DEV_CLASS dc, 2127 BD_NAME bd_name) { 2128 tBTM_REMOTE_DEV_NAME rem_name; 2129 tBTM_STATUS btm_status; 2130 2131 APPL_TRACE_DEBUG("%s name=<%s>", __func__, bd_name); 2132 2133 /* if this is what we are looking for */ 2134 if (bta_dm_search_cb.peer_bdaddr == bd_addr) { 2135 rem_name.length = strlen((char*)bd_name); 2136 if (rem_name.length > (BD_NAME_LEN - 1)) { 2137 rem_name.length = (BD_NAME_LEN - 1); 2138 rem_name.remote_bd_name[(BD_NAME_LEN - 1)] = 0; 2139 } 2140 strlcpy((char*)rem_name.remote_bd_name, (char*)bd_name, BD_NAME_LEN); 2141 rem_name.status = BTM_SUCCESS; 2142 2143 bta_dm_remname_cback(&rem_name); 2144 } else { 2145 /* get name of device */ 2146 btm_status = 2147 BTM_ReadRemoteDeviceName(bta_dm_search_cb.peer_bdaddr, 2148 bta_dm_remname_cback, BT_TRANSPORT_BR_EDR); 2149 if (btm_status == BTM_BUSY) { 2150 /* wait for next chance(notification of remote name discovery done) */ 2151 APPL_TRACE_DEBUG("%s: BTM_ReadRemoteDeviceName is busy", __func__); 2152 } else if (btm_status != BTM_CMD_STARTED) { 2153 /* if failed to start getting remote name then continue */ 2154 APPL_TRACE_WARNING("%s: BTM_ReadRemoteDeviceName returns 0x%02X", 2155 __func__, btm_status); 2156 2157 rem_name.length = 0; 2158 rem_name.remote_bd_name[0] = 0; 2159 rem_name.status = btm_status; 2160 bta_dm_remname_cback(&rem_name); 2161 } 2162 } 2163} 2164 2165/******************************************************************************* 2166 * 2167 * Function bta_dm_remname_cback 2168 * 2169 * Description Remote name complete call back from BTM 2170 * 2171 * Returns void 2172 * 2173 ******************************************************************************/ 2174static void bta_dm_remname_cback(void* p) { 2175 tBTM_REMOTE_DEV_NAME* p_remote_name = (tBTM_REMOTE_DEV_NAME*)p; 2176 APPL_TRACE_DEBUG("bta_dm_remname_cback len = %d name=<%s>", 2177 p_remote_name->length, p_remote_name->remote_bd_name); 2178 2179 /* remote name discovery is done but it could be failed */ 2180 bta_dm_search_cb.name_discover_done = true; 2181 strlcpy((char*)bta_dm_search_cb.peer_name, 2182 (char*)p_remote_name->remote_bd_name, BD_NAME_LEN); 2183 2184 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback); 2185 2186 if (bta_dm_search_cb.transport == BT_TRANSPORT_LE) { 2187 GAP_BleReadPeerPrefConnParams(bta_dm_search_cb.peer_bdaddr); 2188 } 2189 2190 tBTA_DM_REM_NAME* p_msg = 2191 (tBTA_DM_REM_NAME*)osi_malloc(sizeof(tBTA_DM_REM_NAME)); 2192 p_msg->result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr; 2193 strlcpy((char*)p_msg->result.disc_res.bd_name, 2194 (char*)p_remote_name->remote_bd_name, BD_NAME_LEN); 2195 p_msg->hdr.event = BTA_DM_REMT_NAME_EVT; 2196 2197 bta_sys_sendmsg(p_msg); 2198} 2199 2200/******************************************************************************* 2201 * 2202 * Function bta_dm_authorize_cback 2203 * 2204 * Description cback requesting authorization 2205 * 2206 * Returns void 2207 * 2208 ******************************************************************************/ 2209static uint8_t bta_dm_authorize_cback(const RawAddress& bd_addr, 2210 DEV_CLASS dev_class, BD_NAME bd_name, 2211 UNUSED_ATTR uint8_t* service_name, 2212 uint8_t service_id, 2213 UNUSED_ATTR bool is_originator) { 2214 tBTA_DM_SEC sec_event; 2215 uint8_t index = 1; 2216 2217 sec_event.authorize.bd_addr = bd_addr; 2218 memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN); 2219 strlcpy((char*)sec_event.authorize.bd_name, (char*)bd_name, BD_NAME_LEN); 2220 2221#if (BTA_JV_INCLUDED == TRUE) 2222 sec_event.authorize.service = service_id; 2223#endif 2224 2225 while (index < BTA_MAX_SERVICE_ID) { 2226 /* get the BTA service id corresponding to BTM id */ 2227 if (bta_service_id_to_btm_srv_id_lkup_tbl[index] == service_id) { 2228 sec_event.authorize.service = index; 2229 break; 2230 } 2231 index++; 2232 } 2233 2234 /* if supported service callback otherwise not authorized */ 2235 if (bta_dm_cb.p_sec_cback && (index < BTA_MAX_SERVICE_ID 2236#if (BTA_JV_INCLUDED == TRUE) 2237 /* pass through JV service ID */ 2238 || (service_id >= BTA_FIRST_JV_SERVICE_ID && 2239 service_id <= BTA_LAST_JV_SERVICE_ID) 2240#endif 2241 )) { 2242 bta_dm_cb.p_sec_cback(BTA_DM_AUTHORIZE_EVT, &sec_event); 2243 return BTM_CMD_STARTED; 2244 } else { 2245 return BTM_NOT_AUTHORIZED; 2246 } 2247} 2248 2249/******************************************************************************* 2250 * 2251 * Function bta_dm_pinname_cback 2252 * 2253 * Description Callback requesting pin_key 2254 * 2255 * Returns void 2256 * 2257 ******************************************************************************/ 2258static void bta_dm_pinname_cback(void* p_data) { 2259 tBTM_REMOTE_DEV_NAME* p_result = (tBTM_REMOTE_DEV_NAME*)p_data; 2260 tBTA_DM_SEC sec_event; 2261 uint32_t bytes_to_copy; 2262 tBTA_DM_SEC_EVT event = bta_dm_cb.pin_evt; 2263 2264 if (BTA_DM_SP_CFM_REQ_EVT == event) { 2265 /* Retrieved saved device class and bd_addr */ 2266 sec_event.cfm_req.bd_addr = bta_dm_cb.pin_bd_addr; 2267 BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_cb.pin_dev_class); 2268 2269 if (p_result && p_result->status == BTM_SUCCESS) { 2270 bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1)) 2271 ? p_result->length 2272 : (BD_NAME_LEN - 1); 2273 memcpy(sec_event.cfm_req.bd_name, p_result->remote_bd_name, 2274 bytes_to_copy); 2275 sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0; 2276 } else /* No name found */ 2277 sec_event.cfm_req.bd_name[0] = 0; 2278 2279 sec_event.key_notif.passkey = 2280 bta_dm_cb.num_val; /* get PIN code numeric number */ 2281 2282 /* 1 additional event data fields for this event */ 2283 sec_event.cfm_req.just_works = bta_dm_cb.just_works; 2284 /* retrieve the loc and rmt caps */ 2285 sec_event.cfm_req.loc_io_caps = bta_dm_cb.loc_io_caps; 2286 sec_event.cfm_req.rmt_io_caps = bta_dm_cb.rmt_io_caps; 2287 sec_event.cfm_req.loc_auth_req = bta_dm_cb.loc_auth_req; 2288 sec_event.cfm_req.rmt_auth_req = bta_dm_cb.rmt_auth_req; 2289 2290 } else { 2291 /* Retrieved saved device class and bd_addr */ 2292 sec_event.pin_req.bd_addr = bta_dm_cb.pin_bd_addr; 2293 BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_cb.pin_dev_class); 2294 2295 if (p_result && p_result->status == BTM_SUCCESS) { 2296 bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1)) 2297 ? p_result->length 2298 : (BD_NAME_LEN - 1); 2299 memcpy(sec_event.pin_req.bd_name, p_result->remote_bd_name, 2300 bytes_to_copy); 2301 sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0; 2302 } else /* No name found */ 2303 sec_event.pin_req.bd_name[0] = 0; 2304 2305 event = bta_dm_cb.pin_evt; 2306 sec_event.key_notif.passkey = 2307 bta_dm_cb.num_val; /* get PIN code numeric number */ 2308 } 2309 2310 if (bta_dm_cb.p_sec_cback) bta_dm_cb.p_sec_cback(event, &sec_event); 2311} 2312 2313/******************************************************************************* 2314 * 2315 * Function bta_dm_pin_cback 2316 * 2317 * Description Callback requesting pin_key 2318 * 2319 * Returns void 2320 * 2321 ******************************************************************************/ 2322static uint8_t bta_dm_pin_cback(const RawAddress& bd_addr, DEV_CLASS dev_class, 2323 BD_NAME bd_name, bool min_16_digit) { 2324 tBTA_DM_SEC sec_event; 2325 2326 if (!bta_dm_cb.p_sec_cback) return BTM_NOT_AUTHORIZED; 2327 2328 /* If the device name is not known, save bdaddr and devclass and initiate a 2329 * name request */ 2330 if (bd_name[0] == 0) { 2331 bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT; 2332 bta_dm_cb.pin_bd_addr = bd_addr; 2333 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class); 2334 if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, 2335 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) 2336 return BTM_CMD_STARTED; 2337 2338 APPL_TRACE_WARNING( 2339 " bta_dm_pin_cback() -> Failed to start Remote Name Request "); 2340 } 2341 2342 sec_event.pin_req.bd_addr = bd_addr; 2343 BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class); 2344 strlcpy((char*)sec_event.pin_req.bd_name, (char*)bd_name, BD_NAME_LEN); 2345 sec_event.pin_req.min_16_digit = min_16_digit; 2346 2347 bta_dm_cb.p_sec_cback(BTA_DM_PIN_REQ_EVT, &sec_event); 2348 return BTM_CMD_STARTED; 2349} 2350 2351/******************************************************************************* 2352 * 2353 * Function bta_dm_new_link_key_cback 2354 * 2355 * Description Callback from BTM to notify new link key 2356 * 2357 * Returns void 2358 * 2359 ******************************************************************************/ 2360static uint8_t bta_dm_new_link_key_cback(const RawAddress& bd_addr, 2361 UNUSED_ATTR DEV_CLASS dev_class, 2362 BD_NAME bd_name, LINK_KEY key, 2363 uint8_t key_type) { 2364 tBTA_DM_SEC sec_event; 2365 tBTA_DM_AUTH_CMPL* p_auth_cmpl; 2366 uint8_t event; 2367 2368 memset(&sec_event, 0, sizeof(tBTA_DM_SEC)); 2369 2370 /* Not AMP Key type */ 2371 if (key_type != HCI_LKEY_TYPE_AMP_WIFI && key_type != HCI_LKEY_TYPE_AMP_UWB) { 2372 event = BTA_DM_AUTH_CMPL_EVT; 2373 p_auth_cmpl = &sec_event.auth_cmpl; 2374 2375 p_auth_cmpl->bd_addr = bd_addr; 2376 2377 memcpy(p_auth_cmpl->bd_name, bd_name, (BD_NAME_LEN - 1)); 2378 p_auth_cmpl->bd_name[BD_NAME_LEN - 1] = 0; 2379 2380 p_auth_cmpl->key_present = true; 2381 p_auth_cmpl->key_type = key_type; 2382 p_auth_cmpl->success = true; 2383 2384 memcpy(p_auth_cmpl->key, key, LINK_KEY_LEN); 2385 sec_event.auth_cmpl.fail_reason = HCI_SUCCESS; 2386 2387 // Report the BR link key based on the BR/EDR address and type 2388 BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, 2389 &sec_event.auth_cmpl.addr_type); 2390 if (bta_dm_cb.p_sec_cback) bta_dm_cb.p_sec_cback(event, &sec_event); 2391 2392 // Setting remove_dev_pending flag to false, where it will avoid deleting 2393 // the 2394 // security device record when the ACL connection link goes down in case of 2395 // reconnection. 2396 if (bta_dm_cb.device_list.count) 2397 bta_dm_reset_sec_dev_pending(p_auth_cmpl->bd_addr); 2398 } else { 2399 APPL_TRACE_WARNING("%s() Received AMP Key", __func__); 2400 } 2401 2402 return BTM_CMD_STARTED; 2403} 2404 2405/******************************************************************************* 2406 * 2407 * Function bta_dm_authentication_complete_cback 2408 * 2409 * Description Authentication complete callback from BTM 2410 * 2411 * Returns void 2412 * 2413 ******************************************************************************/ 2414static uint8_t bta_dm_authentication_complete_cback( 2415 const RawAddress& bd_addr, UNUSED_ATTR DEV_CLASS dev_class, BD_NAME bd_name, 2416 int result) { 2417 tBTA_DM_SEC sec_event; 2418 2419 if (result != BTM_SUCCESS) { 2420 memset(&sec_event, 0, sizeof(tBTA_DM_SEC)); 2421 sec_event.auth_cmpl.bd_addr = bd_addr; 2422 2423 memcpy(sec_event.auth_cmpl.bd_name, bd_name, (BD_NAME_LEN - 1)); 2424 sec_event.auth_cmpl.bd_name[BD_NAME_LEN - 1] = 0; 2425 2426 // Report the BR link key based on the BR/EDR address and type 2427 BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, 2428 &sec_event.auth_cmpl.addr_type); 2429 sec_event.auth_cmpl.fail_reason = (uint8_t)result; 2430 2431 if (bta_dm_cb.p_sec_cback) 2432 bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event); 2433 2434 if (result == HCI_ERR_AUTH_FAILURE || result == HCI_ERR_KEY_MISSING || 2435 result == HCI_ERR_HOST_REJECT_SECURITY || 2436 result == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE) { 2437 APPL_TRACE_WARNING("%s deleting %s - result: 0x%02x", __func__, 2438 bd_addr.ToString().c_str(), result); 2439 bta_dm_remove_sec_dev_entry(bd_addr); 2440 } 2441 } 2442 2443 return BTM_SUCCESS; 2444} 2445 2446/******************************************************************************* 2447 * 2448 * Function bta_dm_sp_cback 2449 * 2450 * Description simple pairing callback from BTM 2451 * 2452 * Returns void 2453 * 2454 ******************************************************************************/ 2455static uint8_t bta_dm_sp_cback(tBTM_SP_EVT event, tBTM_SP_EVT_DATA* p_data) { 2456 tBTM_STATUS status = BTM_CMD_STARTED; 2457 tBTA_DM_SEC sec_event; 2458 tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT; 2459 2460 APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event); 2461 if (!bta_dm_cb.p_sec_cback) return BTM_NOT_AUTHORIZED; 2462 2463 /* TODO_SP */ 2464 switch (event) { 2465 case BTM_SP_IO_REQ_EVT: 2466#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) 2467 /* translate auth_req */ 2468 bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap, 2469 &p_data->io_req.oob_data, &p_data->io_req.auth_req, 2470 p_data->io_req.is_orig); 2471#endif 2472 APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, 2473 p_data->io_req.oob_data); 2474 break; 2475 case BTM_SP_IO_RSP_EVT: 2476#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) 2477 bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap, 2478 p_data->io_rsp.oob_data, p_data->io_rsp.auth_req); 2479#endif 2480 break; 2481 2482 case BTM_SP_CFM_REQ_EVT: 2483 pin_evt = BTA_DM_SP_CFM_REQ_EVT; 2484 bta_dm_cb.just_works = sec_event.cfm_req.just_works = 2485 p_data->cfm_req.just_works; 2486 sec_event.cfm_req.loc_auth_req = p_data->cfm_req.loc_auth_req; 2487 sec_event.cfm_req.rmt_auth_req = p_data->cfm_req.rmt_auth_req; 2488 sec_event.cfm_req.loc_io_caps = p_data->cfm_req.loc_io_caps; 2489 sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps; 2490 2491 /* continue to next case */ 2492#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) 2493 /* Passkey entry mode, mobile device with output capability is very 2494 unlikely to receive key request, so skip this event */ 2495 /*case BTM_SP_KEY_REQ_EVT: */ 2496 case BTM_SP_KEY_NOTIF_EVT: 2497#endif 2498 bta_dm_cb.num_val = sec_event.key_notif.passkey = 2499 p_data->key_notif.passkey; 2500 2501 if (BTM_SP_CFM_REQ_EVT == event) { 2502 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT, 2503 call remote name request using values from cfm_req */ 2504 if (p_data->cfm_req.bd_name[0] == 0) { 2505 bta_dm_cb.pin_evt = pin_evt; 2506 bta_dm_cb.pin_bd_addr = p_data->cfm_req.bd_addr; 2507 bta_dm_cb.rmt_io_caps = sec_event.cfm_req.rmt_io_caps; 2508 bta_dm_cb.loc_io_caps = sec_event.cfm_req.loc_io_caps; 2509 bta_dm_cb.rmt_auth_req = sec_event.cfm_req.rmt_auth_req; 2510 bta_dm_cb.loc_auth_req = sec_event.cfm_req.loc_auth_req; 2511 2512 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, 2513 p_data->cfm_req.dev_class); 2514 if ((BTM_ReadRemoteDeviceName( 2515 p_data->cfm_req.bd_addr, bta_dm_pinname_cback, 2516 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) 2517 return BTM_CMD_STARTED; 2518 APPL_TRACE_WARNING( 2519 " bta_dm_sp_cback() -> Failed to start Remote Name Request "); 2520 } else { 2521 /* Due to the switch case falling through below to 2522 BTM_SP_KEY_NOTIF_EVT, 2523 copy these values into key_notif from cfm_req */ 2524 sec_event.key_notif.bd_addr = p_data->cfm_req.bd_addr; 2525 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, 2526 p_data->cfm_req.dev_class); 2527 strlcpy((char*)sec_event.key_notif.bd_name, 2528 (char*)p_data->cfm_req.bd_name, BD_NAME_LEN); 2529 } 2530 } 2531 2532 if (BTM_SP_KEY_NOTIF_EVT == event) { 2533 /* If the device name is not known, save bdaddr and devclass 2534 and initiate a name request with values from key_notif */ 2535 if (p_data->key_notif.bd_name[0] == 0) { 2536 bta_dm_cb.pin_evt = pin_evt; 2537 bta_dm_cb.pin_bd_addr = p_data->key_notif.bd_addr; 2538 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, 2539 p_data->key_notif.dev_class); 2540 if ((BTM_ReadRemoteDeviceName( 2541 p_data->key_notif.bd_addr, bta_dm_pinname_cback, 2542 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) 2543 return BTM_CMD_STARTED; 2544 APPL_TRACE_WARNING( 2545 " bta_dm_sp_cback() -> Failed to start Remote Name Request "); 2546 } else { 2547 sec_event.key_notif.bd_addr = p_data->key_notif.bd_addr; 2548 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, 2549 p_data->key_notif.dev_class); 2550 strlcpy((char*)sec_event.key_notif.bd_name, 2551 (char*)p_data->key_notif.bd_name, BD_NAME_LEN); 2552 sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0; 2553 } 2554 } 2555 2556 bta_dm_cb.p_sec_cback(pin_evt, &sec_event); 2557 2558 break; 2559 2560 case BTM_SP_LOC_OOB_EVT: 2561 bta_dm_co_loc_oob((bool)(p_data->loc_oob.status == BTM_SUCCESS), 2562 p_data->loc_oob.c, p_data->loc_oob.r); 2563 break; 2564 2565 case BTM_SP_RMT_OOB_EVT: 2566 /* If the device name is not known, save bdaddr and devclass and initiate 2567 * a name request */ 2568 if (p_data->rmt_oob.bd_name[0] == 0) { 2569 bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT; 2570 bta_dm_cb.pin_bd_addr = p_data->rmt_oob.bd_addr; 2571 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, 2572 p_data->rmt_oob.dev_class); 2573 if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, 2574 bta_dm_pinname_cback, 2575 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) 2576 return BTM_CMD_STARTED; 2577 APPL_TRACE_WARNING( 2578 " bta_dm_sp_cback() -> Failed to start Remote Name Request "); 2579 } 2580 2581 sec_event.rmt_oob.bd_addr = p_data->rmt_oob.bd_addr; 2582 BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, 2583 p_data->rmt_oob.dev_class); 2584 strlcpy((char*)sec_event.rmt_oob.bd_name, (char*)p_data->rmt_oob.bd_name, 2585 BD_NAME_LEN); 2586 2587 bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event); 2588 2589 bta_dm_co_rmt_oob(p_data->rmt_oob.bd_addr); 2590 break; 2591 2592 case BTM_SP_COMPLT_EVT: 2593 /* do not report this event - handled by link_key_callback or 2594 * auth_complete_callback */ 2595 break; 2596 2597 case BTM_SP_KEYPRESS_EVT: 2598 memcpy(&sec_event.key_press, &p_data->key_press, 2599 sizeof(tBTM_SP_KEYPRESS)); 2600 bta_dm_cb.p_sec_cback(BTA_DM_SP_KEYPRESS_EVT, &sec_event); 2601 break; 2602 2603 case BTM_SP_UPGRADE_EVT: 2604 bta_dm_co_lk_upgrade(p_data->upgrade.bd_addr, &p_data->upgrade.upgrade); 2605 break; 2606 2607 default: 2608 status = BTM_NOT_AUTHORIZED; 2609 break; 2610 } 2611 APPL_TRACE_EVENT("dm status: %d", status); 2612 return status; 2613} 2614 2615/******************************************************************************* 2616 * 2617 * Function bta_dm_local_name_cback 2618 * 2619 * Description Callback from btm after local name is read 2620 * 2621 * 2622 * Returns void 2623 * 2624 ******************************************************************************/ 2625static void bta_dm_local_name_cback(UNUSED_ATTR void* p_name) { 2626 tBTA_DM_SEC sec_event; 2627 2628 sec_event.enable.status = BTA_SUCCESS; 2629 2630 if (bta_dm_cb.p_sec_cback) 2631 bta_dm_cb.p_sec_cback(BTA_DM_ENABLE_EVT, &sec_event); 2632} 2633 2634static void send_busy_level_update(uint8_t busy_level, 2635 uint8_t busy_level_flags) { 2636 if (!bta_dm_cb.p_sec_cback) return; 2637 2638 tBTA_DM_SEC conn; 2639 memset(&conn, 0, sizeof(tBTA_DM_SEC)); 2640 conn.busy_level.level = busy_level; 2641 conn.busy_level.level_flags = busy_level_flags; 2642 bta_dm_cb.p_sec_cback(BTA_DM_BUSY_LEVEL_EVT, &conn); 2643} 2644 2645static void handle_role_change(const RawAddress& bd_addr, uint8_t new_role, 2646 uint8_t hci_status) { 2647 tBTA_DM_SEC conn; 2648 memset(&conn, 0, sizeof(tBTA_DM_SEC)); 2649 2650 tBTA_DM_PEER_DEVICE* p_dev = bta_dm_find_peer_device(bd_addr); 2651 if (!p_dev) return; 2652 LOG_INFO(LOG_TAG, 2653 "%s: peer %s info:0x%x new_role:0x%x dev count:%d hci_status=%d", 2654 __func__, bd_addr.ToString().c_str(), p_dev->info, new_role, 2655 bta_dm_cb.device_list.count, hci_status); 2656 if (p_dev->info & BTA_DM_DI_AV_ACTIVE) { 2657 bool need_policy_change = false; 2658 2659 /* there's AV activity on this link */ 2660 if (new_role == HCI_ROLE_SLAVE && bta_dm_cb.device_list.count > 1 && 2661 hci_status == HCI_SUCCESS) { 2662 /* more than one connections and the AV connection is role switched 2663 * to slave 2664 * switch it back to master and remove the switch policy */ 2665 BTM_SwitchRole(bd_addr, BTM_ROLE_MASTER, NULL); 2666 need_policy_change = true; 2667 } else if (p_bta_dm_cfg->avoid_scatter && (new_role == HCI_ROLE_MASTER)) { 2668 /* if the link updated to be master include AV activities, remove 2669 * the switch policy */ 2670 need_policy_change = true; 2671 } 2672 2673 if (need_policy_change) { 2674 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, 2675 p_dev->peer_bdaddr); 2676 } 2677 } else { 2678 /* there's AV no activity on this link and role switch happened 2679 * check if AV is active 2680 * if so, make sure the AV link is master */ 2681 bta_dm_check_av(0); 2682 } 2683 bta_sys_notify_role_chg(bd_addr, new_role, hci_status); 2684 conn.role_chg.bd_addr = bd_addr; 2685 conn.role_chg.new_role = (uint8_t)new_role; 2686 if (bta_dm_cb.p_sec_cback) bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, &conn); 2687} 2688 2689static void bta_dm_acl_change(bool is_new, const RawAddress& bd_addr, 2690 tBT_TRANSPORT transport, uint16_t handle) { 2691 bool issue_unpair_cb = false; 2692 2693 tBTA_DM_SEC conn; 2694 memset(&conn, 0, sizeof(tBTA_DM_SEC)); 2695 2696 if (is_new) { 2697 uint8_t i; 2698 for (i = 0; i < bta_dm_cb.device_list.count; i++) { 2699 if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == bd_addr && 2700 bta_dm_cb.device_list.peer_device[i].conn_handle == handle) 2701 break; 2702 } 2703 2704 if (i == bta_dm_cb.device_list.count) { 2705 if (bta_dm_cb.device_list.count < BTA_DM_NUM_PEER_DEVICE) { 2706 bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count] 2707 .peer_bdaddr = bd_addr; 2708 bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count] 2709 .link_policy = bta_dm_cb.cur_policy; 2710 bta_dm_cb.device_list.count++; 2711 bta_dm_cb.device_list.peer_device[i].conn_handle = handle; 2712 if (transport == BT_TRANSPORT_LE) bta_dm_cb.device_list.le_count++; 2713 } else { 2714 APPL_TRACE_ERROR("%s max active connection reached, no resources", 2715 __func__); 2716 return; 2717 } 2718 } 2719 2720 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED; 2721 bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE; 2722 conn.link_up.bd_addr = bd_addr; 2723 bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE; 2724 conn.link_up.link_type = transport; 2725 bta_dm_cb.device_list.peer_device[i].transport = transport; 2726 2727 uint8_t* p; 2728 if (((NULL != (p = BTM_ReadLocalFeatures())) && 2729 HCI_SNIFF_SUB_RATE_SUPPORTED(p)) && 2730 ((NULL != (p = BTM_ReadRemoteFeatures(bd_addr))) && 2731 HCI_SNIFF_SUB_RATE_SUPPORTED(p))) { 2732 /* both local and remote devices support SSR */ 2733 bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR; 2734 } 2735 APPL_TRACE_WARNING("%s info: 0x%x", __func__, 2736 bta_dm_cb.device_list.peer_device[i].info); 2737 2738 if (bta_dm_cb.p_sec_cback) bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, &conn); 2739 } else { 2740 for (uint8_t i = 0; i < bta_dm_cb.device_list.count; i++) { 2741 if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr != bd_addr || 2742 bta_dm_cb.device_list.peer_device[i].transport != transport) 2743 continue; 2744 2745 if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING) { 2746 if (BTM_SecDeleteDevice( 2747 bta_dm_cb.device_list.peer_device[i].peer_bdaddr)) 2748 issue_unpair_cb = true; 2749 2750 APPL_TRACE_DEBUG("%s: Unpairing: issue unpair CB = %d ", __func__, 2751 issue_unpair_cb); 2752 } 2753 2754 conn.link_down.is_removed = 2755 bta_dm_cb.device_list.peer_device[i].remove_dev_pending; 2756 2757 // Iterate to the one before the last when shrinking the list, 2758 // otherwise we memcpy garbage data into the record. 2759 // Then clear out the last item in the list since we are shrinking. 2760 for (; i < bta_dm_cb.device_list.count - 1; i++) { 2761 memcpy(&bta_dm_cb.device_list.peer_device[i], 2762 &bta_dm_cb.device_list.peer_device[i + 1], 2763 sizeof(bta_dm_cb.device_list.peer_device[i])); 2764 } 2765 if (bta_dm_cb.device_list.count > 0) { 2766 int clear_index = bta_dm_cb.device_list.count - 1; 2767 memset(&bta_dm_cb.device_list.peer_device[clear_index], 0, 2768 sizeof(bta_dm_cb.device_list.peer_device[clear_index])); 2769 } 2770 break; 2771 } 2772 if (bta_dm_cb.device_list.count) bta_dm_cb.device_list.count--; 2773 if ((transport == BT_TRANSPORT_LE) && (bta_dm_cb.device_list.le_count)) 2774 bta_dm_cb.device_list.le_count--; 2775 conn.link_down.link_type = transport; 2776 2777 if (bta_dm_search_cb.wait_disc && bta_dm_search_cb.peer_bdaddr == bd_addr) { 2778 bta_dm_search_cb.wait_disc = false; 2779 2780 if (bta_dm_search_cb.sdp_results) { 2781 APPL_TRACE_EVENT(" timer stopped "); 2782 alarm_cancel(bta_dm_search_cb.search_timer); 2783 bta_dm_discover_next_device(); 2784 } 2785 } 2786 2787 if (bta_dm_cb.disabling) { 2788 if (!BTM_GetNumAclLinks()) { 2789 /* 2790 * Start a timer to make sure that the profiles 2791 * get the disconnect event. 2792 */ 2793 alarm_set_on_mloop(bta_dm_cb.disable_timer, 2794 BTA_DM_DISABLE_CONN_DOWN_TIMER_MS, 2795 bta_dm_disable_conn_down_timer_cback, NULL); 2796 } 2797 } 2798 if (conn.link_down.is_removed) { 2799 BTM_SecDeleteDevice(bd_addr); 2800 /* need to remove all pending background connection */ 2801 BTA_GATTC_CancelOpen(0, bd_addr, false); 2802 /* remove all cached GATT information */ 2803 BTA_GATTC_Refresh(bd_addr); 2804 } 2805 2806 conn.link_down.bd_addr = bd_addr; 2807 conn.link_down.status = (uint8_t)btm_get_acl_disc_reason_code(); 2808 if (bta_dm_cb.p_sec_cback) { 2809 bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn); 2810 if (issue_unpair_cb) 2811 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn); 2812 } 2813 } 2814 2815 bta_dm_adjust_roles(true); 2816} 2817 2818/** Callback from btm when acl connection goes up or down */ 2819static void bta_dm_bl_change_cback(tBTM_BL_EVENT_DATA* p_data) { 2820 switch (p_data->event) { 2821 case BTM_BL_CONN_EVT: 2822 /* connection up */ 2823 do_in_bta_thread(FROM_HERE, 2824 base::Bind(bta_dm_acl_change, true, *p_data->conn.p_bda, 2825 p_data->conn.transport, p_data->conn.handle)); 2826 break; 2827 case BTM_BL_DISCN_EVT: 2828 /* connection down */ 2829 do_in_bta_thread( 2830 FROM_HERE, base::Bind(bta_dm_acl_change, false, *p_data->discn.p_bda, 2831 p_data->discn.transport, p_data->discn.handle)); 2832 break; 2833 2834 case BTM_BL_UPDATE_EVT: { 2835 /* busy level update */ 2836 do_in_bta_thread(FROM_HERE, base::Bind(send_busy_level_update, 2837 p_data->update.busy_level, 2838 p_data->update.busy_level_flags)); 2839 return; 2840 } 2841 case BTM_BL_ROLE_CHG_EVT: { 2842 const auto& tmp = p_data->role_chg; 2843 do_in_bta_thread(FROM_HERE, base::Bind(handle_role_change, *tmp.p_bda, 2844 tmp.new_role, tmp.hci_status)); 2845 return; 2846 } 2847 2848 case BTM_BL_COLLISION_EVT: 2849 /* Collision report from Stack: Notify profiles */ 2850 do_in_bta_thread( 2851 FROM_HERE, base::Bind(bta_sys_notify_collision, *p_data->conn.p_bda)); 2852 return; 2853 } 2854} 2855 2856/******************************************************************************* 2857 * 2858 * Function bta_dm_rs_cback 2859 * 2860 * Description Receives the role switch complete event 2861 * 2862 * Returns 2863 * 2864 ******************************************************************************/ 2865static void bta_dm_rs_cback(UNUSED_ATTR void* p1) { 2866 APPL_TRACE_WARNING("bta_dm_rs_cback:%d", bta_dm_cb.rs_event); 2867 if (bta_dm_cb.rs_event == BTA_DM_API_SEARCH_EVT) { 2868 bta_dm_cb.search_msg.rs_res = 2869 BTA_DM_RS_OK; /* do not care about the result for now */ 2870 bta_dm_cb.rs_event = 0; 2871 bta_dm_search_start((tBTA_DM_MSG*)&bta_dm_cb.search_msg); 2872 } 2873} 2874 2875/******************************************************************************* 2876 * 2877 * Function bta_dm_check_av 2878 * 2879 * Description This function checks if AV is active 2880 * if yes, make sure the AV link is master 2881 * 2882 * Returns bool - true, if switch is in progress 2883 * 2884 ******************************************************************************/ 2885static bool bta_dm_check_av(uint16_t event) { 2886 bool avoid_roleswitch = false; 2887 bool switching = false; 2888 uint8_t i; 2889 tBTA_DM_PEER_DEVICE* p_dev; 2890 2891#if (BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY == TRUE) 2892 2893 /* avoid role switch upon inquiry if a2dp is actively streaming as it 2894 introduces an audioglitch due to FW scheduling delays (unavoidable) */ 2895 if (event == BTA_DM_API_SEARCH_EVT) { 2896 avoid_roleswitch = true; 2897 } 2898#endif 2899 2900 APPL_TRACE_WARNING("bta_dm_check_av:%d", bta_dm_cb.cur_av_count); 2901 if (bta_dm_cb.cur_av_count) { 2902 for (i = 0; i < bta_dm_cb.device_list.count; i++) { 2903 p_dev = &bta_dm_cb.device_list.peer_device[i]; 2904 APPL_TRACE_WARNING("[%d]: state:%d, info:x%x, avoid_rs %d", i, 2905 p_dev->conn_state, p_dev->info, avoid_roleswitch); 2906 if ((p_dev->conn_state == BTA_DM_CONNECTED) && 2907 (p_dev->info & BTA_DM_DI_AV_ACTIVE) && (!avoid_roleswitch)) { 2908 /* make master and take away the role switch policy */ 2909 if (BTM_CMD_STARTED == BTM_SwitchRole(p_dev->peer_bdaddr, 2910 HCI_ROLE_MASTER, 2911 bta_dm_rs_cback)) { 2912 /* the role switch command is actually sent */ 2913 bta_dm_cb.rs_event = event; 2914 switching = true; 2915 } 2916 /* else either already master or can not switch for some reasons */ 2917 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, 2918 p_dev->peer_bdaddr); 2919 break; 2920 } 2921 } 2922 } 2923 return switching; 2924} 2925 2926/******************************************************************************* 2927 * 2928 * Function bta_dm_disable_conn_down_timer_cback 2929 * 2930 * Description Sends disable event to application 2931 * 2932 * 2933 * Returns void 2934 * 2935 ******************************************************************************/ 2936static void bta_dm_disable_conn_down_timer_cback(UNUSED_ATTR void* data) { 2937 tBTA_SYS_HW_MSG* sys_enable_event = 2938 (tBTA_SYS_HW_MSG*)osi_malloc(sizeof(tBTA_SYS_HW_MSG)); 2939 2940 /* disable the power managment module */ 2941 bta_dm_disable_pm(); 2942 2943 /* register our callback to SYS HW manager */ 2944 bta_sys_hw_register(BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback); 2945 2946 /* send a message to BTA SYS */ 2947 sys_enable_event->hdr.event = BTA_SYS_API_DISABLE_EVT; 2948 sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH; 2949 bta_sys_sendmsg(sys_enable_event); 2950 2951 bta_dm_cb.disabling = false; 2952} 2953 2954/******************************************************************************* 2955 * 2956 * Function bta_dm_rm_cback 2957 * 2958 * Description Role management callback from sys 2959 * 2960 * 2961 * Returns void 2962 * 2963 ******************************************************************************/ 2964static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, uint8_t id, 2965 uint8_t app_id, const RawAddress& peer_addr) { 2966 uint8_t j; 2967 tBTA_PREF_ROLES role; 2968 tBTA_DM_PEER_DEVICE* p_dev; 2969 2970 p_dev = bta_dm_find_peer_device(peer_addr); 2971 if (status == BTA_SYS_CONN_OPEN) { 2972 if (p_dev) { 2973 /* Do not set to connected if we are in the middle of unpairing. When AV 2974 * stream is 2975 * started it fakes out a SYS_CONN_OPEN to potentially trigger a role 2976 * switch command. 2977 * But this should not be done if we are in the middle of unpairing. 2978 */ 2979 if (p_dev->conn_state != BTA_DM_UNPAIRING) 2980 p_dev->conn_state = BTA_DM_CONNECTED; 2981 2982 for (j = 1; j <= p_bta_dm_rm_cfg[0].app_id; j++) { 2983 if (((p_bta_dm_rm_cfg[j].app_id == app_id) || 2984 (p_bta_dm_rm_cfg[j].app_id == BTA_ALL_APP_ID)) && 2985 (p_bta_dm_rm_cfg[j].id == id)) { 2986 role = p_bta_dm_rm_cfg[j].cfg; 2987 2988 if (role > p_dev->pref_role) p_dev->pref_role = role; 2989 break; 2990 } 2991 } 2992 } 2993 } 2994 2995 if ((BTA_ID_AV == id) || (BTA_ID_AVK == id)) { 2996 if (status == BTA_SYS_CONN_BUSY) { 2997 if (p_dev) p_dev->info |= BTA_DM_DI_AV_ACTIVE; 2998 /* AV calls bta_sys_conn_open with the A2DP stream count as app_id */ 2999 if (BTA_ID_AV == id) bta_dm_cb.cur_av_count = bta_dm_get_av_count(); 3000 } else if (status == BTA_SYS_CONN_IDLE) { 3001 if (p_dev) p_dev->info &= ~BTA_DM_DI_AV_ACTIVE; 3002 3003 /* get cur_av_count from connected services */ 3004 if (BTA_ID_AV == id) bta_dm_cb.cur_av_count = bta_dm_get_av_count(); 3005 } 3006 APPL_TRACE_WARNING("bta_dm_rm_cback:%d, status:%d", bta_dm_cb.cur_av_count, 3007 status); 3008 } 3009 3010 /* Don't adjust roles for each busy/idle state transition to avoid 3011 excessive switch requests when individual profile busy/idle status 3012 changes */ 3013 if ((status != BTA_SYS_CONN_BUSY) && (status != BTA_SYS_CONN_IDLE)) 3014 bta_dm_adjust_roles(false); 3015} 3016 3017/******************************************************************************* 3018 * 3019 * Function bta_dm_delay_role_switch_cback 3020 * 3021 * Description Callback from btm to delay a role switch 3022 * 3023 * Returns void 3024 * 3025 ******************************************************************************/ 3026static void bta_dm_delay_role_switch_cback(UNUSED_ATTR void* data) { 3027 APPL_TRACE_EVENT("%s: initiating Delayed RS", __func__); 3028 bta_dm_adjust_roles(false); 3029} 3030 3031/******************************************************************************* 3032 * 3033 * Function bta_dm_reset_sec_dev_pending 3034 * 3035 * Description Setting the remove device pending status to false from 3036 * security device DB, when the link key notification 3037 * event comes. 3038 * 3039 * Returns void 3040 * 3041 ******************************************************************************/ 3042static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr) { 3043 for (size_t i = 0; i < bta_dm_cb.device_list.count; i++) { 3044 if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == remote_bd_addr) { 3045 bta_dm_cb.device_list.peer_device[i].remove_dev_pending = false; 3046 return; 3047 } 3048 } 3049} 3050 3051/******************************************************************************* 3052 * 3053 * Function bta_dm_remove_sec_dev_entry 3054 * 3055 * Description Removes device entry from Security device DB if ACL 3056 connection with 3057 * remtoe device does not exist, else schedule for dev entry 3058 removal upon 3059 ACL close 3060 * 3061 * Returns void 3062 * 3063 ******************************************************************************/ 3064static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr) { 3065 if (BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) || 3066 BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR)) { 3067 APPL_TRACE_DEBUG( 3068 "%s ACL is not down. Schedule for Dev Removal when ACL closes", 3069 __func__); 3070 BTM_SecClearSecurityFlags(remote_bd_addr); 3071 for (int i = 0; i < bta_dm_cb.device_list.count; i++) { 3072 if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == remote_bd_addr) { 3073 bta_dm_cb.device_list.peer_device[i].remove_dev_pending = TRUE; 3074 break; 3075 } 3076 } 3077 } else { 3078 BTM_SecDeleteDevice(remote_bd_addr); 3079 /* need to remove all pending background connection */ 3080 BTA_GATTC_CancelOpen(0, remote_bd_addr, false); 3081 /* remove all cached GATT information */ 3082 BTA_GATTC_Refresh(remote_bd_addr); 3083 } 3084} 3085 3086/******************************************************************************* 3087 * 3088 * Function bta_dm_adjust_roles 3089 * 3090 * Description Adjust roles 3091 * 3092 * 3093 * Returns void 3094 * 3095 ******************************************************************************/ 3096static void bta_dm_adjust_roles(bool delay_role_switch) { 3097 uint8_t i; 3098 bool set_master_role = false; 3099 uint8_t br_count = 3100 bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count; 3101 if (br_count) { 3102 /* the configuration is no scatternet 3103 * or AV connection exists and there are more than one ACL link */ 3104 if ((p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) || 3105 (bta_dm_cb.cur_av_count && br_count > 1)) { 3106 L2CA_SetDesireRole(HCI_ROLE_MASTER); 3107 set_master_role = true; 3108 } 3109 3110 for (i = 0; i < bta_dm_cb.device_list.count; i++) { 3111 if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED && 3112 bta_dm_cb.device_list.peer_device[i].transport == 3113 BT_TRANSPORT_BR_EDR) { 3114 if (!set_master_role && 3115 (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE) && 3116 (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET)) { 3117 L2CA_SetDesireRole(HCI_ROLE_MASTER); 3118 set_master_role = true; 3119 } 3120 3121 if ((bta_dm_cb.device_list.peer_device[i].pref_role == 3122 BTA_MASTER_ROLE_ONLY) || 3123 (br_count > 1)) { 3124 /* Initiating immediate role switch with certain remote devices 3125 has caused issues due to role switch colliding with link encryption 3126 setup and 3127 causing encryption (and in turn the link) to fail . These device . 3128 Firmware 3129 versions are stored in a blacklist and role switch with these 3130 devices are 3131 delayed to avoid the collision with link encryption setup */ 3132 3133 if (bta_dm_cb.device_list.peer_device[i].pref_role != 3134 BTA_SLAVE_ROLE_ONLY && 3135 !delay_role_switch) { 3136 BTM_SwitchRole(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, 3137 HCI_ROLE_MASTER, NULL); 3138 } else { 3139 alarm_set_on_mloop(bta_dm_cb.switch_delay_timer, 3140 BTA_DM_SWITCH_DELAY_TIMER_MS, 3141 bta_dm_delay_role_switch_cback, NULL); 3142 } 3143 } 3144 } 3145 } 3146 3147 if (!set_master_role) { 3148 L2CA_SetDesireRole(L2CAP_DESIRED_LINK_ROLE); 3149 } 3150 3151 } else { 3152 L2CA_SetDesireRole(L2CAP_DESIRED_LINK_ROLE); 3153 } 3154} 3155 3156/******************************************************************************* 3157 * 3158 * Function bta_dm_get_remname 3159 * 3160 * Description Returns a pointer to the remote name stored in the DM 3161 * control block if it exists, or from the BTM memory. 3162 * 3163 * Returns char * - Pointer to the remote device name 3164 ******************************************************************************/ 3165static char* bta_dm_get_remname(void) { 3166 char* p_name = (char*)bta_dm_search_cb.peer_name; 3167 char* p_temp; 3168 3169 /* If the name isn't already stored, try retrieving from BTM */ 3170 if (*p_name == '\0') { 3171 p_temp = BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr); 3172 if (p_temp != NULL) p_name = p_temp; 3173 } 3174 3175 return p_name; 3176} 3177 3178/******************************************************************************* 3179 * 3180 * Function bta_dm_bond_cancel_complete_cback 3181 * 3182 * Description Authentication complete callback from BTM 3183 * 3184 * Returns void 3185 * 3186 ******************************************************************************/ 3187static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result) { 3188 tBTA_DM_SEC sec_event; 3189 3190 if (result == BTM_SUCCESS) 3191 sec_event.bond_cancel_cmpl.result = BTA_SUCCESS; 3192 else 3193 sec_event.bond_cancel_cmpl.result = BTA_FAILURE; 3194 3195 if (bta_dm_cb.p_sec_cback) { 3196 bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event); 3197 } 3198} 3199 3200/******************************************************************************* 3201 * 3202 * Function find_utf8_char_boundary 3203 * 3204 * Description This function checks a UTF8 string |utf8str| starting at 3205 * |offset|, moving backwards and returns the offset of the 3206 * next valid UTF8 character boundary found. 3207 * 3208 * Returns Offset of UTF8 character boundary 3209 * 3210 ******************************************************************************/ 3211static size_t find_utf8_char_boundary(const char* utf8str, size_t offset) { 3212 CHECK(utf8str); 3213 CHECK(offset > 0); 3214 3215 while (--offset) { 3216 uint8_t ch = (uint8_t)utf8str[offset]; 3217 if ((ch & 0x80) == 0x00) // ASCII 3218 return offset + 1; 3219 if ((ch & 0xC0) == 0xC0) // Multi-byte sequence start 3220 return offset; 3221 } 3222 3223 return 0; 3224} 3225 3226/******************************************************************************* 3227 * 3228 * Function bta_dm_set_eir 3229 * 3230 * Description This function creates EIR tagged data and writes it to 3231 * controller. 3232 * 3233 * Returns None 3234 * 3235 ******************************************************************************/ 3236static void bta_dm_set_eir(char* local_name) { 3237 uint8_t* p; 3238 uint8_t* p_length; 3239#if (BTA_EIR_CANNED_UUID_LIST != TRUE) 3240 uint8_t* p_type; 3241 uint8_t max_num_uuid; 3242#if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) 3243 uint8_t custom_uuid_idx; 3244#endif // BTA_EIR_SERVER_NUM_CUSTOM_UUID 3245#endif // BTA_EIR_CANNED_UUID_LIST 3246#if (BTM_EIR_DEFAULT_FEC_REQUIRED == FALSE) 3247 uint8_t free_eir_length = HCI_EXT_INQ_RESPONSE_LEN; 3248#else // BTM_EIR_DEFAULT_FEC_REQUIRED 3249 uint8_t free_eir_length = HCI_DM5_PACKET_SIZE; 3250#endif // BTM_EIR_DEFAULT_FEC_REQUIRED 3251 uint8_t num_uuid; 3252 uint8_t data_type; 3253 uint8_t local_name_len; 3254 3255 /* wait until complete to disable */ 3256 if (alarm_is_scheduled(bta_dm_cb.disable_timer)) return; 3257 3258#if (BTA_EIR_CANNED_UUID_LIST != TRUE) 3259 /* if local name is not provided, get it from controller */ 3260 if (local_name == NULL) { 3261 if (BTM_ReadLocalDeviceName(&local_name) != BTM_SUCCESS) { 3262 APPL_TRACE_ERROR("Fail to read local device name for EIR"); 3263 } 3264 } 3265#endif // BTA_EIR_CANNED_UUID_LIST 3266 3267 /* Allocate a buffer to hold HCI command */ 3268 BT_HDR* p_buf = (BT_HDR*)osi_malloc(BTM_CMD_BUF_SIZE); 3269 p = (uint8_t*)p_buf + BTM_HCI_EIR_OFFSET; 3270 3271 memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN); 3272 3273 APPL_TRACE_DEBUG("BTA is generating EIR"); 3274 3275 if (local_name) 3276 local_name_len = strlen(local_name); 3277 else 3278 local_name_len = 0; 3279 3280 data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE; 3281 /* if local name is longer than minimum length of shortened name */ 3282 /* check whether it needs to be shortened or not */ 3283 if (local_name_len > p_bta_dm_eir_cfg->bta_dm_eir_min_name_len) { 3284/* get number of UUID 16-bit list */ 3285#if (BTA_EIR_CANNED_UUID_LIST == TRUE) 3286 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / Uuid::kNumBytes16; 3287#else // BTA_EIR_CANNED_UUID_LIST 3288 max_num_uuid = (free_eir_length - 2) / Uuid::kNumBytes16; 3289 data_type = BTM_GetEirSupportedServices(bta_dm_cb.eir_uuid, &p, 3290 max_num_uuid, &num_uuid); 3291 p = (uint8_t*)p_buf + BTM_HCI_EIR_OFFSET; /* reset p */ 3292#endif // BTA_EIR_CANNED_UUID_LIST 3293 3294 /* if UUID doesn't fit remaing space, shorten local name */ 3295 if (local_name_len > (free_eir_length - 4 - num_uuid * Uuid::kNumBytes16)) { 3296 local_name_len = find_utf8_char_boundary( 3297 local_name, p_bta_dm_eir_cfg->bta_dm_eir_min_name_len); 3298 APPL_TRACE_WARNING("%s local name is shortened (%d)", __func__, 3299 local_name_len); 3300 data_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE; 3301 } else { 3302 data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE; 3303 } 3304 } 3305 3306 UINT8_TO_STREAM(p, local_name_len + 1); 3307 UINT8_TO_STREAM(p, data_type); 3308 3309 if (local_name != NULL) { 3310 memcpy(p, local_name, local_name_len); 3311 p += local_name_len; 3312 } 3313 free_eir_length -= local_name_len + 2; 3314 3315#if (BTA_EIR_CANNED_UUID_LIST == TRUE) 3316 /* if UUID list is provided as static data in configuration */ 3317 if ((p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len > 0) && 3318 (p_bta_dm_eir_cfg->bta_dm_eir_uuid16)) { 3319 if (free_eir_length > Uuid::kNumBytes16 + 2) { 3320 free_eir_length -= 2; 3321 3322 if (free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len) { 3323 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / Uuid::kNumBytes16; 3324 data_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE; 3325 } else /* not enough room for all UUIDs */ 3326 { 3327 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated"); 3328 num_uuid = free_eir_length / Uuid::kNumBytes16; 3329 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE; 3330 } 3331 UINT8_TO_STREAM(p, num_uuid * Uuid::kNumBytes16 + 1); 3332 UINT8_TO_STREAM(p, data_type); 3333 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_uuid16, 3334 num_uuid * Uuid::kNumBytes16); 3335 p += num_uuid * Uuid::kNumBytes16; 3336 free_eir_length -= num_uuid * Uuid::kNumBytes16; 3337 } 3338 } 3339#else /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */ 3340 /* if UUID list is dynamic */ 3341 if (free_eir_length >= 2) { 3342 p_length = p++; 3343 p_type = p++; 3344 num_uuid = 0; 3345 3346 max_num_uuid = (free_eir_length - 2) / Uuid::kNumBytes16; 3347 data_type = BTM_GetEirSupportedServices(bta_dm_cb.eir_uuid, &p, 3348 max_num_uuid, &num_uuid); 3349 3350 if (data_type == BTM_EIR_MORE_16BITS_UUID_TYPE) { 3351 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated"); 3352 } 3353#if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) 3354 else { 3355 for (custom_uuid_idx = 0; 3356 custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; 3357 custom_uuid_idx++) { 3358 const Uuid& curr = bta_dm_cb.custom_uuid[custom_uuid_idx]; 3359 if (curr.GetShortestRepresentationSize() == Uuid::kNumBytes16) { 3360 if (num_uuid < max_num_uuid) { 3361 UINT16_TO_STREAM(p, curr.As16Bit()); 3362 num_uuid++; 3363 } else { 3364 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE; 3365 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated"); 3366 break; 3367 } 3368 } 3369 } 3370 } 3371#endif /* (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */ 3372 3373 UINT8_TO_STREAM(p_length, num_uuid * Uuid::kNumBytes16 + 1); 3374 UINT8_TO_STREAM(p_type, data_type); 3375 free_eir_length -= num_uuid * Uuid::kNumBytes16 + 2; 3376 } 3377#endif /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */ 3378 3379#if (BTA_EIR_CANNED_UUID_LIST != TRUE && BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) 3380 /* Adding 32-bit UUID list */ 3381 if (free_eir_length >= 2) { 3382 p_length = p++; 3383 p_type = p++; 3384 num_uuid = 0; 3385 data_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE; 3386 3387 max_num_uuid = (free_eir_length - 2) / Uuid::kNumBytes32; 3388 3389 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; 3390 custom_uuid_idx++) { 3391 const Uuid& curr = bta_dm_cb.custom_uuid[custom_uuid_idx]; 3392 if (curr.GetShortestRepresentationSize() == Uuid::kNumBytes32) { 3393 if (num_uuid < max_num_uuid) { 3394 UINT32_TO_STREAM(p, curr.As32Bit()); 3395 num_uuid++; 3396 } else { 3397 data_type = BTM_EIR_MORE_32BITS_UUID_TYPE; 3398 APPL_TRACE_WARNING("BTA EIR: UUID 32-bit list is truncated"); 3399 break; 3400 } 3401 } 3402 } 3403 3404 UINT8_TO_STREAM(p_length, num_uuid * Uuid::kNumBytes32 + 1); 3405 UINT8_TO_STREAM(p_type, data_type); 3406 free_eir_length -= num_uuid * Uuid::kNumBytes32 + 2; 3407 } 3408 3409 /* Adding 128-bit UUID list */ 3410 if (free_eir_length >= 2) { 3411 p_length = p++; 3412 p_type = p++; 3413 num_uuid = 0; 3414 data_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE; 3415 3416 max_num_uuid = (free_eir_length - 2) / Uuid::kNumBytes128; 3417 3418 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; 3419 custom_uuid_idx++) { 3420 const Uuid& curr = bta_dm_cb.custom_uuid[custom_uuid_idx]; 3421 if (curr.GetShortestRepresentationSize() == Uuid::kNumBytes128) { 3422 if (num_uuid < max_num_uuid) { 3423 ARRAY16_TO_STREAM(p, curr.To128BitBE().data()); 3424 num_uuid++; 3425 } else { 3426 data_type = BTM_EIR_MORE_128BITS_UUID_TYPE; 3427 APPL_TRACE_WARNING("BTA EIR: UUID 128-bit list is truncated"); 3428 break; 3429 } 3430 } 3431 } 3432 3433 UINT8_TO_STREAM(p_length, num_uuid * Uuid::kNumBytes128 + 1); 3434 UINT8_TO_STREAM(p_type, data_type); 3435 free_eir_length -= num_uuid * Uuid::kNumBytes128 + 2; 3436 } 3437#endif /* ( BTA_EIR_CANNED_UUID_LIST != TRUE \ 3438 )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */ 3439 3440 /* if Flags are provided in configuration */ 3441 if ((p_bta_dm_eir_cfg->bta_dm_eir_flag_len > 0) && 3442 (p_bta_dm_eir_cfg->bta_dm_eir_flags) && 3443 (free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2)) { 3444 UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 1); 3445 UINT8_TO_STREAM(p, BTM_EIR_FLAGS_TYPE); 3446 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_flags, 3447 p_bta_dm_eir_cfg->bta_dm_eir_flag_len); 3448 p += p_bta_dm_eir_cfg->bta_dm_eir_flag_len; 3449 free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2; 3450 } 3451 3452 /* if Manufacturer Specific are provided in configuration */ 3453 if ((p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len > 0) && 3454 (p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec) && 3455 (free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2)) { 3456 p_length = p; 3457 3458 UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 1); 3459 UINT8_TO_STREAM(p, BTM_EIR_MANUFACTURER_SPECIFIC_TYPE); 3460 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec, 3461 p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len); 3462 p += p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len; 3463 free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2; 3464 3465 } else { 3466 p_length = NULL; 3467 } 3468 3469 /* if Inquiry Tx Resp Power compiled */ 3470 if ((p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power) && (free_eir_length >= 3)) { 3471 UINT8_TO_STREAM(p, 2); /* Length field */ 3472 UINT8_TO_STREAM(p, BTM_EIR_TX_POWER_LEVEL_TYPE); 3473 UINT8_TO_STREAM(p, *(p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power)); 3474 free_eir_length -= 3; 3475 } 3476 3477 if (free_eir_length) 3478 UINT8_TO_STREAM(p, 0); /* terminator of significant part */ 3479 3480 BTM_WriteEIR(p_buf); 3481} 3482 3483/******************************************************************************* 3484 * 3485 * Function bta_dm_eir_search_services 3486 * 3487 * Description This function searches services in received EIR 3488 * 3489 * Returns None 3490 * 3491 ******************************************************************************/ 3492static void bta_dm_eir_search_services(tBTM_INQ_RESULTS* p_result, 3493 tBTA_SERVICE_MASK* p_services_to_search, 3494 tBTA_SERVICE_MASK* p_services_found) { 3495 tBTA_SERVICE_MASK service_index = 0; 3496 tBTM_EIR_SEARCH_RESULT result; 3497 3498 VLOG(1) << "BTA searching services in EIR of BDA:" 3499 << p_result->remote_bd_addr; 3500 3501 APPL_TRACE_DEBUG(" with services_to_search=0x%08X", *p_services_to_search); 3502 3503 /* always do GATT based service discovery by SDP instead of from EIR */ 3504 /* if GATT based service is also to be put in EIR, need to modify this */ 3505 while (service_index < (BTA_MAX_SERVICE_ID - 1)) { 3506 if (*p_services_to_search & 3507 (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index))) { 3508 result = BTM_HasInquiryEirService( 3509 p_result, bta_service_id_to_uuid_lkup_tbl[service_index]); 3510 3511 /* Searching for HSP v1.2 only device */ 3512 if ((result != BTM_EIR_FOUND) && 3513 (bta_service_id_to_uuid_lkup_tbl[service_index] == 3514 UUID_SERVCLASS_HEADSET)) { 3515 result = BTM_HasInquiryEirService(p_result, UUID_SERVCLASS_HEADSET_HS); 3516 } 3517 3518 if (result == BTM_EIR_FOUND) { 3519 /* If Plug and Play service record, need to check to see if Broadcom 3520 * stack */ 3521 /* However, EIR data doesn't have EXT_BRCM_VERSION so just skip it */ 3522 if (bta_service_id_to_uuid_lkup_tbl[service_index] != 3523 UUID_SERVCLASS_PNP_INFORMATION) { 3524 *p_services_found |= (tBTA_SERVICE_MASK)( 3525 BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)); 3526 /* remove the service from services to be searched */ 3527 *p_services_to_search &= (tBTA_SERVICE_MASK)( 3528 ~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index))); 3529 } 3530 } else if (result == BTM_EIR_NOT_FOUND) { 3531 /* remove the service from services to be searched */ 3532 *p_services_to_search &= (tBTA_SERVICE_MASK)( 3533 ~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index))); 3534 } 3535 } 3536 3537 service_index++; 3538 } 3539 3540 APPL_TRACE_ERROR( 3541 "BTA EIR search result, services_to_search=0x%08X, services_found=0x%08X", 3542 *p_services_to_search, *p_services_found); 3543} 3544 3545#if (BTA_EIR_CANNED_UUID_LIST != TRUE) 3546/******************************************************************************* 3547 * 3548 * Function bta_dm_eir_update_uuid 3549 * 3550 * Description This function adds or removes service UUID in EIR database. 3551 * 3552 * Returns None 3553 * 3554 ******************************************************************************/ 3555void bta_dm_eir_update_uuid(uint16_t uuid16, bool adding) { 3556 /* if this UUID is not advertised in EIR */ 3557 if (!BTM_HasEirService(p_bta_dm_eir_cfg->uuid_mask, uuid16)) return; 3558 3559 if (adding) { 3560 APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid16); 3561 3562 BTM_AddEirService(bta_dm_cb.eir_uuid, uuid16); 3563 } else { 3564 APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid16); 3565 3566 BTM_RemoveEirService(bta_dm_cb.eir_uuid, uuid16); 3567 } 3568 3569 bta_dm_set_eir(NULL); 3570 3571 APPL_TRACE_EVENT("bta_dm_eir_update_uuid UUID bit mask=0x%08X %08X", 3572 bta_dm_cb.eir_uuid[1], bta_dm_cb.eir_uuid[0]); 3573} 3574#endif 3575 3576/******************************************************************************* 3577 * 3578 * Function bta_dm_encrypt_cback 3579 * 3580 * Description link encryption complete callback. 3581 * 3582 * Returns None 3583 * 3584 ******************************************************************************/ 3585void bta_dm_encrypt_cback(const RawAddress* bd_addr, tBT_TRANSPORT transport, 3586 UNUSED_ATTR void* p_ref_data, tBTM_STATUS result) { 3587 tBTA_STATUS bta_status = BTA_SUCCESS; 3588 tBTA_DM_ENCRYPT_CBACK* p_callback = NULL; 3589 uint8_t i; 3590 3591 for (i = 0; i < bta_dm_cb.device_list.count; i++) { 3592 if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == *bd_addr && 3593 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) 3594 break; 3595 } 3596 3597 if (i < bta_dm_cb.device_list.count) { 3598 p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback; 3599 bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL; 3600 } 3601 3602 switch (result) { 3603 case BTM_SUCCESS: 3604 break; 3605 case BTM_WRONG_MODE: 3606 bta_status = BTA_WRONG_MODE; 3607 break; 3608 case BTM_NO_RESOURCES: 3609 bta_status = BTA_NO_RESOURCES; 3610 break; 3611 case BTM_BUSY: 3612 bta_status = BTA_BUSY; 3613 break; 3614 default: 3615 bta_status = BTA_FAILURE; 3616 break; 3617 } 3618 3619 APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=0x%x", 3620 bta_status, p_callback); 3621 3622 if (p_callback) { 3623 (*p_callback)(*bd_addr, transport, bta_status); 3624 } 3625} 3626 3627/**This function to encrypt the link */ 3628void bta_dm_set_encryption(const RawAddress& bd_addr, tBTA_TRANSPORT transport, 3629 tBTA_DM_ENCRYPT_CBACK* p_callback, 3630 tBTA_DM_BLE_SEC_ACT sec_act) { 3631 uint8_t i; 3632 3633 APPL_TRACE_DEBUG("bta_dm_set_encryption"); // todo 3634 if (!p_callback) { 3635 APPL_TRACE_ERROR("bta_dm_set_encryption callback is not provided"); 3636 return; 3637 } 3638 for (i = 0; i < bta_dm_cb.device_list.count; i++) { 3639 if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == bd_addr && 3640 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) 3641 break; 3642 } 3643 if (i < bta_dm_cb.device_list.count) { 3644 if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback) { 3645 APPL_TRACE_ERROR("earlier enc was not done for same device"); 3646 (*p_callback)(bd_addr, transport, BTA_BUSY); 3647 return; 3648 } 3649 3650 if (BTM_SetEncryption(bd_addr, transport, bta_dm_encrypt_cback, NULL, 3651 sec_act) == BTM_CMD_STARTED) { 3652 bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_callback; 3653 } 3654 } 3655} 3656 3657bool bta_dm_check_if_only_hd_connected(const RawAddress& peer_addr) { 3658 APPL_TRACE_DEBUG("%s: count(%d)", __func__, bta_dm_conn_srvcs.count); 3659 3660 for (uint8_t j = 0; j < bta_dm_conn_srvcs.count; j++) { 3661 // Check if profiles other than hid are connected 3662 if ((bta_dm_conn_srvcs.conn_srvc[j].id != BTA_ID_HD) && 3663 bta_dm_conn_srvcs.conn_srvc[j].peer_bdaddr == peer_addr) { 3664 APPL_TRACE_DEBUG("%s: Another profile (id=%d) is connected", __func__, 3665 bta_dm_conn_srvcs.conn_srvc[j].id); 3666 return false; 3667 } 3668 } 3669 3670 return true; 3671} 3672 3673/******************************************************************************* 3674 * 3675 * Function bta_dm_observe_results_cb 3676 * 3677 * Description Callback for BLE Observe result 3678 * 3679 * 3680 * Returns void 3681 * 3682 ******************************************************************************/ 3683static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS* p_inq, uint8_t* p_eir, 3684 uint16_t eir_len) { 3685 tBTA_DM_SEARCH result; 3686 tBTM_INQ_INFO* p_inq_info; 3687 APPL_TRACE_DEBUG("bta_dm_observe_results_cb"); 3688 3689 result.inq_res.bd_addr = p_inq->remote_bd_addr; 3690 result.inq_res.rssi = p_inq->rssi; 3691 result.inq_res.ble_addr_type = p_inq->ble_addr_type; 3692 result.inq_res.inq_result_type = p_inq->inq_result_type; 3693 result.inq_res.device_type = p_inq->device_type; 3694 result.inq_res.flag = p_inq->flag; 3695 result.inq_res.ble_evt_type = p_inq->ble_evt_type; 3696 result.inq_res.ble_primary_phy = p_inq->ble_primary_phy; 3697 result.inq_res.ble_secondary_phy = p_inq->ble_secondary_phy; 3698 result.inq_res.ble_advertising_sid = p_inq->ble_advertising_sid; 3699 result.inq_res.ble_tx_power = p_inq->ble_tx_power; 3700 result.inq_res.ble_periodic_adv_int = p_inq->ble_periodic_adv_int; 3701 3702 /* application will parse EIR to find out remote device name */ 3703 result.inq_res.p_eir = p_eir; 3704 result.inq_res.eir_len = eir_len; 3705 3706 p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr); 3707 if (p_inq_info != NULL) { 3708 /* initialize remt_name_not_required to false so that we get the name by 3709 * default */ 3710 result.inq_res.remt_name_not_required = false; 3711 } 3712 3713 if (bta_dm_search_cb.p_scan_cback) 3714 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result); 3715 3716 if (p_inq_info) { 3717 /* application indicates if it knows the remote name, inside the callback 3718 copy that to the inquiry data base*/ 3719 if (result.inq_res.remt_name_not_required) 3720 p_inq_info->appl_knows_rem_name = true; 3721 } 3722} 3723 3724/******************************************************************************* 3725 * 3726 * Function bta_dm_observe_cmpl_cb 3727 * 3728 * Description Callback for BLE Observe complete 3729 * 3730 * 3731 * Returns void 3732 * 3733 ******************************************************************************/ 3734static void bta_dm_observe_cmpl_cb(void* p_result) { 3735 tBTA_DM_SEARCH data; 3736 3737 APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb"); 3738 3739 data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL*)p_result)->num_resp; 3740 if (bta_dm_search_cb.p_scan_cback) { 3741 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data); 3742 } 3743} 3744 3745/******************************************************************************* 3746 * 3747 * Function bta_dm_ble_smp_cback 3748 * 3749 * Description Callback for BLE SMP 3750 * 3751 * 3752 * Returns void 3753 * 3754 ******************************************************************************/ 3755static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda, 3756 tBTM_LE_EVT_DATA* p_data) { 3757 tBTM_STATUS status = BTM_SUCCESS; 3758 tBTA_DM_SEC sec_event; 3759 char* p_name = NULL; 3760 3761 if (!bta_dm_cb.p_sec_cback) return BTM_NOT_AUTHORIZED; 3762 3763 memset(&sec_event, 0, sizeof(tBTA_DM_SEC)); 3764 switch (event) { 3765 case BTM_LE_IO_REQ_EVT: 3766#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) 3767 3768 bta_dm_co_ble_io_req( 3769 bda, &p_data->io_req.io_cap, &p_data->io_req.oob_data, 3770 &p_data->io_req.auth_req, &p_data->io_req.max_key_size, 3771 &p_data->io_req.init_keys, &p_data->io_req.resp_keys); 3772#endif 3773 APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, 3774 p_data->io_req.oob_data); 3775 3776 break; 3777 3778 case BTM_LE_SEC_REQUEST_EVT: 3779 sec_event.ble_req.bd_addr = bda; 3780 p_name = BTM_SecReadDevName(bda); 3781 if (p_name != NULL) 3782 strlcpy((char*)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN); 3783 else 3784 sec_event.ble_req.bd_name[0] = 0; 3785 bta_dm_cb.p_sec_cback(BTA_DM_BLE_SEC_REQ_EVT, &sec_event); 3786 break; 3787 3788 case BTM_LE_KEY_NOTIF_EVT: 3789 sec_event.key_notif.bd_addr = bda; 3790 p_name = BTM_SecReadDevName(bda); 3791 if (p_name != NULL) 3792 strlcpy((char*)sec_event.key_notif.bd_name, p_name, BD_NAME_LEN); 3793 else 3794 sec_event.key_notif.bd_name[0] = 0; 3795 sec_event.key_notif.passkey = p_data->key_notif; 3796 bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_NOTIF_EVT, &sec_event); 3797 break; 3798 3799 case BTM_LE_KEY_REQ_EVT: 3800 sec_event.ble_req.bd_addr = bda; 3801 bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_REQ_EVT, &sec_event); 3802 break; 3803 3804 case BTM_LE_OOB_REQ_EVT: 3805 sec_event.ble_req.bd_addr = bda; 3806 bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event); 3807 break; 3808 3809 case BTM_LE_NC_REQ_EVT: 3810 sec_event.key_notif.bd_addr = bda; 3811 strlcpy((char*)sec_event.key_notif.bd_name, bta_dm_get_remname(), 3812 (BD_NAME_LEN)); 3813 sec_event.key_notif.passkey = p_data->key_notif; 3814 bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event); 3815 break; 3816 3817 case BTM_LE_SC_OOB_REQ_EVT: 3818 sec_event.ble_req.bd_addr = bda; 3819 bta_dm_cb.p_sec_cback(BTA_DM_BLE_SC_OOB_REQ_EVT, &sec_event); 3820 break; 3821 3822 case BTM_LE_KEY_EVT: 3823 sec_event.ble_key.bd_addr = bda; 3824 sec_event.ble_key.key_type = p_data->key.key_type; 3825 sec_event.ble_key.p_key_value = p_data->key.p_key_value; 3826 bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event); 3827 break; 3828 3829 case BTM_LE_COMPLT_EVT: 3830 sec_event.auth_cmpl.bd_addr = bda; 3831 BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type, 3832 &sec_event.auth_cmpl.addr_type); 3833 p_name = BTM_SecReadDevName(bda); 3834 if (p_name != NULL) 3835 strlcpy((char*)sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN)); 3836 else 3837 sec_event.auth_cmpl.bd_name[0] = 0; 3838 3839 if (p_data->complt.reason != 0) { 3840 sec_event.auth_cmpl.fail_reason = 3841 BTA_DM_AUTH_CONVERT_SMP_CODE(((uint8_t)p_data->complt.reason)); 3842 /* delete this device entry from Sec Dev DB */ 3843 bta_dm_remove_sec_dev_entry(bda); 3844 } else { 3845 sec_event.auth_cmpl.success = true; 3846 } 3847 3848 if (bta_dm_cb.p_sec_cback) { 3849 // bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event); 3850 bta_dm_cb.p_sec_cback(BTA_DM_BLE_AUTH_CMPL_EVT, &sec_event); 3851 } 3852 break; 3853 3854 default: 3855 status = BTM_NOT_AUTHORIZED; 3856 break; 3857 } 3858 return status; 3859} 3860 3861/******************************************************************************* 3862 * 3863 * Function bta_dm_ble_id_key_cback 3864 * 3865 * Description Callback for BLE local ID keys 3866 * 3867 * 3868 * Returns void 3869 * 3870 ******************************************************************************/ 3871static void bta_dm_ble_id_key_cback(uint8_t key_type, 3872 tBTM_BLE_LOCAL_KEYS* p_key) { 3873 uint8_t evt; 3874 tBTA_DM_SEC dm_key; 3875 3876 switch (key_type) { 3877 case BTM_BLE_KEY_TYPE_ID: 3878 case BTM_BLE_KEY_TYPE_ER: 3879 if (bta_dm_cb.p_sec_cback) { 3880 memcpy(&dm_key.ble_id_keys, p_key, sizeof(tBTM_BLE_LOCAL_KEYS)); 3881 3882 evt = (key_type == BTM_BLE_KEY_TYPE_ID) ? BTA_DM_BLE_LOCAL_IR_EVT 3883 : BTA_DM_BLE_LOCAL_ER_EVT; 3884 bta_dm_cb.p_sec_cback(evt, &dm_key); 3885 } 3886 break; 3887 3888 default: 3889 APPL_TRACE_DEBUG("Unknown key type %d", key_type); 3890 break; 3891 } 3892 return; 3893} 3894 3895/******************************************************************************* 3896 * 3897 * Function bta_dm_add_blekey 3898 * 3899 * Description This function adds an BLE Key to an security database entry. 3900 * This function shall only be called AFTER BTA_DmAddBleDevice 3901 * has been called. 3902 * It is normally called during host startup to restore all 3903 * required information stored in the NVRAM. 3904 * 3905 * Parameters: 3906 * 3907 ******************************************************************************/ 3908void bta_dm_add_blekey(const RawAddress& bd_addr, tBTA_LE_KEY_VALUE blekey, 3909 tBTA_LE_KEY_TYPE key_type) { 3910 if (!BTM_SecAddBleKey(bd_addr, (tBTM_LE_KEY_VALUE*)&blekey, key_type)) { 3911 LOG(ERROR) << "BTA_DM: Error adding BLE Key for device " << bd_addr; 3912 } 3913} 3914 3915/******************************************************************************* 3916 * 3917 * Function bta_dm_add_ble_device 3918 * 3919 * Description This function adds an BLE device to an security database 3920 * entry. 3921 * It is normally called during host startup to restore all 3922 * required information stored in the NVRAM. 3923 * 3924 * Parameters: 3925 * 3926 ******************************************************************************/ 3927void bta_dm_add_ble_device(const RawAddress& bd_addr, tBLE_ADDR_TYPE addr_type, 3928 tBT_DEVICE_TYPE dev_type) { 3929 if (!BTM_SecAddBleDevice(bd_addr, NULL, dev_type, addr_type)) { 3930 LOG(ERROR) << "BTA_DM: Error adding BLE Device for device " << bd_addr; 3931 } 3932} 3933 3934/******************************************************************************* 3935 * 3936 * Function bta_dm_add_ble_device 3937 * 3938 * Description This function adds an BLE device to an security database 3939 * entry. 3940 * It is normally called during host startup to restore all 3941 * required information stored in the NVRAM. 3942 * 3943 * Parameters: 3944 * 3945 ******************************************************************************/ 3946void bta_dm_ble_passkey_reply(const RawAddress& bd_addr, bool accept, 3947 uint32_t passkey) { 3948 BTM_BlePasskeyReply(bd_addr, accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED, 3949 passkey); 3950} 3951 3952/** This is response to SM numeric comparison request submitted to application. 3953 */ 3954void bta_dm_ble_confirm_reply(const RawAddress& bd_addr, bool accept) { 3955 BTM_BleConfirmReply(bd_addr, accept ? BTM_SUCCESS : BTM_NOT_AUTHORIZED); 3956} 3957 3958/** This function set the preferred connection parameters */ 3959void bta_dm_ble_set_conn_params(const RawAddress& bd_addr, 3960 uint16_t conn_int_min, uint16_t conn_int_max, 3961 uint16_t slave_latency, 3962 uint16_t supervision_tout) { 3963 L2CA_AdjustConnectionIntervals(&conn_int_min, &conn_int_max, 3964 BTM_BLE_CONN_INT_MIN); 3965 3966 BTM_BleSetPrefConnParams(bd_addr, conn_int_min, conn_int_max, slave_latency, 3967 supervision_tout); 3968} 3969 3970/** This function set the preferred connection scan parameters */ 3971void bta_dm_ble_set_conn_scan_params(uint32_t scan_interval, 3972 uint32_t scan_window) { 3973 BTM_BleSetConnScanParams(scan_interval, scan_window); 3974} 3975 3976/** This function update LE connection parameters */ 3977void bta_dm_ble_update_conn_params(const RawAddress& bd_addr, uint16_t min_int, 3978 uint16_t max_int, uint16_t latency, 3979 uint16_t timeout, uint16_t min_ce_len, 3980 uint16_t max_ce_len) { 3981 L2CA_AdjustConnectionIntervals(&min_int, &max_int, BTM_BLE_CONN_INT_MIN); 3982 3983 if (!L2CA_UpdateBleConnParams(bd_addr, min_int, max_int, latency, timeout, 3984 min_ce_len, max_ce_len)) { 3985 APPL_TRACE_ERROR("Update connection parameters failed!"); 3986 } 3987} 3988 3989#if (BLE_PRIVACY_SPT == TRUE) 3990/** This function set the local device LE privacy settings. */ 3991void bta_dm_ble_config_local_privacy(bool privacy_enable) { 3992 BTM_BleConfigPrivacy(privacy_enable); 3993} 3994#endif 3995 3996void bta_dm_ble_observe(bool start, uint8_t duration, 3997 tBTA_DM_SEARCH_CBACK* p_cback) { 3998 if (!start) { 3999 bta_dm_search_cb.p_scan_cback = NULL; 4000 BTM_BleObserve(false, 0, NULL, NULL); 4001 return; 4002 } 4003 4004 /*Save the callback to be called when a scan results are available */ 4005 bta_dm_search_cb.p_scan_cback = p_cback; 4006 tBTM_STATUS status = BTM_BleObserve(true, duration, bta_dm_observe_results_cb, 4007 bta_dm_observe_cmpl_cb); 4008 if (status != BTM_CMD_STARTED) { 4009 tBTA_DM_SEARCH data; 4010 APPL_TRACE_WARNING(" %s BTM_BleObserve failed. status %d", __func__, 4011 status); 4012 data.inq_cmpl.num_resps = 0; 4013 if (bta_dm_search_cb.p_scan_cback) { 4014 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data); 4015 } 4016 } 4017} 4018/******************************************************************************* 4019 * 4020 * Function bta_dm_ble_set_adv_params 4021 * 4022 * Description This function set the adv parameters. 4023 * 4024 * Parameters: 4025 * 4026 ******************************************************************************/ 4027void bta_dm_ble_set_adv_params(uint16_t adv_int_min, uint16_t adv_int_max, 4028 tBLE_BD_ADDR* p_dir_bda) { 4029 BTM_BleSetAdvParams(adv_int_min, adv_int_max, p_dir_bda, 4030 BTA_DM_BLE_ADV_CHNL_MAP); 4031} 4032 4033/** This function set the maximum transmission packet size */ 4034void bta_dm_ble_set_data_length(const RawAddress& bd_addr, 4035 uint16_t tx_data_length) { 4036 if (BTM_SetBleDataLength(bd_addr, tx_data_length) != BTM_SUCCESS) { 4037 APPL_TRACE_ERROR("%s failed", __func__); 4038 } 4039} 4040 4041/******************************************************************************* 4042 * 4043 * Function bta_ble_enable_scan_cmpl 4044 * 4045 * Description ADV payload filtering enable / disable complete callback 4046 * 4047 * 4048 * Returns None 4049 * 4050 ******************************************************************************/ 4051static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time, 4052 tBTM_BLE_RX_TIME_MS rx_time, 4053 tBTM_BLE_IDLE_TIME_MS idle_time, 4054 tBTM_BLE_ENERGY_USED energy_used, 4055 tBTM_STATUS status) { 4056 tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE; 4057 tBTA_DM_CONTRL_STATE ctrl_state = 0; 4058 4059 if (BTA_SUCCESS == st) ctrl_state = bta_dm_pm_obtain_controller_state(); 4060 4061 if (bta_dm_cb.p_energy_info_cback) 4062 bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, 4063 ctrl_state, st); 4064} 4065 4066/** This function obtains the energy info */ 4067void bta_dm_ble_get_energy_info( 4068 tBTA_BLE_ENERGY_INFO_CBACK* p_energy_info_cback) { 4069 bta_dm_cb.p_energy_info_cback = p_energy_info_cback; 4070 tBTM_STATUS btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl); 4071 if (BTM_CMD_STARTED != btm_status) 4072 bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status); 4073} 4074 4075#ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT 4076#define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000 4077#endif 4078 4079/******************************************************************************* 4080 * 4081 * Function bta_dm_gattc_register 4082 * 4083 * Description Register with GATTC in DM if BLE is needed. 4084 * 4085 * 4086 * Returns void 4087 * 4088 ******************************************************************************/ 4089static void bta_dm_gattc_register(void) { 4090 if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF) { 4091 BTA_GATTC_AppRegister(bta_dm_gattc_callback, 4092 base::Bind([](uint8_t client_id, uint8_t status) { 4093 if (status == GATT_SUCCESS) 4094 bta_dm_search_cb.client_if = client_id; 4095 else 4096 bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF; 4097 4098 })); 4099 } 4100} 4101 4102/******************************************************************************* 4103 * 4104 * Function btm_dm_start_disc_gatt_services 4105 * 4106 * Description This function starts a GATT service search request. 4107 * 4108 * Parameters: 4109 * 4110 ******************************************************************************/ 4111static void btm_dm_start_disc_gatt_services(uint16_t conn_id) { 4112 Uuid* p_uuid = bta_dm_search_cb.p_srvc_uuid + bta_dm_search_cb.num_uuid - 4113 bta_dm_search_cb.uuid_to_search; 4114 4115 /* always search for all services */ 4116 BTA_GATTC_ServiceSearchRequest(conn_id, p_uuid); 4117} 4118 4119/******************************************************************************* 4120 * 4121 * Function bta_dm_gatt_disc_result 4122 * 4123 * Description This function process the GATT service search result. 4124 * 4125 * Parameters: 4126 * 4127 ******************************************************************************/ 4128static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id) { 4129 tBTA_DM_SEARCH result; 4130 4131 /* 4132 * This logic will not work for gatt case. We are checking against the 4133 * bluetooth profiles here 4134 * just copy the GATTID in raw data field and send it across. 4135 */ 4136 4137 if (bta_dm_search_cb.ble_raw_used + sizeof(tBTA_GATT_ID) < 4138 bta_dm_search_cb.ble_raw_size) { 4139 APPL_TRACE_DEBUG( 4140 "ADDING BLE SERVICE uuid=%s, ble_ptr = 0x%x, ble_raw_used = 0x%x", 4141 service_id.uuid.ToString().c_str(), bta_dm_search_cb.p_ble_rawdata, 4142 bta_dm_search_cb.ble_raw_used); 4143 4144 if (bta_dm_search_cb.p_ble_rawdata) { 4145 // TODO(jpawlowski): the p_ble_raw data is only sent to btif_dm.cc, but is 4146 // never used there. Get rid of this code completly, or implement the 4147 // TODOs from btif_dm.cc 4148 memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used), 4149 &service_id, sizeof(service_id)); 4150 4151 bta_dm_search_cb.ble_raw_used += sizeof(service_id); 4152 } else { 4153 APPL_TRACE_ERROR("p_ble_rawdata is NULL"); 4154 } 4155 4156 } else { 4157 APPL_TRACE_ERROR( 4158 "%s out of room to accomodate more service ids ble_raw_size = %d " 4159 "ble_raw_used = %d", 4160 __func__, bta_dm_search_cb.ble_raw_size, bta_dm_search_cb.ble_raw_used); 4161 } 4162 4163 LOG_INFO(LOG_TAG, "%s service_id_uuid_len=%zu", __func__, 4164 service_id.uuid.GetShortestRepresentationSize()); 4165 if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) { 4166 /* send result back to app now, one by one */ 4167 result.disc_ble_res.bd_addr = bta_dm_search_cb.peer_bdaddr; 4168 strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(), 4169 BD_NAME_LEN); 4170 result.disc_ble_res.service = service_id.uuid; 4171 4172 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result); 4173 } 4174} 4175 4176/******************************************************************************* 4177 * 4178 * Function bta_dm_gatt_disc_complete 4179 * 4180 * Description This function process the GATT service search complete. 4181 * 4182 * Parameters: 4183 * 4184 ******************************************************************************/ 4185static void bta_dm_gatt_disc_complete(uint16_t conn_id, tGATT_STATUS status) { 4186 APPL_TRACE_DEBUG("%s conn_id = %d", __func__, conn_id); 4187 4188 if (bta_dm_search_cb.uuid_to_search > 0) bta_dm_search_cb.uuid_to_search--; 4189 4190 if (status == GATT_SUCCESS && bta_dm_search_cb.uuid_to_search > 0) { 4191 btm_dm_start_disc_gatt_services(conn_id); 4192 } else { 4193 tBTA_DM_MSG* p_msg = (tBTA_DM_MSG*)osi_malloc(sizeof(tBTA_DM_MSG)); 4194 4195 bta_dm_search_cb.uuid_to_search = 0; 4196 4197 /* no more services to be discovered */ 4198 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT; 4199 p_msg->disc_result.result.disc_res.result = 4200 (status == GATT_SUCCESS) ? BTA_SUCCESS : BTA_FAILURE; 4201 APPL_TRACE_DEBUG("%s service found: 0x%08x", __func__, 4202 bta_dm_search_cb.services_found); 4203 p_msg->disc_result.result.disc_res.services = 4204 bta_dm_search_cb.services_found; 4205 p_msg->disc_result.result.disc_res.num_uuids = 0; 4206 p_msg->disc_result.result.disc_res.p_uuid_list = NULL; 4207 p_msg->disc_result.result.disc_res.bd_addr = bta_dm_search_cb.peer_bdaddr; 4208 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name, 4209 bta_dm_get_remname(), BD_NAME_LEN); 4210 4211 p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE; 4212 if (bta_dm_search_cb.ble_raw_used > 0) { 4213 p_msg->disc_result.result.disc_res.p_raw_data = 4214 (uint8_t*)osi_malloc(bta_dm_search_cb.ble_raw_used); 4215 4216 memcpy(p_msg->disc_result.result.disc_res.p_raw_data, 4217 bta_dm_search_cb.p_ble_rawdata, bta_dm_search_cb.ble_raw_used); 4218 4219 p_msg->disc_result.result.disc_res.raw_data_size = 4220 bta_dm_search_cb.ble_raw_used; 4221 } else { 4222 p_msg->disc_result.result.disc_res.p_raw_data = NULL; 4223 bta_dm_search_cb.p_ble_rawdata = 0; 4224 } 4225 4226 bta_sys_sendmsg(p_msg); 4227 4228 if (conn_id != GATT_INVALID_CONN_ID) { 4229 /* start a GATT channel close delay timer */ 4230 bta_sys_start_timer(bta_dm_search_cb.gatt_close_timer, 4231 BTA_DM_GATT_CLOSE_DELAY_TOUT, 4232 BTA_DM_DISC_CLOSE_TOUT_EVT, 0); 4233 bta_dm_search_cb.pending_close_bda = bta_dm_search_cb.peer_bdaddr; 4234 } 4235 bta_dm_search_cb.gatt_disc_active = false; 4236 } 4237} 4238 4239/******************************************************************************* 4240 * 4241 * Function bta_dm_close_gatt_conn 4242 * 4243 * Description This function close the GATT connection after delay 4244 *timeout. 4245 * 4246 * Parameters: 4247 * 4248 ******************************************************************************/ 4249void bta_dm_close_gatt_conn(UNUSED_ATTR tBTA_DM_MSG* p_data) { 4250 if (bta_dm_search_cb.conn_id != GATT_INVALID_CONN_ID) 4251 BTA_GATTC_Close(bta_dm_search_cb.conn_id); 4252 4253 bta_dm_search_cb.pending_close_bda = RawAddress::kEmpty; 4254 bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID; 4255} 4256/******************************************************************************* 4257 * 4258 * Function btm_dm_start_gatt_discovery 4259 * 4260 * Description This is GATT initiate the service search by open a GATT 4261 * connection first. 4262 * 4263 * Parameters: 4264 * 4265 ******************************************************************************/ 4266void btm_dm_start_gatt_discovery(const RawAddress& bd_addr) { 4267 bta_dm_search_cb.gatt_disc_active = true; 4268 4269 /* connection is already open */ 4270 if (bta_dm_search_cb.pending_close_bda == bd_addr && 4271 bta_dm_search_cb.conn_id != GATT_INVALID_CONN_ID) { 4272 bta_dm_search_cb.pending_close_bda = RawAddress::kEmpty; 4273 alarm_cancel(bta_dm_search_cb.gatt_close_timer); 4274 btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id); 4275 } else { 4276 if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) { 4277 BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, true, 4278 GATT_TRANSPORT_LE, true); 4279 } else { 4280 BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, true, 4281 GATT_TRANSPORT_LE, false); 4282 } 4283 } 4284} 4285 4286/******************************************************************************* 4287 * 4288 * Function bta_dm_cancel_gatt_discovery 4289 * 4290 * Description This is GATT cancel the GATT service search. 4291 * 4292 * Parameters: 4293 * 4294 ******************************************************************************/ 4295static void bta_dm_cancel_gatt_discovery(const RawAddress& bd_addr) { 4296 if (bta_dm_search_cb.conn_id == GATT_INVALID_CONN_ID) { 4297 BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, true); 4298 } 4299 4300 bta_dm_gatt_disc_complete(bta_dm_search_cb.conn_id, (tGATT_STATUS)GATT_ERROR); 4301} 4302 4303/******************************************************************************* 4304 * 4305 * Function bta_dm_proc_open_evt 4306 * 4307 * Description process BTA_GATTC_OPEN_EVT in DM. 4308 * 4309 * Parameters: 4310 * 4311 ******************************************************************************/ 4312void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) { 4313 VLOG(1) << "DM Search state= " << bta_dm_search_cb.state 4314 << " search_cb.peer_dbaddr:" << bta_dm_search_cb.peer_bdaddr 4315 << " connected_bda=" << p_data->remote_bda.address; 4316 4317 APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d", 4318 p_data->conn_id, p_data->client_if, p_data->status); 4319 4320 bta_dm_search_cb.conn_id = p_data->conn_id; 4321 4322 if (p_data->status == GATT_SUCCESS) { 4323 btm_dm_start_disc_gatt_services(p_data->conn_id); 4324 } else { 4325 bta_dm_gatt_disc_complete(GATT_INVALID_CONN_ID, p_data->status); 4326 } 4327} 4328 4329/******************************************************************************* 4330 * 4331 * Function bta_dm_gattc_callback 4332 * 4333 * Description This is GATT client callback function used in DM. 4334 * 4335 * Parameters: 4336 * 4337 ******************************************************************************/ 4338static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { 4339 APPL_TRACE_DEBUG("bta_dm_gattc_callback event = %d", event); 4340 4341 switch (event) { 4342 case BTA_GATTC_OPEN_EVT: 4343 bta_dm_proc_open_evt(&p_data->open); 4344 break; 4345 4346 case BTA_GATTC_SEARCH_RES_EVT: 4347 bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid); 4348 break; 4349 4350 case BTA_GATTC_SEARCH_CMPL_EVT: 4351 if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) 4352 bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id, 4353 p_data->search_cmpl.status); 4354 break; 4355 4356 case BTA_GATTC_CLOSE_EVT: 4357 APPL_TRACE_DEBUG("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason); 4358 /* in case of disconnect before search is completed */ 4359 if ((bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) && 4360 (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) && 4361 p_data->close.remote_bda == bta_dm_search_cb.peer_bdaddr) { 4362 bta_dm_gatt_disc_complete((uint16_t)GATT_INVALID_CONN_ID, 4363 (tGATT_STATUS)GATT_ERROR); 4364 } 4365 break; 4366 4367 default: 4368 break; 4369 } 4370} 4371 4372#if (BLE_VND_INCLUDED == TRUE) 4373/******************************************************************************* 4374 * 4375 * Function bta_dm_ctrl_features_rd_cmpl_cback 4376 * 4377 * Description callback to handle controller feature read complete 4378 * 4379 * Parameters: 4380 * 4381 ******************************************************************************/ 4382static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result) { 4383 APPL_TRACE_DEBUG("%s status = %d ", __func__, result); 4384 if (result == BTM_SUCCESS) { 4385 if (bta_dm_cb.p_sec_cback) 4386 bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL); 4387 } else { 4388 APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d", __func__, 4389 result); 4390 } 4391} 4392#endif /* BLE_VND_INCLUDED */ 4393