1 /****************************************************************************** 2 * 3 * Copyright (C) 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 <assert.h> 29 #include <string.h> 30 31 #include "bt_target.h" 32 #include "bt_types.h" 33 #include "bta_api.h" 34 #include "bta_dm_co.h" 35 #include "bta_dm_int.h" 36 #include "bta_sys.h" 37 #include "btm_api.h" 38 #include "btm_int.h" 39 #include "btu.h" 40 #include "gap_api.h" /* For GAP_BleReadPeerPrefConnParams */ 41 #include "bt_common.h" 42 #include "l2c_api.h" 43 #include "osi/include/log.h" 44 #include "osi/include/osi.h" 45 #include "sdp_api.h" 46 #include "utl.h" 47 48 #if (GAP_INCLUDED == TRUE) 49 #include "gap_api.h" 50 #endif 51 52 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir); 53 static void bta_dm_inq_cmpl_cb (void * p_result); 54 static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, BD_NAME bd_name); 55 static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name); 56 static void bta_dm_find_services ( BD_ADDR bd_addr); 57 static void bta_dm_discover_next_device(void); 58 static void bta_dm_sdp_callback (UINT16 sdp_status); 59 static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, UINT8 *service_name, UINT8 service_id, BOOLEAN is_originator); 60 static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, BOOLEAN min_16_digit); 61 static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, LINK_KEY key, UINT8 key_type); 62 static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,BD_NAME bd_name, int result); 63 static void bta_dm_local_name_cback(BD_ADDR bd_addr); 64 static BOOLEAN bta_dm_check_av(UINT16 event); 65 static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data); 66 67 static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr); 68 69 /* Extended Inquiry Response */ 70 static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data); 71 72 static void bta_dm_set_eir (char *local_name); 73 74 static void bta_dm_eir_search_services( tBTM_INQ_RESULTS *p_result, 75 tBTA_SERVICE_MASK *p_services_to_search, 76 tBTA_SERVICE_MASK *p_services_found); 77 78 static void bta_dm_search_timer_cback(void *data); 79 static void bta_dm_disable_conn_down_timer_cback(void *data); 80 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr); 81 static void bta_dm_adjust_roles(BOOLEAN delay_role_switch); 82 static char *bta_dm_get_remname(void); 83 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result); 84 85 static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport); 86 static void bta_dm_discover_device(BD_ADDR remote_bd_addr); 87 88 static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ); 89 static void bta_dm_disable_search_and_disc(void); 90 91 #if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) 92 #if ((defined SMP_INCLUDED) && (SMP_INCLUDED == TRUE)) 93 static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data); 94 #endif 95 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key); 96 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)) 97 static void bta_dm_gattc_register(void); 98 static void btm_dm_start_gatt_discovery(BD_ADDR bd_addr); 99 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr); 100 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data); 101 extern tBTA_DM_CONTRL_STATE bta_dm_pm_obtain_controller_state(void); 102 #endif 103 104 #if BLE_VND_INCLUDED == TRUE 105 static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result); 106 #endif 107 108 #ifndef BTA_DM_BLE_ADV_CHNL_MAP 109 #define BTA_DM_BLE_ADV_CHNL_MAP (BTM_BLE_ADV_CHNL_37|BTM_BLE_ADV_CHNL_38|BTM_BLE_ADV_CHNL_39) 110 #endif 111 #endif 112 113 /* Disable timer interval (in milliseconds) */ 114 #ifndef BTA_DM_DISABLE_TIMER_MS 115 #define BTA_DM_DISABLE_TIMER_MS 5000 116 #endif 117 118 /* Disable timer retrial interval (in milliseconds) */ 119 #ifndef BTA_DM_DISABLE_TIMER_RETRIAL_MS 120 #define BTA_DM_DISABLE_TIMER_RETRIAL_MS 1500 121 #endif 122 123 /* Disable connection down timer (in milliseconds) */ 124 #ifndef BTA_DM_DISABLE_CONN_DOWN_TIMER_MS 125 #define BTA_DM_DISABLE_CONN_DOWN_TIMER_MS 1000 126 #endif 127 128 /* Switch delay timer (in milliseconds) */ 129 #ifndef BTA_DM_SWITCH_DELAY_TIMER_MS 130 #define BTA_DM_SWITCH_DELAY_TIMER_MS 500 131 #endif 132 133 static void bta_dm_reset_sec_dev_pending(BD_ADDR remote_bd_addr); 134 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr); 135 static void bta_dm_observe_results_cb(tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir); 136 static void bta_dm_observe_cmpl_cb(void * p_result); 137 static void bta_dm_delay_role_switch_cback(void *data); 138 extern void sdpu_uuid16_to_uuid128(UINT16 uuid16, UINT8* p_uuid128); 139 static void bta_dm_disable_timer_cback(void *data); 140 141 142 const UINT16 bta_service_id_to_uuid_lkup_tbl [BTA_MAX_SERVICE_ID] = 143 { 144 UUID_SERVCLASS_PNP_INFORMATION, /* Reserved */ 145 UUID_SERVCLASS_SERIAL_PORT, /* BTA_SPP_SERVICE_ID */ 146 UUID_SERVCLASS_DIALUP_NETWORKING, /* BTA_DUN_SERVICE_ID */ 147 UUID_SERVCLASS_AUDIO_SOURCE, /* BTA_A2DP_SOURCE_SERVICE_ID */ 148 UUID_SERVCLASS_LAN_ACCESS_USING_PPP, /* BTA_LAP_SERVICE_ID */ 149 UUID_SERVCLASS_HEADSET, /* BTA_HSP_HS_SERVICE_ID */ 150 UUID_SERVCLASS_HF_HANDSFREE, /* BTA_HFP_HS_SERVICE_ID */ 151 UUID_SERVCLASS_OBEX_OBJECT_PUSH, /* BTA_OPP_SERVICE_ID */ 152 UUID_SERVCLASS_OBEX_FILE_TRANSFER, /* BTA_FTP_SERVICE_ID */ 153 UUID_SERVCLASS_CORDLESS_TELEPHONY, /* BTA_CTP_SERVICE_ID */ 154 UUID_SERVCLASS_INTERCOM, /* BTA_ICP_SERVICE_ID */ 155 UUID_SERVCLASS_IRMC_SYNC, /* BTA_SYNC_SERVICE_ID */ 156 UUID_SERVCLASS_DIRECT_PRINTING, /* BTA_BPP_SERVICE_ID */ 157 UUID_SERVCLASS_IMAGING_RESPONDER, /* BTA_BIP_SERVICE_ID */ 158 UUID_SERVCLASS_PANU, /* BTA_PANU_SERVICE_ID */ 159 UUID_SERVCLASS_NAP, /* BTA_NAP_SERVICE_ID */ 160 UUID_SERVCLASS_GN, /* BTA_GN_SERVICE_ID */ 161 UUID_SERVCLASS_SAP, /* BTA_SAP_SERVICE_ID */ 162 UUID_SERVCLASS_AUDIO_SINK, /* BTA_A2DP_SERVICE_ID */ 163 UUID_SERVCLASS_AV_REMOTE_CONTROL, /* BTA_AVRCP_SERVICE_ID */ 164 UUID_SERVCLASS_HUMAN_INTERFACE, /* BTA_HID_SERVICE_ID */ 165 UUID_SERVCLASS_VIDEO_SINK, /* BTA_VDP_SERVICE_ID */ 166 UUID_SERVCLASS_PBAP_PSE, /* BTA_PBAP_SERVICE_ID */ 167 UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, /* BTA_HSP_SERVICE_ID */ 168 UUID_SERVCLASS_AG_HANDSFREE, /* BTA_HFP_SERVICE_ID */ 169 UUID_SERVCLASS_MESSAGE_ACCESS, /* BTA_MAP_SERVICE_ID */ 170 UUID_SERVCLASS_MESSAGE_NOTIFICATION, /* BTA_MN_SERVICE_ID */ 171 UUID_SERVCLASS_HDP_PROFILE, /* BTA_HDP_SERVICE_ID */ 172 UUID_SERVCLASS_PBAP_PCE /* BTA_PCE_SERVICE_ID */ 173 #if BLE_INCLUDED && BTA_GATT_INCLUDED 174 ,UUID_PROTOCOL_ATT /* BTA_GATT_SERVICE_ID */ 175 #endif 176 }; 177 178 /* 179 * NOTE : The number of element in bta_service_id_to_btm_srv_id_lkup_tbl should be matching with 180 * the value BTA_MAX_SERVICE_ID in bta_api.h 181 * 182 * i.e., If you add new Service ID for BTA, the correct security ID of the new service 183 * from Security service definitions (btm_api.h) should be added to this lookup table. 184 */ 185 const UINT32 bta_service_id_to_btm_srv_id_lkup_tbl [BTA_MAX_SERVICE_ID] = 186 { 187 0, /* Reserved */ 188 BTM_SEC_SERVICE_SERIAL_PORT, /* BTA_SPP_SERVICE_ID */ 189 BTM_SEC_SERVICE_DUN, /* BTA_DUN_SERVICE_ID */ 190 BTM_SEC_SERVICE_AVDTP, /* BTA_AUDIO_SOURCE_SERVICE_ID */ 191 BTM_SEC_SERVICE_LAN_ACCESS, /* BTA_LAP_SERVICE_ID */ 192 BTM_SEC_SERVICE_HEADSET_AG, /* BTA_HSP_SERVICE_ID */ 193 BTM_SEC_SERVICE_AG_HANDSFREE, /* BTA_HFP_SERVICE_ID */ 194 BTM_SEC_SERVICE_OBEX, /* BTA_OPP_SERVICE_ID */ 195 BTM_SEC_SERVICE_OBEX_FTP, /* BTA_FTP_SERVICE_ID */ 196 BTM_SEC_SERVICE_CORDLESS, /* BTA_CTP_SERVICE_ID */ 197 BTM_SEC_SERVICE_INTERCOM, /* BTA_ICP_SERVICE_ID */ 198 BTM_SEC_SERVICE_IRMC_SYNC, /* BTA_SYNC_SERVICE_ID */ 199 BTM_SEC_SERVICE_BPP_JOB, /* BTA_BPP_SERVICE_ID */ 200 BTM_SEC_SERVICE_BIP, /* BTA_BIP_SERVICE_ID */ 201 BTM_SEC_SERVICE_BNEP_PANU, /* BTA_PANU_SERVICE_ID */ 202 BTM_SEC_SERVICE_BNEP_NAP, /* BTA_NAP_SERVICE_ID */ 203 BTM_SEC_SERVICE_BNEP_GN, /* BTA_GN_SERVICE_ID */ 204 BTM_SEC_SERVICE_SAP, /* BTA_SAP_SERVICE_ID */ 205 BTM_SEC_SERVICE_AVDTP, /* BTA_A2DP_SERVICE_ID */ 206 BTM_SEC_SERVICE_AVCTP, /* BTA_AVRCP_SERVICE_ID */ 207 BTM_SEC_SERVICE_HIDH_SEC_CTRL, /* BTA_HID_SERVICE_ID */ 208 BTM_SEC_SERVICE_AVDTP, /* BTA_VDP_SERVICE_ID */ 209 BTM_SEC_SERVICE_PBAP, /* BTA_PBAP_SERVICE_ID */ 210 BTM_SEC_SERVICE_HEADSET, /* BTA_HSP_HS_SERVICE_ID */ 211 BTM_SEC_SERVICE_HF_HANDSFREE, /* BTA_HFP_HS_SERVICE_ID */ 212 BTM_SEC_SERVICE_MAP, /* BTA_MAP_SERVICE_ID */ 213 BTM_SEC_SERVICE_MAP, /* BTA_MN_SERVICE_ID */ 214 BTM_SEC_SERVICE_HDP_SNK, /* BTA_HDP_SERVICE_ID */ 215 BTM_SEC_SERVICE_PBAP /* BTA_PCE_SERVICE_ID */ 216 #if BLE_INCLUDED && BTA_GATT_INCLUDED 217 ,BTM_SEC_SERVICE_ATT /* BTA_GATT_SERVICE_ID */ 218 #endif 219 220 }; 221 222 /* bta security callback */ 223 const tBTM_APPL_INFO bta_security = 224 { 225 &bta_dm_authorize_cback, 226 &bta_dm_pin_cback, 227 &bta_dm_new_link_key_cback, 228 &bta_dm_authentication_complete_cback, 229 &bta_dm_bond_cancel_complete_cback, 230 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) 231 &bta_dm_sp_cback 232 #else 233 NULL 234 #endif 235 #if BLE_INCLUDED == TRUE 236 #if SMP_INCLUDED == TRUE 237 ,&bta_dm_ble_smp_cback 238 #endif 239 ,&bta_dm_ble_id_key_cback 240 #endif 241 242 }; 243 244 #define MAX_DISC_RAW_DATA_BUF (4096) 245 UINT8 g_disc_raw_data_buf[MAX_DISC_RAW_DATA_BUF]; 246 247 extern DEV_CLASS local_device_default_class; 248 extern fixed_queue_t *btu_bta_alarm_queue; 249 250 /******************************************************************************* 251 ** 252 ** Function bta_dm_enable 253 ** 254 ** Description Initialises the BT device manager 255 ** 256 ** 257 ** Returns void 258 ** 259 *******************************************************************************/ 260 void bta_dm_enable(tBTA_DM_MSG *p_data) 261 { 262 tBTA_DM_ENABLE enable_event; 263 264 /* if already in use, return an error */ 265 if( bta_dm_cb.is_bta_dm_active == TRUE ) 266 { 267 APPL_TRACE_WARNING("%s Device already started by another application", __func__); 268 memset(&enable_event, 0, sizeof(tBTA_DM_ENABLE)); 269 enable_event.status = BTA_FAILURE; 270 if (p_data->enable.p_sec_cback != NULL) 271 p_data->enable.p_sec_cback(BTA_DM_ENABLE_EVT, (tBTA_DM_SEC *)&enable_event); 272 return; 273 } 274 275 /* first, register our callback to SYS HW manager */ 276 bta_sys_hw_register( BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback ); 277 278 /* make sure security callback is saved - if no callback, do not erase the previous one, 279 it could be an error recovery mechanism */ 280 if( p_data->enable.p_sec_cback != NULL ) 281 bta_dm_cb.p_sec_cback = p_data->enable.p_sec_cback; 282 /* notify BTA DM is now active */ 283 bta_dm_cb.is_bta_dm_active = TRUE; 284 285 /* send a message to BTA SYS */ 286 tBTA_SYS_HW_MSG *sys_enable_event = 287 (tBTA_SYS_HW_MSG *)osi_malloc(sizeof(tBTA_SYS_HW_MSG)); 288 sys_enable_event->hdr.event = BTA_SYS_API_ENABLE_EVT; 289 sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH; 290 291 bta_sys_sendmsg(sys_enable_event); 292 } 293 294 /******************************************************************************* 295 ** 296 ** Function bta_dm_init_cb 297 ** 298 ** Description Initializes or re-initializes the bta_dm_cb control block 299 ** 300 ** 301 ** Returns void 302 ** 303 *******************************************************************************/ 304 void bta_dm_init_cb(void) 305 { 306 /* 307 * TODO: Should alarm_free() the bta_dm_cb timers during graceful 308 * shutdown. 309 */ 310 alarm_free(bta_dm_cb.disable_timer); 311 alarm_free(bta_dm_cb.switch_delay_timer); 312 for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) { 313 for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) { 314 alarm_free(bta_dm_cb.pm_timer[i].timer[j]); 315 } 316 } 317 memset(&bta_dm_cb, 0, sizeof(bta_dm_cb)); 318 bta_dm_cb.disable_timer = alarm_new("bta_dm.disable_timer"); 319 bta_dm_cb.switch_delay_timer = alarm_new("bta_dm.switch_delay_timer"); 320 for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) { 321 for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) { 322 bta_dm_cb.pm_timer[i].timer[j] = alarm_new("bta_dm.pm_timer"); 323 } 324 } 325 } 326 327 /******************************************************************************* 328 ** 329 ** Function bta_dm_sys_hw_cback 330 ** 331 ** Description callback register to SYS to get HW status updates 332 ** 333 ** 334 ** Returns void 335 ** 336 *******************************************************************************/ 337 static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status ) 338 { 339 DEV_CLASS dev_class; 340 tBTA_DM_SEC_CBACK *temp_cback; 341 #if BLE_INCLUDED == TRUE 342 UINT8 key_mask = 0; 343 BT_OCTET16 er; 344 tBTA_BLE_LOCAL_ID_KEYS id_key; 345 #endif 346 347 APPL_TRACE_DEBUG("%s with event: %i", __func__, status); 348 349 /* On H/W error evt, report to the registered DM application callback */ 350 if (status == BTA_SYS_HW_ERROR_EVT) { 351 if( bta_dm_cb.p_sec_cback != NULL ) 352 bta_dm_cb.p_sec_cback(BTA_DM_HW_ERROR_EVT, NULL); 353 return; 354 } 355 356 if( status == BTA_SYS_HW_OFF_EVT ) 357 { 358 if( bta_dm_cb.p_sec_cback != NULL ) 359 bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL); 360 361 /* reinitialize the control block */ 362 bta_dm_init_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 } 369 else 370 if( status == BTA_SYS_HW_ON_EVT ) 371 { 372 /* FIXME: We should not unregister as the SYS shall invoke this callback on a H/W error. 373 * We need to revisit when this platform has more than one BLuetooth H/W chip */ 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 = 393 alarm_new("bta_dm_search.search_timer"); 394 bta_dm_search_cb.gatt_close_timer = 395 alarm_new("bta_dm_search.gatt_close_timer"); 396 397 memset(&bta_dm_conn_srvcs, 0, sizeof(bta_dm_conn_srvcs)); 398 memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB)); 399 400 memcpy(dev_class, p_bta_dm_cfg->dev_class, sizeof(dev_class)); 401 BTM_SetDeviceClass (dev_class); 402 403 #if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) 404 /* load BLE local information: ID keys, ER if available */ 405 bta_dm_co_ble_load_local_keys(&key_mask, er, &id_key); 406 407 if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ER) 408 { 409 BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ER, (tBTM_BLE_LOCAL_KEYS *)&er); 410 } 411 if (key_mask & BTA_BLE_LOCAL_KEY_TYPE_ID) 412 { 413 BTM_BleLoadLocalKeys(BTA_BLE_LOCAL_KEY_TYPE_ID, (tBTM_BLE_LOCAL_KEYS *)&id_key); 414 } 415 #if (defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)) 416 bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID; 417 #endif // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED) 418 #endif // (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE)) 419 420 BTM_SecRegister((tBTM_APPL_INFO*)&bta_security); 421 BTM_SetDefaultLinkSuperTout(p_bta_dm_cfg->link_timeout); 422 BTM_WritePageTimeout(p_bta_dm_cfg->page_timeout); 423 bta_dm_cb.cur_policy = p_bta_dm_cfg->policy_settings; 424 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy); 425 BTM_RegBusyLevelNotif (bta_dm_bl_change_cback, NULL, BTM_BL_UPDATE_MASK|BTM_BL_ROLE_CHG_MASK); 426 427 #if BLE_VND_INCLUDED == TRUE 428 BTM_BleReadControllerFeatures (bta_dm_ctrl_features_rd_cmpl_cback); 429 #endif 430 431 /* Earlier, we used to invoke BTM_ReadLocalAddr which was just copying the bd_addr 432 from the control block and invoking the callback which was sending the DM_ENABLE_EVT. 433 But then we have a few HCI commands being invoked above which were still in progress 434 when the ENABLE_EVT was sent. So modified this to fetch the local name which forces 435 the DM_ENABLE_EVT to be sent only after all the init steps are complete */ 436 BTM_ReadLocalDeviceNameFromController((tBTM_CMPL_CB *)bta_dm_local_name_cback); 437 438 bta_sys_rm_register((tBTA_SYS_CONN_CBACK*)bta_dm_rm_cback); 439 440 /* initialize bluetooth low power manager */ 441 bta_dm_init_pm(); 442 443 bta_sys_policy_register((tBTA_SYS_CONN_CBACK*)bta_dm_policy_cback); 444 445 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE) 446 bta_dm_gattc_register(); 447 #endif 448 449 } 450 else 451 APPL_TRACE_DEBUG(" --- ignored event"); 452 453 } 454 455 456 /******************************************************************************* 457 ** 458 ** Function bta_dm_disable 459 ** 460 ** Description Disables the BT device manager 461 ** 462 ** 463 ** Returns void 464 ** 465 *******************************************************************************/ 466 void bta_dm_disable (tBTA_DM_MSG *p_data) 467 { 468 UNUSED(p_data); 469 470 /* Set l2cap idle timeout to 0 (so BTE immediately disconnects ACL link after last channel is closed) */ 471 L2CA_SetIdleTimeoutByBdAddr((UINT8 *)BT_BD_ANY, 0, BT_TRANSPORT_BR_EDR); 472 L2CA_SetIdleTimeoutByBdAddr((UINT8 *)BT_BD_ANY, 0, BT_TRANSPORT_LE); 473 474 /* disable all active subsystems */ 475 bta_sys_disable(BTA_SYS_HW_BLUETOOTH); 476 477 BTM_SetDiscoverability(BTM_NON_DISCOVERABLE, 0, 0); 478 BTM_SetConnectability(BTM_NON_CONNECTABLE, 0, 0); 479 480 bta_dm_disable_pm(); 481 bta_dm_disable_search_and_disc(); 482 bta_dm_cb.disabling = TRUE; 483 484 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE 485 BTM_BleClearBgConnDev(); 486 #endif 487 488 if(BTM_GetNumAclLinks()==0) 489 { 490 #if (defined(BTA_DISABLE_DELAY) && BTA_DISABLE_DELAY > 0) 491 /* If BTA_DISABLE_DELAY is defined and greater than zero, then delay the shutdown by 492 * BTA_DISABLE_DELAY milliseconds 493 */ 494 APPL_TRACE_WARNING("%s BTA_DISABLE_DELAY set to %d ms", 495 __FUNCTION__, BTA_DISABLE_DELAY); 496 alarm_set_on_queue(bta_dm_cb.disable_timer, BTA_DISABLE_DELAY, 497 bta_dm_disable_conn_down_timer_cback, NULL, 498 btu_bta_alarm_queue); 499 #else 500 bta_dm_disable_conn_down_timer_cback(NULL); 501 #endif 502 } 503 else 504 { 505 alarm_set_on_queue(bta_dm_cb.disable_timer, BTA_DM_DISABLE_TIMER_MS, 506 bta_dm_disable_timer_cback, UINT_TO_PTR(0), 507 btu_bta_alarm_queue); 508 } 509 } 510 511 /******************************************************************************* 512 ** 513 ** Function bta_dm_disable_timer_cback 514 ** 515 ** Description Called if the disable timer expires 516 ** Used to close ACL connections which are still active 517 ** 518 ** 519 ** 520 ** Returns void 521 ** 522 *******************************************************************************/ 523 static void bta_dm_disable_timer_cback(void *data) 524 { 525 UINT8 i; 526 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; 527 BOOLEAN trigger_disc = FALSE; 528 uint32_t param = PTR_TO_UINT(data); 529 530 APPL_TRACE_EVENT("%s trial %u", __func__, param); 531 532 if (BTM_GetNumAclLinks() && (param == 0)) 533 { 534 for(i=0; i<bta_dm_cb.device_list.count; i++) 535 { 536 #if (BLE_INCLUDED == TRUE) 537 transport = bta_dm_cb.device_list.peer_device[i].transport; 538 #endif 539 btm_remove_acl(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, transport); 540 trigger_disc = TRUE; 541 } 542 543 /* Retrigger disable timer in case ACL disconnect failed, DISABLE_EVT still need 544 to be sent out to avoid jave layer disable timeout */ 545 if (trigger_disc) 546 { 547 alarm_set_on_queue(bta_dm_cb.disable_timer, 548 BTA_DM_DISABLE_TIMER_RETRIAL_MS, 549 bta_dm_disable_timer_cback, UINT_TO_PTR(1), 550 btu_bta_alarm_queue); 551 } 552 } 553 else 554 { 555 bta_dm_cb.disabling = FALSE; 556 557 bta_sys_remove_uuid(UUID_SERVCLASS_PNP_INFORMATION); 558 bta_dm_cb.p_sec_cback(BTA_DM_DISABLE_EVT, NULL); 559 } 560 } 561 562 563 564 565 /******************************************************************************* 566 ** 567 ** Function bta_dm_set_dev_name 568 ** 569 ** Description Sets local device name 570 ** 571 ** 572 ** Returns void 573 ** 574 *******************************************************************************/ 575 void bta_dm_set_dev_name (tBTA_DM_MSG *p_data) 576 { 577 578 BTM_SetLocalDeviceName((char*)p_data->set_name.name); 579 bta_dm_set_eir ((char*)p_data->set_name.name); 580 } 581 582 /******************************************************************************* 583 ** 584 ** Function bta_dm_set_visibility 585 ** 586 ** Description Sets discoverability, connectability and pairability 587 ** 588 ** 589 ** Returns void 590 ** 591 *******************************************************************************/ 592 void bta_dm_set_visibility(tBTA_DM_MSG *p_data) 593 { 594 UINT16 window, interval; 595 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED) 596 UINT16 le_disc_mode = BTM_BleReadDiscoverability(); 597 UINT16 le_conn_mode = BTM_BleReadConnectability(); 598 #endif // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED) 599 UINT16 disc_mode = BTM_ReadDiscoverability(&window, &interval); 600 UINT16 conn_mode = BTM_ReadConnectability(&window, &interval); 601 602 /* set modes for Discoverability and connectability if not ignore */ 603 if (p_data->set_visibility.disc_mode != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE)) 604 { 605 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED) 606 if ((p_data->set_visibility.disc_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE) 607 p_data->set_visibility.disc_mode = 608 ((p_data->set_visibility.disc_mode & ~BTA_DM_LE_IGNORE) | le_disc_mode); 609 #endif // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED) 610 if ((p_data->set_visibility.disc_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE) 611 p_data->set_visibility.disc_mode = 612 ((p_data->set_visibility.disc_mode & ~BTA_DM_IGNORE) | disc_mode); 613 614 BTM_SetDiscoverability(p_data->set_visibility.disc_mode, 615 bta_dm_cb.inquiry_scan_window, 616 bta_dm_cb.inquiry_scan_interval); 617 } 618 619 if (p_data->set_visibility.conn_mode != (BTA_DM_IGNORE | BTA_DM_LE_IGNORE)) 620 { 621 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED) 622 if ((p_data->set_visibility.conn_mode & BTA_DM_LE_IGNORE) == BTA_DM_LE_IGNORE) 623 p_data->set_visibility.conn_mode = 624 ((p_data->set_visibility.conn_mode & ~BTA_DM_LE_IGNORE) | le_conn_mode); 625 #endif // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED) 626 if ((p_data->set_visibility.conn_mode & BTA_DM_IGNORE) == BTA_DM_IGNORE) 627 p_data->set_visibility.conn_mode = 628 ((p_data->set_visibility.conn_mode & ~BTA_DM_IGNORE) | conn_mode); 629 630 BTM_SetConnectability(p_data->set_visibility.conn_mode, 631 bta_dm_cb.page_scan_window, 632 bta_dm_cb.page_scan_interval); 633 } 634 635 /* Send False or True if not ignore */ 636 if (p_data->set_visibility.pair_mode != BTA_DM_IGNORE ) 637 { 638 639 if (p_data->set_visibility.pair_mode == BTA_DM_NON_PAIRABLE) 640 bta_dm_cb.disable_pair_mode = TRUE; 641 else 642 bta_dm_cb.disable_pair_mode = FALSE; 643 644 } 645 646 /* Send False or True if not ignore */ 647 if (p_data->set_visibility.conn_paired_only != BTA_DM_IGNORE) 648 { 649 650 if (p_data->set_visibility.conn_paired_only == BTA_DM_CONN_ALL) 651 bta_dm_cb.conn_paired_only = FALSE; 652 else 653 bta_dm_cb.conn_paired_only = TRUE; 654 655 } 656 657 /* Change mode if either mode is not ignore */ 658 if (p_data->set_visibility.pair_mode != BTA_DM_IGNORE || p_data->set_visibility.conn_paired_only != BTA_DM_IGNORE) 659 BTM_SetPairableMode((BOOLEAN)(!(bta_dm_cb.disable_pair_mode)),bta_dm_cb.conn_paired_only); 660 661 } 662 663 /******************************************************************************* 664 ** 665 ** Function bta_dm_process_remove_device 666 ** 667 ** Description Removes device, Disconnects ACL link if required. 668 **** 669 *******************************************************************************/ 670 void bta_dm_process_remove_device(BD_ADDR bd_addr) 671 { 672 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE) 673 /* need to remove all pending background connection before unpair */ 674 BTA_GATTC_CancelOpen(0, bd_addr, FALSE); 675 #endif 676 677 BTM_SecDeleteDevice(bd_addr); 678 679 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE) 680 /* remove all cached GATT information */ 681 BTA_GATTC_Refresh(bd_addr); 682 #endif 683 684 if (bta_dm_cb.p_sec_cback) 685 { 686 tBTA_DM_SEC sec_event; 687 bdcpy(sec_event.link_down.bd_addr, bd_addr); 688 /* No connection, set status to success (acl disc code not valid) */ 689 sec_event.link_down.status = HCI_SUCCESS; 690 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &sec_event); 691 } 692 } 693 694 /******************************************************************************* 695 ** 696 ** Function bta_dm_remove_device 697 ** 698 ** Description Removes device, disconnects ACL link if required. 699 **** 700 *******************************************************************************/ 701 void bta_dm_remove_device(tBTA_DM_MSG *p_data) 702 { 703 tBTA_DM_API_REMOVE_DEVICE *p_dev = &p_data->remove_dev; 704 BOOLEAN continue_delete_other_dev = FALSE; 705 if (p_dev == NULL) 706 return; 707 708 BD_ADDR other_address; 709 bdcpy(other_address, p_dev->bd_addr); 710 711 /* If ACL exists for the device in the remove_bond message*/ 712 BOOLEAN continue_delete_dev = FALSE; 713 UINT8 other_transport = BT_TRANSPORT_INVALID; 714 715 if (BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_LE) || 716 BTM_IsAclConnectionUp(p_dev->bd_addr, BT_TRANSPORT_BR_EDR)) 717 { 718 APPL_TRACE_DEBUG("%s: ACL Up count %d", __func__, bta_dm_cb.device_list.count); 719 continue_delete_dev = FALSE; 720 721 /* Take the link down first, and mark the device for removal when disconnected */ 722 for(int i=0; i < bta_dm_cb.device_list.count; i++) 723 { 724 if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_dev->bd_addr)) 725 { 726 UINT8 transport = BT_TRANSPORT_BR_EDR; 727 728 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED) 729 transport = bta_dm_cb.device_list.peer_device[i].transport; 730 #endif // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED) 731 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING; 732 btm_remove_acl(p_dev->bd_addr, transport); 733 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED) 734 APPL_TRACE_DEBUG("%s:transport = %d", __func__, 735 bta_dm_cb.device_list.peer_device[i].transport); 736 737 /* save the other transport to check if device is connected on other_transport */ 738 if(bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_LE) 739 other_transport = BT_TRANSPORT_BR_EDR; 740 else 741 other_transport = BT_TRANSPORT_LE; 742 #endif // (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED) 743 744 break; 745 } 746 } 747 } 748 else 749 { 750 continue_delete_dev = TRUE; 751 } 752 #if (defined(BTA_GATT_INCLUDED) && BTA_GATT_INCLUDED) 753 // If it is DUMO device and device is paired as different address, unpair that device 754 // if different address 755 if ((other_transport && (BTM_ReadConnectedTransportAddress(other_address, other_transport))) || 756 (!other_transport && (BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_BR_EDR) || 757 BTM_ReadConnectedTransportAddress(other_address, BT_TRANSPORT_LE)))) 758 { 759 continue_delete_other_dev = FALSE; 760 /* Take the link down first, and mark the device for removal when disconnected */ 761 for(int i=0; i < bta_dm_cb.device_list.count; i++) 762 { 763 if (!bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, other_address)) 764 { 765 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_UNPAIRING; 766 btm_remove_acl(other_address,bta_dm_cb.device_list.peer_device[i].transport); 767 break; 768 } 769 } 770 } 771 else 772 { 773 APPL_TRACE_DEBUG("%s: continue to delete the other dev ", __func__); 774 continue_delete_other_dev = TRUE; 775 } 776 #endif 777 /* Delete the device mentioned in the msg */ 778 if (continue_delete_dev) 779 bta_dm_process_remove_device(p_dev->bd_addr); 780 781 /* Delete the other paired device too */ 782 BD_ADDR dummy_bda = {0}; 783 if (continue_delete_other_dev && (bdcmp(other_address, dummy_bda) != 0)) 784 bta_dm_process_remove_device(other_address); 785 } 786 787 /******************************************************************************* 788 ** 789 ** Function bta_dm_add_device 790 ** 791 ** Description This function adds a Link Key to an security database entry. 792 ** It is normally called during host startup to restore all required information 793 ** stored in the NVRAM. 794 **** 795 *******************************************************************************/ 796 void bta_dm_add_device (tBTA_DM_MSG *p_data) 797 { 798 tBTA_DM_API_ADD_DEVICE *p_dev = &p_data->add_dev; 799 UINT8 *p_dc = NULL; 800 UINT8 *p_lc = NULL; 801 UINT32 trusted_services_mask[BTM_SEC_SERVICE_ARRAY_SIZE]; 802 UINT8 index = 0; 803 UINT8 btm_mask_index = 0; 804 805 memset (trusted_services_mask, 0, sizeof(trusted_services_mask)); 806 807 /* If not all zeros, the device class has been specified */ 808 if (p_dev->dc_known) 809 p_dc = (UINT8 *)p_dev->dc; 810 811 if (p_dev->link_key_known) 812 p_lc = (UINT8 *)p_dev->link_key; 813 814 if (p_dev->is_trusted) 815 { 816 /* covert BTA service mask to BTM mask */ 817 while (p_dev->tm && (index < BTA_MAX_SERVICE_ID)) 818 { 819 if (p_dev->tm & (UINT32)(1<<index)) 820 { 821 822 btm_mask_index = bta_service_id_to_btm_srv_id_lkup_tbl[index] / BTM_SEC_ARRAY_BITS; 823 trusted_services_mask[btm_mask_index] |= (UINT32)(1 << (bta_service_id_to_btm_srv_id_lkup_tbl[index] - (UINT32)(btm_mask_index * 32))); 824 825 p_dev->tm &= (UINT32)(~(1<<index)); 826 827 } 828 index++; 829 } 830 } 831 832 if (!BTM_SecAddDevice (p_dev->bd_addr, p_dc, p_dev->bd_name, p_dev->features, 833 trusted_services_mask, p_lc, p_dev->key_type, p_dev->io_cap, 834 p_dev->pin_length)) 835 { 836 APPL_TRACE_ERROR ("BTA_DM: Error adding device %08x%04x", 837 (p_dev->bd_addr[0]<<24)+(p_dev->bd_addr[1]<<16)+(p_dev->bd_addr[2]<<8)+p_dev->bd_addr[3], 838 (p_dev->bd_addr[4]<<8)+p_dev->bd_addr[5]); 839 } 840 } 841 842 /******************************************************************************* 843 ** 844 ** Function bta_dm_close_acl 845 ** 846 ** Description This function forces to close the connection to a remote device 847 ** and optionaly remove the device from security database if 848 ** required. 849 **** 850 *******************************************************************************/ 851 void bta_dm_close_acl(tBTA_DM_MSG *p_data) 852 { 853 tBTA_DM_API_REMOVE_ACL *p_remove_acl = &p_data->remove_acl; 854 UINT8 index; 855 856 APPL_TRACE_DEBUG("bta_dm_close_acl"); 857 858 if (BTM_IsAclConnectionUp(p_remove_acl->bd_addr, p_remove_acl->transport)) 859 { 860 for (index = 0; index < bta_dm_cb.device_list.count; index ++) 861 { 862 if (!bdcmp( bta_dm_cb.device_list.peer_device[index].peer_bdaddr, p_remove_acl->bd_addr)) 863 break; 864 } 865 if (index != bta_dm_cb.device_list.count) 866 { 867 if (p_remove_acl->remove_dev) 868 bta_dm_cb.device_list.peer_device[index].remove_dev_pending = TRUE; 869 } 870 else 871 { 872 APPL_TRACE_ERROR("unknown device, remove ACL failed"); 873 } 874 /* Disconnect the ACL link */ 875 btm_remove_acl(p_remove_acl->bd_addr, p_remove_acl->transport); 876 } 877 /* if to remove the device from security database ? do it now */ 878 else if (p_remove_acl->remove_dev) 879 { 880 if (!BTM_SecDeleteDevice(p_remove_acl->bd_addr)) 881 { 882 APPL_TRACE_ERROR("delete device from security database failed."); 883 } 884 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE) 885 /* need to remove all pending background connection if any */ 886 BTA_GATTC_CancelOpen(0, p_remove_acl->bd_addr, FALSE); 887 /* remove all cached GATT information */ 888 BTA_GATTC_Refresh(p_remove_acl->bd_addr); 889 #endif 890 } 891 /* otherwise, no action needed */ 892 893 } 894 895 /******************************************************************************* 896 ** 897 ** Function bta_dm_remove_all_acl 898 ** 899 ** Description This function forces to close all the ACL links specified by link type 900 **** 901 *******************************************************************************/ 902 void bta_dm_remove_all_acl(tBTA_DM_MSG *p_data) 903 { 904 const tBTA_DM_LINK_TYPE link_type = p_data->remove_all_acl.link_type; 905 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; 906 907 APPL_TRACE_DEBUG("%s link type = %d", __func__, link_type); 908 909 for (UINT8 i=0; i < bta_dm_cb.device_list.count; i++) 910 { 911 BD_ADDR addr = {0}; 912 bdcpy(addr, bta_dm_cb.device_list.peer_device[i].peer_bdaddr); 913 #if defined (BLE_INCLUDED) && (BLE_INCLUDED == TRUE) 914 transport = bta_dm_cb.device_list.peer_device[i].transport; 915 #endif 916 if ((link_type == BTA_DM_LINK_TYPE_ALL) || 917 ((link_type == BTA_DM_LINK_TYPE_LE) && (transport == BT_TRANSPORT_LE)) || 918 ((link_type == BTA_DM_LINK_TYPE_BR_EDR) && (transport == BT_TRANSPORT_BR_EDR))) 919 { 920 /* Disconnect the ACL link */ 921 btm_remove_acl(addr, transport); 922 } 923 } 924 } 925 926 927 /******************************************************************************* 928 ** 929 ** Function bta_dm_bond 930 ** 931 ** Description Bonds with peer device 932 ** 933 ** 934 ** Returns void 935 ** 936 *******************************************************************************/ 937 void bta_dm_bond (tBTA_DM_MSG *p_data) 938 { 939 tBTM_STATUS status; 940 tBTA_DM_SEC sec_event; 941 char *p_name; 942 943 if (p_data->bond.transport == BTA_TRANSPORT_UNKNOWN) 944 status = BTM_SecBond ( p_data->bond.bd_addr, 0, NULL, 0 ); 945 else 946 status = BTM_SecBondByTransport ( p_data->bond.bd_addr, p_data->bond.transport, 0, NULL, 0 ); 947 948 949 if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED)) 950 { 951 952 memset(&sec_event, 0, sizeof(tBTA_DM_SEC)); 953 bdcpy(sec_event.auth_cmpl.bd_addr, p_data->bond.bd_addr); 954 p_name = BTM_SecReadDevName(p_data->bond.bd_addr); 955 if (p_name != NULL) 956 { 957 memcpy(sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN-1)); 958 sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0; 959 } 960 961 /* taken care of by memset [above] 962 sec_event.auth_cmpl.key_present = FALSE; 963 sec_event.auth_cmpl.success = FALSE; 964 */ 965 sec_event.auth_cmpl.fail_reason = HCI_ERR_ILLEGAL_COMMAND; 966 if (status == BTM_SUCCESS) 967 { 968 sec_event.auth_cmpl.success = TRUE; 969 } 970 else 971 { 972 /* delete this device entry from Sec Dev DB */ 973 bta_dm_remove_sec_dev_entry(p_data->bond.bd_addr); 974 } 975 bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event); 976 } 977 978 } 979 980 /******************************************************************************* 981 ** 982 ** Function bta_dm_bond_cancel 983 ** 984 ** Description Cancels bonding with a peer device 985 ** 986 ** 987 ** Returns void 988 ** 989 *******************************************************************************/ 990 void bta_dm_bond_cancel (tBTA_DM_MSG *p_data) 991 { 992 tBTM_STATUS status; 993 tBTA_DM_SEC sec_event; 994 995 APPL_TRACE_EVENT(" bta_dm_bond_cancel "); 996 status = BTM_SecBondCancel ( p_data->bond_cancel.bd_addr ); 997 998 if (bta_dm_cb.p_sec_cback && (status != BTM_CMD_STARTED && status != BTM_SUCCESS)) 999 { 1000 sec_event.bond_cancel_cmpl.result = BTA_FAILURE; 1001 1002 bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event); 1003 } 1004 1005 } 1006 1007 /******************************************************************************* 1008 ** 1009 ** Function bta_dm_pin_reply 1010 ** 1011 ** Description Send the pin_reply to a request from BTM 1012 ** 1013 ** 1014 ** Returns void 1015 ** 1016 *******************************************************************************/ 1017 void bta_dm_pin_reply (tBTA_DM_MSG *p_data) 1018 { 1019 UINT32 trusted_mask[BTM_SEC_SERVICE_ARRAY_SIZE]; 1020 UINT32 * current_trusted_mask; 1021 1022 current_trusted_mask = BTM_ReadTrustedMask(p_data->pin_reply.bd_addr); 1023 1024 if(current_trusted_mask) 1025 { 1026 memcpy(trusted_mask, current_trusted_mask, sizeof(trusted_mask)); 1027 } 1028 else 1029 { 1030 memset(trusted_mask, 0, sizeof(trusted_mask)); 1031 } 1032 1033 if(p_data->pin_reply.accept) 1034 { 1035 1036 BTM_PINCodeReply(p_data->pin_reply.bd_addr, BTM_SUCCESS, p_data->pin_reply.pin_len, p_data->pin_reply.p_pin, trusted_mask ); 1037 } 1038 else 1039 { 1040 BTM_PINCodeReply(p_data->pin_reply.bd_addr, BTM_NOT_AUTHORIZED, 0, NULL, trusted_mask ); 1041 } 1042 1043 } 1044 1045 /******************************************************************************* 1046 ** 1047 ** Function bta_dm_policy_cback 1048 ** 1049 ** Description process the link policy changes 1050 ** 1051 ** Returns void 1052 ** 1053 *******************************************************************************/ 1054 static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr) 1055 { 1056 tBTA_DM_PEER_DEVICE *p_dev = NULL; 1057 UINT16 policy = app_id; 1058 UINT32 mask = (UINT32)(1 << id); 1059 1060 if(peer_addr) 1061 p_dev = bta_dm_find_peer_device(peer_addr); 1062 1063 APPL_TRACE_DEBUG(" bta_dm_policy_cback cmd:%d, policy:0x%x", 1064 status, policy); 1065 switch(status) 1066 { 1067 case BTA_SYS_PLCY_SET: 1068 if(!p_dev) 1069 return; 1070 /* restore the default link policy */ 1071 p_dev->link_policy |= policy; 1072 BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy)); 1073 break; 1074 1075 case BTA_SYS_PLCY_CLR: 1076 if(!p_dev) 1077 return; 1078 /* clear the policy from the default link policy */ 1079 p_dev->link_policy &= (~policy); 1080 BTM_SetLinkPolicy(p_dev->peer_bdaddr, &(p_dev->link_policy)); 1081 1082 if(policy & (HCI_ENABLE_SNIFF_MODE | HCI_ENABLE_PARK_MODE)) 1083 { 1084 /* if clearing sniff/park, wake the link */ 1085 bta_dm_pm_active(p_dev->peer_bdaddr); 1086 } 1087 break; 1088 1089 case BTA_SYS_PLCY_DEF_SET: 1090 /* want to restore/set the role switch policy */ 1091 bta_dm_cb.role_policy_mask &= ~mask; 1092 if(0 == bta_dm_cb.role_policy_mask) 1093 { 1094 /* if nobody wants to insist on the role */ 1095 bta_dm_cb.cur_policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH; 1096 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy); 1097 } 1098 break; 1099 1100 case BTA_SYS_PLCY_DEF_CLR: 1101 /* want to remove the role switch policy */ 1102 bta_dm_cb.role_policy_mask |= mask; 1103 bta_dm_cb.cur_policy &= ~HCI_ENABLE_MASTER_SLAVE_SWITCH; 1104 BTM_SetDefaultLinkPolicy(bta_dm_cb.cur_policy); 1105 break; 1106 } 1107 } 1108 1109 /******************************************************************************* 1110 ** 1111 ** Function bta_dm_confirm 1112 ** 1113 ** Description Send the user confirm request reply in response to a 1114 ** request from BTM 1115 ** 1116 ** Returns void 1117 ** 1118 *******************************************************************************/ 1119 void bta_dm_confirm(tBTA_DM_MSG *p_data) 1120 { 1121 tBTM_STATUS res = BTM_NOT_AUTHORIZED; 1122 1123 if(p_data->confirm.accept == TRUE) 1124 res = BTM_SUCCESS; 1125 BTM_ConfirmReqReply(res, p_data->confirm.bd_addr); 1126 } 1127 1128 /******************************************************************************* 1129 ** 1130 ** Function bta_dm_loc_oob 1131 ** 1132 ** Description Retrieve the OOB data from the local LM 1133 ** 1134 ** Returns void 1135 ** 1136 *******************************************************************************/ 1137 void bta_dm_loc_oob(tBTA_DM_MSG *p_data) 1138 { 1139 UNUSED(p_data); 1140 BTM_ReadLocalOobData(); 1141 } 1142 1143 /******************************************************************************* 1144 ** 1145 ** Function bta_dm_ci_io_req_act 1146 ** 1147 ** Description respond to the IO capabilities request from BTM 1148 ** 1149 ** Returns void 1150 ** 1151 *******************************************************************************/ 1152 void bta_dm_ci_io_req_act(tBTA_DM_MSG *p_data) 1153 { 1154 tBTM_AUTH_REQ auth_req = BTM_AUTH_AP_NO; 1155 if(p_data->ci_io_req.auth_req) 1156 auth_req = BTM_AUTH_AP_YES; 1157 BTM_IoCapRsp(p_data->ci_io_req.bd_addr, p_data->ci_io_req.io_cap, 1158 p_data->ci_io_req.oob_data, auth_req); 1159 } 1160 1161 /******************************************************************************* 1162 ** 1163 ** Function bta_dm_ci_rmt_oob_act 1164 ** 1165 ** Description respond to the OOB data request for the remote device from BTM 1166 ** 1167 ** 1168 ** Returns void 1169 ** 1170 *******************************************************************************/ 1171 void bta_dm_ci_rmt_oob_act(tBTA_DM_MSG *p_data) 1172 { 1173 tBTM_STATUS res = BTM_NOT_AUTHORIZED; 1174 1175 if(p_data->ci_rmt_oob.accept == TRUE) 1176 res = BTM_SUCCESS; 1177 BTM_RemoteOobDataReply(res, p_data->ci_rmt_oob.bd_addr, 1178 p_data->ci_rmt_oob.c, p_data->ci_rmt_oob.r ); 1179 } 1180 1181 /******************************************************************************* 1182 ** 1183 ** Function bta_dm_search_start 1184 ** 1185 ** Description Starts an inquiry 1186 ** 1187 ** 1188 ** Returns void 1189 ** 1190 *******************************************************************************/ 1191 void bta_dm_search_start (tBTA_DM_MSG *p_data) 1192 { 1193 tBTM_INQUIRY_CMPL result; 1194 1195 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE) 1196 size_t len = sizeof(tBT_UUID) * p_data->search.num_uuid; 1197 bta_dm_gattc_register(); 1198 #endif 1199 1200 APPL_TRACE_DEBUG("%s avoid_scatter=%d", __func__, p_bta_dm_cfg->avoid_scatter); 1201 1202 if (p_bta_dm_cfg->avoid_scatter && 1203 (p_data->search.rs_res == BTA_DM_RS_NONE) && bta_dm_check_av(BTA_DM_API_SEARCH_EVT)) 1204 { 1205 memcpy(&bta_dm_cb.search_msg, &p_data->search, sizeof(tBTA_DM_API_SEARCH)); 1206 return; 1207 } 1208 1209 BTM_ClearInqDb(NULL); 1210 /* save search params */ 1211 bta_dm_search_cb.p_search_cback = p_data->search.p_cback; 1212 bta_dm_search_cb.services = p_data->search.services; 1213 1214 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE) 1215 osi_free_and_reset((void **)&bta_dm_search_cb.p_srvc_uuid); 1216 1217 if ((bta_dm_search_cb.num_uuid = p_data->search.num_uuid) != 0 && 1218 p_data->search.p_uuid != NULL) { 1219 bta_dm_search_cb.p_srvc_uuid = (tBT_UUID *)osi_malloc(len); 1220 memcpy(bta_dm_search_cb.p_srvc_uuid, p_data->search.p_uuid, len); 1221 } 1222 #endif 1223 result.status = BTM_StartInquiry( (tBTM_INQ_PARMS*)&p_data->search.inq_params, 1224 bta_dm_inq_results_cb, 1225 (tBTM_CMPL_CB*) bta_dm_inq_cmpl_cb); 1226 1227 APPL_TRACE_EVENT("%s status=%d", __func__, result.status); 1228 if (result.status != BTM_CMD_STARTED) 1229 { 1230 result.num_resp = 0; 1231 bta_dm_inq_cmpl_cb ((void *)&result); 1232 } 1233 } 1234 1235 /******************************************************************************* 1236 ** 1237 ** Function bta_dm_search_cancel 1238 ** 1239 ** Description Cancels an ongoing search for devices 1240 ** 1241 ** 1242 ** Returns void 1243 ** 1244 *******************************************************************************/ 1245 void bta_dm_search_cancel (tBTA_DM_MSG *p_data) 1246 { 1247 UNUSED(p_data); 1248 tBTA_DM_MSG *p_msg; 1249 1250 if (BTM_IsInquiryActive()) 1251 { 1252 if (BTM_CancelInquiry() == BTM_SUCCESS) 1253 { 1254 bta_dm_search_cancel_notify(NULL); 1255 p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 1256 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1257 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 1258 bta_sys_sendmsg(p_msg); 1259 } else { 1260 /* flag a search cancel is pending */ 1261 bta_dm_search_cb.cancel_pending = TRUE; 1262 } 1263 } 1264 /* If no Service Search going on then issue cancel remote name in case it is active */ 1265 else if (!bta_dm_search_cb.name_discover_done) 1266 { 1267 BTM_CancelRemoteDeviceName(); 1268 1269 p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 1270 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1271 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 1272 bta_sys_sendmsg(p_msg); 1273 } else { 1274 p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 1275 p_msg->hdr.event = BTA_DM_INQUIRY_CMPL_EVT; 1276 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 1277 bta_sys_sendmsg(p_msg); 1278 } 1279 1280 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE 1281 if (bta_dm_search_cb.gatt_disc_active) 1282 { 1283 bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr); 1284 } 1285 #endif 1286 } 1287 1288 /******************************************************************************* 1289 ** 1290 ** Function bta_dm_discover 1291 ** 1292 ** Description Discovers services on a remote device 1293 ** 1294 ** 1295 ** Returns void 1296 ** 1297 *******************************************************************************/ 1298 void bta_dm_discover (tBTA_DM_MSG *p_data) 1299 { 1300 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE 1301 size_t len = sizeof(tBT_UUID) * p_data->discover.num_uuid; 1302 #endif 1303 APPL_TRACE_EVENT("%s services_to_search=0x%04X, sdp_search=%d", __func__, 1304 p_data->discover.services, p_data->discover.sdp_search); 1305 1306 /* save the search condition */ 1307 bta_dm_search_cb.services = p_data->discover.services; 1308 1309 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE 1310 bta_dm_gattc_register(); 1311 osi_free_and_reset((void **)&bta_dm_search_cb.p_srvc_uuid); 1312 if ((bta_dm_search_cb.num_uuid = p_data->discover.num_uuid) != 0 && 1313 p_data->discover.p_uuid != NULL) { 1314 bta_dm_search_cb.p_srvc_uuid = (tBT_UUID *)osi_malloc(len); 1315 memcpy(bta_dm_search_cb.p_srvc_uuid, p_data->discover.p_uuid, len); 1316 } 1317 bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid; 1318 #endif 1319 1320 bta_dm_search_cb.p_search_cback = p_data->discover.p_cback; 1321 bta_dm_search_cb.sdp_search = p_data->discover.sdp_search; 1322 bta_dm_search_cb.services_to_search = bta_dm_search_cb.services; 1323 bta_dm_search_cb.service_index = 0; 1324 bta_dm_search_cb.services_found = 0; 1325 bta_dm_search_cb.peer_name[0] = 0; 1326 bta_dm_search_cb.sdp_search = p_data->discover.sdp_search; 1327 bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead (p_data->discover.bd_addr); 1328 bta_dm_search_cb.transport = p_data->discover.transport; 1329 1330 bta_dm_search_cb.name_discover_done = FALSE; 1331 memcpy(&bta_dm_search_cb.uuid, &p_data->discover.uuid, sizeof(tSDP_UUID)); 1332 bta_dm_discover_device(p_data->discover.bd_addr); 1333 } 1334 1335 /******************************************************************************* 1336 ** 1337 ** Function bta_dm_di_disc_cmpl 1338 ** 1339 ** Description Sends event to application when DI discovery complete 1340 ** 1341 ** Returns void 1342 ** 1343 *******************************************************************************/ 1344 void bta_dm_di_disc_cmpl(tBTA_DM_MSG *p_data) 1345 { 1346 tBTA_DM_DI_DISC_CMPL di_disc; 1347 1348 memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL)); 1349 bdcpy(di_disc.bd_addr, bta_dm_search_cb.peer_bdaddr); 1350 1351 if((p_data->hdr.offset == SDP_SUCCESS) 1352 || (p_data->hdr.offset == SDP_DB_FULL)) 1353 { 1354 di_disc.num_record = SDP_GetNumDiRecords(bta_dm_di_cb.p_di_db); 1355 } 1356 else 1357 di_disc.result = BTA_FAILURE; 1358 1359 bta_dm_di_cb.p_di_db = NULL; 1360 bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT, (tBTA_DM_SEARCH *) &di_disc); 1361 } 1362 1363 /******************************************************************************* 1364 ** 1365 ** Function bta_dm_di_disc_callback 1366 ** 1367 ** Description This function queries a remote device for DI information. 1368 ** 1369 ** 1370 ** Returns void 1371 ** 1372 *******************************************************************************/ 1373 static void bta_dm_di_disc_callback(UINT16 result) 1374 { 1375 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 1376 1377 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1378 p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT; 1379 p_msg->hdr.offset = result; 1380 1381 bta_sys_sendmsg(p_msg); 1382 } 1383 1384 /******************************************************************************* 1385 ** 1386 ** Function bta_dm_disable_search_and_disc 1387 ** 1388 ** Description Cancels an ongoing search or discovery for devices in case of 1389 ** a Bluetooth disable 1390 ** 1391 ** 1392 ** Returns void 1393 ** 1394 *******************************************************************************/ 1395 static void bta_dm_disable_search_and_disc (void) 1396 { 1397 tBTA_DM_DI_DISC_CMPL di_disc; 1398 1399 if (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) 1400 bta_dm_search_cancel(NULL); 1401 1402 if (bta_dm_di_cb.p_di_db != NULL) 1403 { 1404 memset(&di_disc, 0, sizeof(tBTA_DM_DI_DISC_CMPL)); 1405 bdcpy(di_disc.bd_addr, bta_dm_search_cb.peer_bdaddr); 1406 di_disc.result = BTA_FAILURE; 1407 1408 bta_dm_di_cb.p_di_db = NULL; 1409 bta_dm_search_cb.p_search_cback(BTA_DM_DI_DISC_CMPL_EVT, NULL); 1410 } 1411 } 1412 1413 /******************************************************************************* 1414 ** 1415 ** Function bta_dm_di_disc 1416 ** 1417 ** Description This function queries a remote device for DI information. 1418 ** 1419 ** 1420 ** Returns void 1421 ** 1422 *******************************************************************************/ 1423 void bta_dm_di_disc (tBTA_DM_MSG *p_data) 1424 { 1425 UINT16 result = BTA_FAILURE; 1426 1427 bta_dm_search_cb.p_search_cback = p_data->di_disc.p_cback; 1428 bdcpy(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.bd_addr); 1429 bta_dm_di_cb.p_di_db = p_data->di_disc.p_sdp_db; 1430 1431 bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(BTA_DM_SDP_DB_SIZE); 1432 if (SDP_DiDiscover(bta_dm_search_cb.peer_bdaddr, p_data->di_disc.p_sdp_db, 1433 p_data->di_disc.len, 1434 bta_dm_di_disc_callback) == SDP_SUCCESS) { 1435 result = BTA_SUCCESS; 1436 } 1437 1438 if (result == BTA_FAILURE) { 1439 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 1440 1441 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1442 p_msg->hdr.layer_specific = BTA_DM_API_DI_DISCOVER_EVT; 1443 p_data->hdr.offset = result; 1444 bta_sys_sendmsg(p_msg); 1445 } 1446 } 1447 1448 /******************************************************************************* 1449 ** 1450 ** Function bta_dm_read_remote_device_name 1451 ** 1452 ** Description Initiate to get remote device name 1453 ** 1454 ** Returns TRUE if started to get remote name 1455 ** 1456 *******************************************************************************/ 1457 static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr,tBT_TRANSPORT transport) 1458 { 1459 tBTM_STATUS btm_status; 1460 1461 APPL_TRACE_DEBUG("bta_dm_read_remote_device_name"); 1462 1463 bdcpy(bta_dm_search_cb.peer_bdaddr, bd_addr); 1464 bta_dm_search_cb.peer_name[0] = 0; 1465 1466 btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr, 1467 (tBTM_CMPL_CB *) bta_dm_remname_cback, 1468 transport); 1469 1470 if ( btm_status == BTM_CMD_STARTED ) 1471 { 1472 APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is started"); 1473 1474 return (TRUE); 1475 } 1476 else if ( btm_status == BTM_BUSY ) 1477 { 1478 APPL_TRACE_DEBUG("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName is busy"); 1479 1480 /* Remote name discovery is on going now so BTM cannot notify through "bta_dm_remname_cback" */ 1481 /* adding callback to get notified that current reading remore name done */ 1482 BTM_SecAddRmtNameNotifyCallback(&bta_dm_service_search_remname_cback); 1483 1484 return (TRUE); 1485 } 1486 else 1487 { 1488 APPL_TRACE_WARNING("bta_dm_read_remote_device_name: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status); 1489 1490 return (FALSE); 1491 } 1492 } 1493 1494 /******************************************************************************* 1495 ** 1496 ** Function bta_dm_inq_cmpl 1497 ** 1498 ** Description Process the inquiry complete event from BTM 1499 ** 1500 ** Returns void 1501 ** 1502 *******************************************************************************/ 1503 void bta_dm_inq_cmpl (tBTA_DM_MSG *p_data) 1504 { 1505 tBTA_DM_SEARCH data; 1506 1507 APPL_TRACE_DEBUG("bta_dm_inq_cmpl"); 1508 1509 data.inq_cmpl.num_resps = p_data->inq_cmpl.num; 1510 bta_dm_search_cb.p_search_cback(BTA_DM_INQ_CMPL_EVT, &data); 1511 1512 if((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbFirst()) != NULL) 1513 { 1514 /* start name and service discovery from the first device on inquiry result */ 1515 bta_dm_search_cb.name_discover_done = FALSE; 1516 bta_dm_search_cb.peer_name[0] = 0; 1517 bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr); 1518 } else { 1519 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 1520 1521 /* no devices, search complete */ 1522 bta_dm_search_cb.services = 0; 1523 1524 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1525 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 1526 bta_sys_sendmsg(p_msg); 1527 } 1528 } 1529 1530 /******************************************************************************* 1531 ** 1532 ** Function bta_dm_rmt_name 1533 ** 1534 ** Description Process the remote name result from BTM 1535 ** 1536 ** Returns void 1537 ** 1538 *******************************************************************************/ 1539 void bta_dm_rmt_name (tBTA_DM_MSG *p_data) 1540 { 1541 APPL_TRACE_DEBUG("bta_dm_rmt_name"); 1542 1543 if( p_data->rem_name.result.disc_res.bd_name[0] && bta_dm_search_cb.p_btm_inq_info) 1544 { 1545 bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name = TRUE; 1546 } 1547 1548 bta_dm_discover_device(bta_dm_search_cb.peer_bdaddr); 1549 } 1550 1551 /******************************************************************************* 1552 ** 1553 ** Function bta_dm_disc_rmt_name 1554 ** 1555 ** Description Process the remote name result from BTM when application 1556 ** wants to find the name for a bdaddr 1557 ** 1558 ** Returns void 1559 ** 1560 *******************************************************************************/ 1561 void bta_dm_disc_rmt_name (tBTA_DM_MSG *p_data) 1562 { 1563 tBTM_INQ_INFO *p_btm_inq_info; 1564 1565 APPL_TRACE_DEBUG("bta_dm_disc_rmt_name"); 1566 1567 p_btm_inq_info = BTM_InqDbRead (p_data->rem_name.result.disc_res.bd_addr); 1568 if( p_btm_inq_info ) 1569 { 1570 if( p_data->rem_name.result.disc_res.bd_name[0] ) 1571 { 1572 p_btm_inq_info->appl_knows_rem_name = TRUE; 1573 } 1574 } 1575 1576 bta_dm_discover_device(p_data->rem_name.result.disc_res.bd_addr); 1577 } 1578 1579 /******************************************************************************* 1580 ** 1581 ** Function bta_dm_sdp_result 1582 ** 1583 ** Description Process the discovery result from sdp 1584 ** 1585 ** Returns void 1586 ** 1587 *******************************************************************************/ 1588 void bta_dm_sdp_result (tBTA_DM_MSG *p_data) 1589 { 1590 1591 tSDP_DISC_REC *p_sdp_rec = NULL; 1592 tBTA_DM_MSG *p_msg; 1593 BOOLEAN scn_found = FALSE; 1594 UINT16 service = 0xFFFF; 1595 tSDP_PROTOCOL_ELEM pe; 1596 1597 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE 1598 tBT_UUID *p_uuid = bta_dm_search_cb.p_srvc_uuid; 1599 tBTA_DM_SEARCH result; 1600 tBT_UUID service_uuid; 1601 #endif 1602 1603 UINT32 num_uuids = 0; 1604 UINT8 uuid_list[32][MAX_UUID_SIZE]; // assuming a max of 32 services 1605 1606 if((p_data->sdp_event.sdp_result == SDP_SUCCESS) 1607 || (p_data->sdp_event.sdp_result == SDP_NO_RECS_MATCH) 1608 || (p_data->sdp_event.sdp_result == SDP_DB_FULL)) 1609 { 1610 APPL_TRACE_DEBUG("sdp_result::0x%x", p_data->sdp_event.sdp_result); 1611 do 1612 { 1613 1614 p_sdp_rec = NULL; 1615 if( bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID+1) ) 1616 { 1617 p_sdp_rec = SDP_FindServiceUUIDInDb(bta_dm_search_cb.p_sdp_db, &bta_dm_search_cb.uuid, p_sdp_rec); 1618 1619 if (p_sdp_rec && SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) 1620 { 1621 bta_dm_search_cb.peer_scn = (UINT8) pe.params[0]; 1622 scn_found = TRUE; 1623 } 1624 } 1625 else 1626 { 1627 service = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index-1]; 1628 p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, service, p_sdp_rec); 1629 } 1630 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE 1631 /* finished with BR/EDR services, now we check the result for GATT based service UUID */ 1632 if (bta_dm_search_cb.service_index == BTA_MAX_SERVICE_ID) 1633 { 1634 if (bta_dm_search_cb.uuid_to_search != 0 && p_uuid != NULL) 1635 { 1636 p_uuid += (bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search); 1637 /* only support 16 bits UUID for now */ 1638 service = p_uuid->uu.uuid16; 1639 1640 } 1641 /* all GATT based services */ 1642 do 1643 { 1644 /* find a service record, report it */ 1645 p_sdp_rec = SDP_FindServiceInDb(bta_dm_search_cb.p_sdp_db, 1646 0, p_sdp_rec); 1647 if (p_sdp_rec) 1648 { 1649 if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) 1650 { 1651 /* send result back to app now, one by one */ 1652 bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr); 1653 strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN); 1654 result.disc_ble_res.service.len = service_uuid.len; 1655 result.disc_ble_res.service.uu.uuid16 = service_uuid.uu.uuid16; 1656 1657 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result); 1658 } 1659 } 1660 1661 if (bta_dm_search_cb.uuid_to_search > 0) 1662 break; 1663 1664 } while (p_sdp_rec); 1665 } 1666 else 1667 #endif 1668 { 1669 /* SDP_DB_FULL means some records with the 1670 required attributes were received */ 1671 if (((p_data->sdp_event.sdp_result == SDP_DB_FULL) && 1672 bta_dm_search_cb.services != BTA_ALL_SERVICE_MASK) || 1673 (p_sdp_rec != NULL)) 1674 { 1675 if (service != UUID_SERVCLASS_PNP_INFORMATION) 1676 { 1677 UINT16 tmp_svc = 0xFFFF; 1678 bta_dm_search_cb.services_found |= 1679 (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index-1)); 1680 tmp_svc = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index-1]; 1681 /* Add to the list of UUIDs */ 1682 sdpu_uuid16_to_uuid128(tmp_svc, uuid_list[num_uuids]); 1683 num_uuids++; 1684 } 1685 } 1686 } 1687 1688 if(bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK && 1689 bta_dm_search_cb.services_to_search == 0) 1690 { 1691 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE 1692 if ( bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID && 1693 bta_dm_search_cb.uuid_to_search > 0) 1694 bta_dm_search_cb.uuid_to_search --; 1695 1696 if (bta_dm_search_cb.uuid_to_search == 0 || 1697 bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID) 1698 #endif 1699 bta_dm_search_cb.service_index++; 1700 } 1701 else /* regular one service per search or PNP search */ 1702 break; 1703 1704 } while (bta_dm_search_cb.service_index <= BTA_MAX_SERVICE_ID); 1705 1706 APPL_TRACE_DEBUG("%s services_found = %04x", __FUNCTION__, 1707 bta_dm_search_cb.services_found); 1708 1709 /* Collect the 128-bit services here and put them into the list */ 1710 if(bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) 1711 { 1712 p_sdp_rec = NULL; 1713 do 1714 { 1715 tBT_UUID temp_uuid; 1716 /* find a service record, report it */ 1717 p_sdp_rec = SDP_FindServiceInDb_128bit(bta_dm_search_cb.p_sdp_db, p_sdp_rec); 1718 if (p_sdp_rec) 1719 { 1720 if (SDP_FindServiceUUIDInRec_128bit(p_sdp_rec, &temp_uuid)) 1721 { 1722 memcpy(uuid_list[num_uuids], temp_uuid.uu.uuid128, MAX_UUID_SIZE); 1723 num_uuids++; 1724 } 1725 } 1726 } while (p_sdp_rec); 1727 } 1728 /* if there are more services to search for */ 1729 if(bta_dm_search_cb.services_to_search) 1730 { 1731 /* Free up the p_sdp_db before checking the next one */ 1732 bta_dm_free_sdp_db(NULL); 1733 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr); 1734 } 1735 else 1736 { 1737 /* callbacks */ 1738 /* start next bd_addr if necessary */ 1739 1740 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback); 1741 1742 p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 1743 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT; 1744 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS; 1745 p_msg->disc_result.result.disc_res.p_raw_data = NULL; 1746 p_msg->disc_result.result.disc_res.raw_data_size = 0; 1747 p_msg->disc_result.result.disc_res.num_uuids = num_uuids; 1748 p_msg->disc_result.result.disc_res.p_uuid_list = NULL; 1749 if (num_uuids > 0) { 1750 p_msg->disc_result.result.disc_res.p_uuid_list = 1751 (UINT8 *)osi_malloc(num_uuids * MAX_UUID_SIZE); 1752 memcpy(p_msg->disc_result.result.disc_res.p_uuid_list, 1753 uuid_list, num_uuids * MAX_UUID_SIZE); 1754 } 1755 // Copy the raw_data to the discovery result structure 1756 if (bta_dm_search_cb.p_sdp_db != NULL && 1757 bta_dm_search_cb.p_sdp_db->raw_used != 0 && 1758 bta_dm_search_cb.p_sdp_db->raw_data != NULL) { 1759 APPL_TRACE_DEBUG("%s raw_data used = 0x%x raw_data_ptr = 0x%x", 1760 __func__, 1761 bta_dm_search_cb.p_sdp_db->raw_used, 1762 bta_dm_search_cb.p_sdp_db->raw_data); 1763 1764 p_msg->disc_result.result.disc_res.p_raw_data = 1765 osi_malloc(bta_dm_search_cb.p_sdp_db->raw_used); 1766 memcpy(p_msg->disc_result.result.disc_res.p_raw_data, 1767 bta_dm_search_cb.p_sdp_db->raw_data, 1768 bta_dm_search_cb.p_sdp_db->raw_used); 1769 1770 p_msg->disc_result.result.disc_res.raw_data_size = 1771 bta_dm_search_cb.p_sdp_db->raw_used; 1772 1773 bta_dm_search_cb.p_sdp_db->raw_data = NULL; //no need to free this - it is a global assigned. 1774 bta_dm_search_cb.p_sdp_db->raw_used = 0; 1775 bta_dm_search_cb.p_sdp_db->raw_size = 0; 1776 } else { 1777 APPL_TRACE_DEBUG("%s raw data size is 0 or raw_data is null!!", 1778 __func__); 1779 } 1780 /* Done with p_sdp_db. Free it */ 1781 bta_dm_free_sdp_db(NULL); 1782 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found; 1783 1784 // Piggy back the SCN over result field 1785 if (scn_found) { 1786 p_msg->disc_result.result.disc_res.result = (3 + bta_dm_search_cb.peer_scn); 1787 p_msg->disc_result.result.disc_res.services |= BTA_USER_SERVICE_MASK; 1788 1789 APPL_TRACE_EVENT(" Piggy back the SCN over result field SCN=%d", bta_dm_search_cb.peer_scn); 1790 1791 } 1792 bdcpy(p_msg->disc_result.result.disc_res.bd_addr, 1793 bta_dm_search_cb.peer_bdaddr); 1794 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name, 1795 bta_dm_get_remname(), BD_NAME_LEN); 1796 1797 bta_sys_sendmsg(p_msg); 1798 } 1799 } else { 1800 /* conn failed. No need for timer */ 1801 if(p_data->sdp_event.sdp_result == SDP_CONN_FAILED || p_data->sdp_event.sdp_result == SDP_CONN_REJECTED 1802 || p_data->sdp_event.sdp_result == SDP_SECURITY_ERR) 1803 bta_dm_search_cb.wait_disc = FALSE; 1804 1805 /* not able to connect go to next device */ 1806 if (bta_dm_search_cb.p_sdp_db) 1807 osi_free_and_reset((void **)&bta_dm_search_cb.p_sdp_db); 1808 1809 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback); 1810 1811 p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 1812 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT; 1813 p_msg->disc_result.result.disc_res.result = BTA_FAILURE; 1814 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found; 1815 bdcpy(p_msg->disc_result.result.disc_res.bd_addr, 1816 bta_dm_search_cb.peer_bdaddr); 1817 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name, 1818 bta_dm_get_remname(), BD_NAME_LEN); 1819 1820 bta_sys_sendmsg(p_msg); 1821 } 1822 } 1823 1824 /******************************************************************************* 1825 ** 1826 ** Function bta_dm_search_cmpl 1827 ** 1828 ** Description Sends event to application 1829 ** 1830 ** Returns void 1831 ** 1832 *******************************************************************************/ 1833 void bta_dm_search_cmpl(tBTA_DM_MSG *p_data) 1834 { 1835 APPL_TRACE_EVENT("%s", __func__); 1836 1837 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE) 1838 osi_free_and_reset((void **)&bta_dm_search_cb.p_srvc_uuid); 1839 #endif 1840 1841 if (p_data->hdr.layer_specific == BTA_DM_API_DI_DISCOVER_EVT) 1842 bta_dm_di_disc_cmpl(p_data); 1843 else 1844 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_CMPL_EVT, NULL); 1845 } 1846 1847 /******************************************************************************* 1848 ** 1849 ** Function bta_dm_disc_result 1850 ** 1851 ** Description Service discovery result when discovering services on a device 1852 ** 1853 ** Returns void 1854 ** 1855 *******************************************************************************/ 1856 void bta_dm_disc_result (tBTA_DM_MSG *p_data) 1857 { 1858 APPL_TRACE_EVENT("%s", __func__); 1859 1860 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE 1861 /* if any BR/EDR service discovery has been done, report the event */ 1862 if ((bta_dm_search_cb.services & ((BTA_ALL_SERVICE_MASK | BTA_USER_SERVICE_MASK ) & ~BTA_BLE_SERVICE_MASK))) 1863 #endif 1864 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result); 1865 1866 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 1867 1868 /* send a message to change state */ 1869 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 1870 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 1871 bta_sys_sendmsg(p_msg); 1872 } 1873 1874 /******************************************************************************* 1875 ** 1876 ** Function bta_dm_search_result 1877 ** 1878 ** Description Service discovery result while searching for devices 1879 ** 1880 ** Returns void 1881 ** 1882 *******************************************************************************/ 1883 void bta_dm_search_result (tBTA_DM_MSG *p_data) 1884 { 1885 APPL_TRACE_DEBUG("%s searching:0x%04x, result:0x%04x", __func__, 1886 bta_dm_search_cb.services, 1887 p_data->disc_result.result.disc_res.services); 1888 1889 /* call back if application wants name discovery or found services that application is searching */ 1890 if (( !bta_dm_search_cb.services ) 1891 ||(( bta_dm_search_cb.services ) && ( p_data->disc_result.result.disc_res.services ))) 1892 { 1893 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result); 1894 } 1895 1896 /* if searching did not initiate to create link */ 1897 if(!bta_dm_search_cb.wait_disc ) 1898 { 1899 /* if service searching is done with EIR, don't search next device */ 1900 if( bta_dm_search_cb.p_btm_inq_info ) 1901 bta_dm_discover_next_device(); 1902 } 1903 else 1904 { 1905 /* wait until link is disconnected or timeout */ 1906 bta_dm_search_cb.sdp_results = TRUE; 1907 alarm_set_on_queue(bta_dm_search_cb.search_timer, 1908 1000 * (L2CAP_LINK_INACTIVITY_TOUT + 1), 1909 bta_dm_search_timer_cback, NULL, 1910 btu_bta_alarm_queue); 1911 } 1912 } 1913 1914 /******************************************************************************* 1915 ** 1916 ** Function bta_dm_search_timer_cback 1917 ** 1918 ** Description Called when ACL disconnect time is over 1919 ** 1920 ** 1921 ** Returns void 1922 ** 1923 *******************************************************************************/ 1924 static void bta_dm_search_timer_cback(UNUSED_ATTR void *data) 1925 { 1926 APPL_TRACE_EVENT("%s", __func__); 1927 bta_dm_search_cb.wait_disc = FALSE; 1928 1929 /* proceed with next device */ 1930 bta_dm_discover_next_device(); 1931 1932 } 1933 1934 1935 /******************************************************************************* 1936 ** 1937 ** Function bta_dm_free_sdp_db 1938 ** 1939 ** Description Frees SDP data base 1940 ** 1941 ** Returns void 1942 ** 1943 *******************************************************************************/ 1944 void bta_dm_free_sdp_db (tBTA_DM_MSG *p_data) 1945 { 1946 UNUSED(p_data); 1947 osi_free_and_reset((void **)&bta_dm_search_cb.p_sdp_db); 1948 } 1949 1950 /******************************************************************************* 1951 ** 1952 ** Function bta_dm_queue_search 1953 ** 1954 ** Description Queues search command while search is being cancelled 1955 ** 1956 ** Returns void 1957 ** 1958 *******************************************************************************/ 1959 void bta_dm_queue_search(tBTA_DM_MSG *p_data) 1960 { 1961 osi_free(bta_dm_search_cb.p_search_queue); 1962 bta_dm_search_cb.p_search_queue = 1963 (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_SEARCH)); 1964 memcpy(bta_dm_search_cb.p_search_queue, p_data, 1965 sizeof(tBTA_DM_API_SEARCH)); 1966 } 1967 1968 /******************************************************************************* 1969 ** 1970 ** Function bta_dm_queue_disc 1971 ** 1972 ** Description Queues discovery command while search is being cancelled 1973 ** 1974 ** Returns void 1975 ** 1976 *******************************************************************************/ 1977 void bta_dm_queue_disc(tBTA_DM_MSG *p_data) 1978 { 1979 osi_free(bta_dm_search_cb.p_search_queue); 1980 bta_dm_search_cb.p_search_queue = 1981 (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_API_DISCOVER)); 1982 memcpy(bta_dm_search_cb.p_search_queue, p_data, 1983 sizeof(tBTA_DM_API_DISCOVER)); 1984 } 1985 1986 /******************************************************************************* 1987 ** 1988 ** Function bta_dm_search_clear_queue 1989 ** 1990 ** Description Clears the queue if API search cancel is called 1991 ** 1992 ** Returns void 1993 ** 1994 *******************************************************************************/ 1995 void bta_dm_search_clear_queue(tBTA_DM_MSG *p_data) 1996 { 1997 UNUSED(p_data); 1998 osi_free_and_reset((void **)&bta_dm_search_cb.p_search_queue); 1999 } 2000 2001 /******************************************************************************* 2002 ** 2003 ** Function bta_dm_search_cancel_cmpl 2004 ** 2005 ** Description Search cancel is complete 2006 ** 2007 ** Returns void 2008 ** 2009 *******************************************************************************/ 2010 void bta_dm_search_cancel_cmpl (tBTA_DM_MSG *p_data) 2011 { 2012 UNUSED(p_data); 2013 if(bta_dm_search_cb.p_search_queue) 2014 { 2015 bta_sys_sendmsg(bta_dm_search_cb.p_search_queue); 2016 bta_dm_search_cb.p_search_queue = NULL; 2017 } 2018 2019 } 2020 2021 /******************************************************************************* 2022 ** 2023 ** Function bta_dm_search_cancel_transac_cmpl 2024 ** 2025 ** Description Current Service Discovery or remote name procedure is 2026 ** completed after search cancellation 2027 ** 2028 ** Returns void 2029 ** 2030 *******************************************************************************/ 2031 void bta_dm_search_cancel_transac_cmpl(tBTA_DM_MSG *p_data) 2032 { 2033 UNUSED(p_data); 2034 2035 osi_free_and_reset((void **)&bta_dm_search_cb.p_sdp_db); 2036 bta_dm_search_cancel_notify(NULL); 2037 } 2038 2039 2040 /******************************************************************************* 2041 ** 2042 ** Function bta_dm_search_cancel_notify 2043 ** 2044 ** Description Notify application that search has been cancelled 2045 ** 2046 ** Returns void 2047 ** 2048 *******************************************************************************/ 2049 void bta_dm_search_cancel_notify (tBTA_DM_MSG *p_data) 2050 { 2051 UNUSED(p_data); 2052 if (bta_dm_search_cb.p_search_cback) 2053 { 2054 bta_dm_search_cb.p_search_cback(BTA_DM_SEARCH_CANCEL_CMPL_EVT, NULL); 2055 } 2056 if (!bta_dm_search_cb.name_discover_done) 2057 { 2058 BTM_CancelRemoteDeviceName(); 2059 } 2060 #if (BLE_INCLUDED == TRUE) && (BTA_GATT_INCLUDED == TRUE) 2061 if (bta_dm_search_cb.gatt_disc_active) 2062 { 2063 bta_dm_cancel_gatt_discovery(bta_dm_search_cb.peer_bdaddr); 2064 } 2065 #endif 2066 2067 } 2068 2069 /******************************************************************************* 2070 ** 2071 ** Function bta_dm_find_services 2072 ** 2073 ** Description Starts discovery on a device 2074 ** 2075 ** Returns void 2076 ** 2077 *******************************************************************************/ 2078 static void bta_dm_find_services ( BD_ADDR bd_addr) 2079 { 2080 2081 tSDP_UUID uuid; 2082 2083 memset(&uuid, 0, sizeof(tSDP_UUID)); 2084 2085 while(bta_dm_search_cb.service_index < BTA_MAX_SERVICE_ID) 2086 { 2087 if( bta_dm_search_cb.services_to_search 2088 & (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index))) 2089 { 2090 bta_dm_search_cb.p_sdp_db = (tSDP_DISCOVERY_DB *)osi_malloc(BTA_DM_SDP_DB_SIZE); 2091 APPL_TRACE_DEBUG("bta_dm_search_cb.services = %04x***********", bta_dm_search_cb.services); 2092 /* try to search all services by search based on L2CAP UUID */ 2093 if (bta_dm_search_cb.services == BTA_ALL_SERVICE_MASK) { 2094 LOG_INFO(LOG_TAG, "%s services_to_search=%08x", __func__, 2095 bta_dm_search_cb.services_to_search); 2096 if (bta_dm_search_cb.services_to_search & BTA_RES_SERVICE_MASK) { 2097 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[0]; 2098 bta_dm_search_cb.services_to_search &= ~BTA_RES_SERVICE_MASK; 2099 } else { 2100 uuid.uu.uuid16 = UUID_PROTOCOL_L2CAP; 2101 bta_dm_search_cb.services_to_search = 0; 2102 } 2103 } else { 2104 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE 2105 /* for LE only profile */ 2106 if (bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID) { 2107 if (bta_dm_search_cb.uuid_to_search > 0 && 2108 bta_dm_search_cb.p_srvc_uuid) { 2109 memcpy(&uuid, 2110 (const void *)(bta_dm_search_cb.p_srvc_uuid + 2111 bta_dm_search_cb.num_uuid - 2112 bta_dm_search_cb.uuid_to_search), 2113 sizeof(tBT_UUID)); 2114 2115 bta_dm_search_cb.uuid_to_search--; 2116 } else { 2117 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index]; 2118 } 2119 2120 /* last one? clear the BLE service bit if all discovery has been done */ 2121 if (bta_dm_search_cb.uuid_to_search == 0) 2122 bta_dm_search_cb.services_to_search &= 2123 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index))); 2124 2125 } else 2126 #endif 2127 { 2128 /* remove the service from services to be searched */ 2129 bta_dm_search_cb.services_to_search &= 2130 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(bta_dm_search_cb.service_index))); 2131 uuid.uu.uuid16 = bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index]; 2132 } 2133 } 2134 2135 if (uuid.len == 0) 2136 uuid.len = LEN_UUID_16; 2137 2138 if (bta_dm_search_cb.service_index == BTA_USER_SERVICE_ID) { 2139 memcpy(&uuid, &bta_dm_search_cb.uuid, sizeof(tSDP_UUID)); 2140 } 2141 2142 LOG_INFO(LOG_TAG, "%s search UUID = %04x", __func__, 2143 uuid.uu.uuid16); 2144 SDP_InitDiscoveryDb(bta_dm_search_cb.p_sdp_db, BTA_DM_SDP_DB_SIZE, 2145 1, &uuid, 0, NULL); 2146 2147 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf)); 2148 bta_dm_search_cb.p_sdp_db->raw_data = g_disc_raw_data_buf; 2149 2150 bta_dm_search_cb.p_sdp_db->raw_size = MAX_DISC_RAW_DATA_BUF; 2151 2152 if (!SDP_ServiceSearchAttributeRequest(bd_addr, bta_dm_search_cb.p_sdp_db, &bta_dm_sdp_callback)) { 2153 /* 2154 * If discovery is not successful with this device, then 2155 * proceed with the next one. 2156 */ 2157 osi_free_and_reset((void **)&bta_dm_search_cb.p_sdp_db); 2158 bta_dm_search_cb.service_index = BTA_MAX_SERVICE_ID; 2159 2160 } else { 2161 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE 2162 if ((bta_dm_search_cb.service_index == BTA_BLE_SERVICE_ID && 2163 bta_dm_search_cb.uuid_to_search == 0) || 2164 bta_dm_search_cb.service_index != BTA_BLE_SERVICE_ID) 2165 #endif 2166 bta_dm_search_cb.service_index++; 2167 return; 2168 } 2169 } 2170 2171 bta_dm_search_cb.service_index++; 2172 } 2173 2174 /* no more services to be discovered */ 2175 if (bta_dm_search_cb.service_index >= BTA_MAX_SERVICE_ID) { 2176 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 2177 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT; 2178 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found; 2179 bdcpy(p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr); 2180 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name, 2181 bta_dm_get_remname(), BD_NAME_LEN); 2182 2183 bta_sys_sendmsg(p_msg); 2184 } 2185 } 2186 2187 /******************************************************************************* 2188 ** 2189 ** Function bta_dm_discover_next_device 2190 ** 2191 ** Description Starts discovery on the next device in Inquiry data base 2192 ** 2193 ** Returns void 2194 ** 2195 *******************************************************************************/ 2196 static void bta_dm_discover_next_device(void) 2197 { 2198 APPL_TRACE_DEBUG("bta_dm_discover_next_device"); 2199 2200 /* searching next device on inquiry result */ 2201 if((bta_dm_search_cb.p_btm_inq_info = BTM_InqDbNext(bta_dm_search_cb.p_btm_inq_info)) != NULL) { 2202 bta_dm_search_cb.name_discover_done = FALSE; 2203 bta_dm_search_cb.peer_name[0] = 0; 2204 bta_dm_discover_device(bta_dm_search_cb.p_btm_inq_info->results.remote_bd_addr); 2205 } else { 2206 tBTA_DM_MSG *p_msg = 2207 (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 2208 2209 /* no devices, search complete */ 2210 bta_dm_search_cb.services = 0; 2211 2212 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 2213 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 2214 2215 bta_sys_sendmsg(p_msg); 2216 } 2217 } 2218 2219 /******************************************************************************* 2220 ** 2221 ** Function bta_dm_discover_device 2222 ** 2223 ** Description Starts name and service discovery on the device 2224 ** 2225 ** Returns void 2226 ** 2227 *******************************************************************************/ 2228 static void bta_dm_discover_device(BD_ADDR remote_bd_addr) 2229 { 2230 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR; 2231 2232 #if BLE_INCLUDED == TRUE 2233 if (bta_dm_search_cb.transport == BTA_TRANSPORT_UNKNOWN) 2234 { 2235 tBT_DEVICE_TYPE dev_type; 2236 tBLE_ADDR_TYPE addr_type; 2237 2238 BTM_ReadDevInfo(remote_bd_addr, &dev_type, &addr_type); 2239 if (dev_type == BT_DEVICE_TYPE_BLE || addr_type == BLE_ADDR_RANDOM) 2240 transport = BT_TRANSPORT_LE; 2241 } else { 2242 transport = bta_dm_search_cb.transport; 2243 } 2244 #endif 2245 2246 /* Reset transport state for next discovery */ 2247 bta_dm_search_cb.transport = BTA_TRANSPORT_UNKNOWN; 2248 2249 APPL_TRACE_DEBUG("%s BDA:0x%02X%02X%02X%02X%02X%02X", __func__, 2250 remote_bd_addr[0],remote_bd_addr[1], 2251 remote_bd_addr[2],remote_bd_addr[3], 2252 remote_bd_addr[4],remote_bd_addr[5]); 2253 2254 bdcpy(bta_dm_search_cb.peer_bdaddr, remote_bd_addr); 2255 2256 APPL_TRACE_DEBUG("%s name_discover_done = %d p_btm_inq_info 0x%x state = %d, transport=%d", 2257 __func__, 2258 bta_dm_search_cb.name_discover_done, 2259 bta_dm_search_cb.p_btm_inq_info, 2260 bta_dm_search_cb.state, 2261 transport); 2262 2263 if (bta_dm_search_cb.p_btm_inq_info) 2264 { 2265 APPL_TRACE_DEBUG("%s appl_knows_rem_name %d", __func__, 2266 bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name); 2267 } 2268 #if (defined(BLE_INCLUDED) && BLE_INCLUDED == TRUE) 2269 if((bta_dm_search_cb.p_btm_inq_info) 2270 && (bta_dm_search_cb.p_btm_inq_info->results.device_type == BT_DEVICE_TYPE_BLE) 2271 && (bta_dm_search_cb.state == BTA_DM_SEARCH_ACTIVE)) 2272 { 2273 /* Do not perform RNR for LE devices at inquiry complete*/ 2274 bta_dm_search_cb.name_discover_done = TRUE; 2275 } 2276 #endif 2277 /* if name discovery is not done and application needs remote name */ 2278 if ((!bta_dm_search_cb.name_discover_done) 2279 && (( bta_dm_search_cb.p_btm_inq_info == NULL ) 2280 ||(bta_dm_search_cb.p_btm_inq_info && (!bta_dm_search_cb.p_btm_inq_info->appl_knows_rem_name)))) 2281 { 2282 if (bta_dm_read_remote_device_name(bta_dm_search_cb.peer_bdaddr, transport) == TRUE) 2283 return; 2284 2285 /* starting name discovery failed */ 2286 bta_dm_search_cb.name_discover_done = TRUE; 2287 } 2288 2289 /* if application wants to discover service */ 2290 if ( bta_dm_search_cb.services ) 2291 { 2292 /* initialize variables */ 2293 bta_dm_search_cb.service_index = 0; 2294 bta_dm_search_cb.services_found = 0; 2295 bta_dm_search_cb.services_to_search = bta_dm_search_cb.services; 2296 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE 2297 bta_dm_search_cb.uuid_to_search = bta_dm_search_cb.num_uuid; 2298 #endif 2299 if ((bta_dm_search_cb.p_btm_inq_info != NULL) && 2300 bta_dm_search_cb.services != BTA_USER_SERVICE_MASK 2301 &&(bta_dm_search_cb.sdp_search == FALSE)) 2302 { 2303 /* check if EIR provides the information of supported services */ 2304 bta_dm_eir_search_services( &bta_dm_search_cb.p_btm_inq_info->results, 2305 &bta_dm_search_cb.services_to_search, 2306 &bta_dm_search_cb.services_found ); 2307 } 2308 2309 /* if seaching with EIR is not completed */ 2310 if(bta_dm_search_cb.services_to_search) 2311 { 2312 /* check whether connection already exists to the device 2313 if connection exists, we don't have to wait for ACL 2314 link to go down to start search on next device */ 2315 if (BTM_IsAclConnectionUp(bta_dm_search_cb.peer_bdaddr, BT_TRANSPORT_BR_EDR)) 2316 bta_dm_search_cb.wait_disc = FALSE; 2317 else 2318 bta_dm_search_cb.wait_disc = TRUE; 2319 2320 #if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)) 2321 if ( bta_dm_search_cb.p_btm_inq_info ) 2322 { 2323 APPL_TRACE_DEBUG("%s p_btm_inq_info 0x%x results.device_type 0x%x services_to_search 0x%x", 2324 __func__, 2325 bta_dm_search_cb.p_btm_inq_info, 2326 bta_dm_search_cb.p_btm_inq_info->results.device_type, 2327 bta_dm_search_cb.services_to_search); 2328 } 2329 2330 if (transport == BT_TRANSPORT_LE) 2331 { 2332 if (bta_dm_search_cb.services_to_search & BTA_BLE_SERVICE_MASK) 2333 { 2334 //set the raw data buffer here 2335 memset(g_disc_raw_data_buf, 0, sizeof(g_disc_raw_data_buf)); 2336 bta_dm_search_cb.p_ble_rawdata = g_disc_raw_data_buf; 2337 2338 bta_dm_search_cb.ble_raw_size = MAX_DISC_RAW_DATA_BUF; 2339 bta_dm_search_cb.ble_raw_used = 0; 2340 2341 /* start GATT for service discovery */ 2342 btm_dm_start_gatt_discovery(bta_dm_search_cb.peer_bdaddr); 2343 return; 2344 } 2345 } 2346 else 2347 #endif 2348 { 2349 bta_dm_search_cb.sdp_results = FALSE; 2350 bta_dm_find_services(bta_dm_search_cb.peer_bdaddr); 2351 return; 2352 } 2353 } 2354 } 2355 2356 /* name discovery and service discovery are done for this device */ 2357 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 2358 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT; 2359 /* initialize the data structure - includes p_raw_data and raw_data_size */ 2360 memset(&(p_msg->disc_result.result), 0, sizeof(tBTA_DM_DISC_RES)); 2361 p_msg->disc_result.result.disc_res.result = BTA_SUCCESS; 2362 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found; 2363 bdcpy(p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr); 2364 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name, 2365 (char*)bta_dm_search_cb.peer_name, BD_NAME_LEN); 2366 2367 bta_sys_sendmsg(p_msg); 2368 } 2369 2370 /******************************************************************************* 2371 ** 2372 ** Function bta_dm_sdp_callback 2373 ** 2374 ** Description Callback from sdp with discovery status 2375 ** 2376 ** Returns void 2377 ** 2378 *******************************************************************************/ 2379 static void bta_dm_sdp_callback (UINT16 sdp_status) 2380 { 2381 2382 tBTA_DM_SDP_RESULT *p_msg = 2383 (tBTA_DM_SDP_RESULT *)osi_malloc(sizeof(tBTA_DM_SDP_RESULT)); 2384 2385 p_msg->hdr.event = BTA_DM_SDP_RESULT_EVT; 2386 p_msg->sdp_result = sdp_status; 2387 2388 bta_sys_sendmsg(p_msg); 2389 } 2390 2391 /******************************************************************************* 2392 ** 2393 ** Function bta_dm_inq_results_cb 2394 ** 2395 ** Description Inquiry results callback from BTM 2396 ** 2397 ** Returns void 2398 ** 2399 *******************************************************************************/ 2400 static void bta_dm_inq_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir) 2401 { 2402 2403 tBTA_DM_SEARCH result; 2404 tBTM_INQ_INFO *p_inq_info; 2405 UINT16 service_class; 2406 2407 bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr); 2408 memcpy(result.inq_res.dev_class, p_inq->dev_class, DEV_CLASS_LEN); 2409 BTM_COD_SERVICE_CLASS(service_class, p_inq->dev_class); 2410 result.inq_res.is_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER)?TRUE:FALSE; 2411 result.inq_res.rssi = p_inq->rssi; 2412 2413 #if (BLE_INCLUDED == TRUE) 2414 result.inq_res.ble_addr_type = p_inq->ble_addr_type; 2415 result.inq_res.inq_result_type = p_inq->inq_result_type; 2416 result.inq_res.device_type = p_inq->device_type; 2417 result.inq_res.flag = p_inq->flag; 2418 #endif 2419 2420 /* application will parse EIR to find out remote device name */ 2421 result.inq_res.p_eir = p_eir; 2422 2423 if((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL) 2424 { 2425 /* initialize remt_name_not_required to FALSE so that we get the name by default */ 2426 result.inq_res.remt_name_not_required = FALSE; 2427 2428 } 2429 2430 if(bta_dm_search_cb.p_search_cback) 2431 bta_dm_search_cb.p_search_cback(BTA_DM_INQ_RES_EVT, &result); 2432 2433 if(p_inq_info) 2434 { 2435 /* application indicates if it knows the remote name, inside the callback 2436 copy that to the inquiry data base*/ 2437 if(result.inq_res.remt_name_not_required) 2438 p_inq_info->appl_knows_rem_name = TRUE; 2439 2440 } 2441 2442 2443 } 2444 2445 2446 /******************************************************************************* 2447 ** 2448 ** Function bta_dm_inq_cmpl_cb 2449 ** 2450 ** Description Inquiry complete callback from BTM 2451 ** 2452 ** Returns void 2453 ** 2454 *******************************************************************************/ 2455 static void bta_dm_inq_cmpl_cb (void * p_result) 2456 { 2457 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 2458 2459 APPL_TRACE_DEBUG("%s", __func__); 2460 2461 if (bta_dm_search_cb.cancel_pending == FALSE) { 2462 p_msg->inq_cmpl.hdr.event = BTA_DM_INQUIRY_CMPL_EVT; 2463 p_msg->inq_cmpl.num = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp; 2464 } else { 2465 bta_dm_search_cb.cancel_pending = FALSE; 2466 bta_dm_search_cancel_notify(NULL); 2467 p_msg->hdr.event = BTA_DM_SEARCH_CMPL_EVT; 2468 p_msg->hdr.layer_specific = BTA_DM_API_DISCOVER_EVT; 2469 } 2470 2471 bta_sys_sendmsg(p_msg); 2472 } 2473 2474 /******************************************************************************* 2475 ** 2476 ** Function bta_dm_service_search_remname_cback 2477 ** 2478 ** Description Remote name call back from BTM during service discovery 2479 ** 2480 ** Returns void 2481 ** 2482 *******************************************************************************/ 2483 static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc, BD_NAME bd_name) 2484 { 2485 tBTM_REMOTE_DEV_NAME rem_name; 2486 tBTM_STATUS btm_status; 2487 UNUSED(dc); 2488 2489 APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback name=<%s>", bd_name); 2490 2491 /* if this is what we are looking for */ 2492 if (!bdcmp( bta_dm_search_cb.peer_bdaddr, bd_addr)) 2493 { 2494 rem_name.length = strlen((char*)bd_name); 2495 if (rem_name.length > (BD_NAME_LEN-1)) 2496 { 2497 rem_name.length = (BD_NAME_LEN-1); 2498 rem_name.remote_bd_name[(BD_NAME_LEN-1)] = 0; 2499 } 2500 strlcpy((char*)rem_name.remote_bd_name, (char*)bd_name, BD_NAME_LEN); 2501 rem_name.status = BTM_SUCCESS; 2502 2503 bta_dm_remname_cback(&rem_name); 2504 } 2505 else 2506 { 2507 /* get name of device */ 2508 btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr, 2509 (tBTM_CMPL_CB *) bta_dm_remname_cback, 2510 BT_TRANSPORT_BR_EDR); 2511 if ( btm_status == BTM_BUSY ) 2512 { 2513 /* wait for next chance(notification of remote name discovery done) */ 2514 APPL_TRACE_DEBUG("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName is busy"); 2515 } 2516 else if ( btm_status != BTM_CMD_STARTED ) 2517 { 2518 /* if failed to start getting remote name then continue */ 2519 APPL_TRACE_WARNING("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status); 2520 2521 rem_name.length = 0; 2522 rem_name.remote_bd_name[0] = 0; 2523 rem_name.status = btm_status; 2524 bta_dm_remname_cback(&rem_name); 2525 } 2526 } 2527 } 2528 2529 2530 /******************************************************************************* 2531 ** 2532 ** Function bta_dm_remname_cback 2533 ** 2534 ** Description Remote name complete call back from BTM 2535 ** 2536 ** Returns void 2537 ** 2538 *******************************************************************************/ 2539 static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name) 2540 { 2541 APPL_TRACE_DEBUG("bta_dm_remname_cback len = %d name=<%s>", p_remote_name->length, 2542 p_remote_name->remote_bd_name); 2543 2544 /* remote name discovery is done but it could be failed */ 2545 bta_dm_search_cb.name_discover_done = TRUE; 2546 strlcpy((char*)bta_dm_search_cb.peer_name, 2547 (char*)p_remote_name->remote_bd_name, BD_NAME_LEN); 2548 2549 BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback); 2550 2551 #if BLE_INCLUDED == TRUE 2552 if (bta_dm_search_cb.transport == BT_TRANSPORT_LE ) 2553 { 2554 GAP_BleReadPeerPrefConnParams (bta_dm_search_cb.peer_bdaddr); 2555 } 2556 #endif 2557 2558 tBTA_DM_REM_NAME *p_msg = 2559 (tBTA_DM_REM_NAME *)osi_malloc(sizeof(tBTA_DM_REM_NAME)); 2560 bdcpy(p_msg->result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr); 2561 strlcpy((char*)p_msg->result.disc_res.bd_name, 2562 (char*)p_remote_name->remote_bd_name, BD_NAME_LEN); 2563 p_msg->hdr.event = BTA_DM_REMT_NAME_EVT; 2564 2565 bta_sys_sendmsg(p_msg); 2566 } 2567 2568 /******************************************************************************* 2569 ** 2570 ** Function bta_dm_authorize_cback 2571 ** 2572 ** Description cback requesting authorization 2573 ** 2574 ** Returns void 2575 ** 2576 *******************************************************************************/ 2577 static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, 2578 UINT8 *service_name, UINT8 service_id, BOOLEAN is_originator) 2579 { 2580 tBTA_DM_SEC sec_event; 2581 UINT8 index = 1; 2582 UNUSED(service_name); 2583 UNUSED(is_originator); 2584 2585 bdcpy(sec_event.authorize.bd_addr, bd_addr); 2586 memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN); 2587 strlcpy((char*)sec_event.authorize.bd_name, (char*)bd_name, BD_NAME_LEN); 2588 2589 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE ) 2590 sec_event.authorize.service = service_id; 2591 #endif 2592 2593 while(index < BTA_MAX_SERVICE_ID) 2594 { 2595 /* get the BTA service id corresponding to BTM id */ 2596 if(bta_service_id_to_btm_srv_id_lkup_tbl[index] == service_id) 2597 { 2598 sec_event.authorize.service = index; 2599 break; 2600 } 2601 index++; 2602 } 2603 2604 2605 /* if supported service callback otherwise not authorized */ 2606 if(bta_dm_cb.p_sec_cback && (index < BTA_MAX_SERVICE_ID 2607 #if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE ) 2608 /* pass through JV service ID */ 2609 || (service_id >= BTA_FIRST_JV_SERVICE_ID && service_id <= BTA_LAST_JV_SERVICE_ID) 2610 #endif 2611 )) 2612 { 2613 bta_dm_cb.p_sec_cback(BTA_DM_AUTHORIZE_EVT, &sec_event); 2614 return BTM_CMD_STARTED; 2615 } 2616 else 2617 { 2618 return BTM_NOT_AUTHORIZED; 2619 } 2620 } 2621 2622 2623 2624 2625 2626 /******************************************************************************* 2627 ** 2628 ** Function bta_dm_pinname_cback 2629 ** 2630 ** Description Callback requesting pin_key 2631 ** 2632 ** Returns void 2633 ** 2634 *******************************************************************************/ 2635 static void bta_dm_pinname_cback (void *p_data) 2636 { 2637 tBTM_REMOTE_DEV_NAME *p_result = (tBTM_REMOTE_DEV_NAME *)p_data; 2638 tBTA_DM_SEC sec_event; 2639 UINT32 bytes_to_copy; 2640 tBTA_DM_SEC_EVT event = bta_dm_cb.pin_evt; 2641 2642 if (BTA_DM_SP_CFM_REQ_EVT == event) 2643 { 2644 /* Retrieved saved device class and bd_addr */ 2645 bdcpy(sec_event.cfm_req.bd_addr, bta_dm_cb.pin_bd_addr); 2646 BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_cb.pin_dev_class); 2647 2648 if (p_result && p_result->status == BTM_SUCCESS) 2649 { 2650 bytes_to_copy = (p_result->length < (BD_NAME_LEN-1)) 2651 ? p_result->length : (BD_NAME_LEN-1); 2652 memcpy(sec_event.cfm_req.bd_name, p_result->remote_bd_name, bytes_to_copy); 2653 sec_event.pin_req.bd_name[BD_NAME_LEN-1] = 0; 2654 } 2655 else /* No name found */ 2656 sec_event.cfm_req.bd_name[0] = 0; 2657 2658 sec_event.key_notif.passkey = bta_dm_cb.num_val; /* get PIN code numeric number */ 2659 2660 /* 1 additional event data fields for this event */ 2661 sec_event.cfm_req.just_works = bta_dm_cb.just_works; 2662 } 2663 else 2664 { 2665 /* Retrieved saved device class and bd_addr */ 2666 bdcpy(sec_event.pin_req.bd_addr, bta_dm_cb.pin_bd_addr); 2667 BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_cb.pin_dev_class); 2668 2669 if (p_result && p_result->status == BTM_SUCCESS) 2670 { 2671 bytes_to_copy = (p_result->length < (BD_NAME_LEN-1)) 2672 ? p_result->length : (BD_NAME_LEN-1); 2673 memcpy(sec_event.pin_req.bd_name, p_result->remote_bd_name, bytes_to_copy); 2674 sec_event.pin_req.bd_name[BD_NAME_LEN-1] = 0; 2675 } 2676 else /* No name found */ 2677 sec_event.pin_req.bd_name[0] = 0; 2678 2679 event = bta_dm_cb.pin_evt; 2680 sec_event.key_notif.passkey = bta_dm_cb.num_val; /* get PIN code numeric number */ 2681 } 2682 2683 if( bta_dm_cb.p_sec_cback ) 2684 bta_dm_cb.p_sec_cback(event, &sec_event); 2685 } 2686 2687 /******************************************************************************* 2688 ** 2689 ** Function bta_dm_pin_cback 2690 ** 2691 ** Description Callback requesting pin_key 2692 ** 2693 ** Returns void 2694 ** 2695 *******************************************************************************/ 2696 static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, 2697 BOOLEAN min_16_digit) 2698 { 2699 tBTA_DM_SEC sec_event; 2700 2701 if (!bta_dm_cb.p_sec_cback) 2702 return BTM_NOT_AUTHORIZED; 2703 2704 /* If the device name is not known, save bdaddr and devclass and initiate a name request */ 2705 if (bd_name[0] == 0) 2706 { 2707 bta_dm_cb.pin_evt = BTA_DM_PIN_REQ_EVT; 2708 bdcpy(bta_dm_cb.pin_bd_addr, bd_addr); 2709 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, dev_class); 2710 if ((BTM_ReadRemoteDeviceName(bd_addr, bta_dm_pinname_cback, BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) 2711 return BTM_CMD_STARTED; 2712 2713 APPL_TRACE_WARNING(" bta_dm_pin_cback() -> Failed to start Remote Name Request "); 2714 } 2715 2716 bdcpy(sec_event.pin_req.bd_addr, bd_addr); 2717 BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class); 2718 strlcpy((char*)sec_event.pin_req.bd_name, (char*)bd_name, BD_NAME_LEN); 2719 sec_event.pin_req.min_16_digit = min_16_digit; 2720 2721 bta_dm_cb.p_sec_cback(BTA_DM_PIN_REQ_EVT, &sec_event); 2722 return BTM_CMD_STARTED; 2723 } 2724 2725 /******************************************************************************* 2726 ** 2727 ** Function bta_dm_new_link_key_cback 2728 ** 2729 ** Description Callback from BTM to notify new link key 2730 ** 2731 ** Returns void 2732 ** 2733 *******************************************************************************/ 2734 static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, 2735 BD_NAME bd_name, LINK_KEY key, UINT8 key_type) 2736 { 2737 tBTA_DM_SEC sec_event; 2738 tBTA_DM_AUTH_CMPL *p_auth_cmpl; 2739 UINT8 event; 2740 UNUSED(dev_class); 2741 2742 memset (&sec_event, 0, sizeof(tBTA_DM_SEC)); 2743 2744 /* Not AMP Key type */ 2745 if (key_type != HCI_LKEY_TYPE_AMP_WIFI && key_type != HCI_LKEY_TYPE_AMP_UWB) 2746 { 2747 event = BTA_DM_AUTH_CMPL_EVT; 2748 p_auth_cmpl = &sec_event.auth_cmpl; 2749 2750 bdcpy(p_auth_cmpl->bd_addr, bd_addr); 2751 2752 memcpy(p_auth_cmpl->bd_name, bd_name, (BD_NAME_LEN-1)); 2753 p_auth_cmpl->bd_name[BD_NAME_LEN-1] = 0; 2754 2755 p_auth_cmpl->key_present = TRUE; 2756 p_auth_cmpl->key_type = key_type; 2757 p_auth_cmpl->success = TRUE; 2758 2759 memcpy(p_auth_cmpl->key, key, LINK_KEY_LEN); 2760 sec_event.auth_cmpl.fail_reason = HCI_SUCCESS; 2761 2762 #if BLE_INCLUDED == TRUE 2763 // Report the BR link key based on the BR/EDR address and type 2764 BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type); 2765 #endif 2766 if(bta_dm_cb.p_sec_cback) 2767 bta_dm_cb.p_sec_cback(event, &sec_event); 2768 2769 // Setting remove_dev_pending flag to FALSE, where it will avoid deleting the 2770 // security device record when the ACL connection link goes down in case of 2771 // reconnection. 2772 if (bta_dm_cb.device_list.count) 2773 bta_dm_reset_sec_dev_pending(p_auth_cmpl->bd_addr); 2774 } 2775 else 2776 { 2777 APPL_TRACE_WARNING("%s() Received AMP Key", __func__); 2778 } 2779 2780 return BTM_CMD_STARTED; 2781 } 2782 2783 2784 /******************************************************************************* 2785 ** 2786 ** Function bta_dm_authentication_complete_cback 2787 ** 2788 ** Description Authentication complete callback from BTM 2789 ** 2790 ** Returns void 2791 ** 2792 *******************************************************************************/ 2793 static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,BD_NAME bd_name, int result) 2794 { 2795 tBTA_DM_SEC sec_event; 2796 UNUSED(dev_class); 2797 2798 if(result != BTM_SUCCESS) 2799 { 2800 memset(&sec_event, 0, sizeof(tBTA_DM_SEC)); 2801 bdcpy(sec_event.auth_cmpl.bd_addr, bd_addr); 2802 2803 memcpy(sec_event.auth_cmpl.bd_name, bd_name, (BD_NAME_LEN-1)); 2804 sec_event.auth_cmpl.bd_name[BD_NAME_LEN-1] = 0; 2805 2806 #if BLE_INCLUDED == TRUE 2807 // Report the BR link key based on the BR/EDR address and type 2808 BTM_ReadDevInfo(bd_addr, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type); 2809 #endif 2810 sec_event.auth_cmpl.fail_reason = (UINT8)result; 2811 2812 if(bta_dm_cb.p_sec_cback) 2813 bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event); 2814 2815 bta_dm_remove_sec_dev_entry(bd_addr); 2816 } 2817 2818 return BTM_SUCCESS; 2819 } 2820 2821 /******************************************************************************* 2822 ** 2823 ** Function bta_dm_sp_cback 2824 ** 2825 ** Description simple pairing callback from BTM 2826 ** 2827 ** Returns void 2828 ** 2829 *******************************************************************************/ 2830 static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data) 2831 { 2832 tBTM_STATUS status = BTM_CMD_STARTED; 2833 tBTA_DM_SEC sec_event; 2834 tBTA_DM_SEC_EVT pin_evt = BTA_DM_SP_KEY_NOTIF_EVT; 2835 2836 APPL_TRACE_EVENT("bta_dm_sp_cback: %d", event); 2837 if (!bta_dm_cb.p_sec_cback) 2838 return BTM_NOT_AUTHORIZED; 2839 2840 /* TODO_SP */ 2841 switch(event) 2842 { 2843 case BTM_SP_IO_REQ_EVT: 2844 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) 2845 /* translate auth_req */ 2846 bta_dm_co_io_req(p_data->io_req.bd_addr, &p_data->io_req.io_cap, 2847 &p_data->io_req.oob_data, &p_data->io_req.auth_req, p_data->io_req.is_orig); 2848 #endif 2849 APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data); 2850 break; 2851 case BTM_SP_IO_RSP_EVT: 2852 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) 2853 bta_dm_co_io_rsp(p_data->io_rsp.bd_addr, p_data->io_rsp.io_cap, 2854 p_data->io_rsp.oob_data, p_data->io_rsp.auth_req ); 2855 #endif 2856 break; 2857 2858 case BTM_SP_CFM_REQ_EVT: 2859 pin_evt = BTA_DM_SP_CFM_REQ_EVT; 2860 bta_dm_cb.just_works = sec_event.cfm_req.just_works = p_data->cfm_req.just_works; 2861 sec_event.cfm_req.loc_auth_req = p_data->cfm_req.loc_auth_req; 2862 sec_event.cfm_req.rmt_auth_req = p_data->cfm_req.rmt_auth_req; 2863 sec_event.cfm_req.loc_io_caps = p_data->cfm_req.loc_io_caps; 2864 sec_event.cfm_req.rmt_io_caps = p_data->cfm_req.rmt_io_caps; 2865 2866 /* continue to next case */ 2867 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) 2868 /* Passkey entry mode, mobile device with output capability is very 2869 unlikely to receive key request, so skip this event */ 2870 /*case BTM_SP_KEY_REQ_EVT: */ 2871 case BTM_SP_KEY_NOTIF_EVT: 2872 #endif 2873 if(BTM_SP_CFM_REQ_EVT == event) 2874 { 2875 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT, 2876 call remote name request using values from cfm_req */ 2877 if(p_data->cfm_req.bd_name[0] == 0) 2878 { 2879 bta_dm_cb.pin_evt = pin_evt; 2880 bdcpy(bta_dm_cb.pin_bd_addr, p_data->cfm_req.bd_addr); 2881 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->cfm_req.dev_class); 2882 if ((BTM_ReadRemoteDeviceName(p_data->cfm_req.bd_addr, bta_dm_pinname_cback, 2883 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) 2884 return BTM_CMD_STARTED; 2885 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request "); 2886 } 2887 else 2888 { 2889 /* Due to the switch case falling through below to BTM_SP_KEY_NOTIF_EVT, 2890 copy these values into key_notif from cfm_req */ 2891 bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr); 2892 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class); 2893 strlcpy((char*)sec_event.key_notif.bd_name, 2894 (char*)p_data->cfm_req.bd_name, BD_NAME_LEN); 2895 } 2896 } 2897 2898 bta_dm_cb.num_val = sec_event.key_notif.passkey = p_data->key_notif.passkey; 2899 if (BTM_SP_KEY_NOTIF_EVT == event) 2900 { 2901 /* If the device name is not known, save bdaddr and devclass 2902 and initiate a name request with values from key_notif */ 2903 if(p_data->key_notif.bd_name[0] == 0) 2904 { 2905 bta_dm_cb.pin_evt = pin_evt; 2906 bdcpy(bta_dm_cb.pin_bd_addr, p_data->key_notif.bd_addr); 2907 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->key_notif.dev_class); 2908 if ((BTM_ReadRemoteDeviceName(p_data->key_notif.bd_addr, bta_dm_pinname_cback, 2909 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) 2910 return BTM_CMD_STARTED; 2911 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request "); 2912 } 2913 else 2914 { 2915 bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr); 2916 BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class); 2917 strlcpy((char*)sec_event.key_notif.bd_name, 2918 (char*)p_data->key_notif.bd_name, BD_NAME_LEN); 2919 sec_event.key_notif.bd_name[BD_NAME_LEN-1] = 0; 2920 } 2921 } 2922 2923 bta_dm_cb.p_sec_cback(pin_evt, &sec_event); 2924 2925 break; 2926 2927 case BTM_SP_LOC_OOB_EVT: 2928 bta_dm_co_loc_oob((BOOLEAN)(p_data->loc_oob.status == BTM_SUCCESS), 2929 p_data->loc_oob.c, p_data->loc_oob.r); 2930 break; 2931 2932 case BTM_SP_RMT_OOB_EVT: 2933 /* If the device name is not known, save bdaddr and devclass and initiate a name request */ 2934 if (p_data->rmt_oob.bd_name[0] == 0) 2935 { 2936 bta_dm_cb.pin_evt = BTA_DM_SP_RMT_OOB_EVT; 2937 bdcpy(bta_dm_cb.pin_bd_addr, p_data->rmt_oob.bd_addr); 2938 BTA_COPY_DEVICE_CLASS(bta_dm_cb.pin_dev_class, p_data->rmt_oob.dev_class); 2939 if ((BTM_ReadRemoteDeviceName(p_data->rmt_oob.bd_addr, bta_dm_pinname_cback, 2940 BT_TRANSPORT_BR_EDR)) == BTM_CMD_STARTED) 2941 return BTM_CMD_STARTED; 2942 APPL_TRACE_WARNING(" bta_dm_sp_cback() -> Failed to start Remote Name Request "); 2943 } 2944 2945 bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr); 2946 BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class); 2947 strlcpy((char*)sec_event.rmt_oob.bd_name, (char*)p_data->rmt_oob.bd_name, BD_NAME_LEN); 2948 2949 bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event); 2950 2951 bta_dm_co_rmt_oob(p_data->rmt_oob.bd_addr); 2952 break; 2953 2954 case BTM_SP_COMPLT_EVT: 2955 /* do not report this event - handled by link_key_callback or auth_complete_callback */ 2956 break; 2957 2958 case BTM_SP_KEYPRESS_EVT: 2959 memcpy(&sec_event.key_press, &p_data->key_press, sizeof(tBTM_SP_KEYPRESS)); 2960 bta_dm_cb.p_sec_cback(BTA_DM_SP_KEYPRESS_EVT, &sec_event); 2961 break; 2962 2963 case BTM_SP_UPGRADE_EVT: 2964 bta_dm_co_lk_upgrade(p_data->upgrade.bd_addr, &p_data->upgrade.upgrade ); 2965 break; 2966 2967 default: 2968 status = BTM_NOT_AUTHORIZED; 2969 break; 2970 } 2971 APPL_TRACE_EVENT("dm status: %d", status); 2972 return status; 2973 } 2974 2975 /******************************************************************************* 2976 ** 2977 ** Function bta_dm_local_name_cback 2978 ** 2979 ** Description Callback from btm after local name is read 2980 ** 2981 ** 2982 ** Returns void 2983 ** 2984 *******************************************************************************/ 2985 static void bta_dm_local_name_cback(UINT8 *p_name) 2986 { 2987 tBTA_DM_SEC sec_event; 2988 UNUSED(p_name); 2989 2990 sec_event.enable.status = BTA_SUCCESS; 2991 2992 if(bta_dm_cb.p_sec_cback) 2993 bta_dm_cb.p_sec_cback(BTA_DM_ENABLE_EVT, &sec_event); 2994 2995 } 2996 2997 /******************************************************************************* 2998 ** 2999 ** Function bta_dm_bl_change_cback 3000 ** 3001 ** Description Callback from btm when acl connection goes up or down 3002 ** 3003 ** 3004 ** Returns void 3005 ** 3006 *******************************************************************************/ 3007 static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data) 3008 { 3009 tBTA_DM_ACL_CHANGE *p_msg = 3010 (tBTA_DM_ACL_CHANGE *)osi_malloc(sizeof(tBTA_DM_ACL_CHANGE)); 3011 3012 p_msg->event = p_data->event; 3013 p_msg->is_new = FALSE; 3014 3015 switch (p_msg->event) { 3016 case BTM_BL_CONN_EVT: 3017 p_msg->is_new = TRUE; 3018 bdcpy(p_msg->bd_addr, p_data->conn.p_bda); 3019 #if BLE_INCLUDED == TRUE 3020 p_msg->transport = p_data->conn.transport; 3021 p_msg->handle = p_data->conn.handle; 3022 #endif 3023 break; 3024 case BTM_BL_DISCN_EVT: 3025 bdcpy(p_msg->bd_addr, p_data->discn.p_bda); 3026 #if BLE_INCLUDED == TRUE 3027 p_msg->transport = p_data->discn.transport; 3028 p_msg->handle = p_data->discn.handle; 3029 #endif 3030 break; 3031 case BTM_BL_UPDATE_EVT: 3032 p_msg->busy_level = p_data->update.busy_level; 3033 p_msg->busy_level_flags = p_data->update.busy_level_flags; 3034 break; 3035 case BTM_BL_ROLE_CHG_EVT: 3036 p_msg->new_role = p_data->role_chg.new_role; 3037 p_msg->hci_status = p_data->role_chg.hci_status; 3038 bdcpy(p_msg->bd_addr, p_data->role_chg.p_bda); 3039 break; 3040 case BTM_BL_COLLISION_EVT: 3041 bdcpy(p_msg->bd_addr, p_data->conn.p_bda); 3042 break; 3043 } 3044 3045 p_msg->hdr.event = BTA_DM_ACL_CHANGE_EVT; 3046 bta_sys_sendmsg(p_msg); 3047 } 3048 3049 /******************************************************************************* 3050 ** 3051 ** Function bta_dm_rs_cback 3052 ** 3053 ** Description Receives the role switch complete event 3054 ** 3055 ** Returns 3056 ** 3057 *******************************************************************************/ 3058 static void bta_dm_rs_cback (tBTM_ROLE_SWITCH_CMPL *p1) 3059 { 3060 UNUSED(p1); 3061 APPL_TRACE_WARNING("bta_dm_rs_cback:%d", bta_dm_cb.rs_event); 3062 if(bta_dm_cb.rs_event == BTA_DM_API_SEARCH_EVT) 3063 { 3064 bta_dm_cb.search_msg.rs_res = BTA_DM_RS_OK; /* do not care about the result for now */ 3065 bta_dm_cb.rs_event = 0; 3066 bta_dm_search_start((tBTA_DM_MSG *)&bta_dm_cb.search_msg); 3067 } 3068 } 3069 3070 /******************************************************************************* 3071 ** 3072 ** Function bta_dm_check_av 3073 ** 3074 ** Description This function checks if AV is active 3075 ** if yes, make sure the AV link is master 3076 ** 3077 ** Returns BOOLEAN - TRUE, if switch is in progress 3078 ** 3079 *******************************************************************************/ 3080 static BOOLEAN bta_dm_check_av(UINT16 event) 3081 { 3082 BOOLEAN avoid_roleswitch = FALSE; 3083 BOOLEAN switching = FALSE; 3084 UINT8 i; 3085 tBTA_DM_PEER_DEVICE *p_dev; 3086 3087 #if defined(BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY) && (BTA_DM_AVOID_A2DP_ROLESWITCH_ON_INQUIRY == TRUE) 3088 3089 /* avoid role switch upon inquiry if a2dp is actively streaming as it 3090 introduces an audioglitch due to FW scheduling delays (unavoidable) */ 3091 if (event == BTA_DM_API_SEARCH_EVT) 3092 { 3093 avoid_roleswitch = TRUE; 3094 } 3095 #endif 3096 3097 APPL_TRACE_WARNING("bta_dm_check_av:%d", bta_dm_cb.cur_av_count); 3098 if(bta_dm_cb.cur_av_count) 3099 { 3100 for(i=0; i<bta_dm_cb.device_list.count; i++) 3101 { 3102 p_dev = &bta_dm_cb.device_list.peer_device[i]; 3103 APPL_TRACE_WARNING("[%d]: state:%d, info:x%x, avoid_rs %d", 3104 i, p_dev->conn_state, p_dev->info, avoid_roleswitch); 3105 if((p_dev->conn_state == BTA_DM_CONNECTED) && (p_dev->info & BTA_DM_DI_AV_ACTIVE) && 3106 (avoid_roleswitch == FALSE)) 3107 { 3108 /* make master and take away the role switch policy */ 3109 if(BTM_CMD_STARTED == BTM_SwitchRole (p_dev->peer_bdaddr, HCI_ROLE_MASTER, (tBTM_CMPL_CB *)bta_dm_rs_cback)) 3110 { 3111 /* the role switch command is actually sent */ 3112 bta_dm_cb.rs_event = event; 3113 switching = TRUE; 3114 } 3115 /* else either already master or can not switch for some reasons */ 3116 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr); 3117 break; 3118 } 3119 } 3120 } 3121 return switching; 3122 } 3123 3124 /******************************************************************************* 3125 ** 3126 ** Function bta_dm_acl_change 3127 ** 3128 ** Description Process BTA_DM_ACL_CHANGE_EVT 3129 ** 3130 ** 3131 ** Returns void 3132 ** 3133 *******************************************************************************/ 3134 void bta_dm_acl_change(tBTA_DM_MSG *p_data) 3135 { 3136 3137 UINT8 i; 3138 UINT8 *p; 3139 tBTA_DM_SEC conn; 3140 BOOLEAN is_new = p_data->acl_change.is_new; 3141 BD_ADDR_PTR p_bda = p_data->acl_change.bd_addr; 3142 BOOLEAN need_policy_change = FALSE; 3143 BOOLEAN issue_unpair_cb = FALSE; 3144 3145 tBTA_DM_PEER_DEVICE *p_dev; 3146 memset(&conn, 0, sizeof(tBTA_DM_SEC)); 3147 3148 switch(p_data->acl_change.event) 3149 { 3150 case BTM_BL_UPDATE_EVT: /* busy level update */ 3151 if( bta_dm_cb.p_sec_cback ) 3152 { 3153 conn.busy_level.level = p_data->acl_change.busy_level; 3154 conn.busy_level.level_flags = p_data->acl_change.busy_level_flags; 3155 bta_dm_cb.p_sec_cback(BTA_DM_BUSY_LEVEL_EVT, &conn); 3156 } 3157 return; 3158 3159 case BTM_BL_ROLE_CHG_EVT: /* role change event */ 3160 p_dev = bta_dm_find_peer_device(p_bda); 3161 if(p_dev) 3162 { 3163 APPL_TRACE_DEBUG("bta_dm_acl_change role chg info:x%x new_role:%d dev count:%d", 3164 p_dev->info, p_data->acl_change.new_role, bta_dm_cb.device_list.count); 3165 if(p_dev->info & BTA_DM_DI_AV_ACTIVE) 3166 { 3167 /* there's AV activity on this link */ 3168 if(p_data->acl_change.new_role == HCI_ROLE_SLAVE && bta_dm_cb.device_list.count > 1 3169 && p_data->acl_change.hci_status == HCI_SUCCESS) 3170 { 3171 /* more than one connections and the AV connection is role switched to slave 3172 * switch it back to master and remove the switch policy */ 3173 BTM_SwitchRole(p_bda, BTM_ROLE_MASTER, NULL); 3174 need_policy_change = TRUE; 3175 } 3176 else if (p_bta_dm_cfg->avoid_scatter && (p_data->acl_change.new_role == HCI_ROLE_MASTER)) 3177 { 3178 /* if the link updated to be master include AV activities, remove the switch policy */ 3179 need_policy_change = TRUE; 3180 } 3181 3182 if(need_policy_change) 3183 { 3184 bta_dm_policy_cback(BTA_SYS_PLCY_CLR, 0, HCI_ENABLE_MASTER_SLAVE_SWITCH, p_dev->peer_bdaddr); 3185 } 3186 } 3187 else 3188 { 3189 /* there's AV no activity on this link and role switch happened 3190 * check if AV is active 3191 * if so, make sure the AV link is master */ 3192 bta_dm_check_av(0); 3193 } 3194 bta_sys_notify_role_chg(p_data->acl_change.bd_addr, p_data->acl_change.new_role, p_data->acl_change.hci_status); 3195 bdcpy(conn.role_chg.bd_addr, p_bda); 3196 conn.role_chg.new_role = (UINT8) p_data->acl_change.new_role; 3197 if( bta_dm_cb.p_sec_cback ) 3198 bta_dm_cb.p_sec_cback(BTA_DM_ROLE_CHG_EVT, (tBTA_DM_SEC *)&conn); 3199 } 3200 return; 3201 } 3202 3203 /* Collision report from Stack: Notify profiles */ 3204 if (p_data->acl_change.event == BTM_BL_COLLISION_EVT) 3205 { 3206 bta_sys_notify_collision (p_bda); 3207 return; 3208 } 3209 3210 if(is_new) 3211 { 3212 for(i=0; i<bta_dm_cb.device_list.count; i++) 3213 { 3214 if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda) 3215 #if BLE_INCLUDED == TRUE 3216 && bta_dm_cb.device_list.peer_device[i].conn_handle == p_data->acl_change.handle 3217 #endif 3218 ) 3219 break; 3220 3221 } 3222 3223 if(i == bta_dm_cb.device_list.count) 3224 { 3225 if (bta_dm_cb.device_list.count < BTA_DM_NUM_PEER_DEVICE) 3226 { 3227 bdcpy(bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].peer_bdaddr, p_bda); 3228 bta_dm_cb.device_list.peer_device[bta_dm_cb.device_list.count].link_policy = bta_dm_cb.cur_policy; 3229 bta_dm_cb.device_list.count++; 3230 #if BLE_INCLUDED == TRUE 3231 bta_dm_cb.device_list.peer_device[i].conn_handle = p_data->acl_change.handle; 3232 if (p_data->acl_change.transport == BT_TRANSPORT_LE) 3233 bta_dm_cb.device_list.le_count++; 3234 #endif 3235 } else { 3236 APPL_TRACE_ERROR("%s max active connection reached, no resources", __func__); 3237 return; 3238 } 3239 } 3240 3241 bta_dm_cb.device_list.peer_device[i].conn_state = BTA_DM_CONNECTED; 3242 bta_dm_cb.device_list.peer_device[i].pref_role = BTA_ANY_ROLE; 3243 bdcpy(conn.link_up.bd_addr, p_bda); 3244 bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_NONE; 3245 #if BLE_INCLUDED == TRUE 3246 conn.link_up.link_type = p_data->acl_change.transport; 3247 bta_dm_cb.device_list.peer_device[i].transport = p_data->acl_change.transport; 3248 #endif 3249 3250 if (((NULL != (p = BTM_ReadLocalFeatures ())) && HCI_SNIFF_SUB_RATE_SUPPORTED(p)) && 3251 ((NULL != (p = BTM_ReadRemoteFeatures (p_bda))) && HCI_SNIFF_SUB_RATE_SUPPORTED(p))) 3252 { 3253 /* both local and remote devices support SSR */ 3254 bta_dm_cb.device_list.peer_device[i].info = BTA_DM_DI_USE_SSR; 3255 } 3256 APPL_TRACE_WARNING("%s info: 0x%x", __func__, bta_dm_cb.device_list.peer_device[i].info); 3257 3258 if (bta_dm_cb.p_sec_cback) 3259 bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, (tBTA_DM_SEC *)&conn); 3260 } else { 3261 for(i=0; i<bta_dm_cb.device_list.count; i++) 3262 { 3263 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_bda) 3264 #if BLE_INCLUDED == TRUE 3265 ||bta_dm_cb.device_list.peer_device[i].transport != p_data->acl_change.transport 3266 #endif 3267 ) 3268 continue; 3269 3270 if( bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_UNPAIRING ) 3271 { 3272 if (BTM_SecDeleteDevice(bta_dm_cb.device_list.peer_device[i].peer_bdaddr)) 3273 issue_unpair_cb = TRUE; 3274 3275 APPL_TRACE_DEBUG("%s: Unpairing: issue unpair CB = %d ",__FUNCTION__, issue_unpair_cb); 3276 } 3277 3278 conn.link_down.is_removed = bta_dm_cb.device_list.peer_device[i].remove_dev_pending; 3279 3280 for(; i<bta_dm_cb.device_list.count ; i++) 3281 { 3282 memcpy(&bta_dm_cb.device_list.peer_device[i], &bta_dm_cb.device_list.peer_device[i+1], sizeof(bta_dm_cb.device_list.peer_device[i])); 3283 } 3284 break; 3285 } 3286 if(bta_dm_cb.device_list.count) 3287 bta_dm_cb.device_list.count--; 3288 #if BLE_INCLUDED == TRUE 3289 if ((p_data->acl_change.transport == BT_TRANSPORT_LE) && 3290 (bta_dm_cb.device_list.le_count)) 3291 bta_dm_cb.device_list.le_count--; 3292 conn.link_down.link_type = p_data->acl_change.transport; 3293 #endif 3294 3295 if(bta_dm_search_cb.wait_disc && !bdcmp(bta_dm_search_cb.peer_bdaddr, p_bda)) 3296 { 3297 bta_dm_search_cb.wait_disc = FALSE; 3298 3299 if(bta_dm_search_cb.sdp_results) 3300 { 3301 APPL_TRACE_EVENT(" timer stopped "); 3302 alarm_cancel(bta_dm_search_cb.search_timer); 3303 bta_dm_discover_next_device(); 3304 } 3305 3306 } 3307 3308 if(bta_dm_cb.disabling) 3309 { 3310 if(!BTM_GetNumAclLinks()) 3311 { 3312 /* 3313 * Start a timer to make sure that the profiles 3314 * get the disconnect event. 3315 */ 3316 alarm_set_on_queue(bta_dm_cb.disable_timer, 3317 BTA_DM_DISABLE_CONN_DOWN_TIMER_MS, 3318 bta_dm_disable_conn_down_timer_cback, NULL, 3319 btu_bta_alarm_queue); 3320 } 3321 } 3322 if (conn.link_down.is_removed) 3323 { 3324 BTM_SecDeleteDevice(p_bda); 3325 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE) 3326 /* need to remove all pending background connection */ 3327 BTA_GATTC_CancelOpen(0, p_bda, FALSE); 3328 /* remove all cached GATT information */ 3329 BTA_GATTC_Refresh(p_bda); 3330 #endif 3331 } 3332 3333 bdcpy(conn.link_down.bd_addr, p_bda); 3334 conn.link_down.status = (UINT8) btm_get_acl_disc_reason_code(); 3335 if( bta_dm_cb.p_sec_cback ) 3336 { 3337 bta_dm_cb.p_sec_cback(BTA_DM_LINK_DOWN_EVT, &conn); 3338 if( issue_unpair_cb ) 3339 bta_dm_cb.p_sec_cback(BTA_DM_DEV_UNPAIRED_EVT, &conn); 3340 } 3341 } 3342 3343 bta_dm_adjust_roles(TRUE); 3344 } 3345 3346 /******************************************************************************* 3347 ** 3348 ** Function bta_dm_disable_conn_down_timer_cback 3349 ** 3350 ** Description Sends disable event to application 3351 ** 3352 ** 3353 ** Returns void 3354 ** 3355 *******************************************************************************/ 3356 static void bta_dm_disable_conn_down_timer_cback(UNUSED_ATTR void *data) 3357 { 3358 tBTA_SYS_HW_MSG *sys_enable_event = 3359 (tBTA_SYS_HW_MSG *)osi_malloc(sizeof(tBTA_SYS_HW_MSG)); 3360 3361 /* disable the power managment module */ 3362 bta_dm_disable_pm(); 3363 3364 /* register our callback to SYS HW manager */ 3365 bta_sys_hw_register(BTA_SYS_HW_BLUETOOTH, bta_dm_sys_hw_cback ); 3366 3367 /* send a message to BTA SYS */ 3368 sys_enable_event->hdr.event = BTA_SYS_API_DISABLE_EVT; 3369 sys_enable_event->hw_module = BTA_SYS_HW_BLUETOOTH; 3370 bta_sys_sendmsg(sys_enable_event); 3371 3372 bta_dm_cb.disabling = FALSE; 3373 } 3374 3375 /******************************************************************************* 3376 ** 3377 ** Function bta_dm_rm_cback 3378 ** 3379 ** Description Role management callback from sys 3380 ** 3381 ** 3382 ** Returns void 3383 ** 3384 *******************************************************************************/ 3385 static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr) 3386 { 3387 UINT8 j; 3388 tBTA_PREF_ROLES role; 3389 tBTA_DM_PEER_DEVICE *p_dev; 3390 3391 p_dev = bta_dm_find_peer_device(peer_addr); 3392 if( status == BTA_SYS_CONN_OPEN) 3393 { 3394 if(p_dev) 3395 { 3396 /* Do not set to connected if we are in the middle of unpairing. When AV stream is 3397 * started it fakes out a SYS_CONN_OPEN to potentially trigger a role switch command. 3398 * But this should not be done if we are in the middle of unpairing. 3399 */ 3400 if (p_dev->conn_state != BTA_DM_UNPAIRING) 3401 p_dev->conn_state = BTA_DM_CONNECTED; 3402 3403 for(j=1; j<= p_bta_dm_rm_cfg[0].app_id; j++) 3404 { 3405 if(((p_bta_dm_rm_cfg[j].app_id == app_id) || (p_bta_dm_rm_cfg[j].app_id == BTA_ALL_APP_ID)) 3406 && (p_bta_dm_rm_cfg[j].id == id)) 3407 { 3408 role = p_bta_dm_rm_cfg[j].cfg; 3409 3410 if(role > p_dev->pref_role ) 3411 p_dev->pref_role = role; 3412 break; 3413 } 3414 } 3415 } 3416 } 3417 3418 if((BTA_ID_AV == id)||(BTA_ID_AVK ==id)) 3419 { 3420 if( status == BTA_SYS_CONN_BUSY) 3421 { 3422 if(p_dev) 3423 p_dev->info |= BTA_DM_DI_AV_ACTIVE; 3424 /* AV calls bta_sys_conn_open with the A2DP stream count as app_id */ 3425 if(BTA_ID_AV == id) 3426 bta_dm_cb.cur_av_count = bta_dm_get_av_count(); 3427 } 3428 else if( status == BTA_SYS_CONN_IDLE) 3429 { 3430 if(p_dev) 3431 p_dev->info &= ~BTA_DM_DI_AV_ACTIVE; 3432 3433 /* get cur_av_count from connected services */ 3434 if(BTA_ID_AV == id) 3435 bta_dm_cb.cur_av_count = bta_dm_get_av_count(); 3436 } 3437 APPL_TRACE_WARNING("bta_dm_rm_cback:%d, status:%d", bta_dm_cb.cur_av_count, status); 3438 } 3439 3440 /* Don't adjust roles for each busy/idle state transition to avoid 3441 excessive switch requests when individual profile busy/idle status 3442 changes */ 3443 if ((status != BTA_SYS_CONN_BUSY) && (status != BTA_SYS_CONN_IDLE)) 3444 bta_dm_adjust_roles(FALSE); 3445 } 3446 3447 /******************************************************************************* 3448 ** 3449 ** Function bta_dm_delay_role_switch_cback 3450 ** 3451 ** Description Callback from btm to delay a role switch 3452 ** 3453 ** Returns void 3454 ** 3455 *******************************************************************************/ 3456 static void bta_dm_delay_role_switch_cback(UNUSED_ATTR void *data) 3457 { 3458 APPL_TRACE_EVENT("%s: initiating Delayed RS", __func__); 3459 bta_dm_adjust_roles(FALSE); 3460 } 3461 3462 /******************************************************************************* 3463 ** 3464 ** Function bta_dm_reset_sec_dev_pending 3465 ** 3466 ** Description Setting the remove device pending status to FALSE from 3467 ** security device DB, when the link key notification 3468 ** event comes. 3469 ** 3470 ** Returns void 3471 ** 3472 *******************************************************************************/ 3473 static void bta_dm_reset_sec_dev_pending(BD_ADDR remote_bd_addr) 3474 { 3475 for (size_t i = 0; i < bta_dm_cb.device_list.count; i++) 3476 { 3477 if (bdcmp(bta_dm_cb.device_list.peer_device[i].peer_bdaddr, remote_bd_addr) == 0) 3478 { 3479 bta_dm_cb.device_list.peer_device[i].remove_dev_pending = FALSE; 3480 return; 3481 } 3482 } 3483 } 3484 3485 /******************************************************************************* 3486 ** 3487 ** Function bta_dm_remove_sec_dev_entry 3488 ** 3489 ** Description Removes device entry from Security device DB if ACL connection with 3490 ** remtoe device does not exist, else schedule for dev entry removal upon 3491 ACL close 3492 ** 3493 ** Returns void 3494 ** 3495 *******************************************************************************/ 3496 static void bta_dm_remove_sec_dev_entry(BD_ADDR remote_bd_addr) 3497 { 3498 if ( BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_LE) || 3499 BTM_IsAclConnectionUp(remote_bd_addr, BT_TRANSPORT_BR_EDR)) 3500 { 3501 APPL_TRACE_DEBUG("%s ACL is not down. Schedule for Dev Removal when ACL closes", 3502 __func__); 3503 BTM_SecClearSecurityFlags (remote_bd_addr); 3504 for (int i = 0; i < bta_dm_cb.device_list.count; i++) 3505 { 3506 if (!bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, remote_bd_addr)) 3507 { 3508 bta_dm_cb.device_list.peer_device[i].remove_dev_pending = TRUE; 3509 break; 3510 } 3511 } 3512 } 3513 else 3514 { 3515 BTM_SecDeleteDevice (remote_bd_addr); 3516 #if (BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE) 3517 /* need to remove all pending background connection */ 3518 BTA_GATTC_CancelOpen(0, remote_bd_addr, FALSE); 3519 /* remove all cached GATT information */ 3520 BTA_GATTC_Refresh(remote_bd_addr); 3521 #endif 3522 } 3523 } 3524 3525 3526 /******************************************************************************* 3527 ** 3528 ** Function bta_dm_adjust_roles 3529 ** 3530 ** Description Adjust roles 3531 ** 3532 ** 3533 ** Returns void 3534 ** 3535 *******************************************************************************/ 3536 static void bta_dm_adjust_roles(BOOLEAN delay_role_switch) 3537 { 3538 3539 UINT8 i; 3540 BOOLEAN set_master_role = FALSE; 3541 #if BLE_INCLUDED == TRUE 3542 UINT8 br_count = bta_dm_cb.device_list.count - bta_dm_cb.device_list.le_count; 3543 #else 3544 UINT8 br_count = bta_dm_cb.device_list.count; 3545 #endif 3546 if (br_count) 3547 { 3548 3549 /* the configuration is no scatternet 3550 * or AV connection exists and there are more than one ACL link */ 3551 if ( (p_bta_dm_rm_cfg[0].cfg == BTA_DM_NO_SCATTERNET) || 3552 (bta_dm_cb.cur_av_count && br_count > 1) ) 3553 { 3554 3555 L2CA_SetDesireRole (HCI_ROLE_MASTER); 3556 set_master_role = TRUE; 3557 3558 } 3559 3560 for(i=0; i<bta_dm_cb.device_list.count; i++) 3561 { 3562 if (bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED 3563 #if BLE_INCLUDED == TRUE 3564 && bta_dm_cb.device_list.peer_device[i].transport == BT_TRANSPORT_BR_EDR 3565 #endif 3566 ) 3567 { 3568 if(!set_master_role && (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_ANY_ROLE) 3569 && (p_bta_dm_rm_cfg[0].cfg == BTA_DM_PARTIAL_SCATTERNET)) 3570 { 3571 L2CA_SetDesireRole (HCI_ROLE_MASTER); 3572 set_master_role = TRUE; 3573 } 3574 3575 if((bta_dm_cb.device_list.peer_device[i].pref_role == BTA_MASTER_ROLE_ONLY) 3576 || (br_count > 1)) 3577 { 3578 3579 /* Initiating immediate role switch with certain remote devices 3580 has caused issues due to role switch colliding with link encryption setup and 3581 causing encryption (and in turn the link) to fail . These device . Firmware 3582 versions are stored in a blacklist and role switch with these devices are 3583 delayed to avoid the collision with link encryption setup */ 3584 3585 if (bta_dm_cb.device_list.peer_device[i].pref_role != BTA_SLAVE_ROLE_ONLY && 3586 delay_role_switch == FALSE) 3587 { 3588 BTM_SwitchRole (bta_dm_cb.device_list.peer_device[i].peer_bdaddr, 3589 HCI_ROLE_MASTER, NULL); 3590 } 3591 else 3592 { 3593 alarm_set_on_queue(bta_dm_cb.switch_delay_timer, 3594 BTA_DM_SWITCH_DELAY_TIMER_MS, 3595 bta_dm_delay_role_switch_cback, 3596 NULL, btu_bta_alarm_queue); 3597 } 3598 } 3599 } 3600 } 3601 3602 3603 if(!set_master_role) 3604 { 3605 3606 L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE); 3607 3608 } 3609 3610 } 3611 else 3612 { 3613 L2CA_SetDesireRole (L2CAP_DESIRED_LINK_ROLE); 3614 } 3615 3616 3617 } 3618 3619 /******************************************************************************* 3620 ** 3621 ** Function bta_dm_get_remname 3622 ** 3623 ** Description Returns a pointer to the remote name stored in the DM control 3624 ** block if it exists, or from the BTM memory. 3625 ** 3626 ** Returns char * - Pointer to the remote device name 3627 *******************************************************************************/ 3628 static char *bta_dm_get_remname(void) 3629 { 3630 char *p_name = (char *)bta_dm_search_cb.peer_name; 3631 char *p_temp; 3632 3633 /* If the name isn't already stored, try retrieving from BTM */ 3634 if (*p_name == '\0') 3635 if ((p_temp = BTM_SecReadDevName(bta_dm_search_cb.peer_bdaddr)) != NULL) 3636 p_name = p_temp; 3637 3638 return p_name; 3639 } 3640 3641 /******************************************************************************* 3642 ** 3643 ** Function bta_dm_bond_cancel_complete_cback 3644 ** 3645 ** Description Authentication complete callback from BTM 3646 ** 3647 ** Returns void 3648 ** 3649 *******************************************************************************/ 3650 static void bta_dm_bond_cancel_complete_cback(tBTM_STATUS result) 3651 { 3652 3653 tBTA_DM_SEC sec_event; 3654 3655 if (result == BTM_SUCCESS) 3656 sec_event.bond_cancel_cmpl.result = BTA_SUCCESS; 3657 else 3658 sec_event.bond_cancel_cmpl.result = BTA_FAILURE; 3659 3660 if(bta_dm_cb.p_sec_cback) 3661 { 3662 bta_dm_cb.p_sec_cback(BTA_DM_BOND_CANCEL_CMPL_EVT, &sec_event); 3663 } 3664 } 3665 3666 /******************************************************************************* 3667 ** 3668 ** Function find_utf8_char_boundary 3669 ** 3670 ** Description This function checks a UTF8 string |utf8str| starting at 3671 ** |offset|, moving backwards and returns the offset of the 3672 ** next valid UTF8 character boundary found. 3673 ** 3674 ** Returns Offset of UTF8 character boundary 3675 ** 3676 *******************************************************************************/ 3677 static size_t find_utf8_char_boundary(const char *utf8str, size_t offset) 3678 { 3679 assert(utf8str); 3680 assert(offset > 0); 3681 3682 while (--offset) 3683 { 3684 uint8_t ch = (uint8_t)utf8str[offset]; 3685 if ((ch & 0x80) == 0x00) // ASCII 3686 return offset + 1; 3687 if ((ch & 0xC0) == 0xC0) // Multi-byte sequence start 3688 return offset; 3689 } 3690 3691 return 0; 3692 } 3693 3694 /******************************************************************************* 3695 ** 3696 ** Function bta_dm_set_eir 3697 ** 3698 ** Description This function creates EIR tagged data and writes it to controller. 3699 ** 3700 ** Returns None 3701 ** 3702 *******************************************************************************/ 3703 static void bta_dm_set_eir (char *local_name) 3704 { 3705 UINT8 *p; 3706 UINT8 *p_length; 3707 #if (BTA_EIR_CANNED_UUID_LIST != TRUE) 3708 UINT8 *p_type; 3709 UINT8 max_num_uuid; 3710 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) 3711 UINT8 custom_uuid_idx; 3712 #endif // BTA_EIR_SERVER_NUM_CUSTOM_UUID 3713 #endif // BTA_EIR_CANNED_UUID_LIST 3714 #if (BTM_EIR_DEFAULT_FEC_REQUIRED == FALSE) 3715 UINT8 free_eir_length = HCI_EXT_INQ_RESPONSE_LEN; 3716 #else // BTM_EIR_DEFAULT_FEC_REQUIRED 3717 UINT8 free_eir_length = HCI_DM5_PACKET_SIZE; 3718 #endif // BTM_EIR_DEFAULT_FEC_REQUIRED 3719 UINT8 num_uuid; 3720 UINT8 data_type; 3721 UINT8 local_name_len; 3722 3723 /* wait until complete to disable */ 3724 if (alarm_is_scheduled(bta_dm_cb.disable_timer)) 3725 return; 3726 3727 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE ) 3728 /* if local name is not provided, get it from controller */ 3729 if( local_name == NULL ) 3730 { 3731 if( BTM_ReadLocalDeviceName( &local_name ) != BTM_SUCCESS ) 3732 { 3733 APPL_TRACE_ERROR("Fail to read local device name for EIR"); 3734 } 3735 } 3736 #endif // BTA_EIR_CANNED_UUID_LIST 3737 3738 /* Allocate a buffer to hold HCI command */ 3739 BT_HDR *p_buf = (BT_HDR *)osi_malloc(BTM_CMD_BUF_SIZE); 3740 p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET; 3741 3742 memset(p, 0x00, HCI_EXT_INQ_RESPONSE_LEN ); 3743 3744 APPL_TRACE_DEBUG("BTA is generating EIR"); 3745 3746 if( local_name ) 3747 local_name_len = strlen( local_name ); 3748 else 3749 local_name_len = 0; 3750 3751 data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE; 3752 /* if local name is longer than minimum length of shortened name */ 3753 /* check whether it needs to be shortened or not */ 3754 if( local_name_len > p_bta_dm_eir_cfg->bta_dm_eir_min_name_len ) 3755 { 3756 /* get number of UUID 16-bit list */ 3757 #if (BTA_EIR_CANNED_UUID_LIST == TRUE) 3758 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len/LEN_UUID_16; 3759 #else // BTA_EIR_CANNED_UUID_LIST 3760 max_num_uuid = (free_eir_length - 2)/LEN_UUID_16; 3761 data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p, 3762 max_num_uuid, &num_uuid ); 3763 p = (UINT8 *)p_buf + BTM_HCI_EIR_OFFSET; /* reset p */ 3764 #endif // BTA_EIR_CANNED_UUID_LIST 3765 3766 /* if UUID doesn't fit remaing space, shorten local name */ 3767 if (local_name_len > (free_eir_length - 4 - num_uuid*LEN_UUID_16)) 3768 { 3769 local_name_len = find_utf8_char_boundary(local_name, 3770 p_bta_dm_eir_cfg->bta_dm_eir_min_name_len); 3771 APPL_TRACE_WARNING("%s local name is shortened (%d)", __func__, local_name_len); 3772 data_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE; 3773 } else { 3774 data_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE; 3775 } 3776 } 3777 3778 UINT8_TO_STREAM(p, local_name_len + 1); 3779 UINT8_TO_STREAM(p, data_type); 3780 3781 if (local_name != NULL) 3782 { 3783 memcpy(p, local_name, local_name_len); 3784 p += local_name_len; 3785 } 3786 free_eir_length -= local_name_len + 2; 3787 3788 #if (BTA_EIR_CANNED_UUID_LIST == TRUE) 3789 /* if UUID list is provided as static data in configuration */ 3790 if(( p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len > 0 ) 3791 &&(p_bta_dm_eir_cfg->bta_dm_eir_uuid16)) 3792 { 3793 if( free_eir_length > LEN_UUID_16 + 2) 3794 { 3795 free_eir_length -= 2; 3796 3797 if( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len) 3798 { 3799 num_uuid = p_bta_dm_eir_cfg->bta_dm_eir_uuid16_len / LEN_UUID_16; 3800 data_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE; 3801 } 3802 else /* not enough room for all UUIDs */ 3803 { 3804 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated"); 3805 num_uuid = free_eir_length / LEN_UUID_16; 3806 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE; 3807 } 3808 UINT8_TO_STREAM(p, num_uuid * LEN_UUID_16 + 1); 3809 UINT8_TO_STREAM(p, data_type); 3810 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_uuid16, num_uuid * LEN_UUID_16 ); 3811 p += num_uuid * LEN_UUID_16; 3812 free_eir_length -= num_uuid * LEN_UUID_16; 3813 } 3814 } 3815 #else /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */ 3816 /* if UUID list is dynamic */ 3817 if ( free_eir_length >= 2) 3818 { 3819 p_length = p++; 3820 p_type = p++; 3821 num_uuid = 0; 3822 3823 max_num_uuid = (free_eir_length - 2)/LEN_UUID_16; 3824 data_type = BTM_GetEirSupportedServices( bta_dm_cb.eir_uuid, &p, max_num_uuid, &num_uuid ); 3825 3826 if( data_type == BTM_EIR_MORE_16BITS_UUID_TYPE ) 3827 { 3828 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated"); 3829 } 3830 #if (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) 3831 else 3832 { 3833 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) 3834 { 3835 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_16) 3836 { 3837 if ( num_uuid < max_num_uuid ) 3838 { 3839 UINT16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid16); 3840 num_uuid++; 3841 } 3842 else 3843 { 3844 data_type = BTM_EIR_MORE_16BITS_UUID_TYPE; 3845 APPL_TRACE_WARNING("BTA EIR: UUID 16-bit list is truncated"); 3846 break; 3847 } 3848 } 3849 } 3850 } 3851 #endif /* (BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */ 3852 3853 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_16 + 1); 3854 UINT8_TO_STREAM(p_type, data_type); 3855 free_eir_length -= num_uuid * LEN_UUID_16 + 2; 3856 } 3857 #endif /* (BTA_EIR_CANNED_UUID_LIST == TRUE) */ 3858 3859 #if ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) 3860 /* Adding 32-bit UUID list */ 3861 if ( free_eir_length >= 2) 3862 { 3863 p_length = p++; 3864 p_type = p++; 3865 num_uuid = 0; 3866 data_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE; 3867 3868 max_num_uuid = (free_eir_length - 2)/LEN_UUID_32; 3869 3870 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) 3871 { 3872 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_32) 3873 { 3874 if ( num_uuid < max_num_uuid ) 3875 { 3876 UINT32_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid32); 3877 num_uuid++; 3878 } 3879 else 3880 { 3881 data_type = BTM_EIR_MORE_32BITS_UUID_TYPE; 3882 APPL_TRACE_WARNING("BTA EIR: UUID 32-bit list is truncated"); 3883 break; 3884 } 3885 } 3886 } 3887 3888 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_32 + 1); 3889 UINT8_TO_STREAM(p_type, data_type); 3890 free_eir_length -= num_uuid * LEN_UUID_32 + 2; 3891 } 3892 3893 /* Adding 128-bit UUID list */ 3894 if ( free_eir_length >= 2) 3895 { 3896 p_length = p++; 3897 p_type = p++; 3898 num_uuid = 0; 3899 data_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE; 3900 3901 max_num_uuid = (free_eir_length - 2)/LEN_UUID_128; 3902 3903 for (custom_uuid_idx = 0; custom_uuid_idx < BTA_EIR_SERVER_NUM_CUSTOM_UUID; custom_uuid_idx++) 3904 { 3905 if (bta_dm_cb.custom_uuid[custom_uuid_idx].len == LEN_UUID_128) 3906 { 3907 if ( num_uuid < max_num_uuid ) 3908 { 3909 ARRAY16_TO_STREAM(p, bta_dm_cb.custom_uuid[custom_uuid_idx].uu.uuid128); 3910 num_uuid++; 3911 } 3912 else 3913 { 3914 data_type = BTM_EIR_MORE_128BITS_UUID_TYPE; 3915 APPL_TRACE_WARNING("BTA EIR: UUID 128-bit list is truncated"); 3916 break; 3917 } 3918 } 3919 } 3920 3921 UINT8_TO_STREAM(p_length, num_uuid * LEN_UUID_128 + 1); 3922 UINT8_TO_STREAM(p_type, data_type); 3923 free_eir_length -= num_uuid * LEN_UUID_128 + 2; 3924 } 3925 #endif /* ( BTA_EIR_CANNED_UUID_LIST != TRUE )&&(BTA_EIR_SERVER_NUM_CUSTOM_UUID > 0) */ 3926 3927 /* if Flags are provided in configuration */ 3928 if(( p_bta_dm_eir_cfg->bta_dm_eir_flag_len > 0 ) 3929 &&( p_bta_dm_eir_cfg->bta_dm_eir_flags ) 3930 &&( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2 )) 3931 { 3932 UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 1); 3933 UINT8_TO_STREAM(p, BTM_EIR_FLAGS_TYPE); 3934 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_flags, 3935 p_bta_dm_eir_cfg->bta_dm_eir_flag_len); 3936 p += p_bta_dm_eir_cfg->bta_dm_eir_flag_len; 3937 free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_flag_len + 2; 3938 } 3939 3940 /* if Manufacturer Specific are provided in configuration */ 3941 if(( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len > 0 ) 3942 &&( p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec ) 3943 &&( free_eir_length >= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2 )) 3944 { 3945 p_length = p; 3946 3947 UINT8_TO_STREAM(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 1); 3948 UINT8_TO_STREAM(p, BTM_EIR_MANUFACTURER_SPECIFIC_TYPE); 3949 memcpy(p, p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec, 3950 p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len); 3951 p += p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len; 3952 free_eir_length -= p_bta_dm_eir_cfg->bta_dm_eir_manufac_spec_len + 2; 3953 3954 } 3955 else 3956 { 3957 p_length = NULL; 3958 } 3959 3960 /* if Inquiry Tx Resp Power compiled */ 3961 if ((p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power) && 3962 (free_eir_length >= 3)) 3963 { 3964 UINT8_TO_STREAM(p, 2); /* Length field */ 3965 UINT8_TO_STREAM(p, BTM_EIR_TX_POWER_LEVEL_TYPE); 3966 UINT8_TO_STREAM(p, *(p_bta_dm_eir_cfg->bta_dm_eir_inq_tx_power)); 3967 free_eir_length -= 3; 3968 } 3969 3970 if( free_eir_length ) 3971 UINT8_TO_STREAM(p, 0); /* terminator of significant part */ 3972 3973 BTM_WriteEIR( p_buf ); 3974 3975 } 3976 3977 /******************************************************************************* 3978 ** 3979 ** Function bta_dm_eir_search_services 3980 ** 3981 ** Description This function searches services in received EIR 3982 ** 3983 ** Returns None 3984 ** 3985 *******************************************************************************/ 3986 static void bta_dm_eir_search_services( tBTM_INQ_RESULTS *p_result, 3987 tBTA_SERVICE_MASK *p_services_to_search, 3988 tBTA_SERVICE_MASK *p_services_found) 3989 { 3990 tBTA_SERVICE_MASK service_index = 0; 3991 tBTM_EIR_SEARCH_RESULT result; 3992 3993 APPL_TRACE_DEBUG("BTA searching services in EIR of BDA:0x%02X%02X%02X%02X%02X%02X", 3994 p_result->remote_bd_addr[0],p_result->remote_bd_addr[1], 3995 p_result->remote_bd_addr[2],p_result->remote_bd_addr[3], 3996 p_result->remote_bd_addr[4],p_result->remote_bd_addr[5]); 3997 3998 APPL_TRACE_DEBUG(" with services_to_search=0x%08X", *p_services_to_search); 3999 4000 #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE 4001 /* always do GATT based service discovery by SDP instead of from EIR */ 4002 /* if GATT based service is also to be put in EIR, need to modify this */ 4003 while (service_index < (BTA_MAX_SERVICE_ID - 1)) 4004 #else 4005 while(service_index < BTA_MAX_SERVICE_ID) 4006 #endif 4007 { 4008 if( *p_services_to_search 4009 & (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index))) 4010 { 4011 result = BTM_HasInquiryEirService( p_result, 4012 bta_service_id_to_uuid_lkup_tbl[service_index] ); 4013 4014 /* Searching for HSP v1.2 only device */ 4015 if ((result != BTM_EIR_FOUND) && 4016 (bta_service_id_to_uuid_lkup_tbl[service_index] == UUID_SERVCLASS_HEADSET)) 4017 { 4018 result = BTM_HasInquiryEirService (p_result, UUID_SERVCLASS_HEADSET_HS); 4019 } 4020 4021 if( result == BTM_EIR_FOUND ) 4022 { 4023 /* If Plug and Play service record, need to check to see if Broadcom stack */ 4024 /* However, EIR data doesn't have EXT_BRCM_VERSION so just skip it */ 4025 if( bta_service_id_to_uuid_lkup_tbl[service_index] 4026 != UUID_SERVCLASS_PNP_INFORMATION ) 4027 { 4028 4029 *p_services_found |= 4030 (tBTA_SERVICE_MASK)(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index)); 4031 /* remove the service from services to be searched */ 4032 *p_services_to_search &= 4033 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index))); 4034 } 4035 } 4036 else if( result == BTM_EIR_NOT_FOUND ) 4037 { 4038 /* remove the service from services to be searched */ 4039 *p_services_to_search &= 4040 (tBTA_SERVICE_MASK)(~(BTA_SERVICE_ID_TO_SERVICE_MASK(service_index))); 4041 } 4042 } 4043 4044 service_index++; 4045 } 4046 4047 APPL_TRACE_ERROR("BTA EIR search result, services_to_search=0x%08X, services_found=0x%08X", 4048 *p_services_to_search, *p_services_found); 4049 } 4050 4051 #if (BTA_EIR_CANNED_UUID_LIST != TRUE) 4052 /******************************************************************************* 4053 ** 4054 ** Function bta_dm_eir_update_uuid 4055 ** 4056 ** Description This function adds or removes service UUID in EIR database. 4057 ** 4058 ** Returns None 4059 ** 4060 *******************************************************************************/ 4061 void bta_dm_eir_update_uuid(UINT16 uuid16, BOOLEAN adding) 4062 { 4063 /* if this UUID is not advertised in EIR */ 4064 if( !BTM_HasEirService( p_bta_dm_eir_cfg->uuid_mask, uuid16 )) 4065 return; 4066 4067 if( adding ) 4068 { 4069 APPL_TRACE_EVENT("Adding UUID=0x%04X into EIR", uuid16); 4070 4071 BTM_AddEirService( bta_dm_cb.eir_uuid, uuid16 ); 4072 } 4073 else 4074 { 4075 APPL_TRACE_EVENT("Removing UUID=0x%04X from EIR", uuid16); 4076 4077 BTM_RemoveEirService( bta_dm_cb.eir_uuid, uuid16 ); 4078 } 4079 4080 bta_dm_set_eir (NULL); 4081 4082 APPL_TRACE_EVENT("bta_dm_eir_update_uuid UUID bit mask=0x%08X %08X", 4083 bta_dm_cb.eir_uuid[1], bta_dm_cb.eir_uuid[0] ); 4084 } 4085 #endif 4086 4087 /******************************************************************************* 4088 ** 4089 ** Function bta_dm_enable_test_mode 4090 ** 4091 ** Description enable test mode 4092 ** 4093 ** 4094 ** Returns void 4095 ** 4096 *******************************************************************************/ 4097 void bta_dm_enable_test_mode(tBTA_DM_MSG *p_data) 4098 { 4099 UNUSED(p_data); 4100 BTM_EnableTestMode(); 4101 } 4102 4103 /******************************************************************************* 4104 ** 4105 ** Function bta_dm_disable_test_mode 4106 ** 4107 ** Description disable test mode 4108 ** 4109 ** 4110 ** Returns void 4111 ** 4112 *******************************************************************************/ 4113 void bta_dm_disable_test_mode(tBTA_DM_MSG *p_data) 4114 { 4115 UNUSED(p_data); 4116 BTM_DeviceReset(NULL); 4117 } 4118 4119 /******************************************************************************* 4120 ** 4121 ** Function bta_dm_execute_callback 4122 ** 4123 ** Description Just execute a generic call back in the context of the BTU/BTA tack 4124 ** 4125 ** 4126 ** Returns void 4127 ** 4128 *******************************************************************************/ 4129 void bta_dm_execute_callback(tBTA_DM_MSG *p_data) 4130 { 4131 /* sanity check */ 4132 if(p_data->exec_cback.p_exec_cback == NULL) 4133 { 4134 return; 4135 } 4136 4137 p_data->exec_cback.p_exec_cback(p_data->exec_cback.p_param); 4138 } 4139 4140 /******************************************************************************* 4141 ** 4142 ** Function bta_dm_encrypt_cback 4143 ** 4144 ** Description link encryption complete callback. 4145 ** 4146 ** Returns None 4147 ** 4148 *******************************************************************************/ 4149 void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_data, tBTM_STATUS result) 4150 { 4151 tBTA_STATUS bta_status = BTA_SUCCESS; 4152 tBTA_DM_ENCRYPT_CBACK *p_callback = NULL; 4153 UINT8 i ; 4154 UNUSED(p_ref_data); 4155 4156 for (i=0; i<bta_dm_cb.device_list.count; i++) 4157 { 4158 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, bd_addr) == 0 && 4159 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) 4160 break; 4161 } 4162 4163 if (i < bta_dm_cb.device_list.count) 4164 { 4165 p_callback = bta_dm_cb.device_list.peer_device[i].p_encrypt_cback; 4166 bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = NULL; 4167 } 4168 4169 switch (result) 4170 { 4171 case BTM_SUCCESS: 4172 break; 4173 case BTM_WRONG_MODE: 4174 bta_status = BTA_WRONG_MODE; 4175 break; 4176 case BTM_NO_RESOURCES: 4177 bta_status = BTA_NO_RESOURCES; 4178 break; 4179 case BTM_BUSY: 4180 bta_status = BTA_BUSY; 4181 break; 4182 default: 4183 bta_status = BTA_FAILURE; 4184 break; 4185 } 4186 4187 APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=0x%x", bta_status, p_callback); 4188 4189 if (p_callback) 4190 { 4191 (*p_callback)(bd_addr, transport, bta_status); 4192 } 4193 } 4194 4195 /******************************************************************************* 4196 ** 4197 ** Function bta_dm_set_encryption 4198 ** 4199 ** Description This function to encrypt the link 4200 ** 4201 ** Returns None 4202 ** 4203 *******************************************************************************/ 4204 void bta_dm_set_encryption (tBTA_DM_MSG *p_data) 4205 { 4206 UINT8 i ; 4207 4208 APPL_TRACE_DEBUG("bta_dm_set_encryption"); //todo 4209 if (!p_data->set_encryption.p_callback) 4210 { 4211 APPL_TRACE_ERROR("bta_dm_set_encryption callback is not provided"); 4212 return; 4213 } 4214 for (i=0; i<bta_dm_cb.device_list.count; i++) 4215 { 4216 if (bdcmp( bta_dm_cb.device_list.peer_device[i].peer_bdaddr, p_data->set_encryption.bd_addr) == 0 && 4217 bta_dm_cb.device_list.peer_device[i].conn_state == BTA_DM_CONNECTED) 4218 break; 4219 } 4220 if (i < bta_dm_cb.device_list.count) 4221 { 4222 if (bta_dm_cb.device_list.peer_device[i].p_encrypt_cback) 4223 { 4224 APPL_TRACE_ERROR("earlier enc was not done for same device"); 4225 (*p_data->set_encryption.p_callback)(p_data->set_encryption.bd_addr, 4226 p_data->set_encryption.transport, 4227 BTA_BUSY); 4228 return; 4229 } 4230 4231 if (BTM_SetEncryption(p_data->set_encryption.bd_addr, p_data->set_encryption.transport, 4232 bta_dm_encrypt_cback, NULL, p_data->set_encryption.sec_act) 4233 == BTM_CMD_STARTED) 4234 { 4235 bta_dm_cb.device_list.peer_device[i].p_encrypt_cback = p_data->set_encryption.p_callback; 4236 } 4237 } 4238 } 4239 4240 #if (BLE_INCLUDED == TRUE) 4241 /******************************************************************************* 4242 ** 4243 ** Function bta_dm_observe_results_cb 4244 ** 4245 ** Description Callback for BLE Observe result 4246 ** 4247 ** 4248 ** Returns void 4249 ** 4250 *******************************************************************************/ 4251 static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir) 4252 { 4253 ; 4254 tBTA_DM_SEARCH result; 4255 tBTM_INQ_INFO *p_inq_info; 4256 APPL_TRACE_DEBUG("bta_dm_observe_results_cb") 4257 4258 bdcpy(result.inq_res.bd_addr, p_inq->remote_bd_addr); 4259 result.inq_res.rssi = p_inq->rssi; 4260 result.inq_res.ble_addr_type = p_inq->ble_addr_type; 4261 result.inq_res.inq_result_type = p_inq->inq_result_type; 4262 result.inq_res.device_type = p_inq->device_type; 4263 result.inq_res.flag = p_inq->flag; 4264 4265 /* application will parse EIR to find out remote device name */ 4266 result.inq_res.p_eir = p_eir; 4267 4268 if((p_inq_info = BTM_InqDbRead(p_inq->remote_bd_addr)) != NULL) 4269 { 4270 /* initialize remt_name_not_required to FALSE so that we get the name by default */ 4271 result.inq_res.remt_name_not_required = FALSE; 4272 } 4273 4274 if(bta_dm_search_cb.p_scan_cback) 4275 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_RES_EVT, &result); 4276 4277 if(p_inq_info) 4278 { 4279 /* application indicates if it knows the remote name, inside the callback 4280 copy that to the inquiry data base*/ 4281 if(result.inq_res.remt_name_not_required) 4282 p_inq_info->appl_knows_rem_name = TRUE; 4283 } 4284 } 4285 4286 /******************************************************************************* 4287 ** 4288 ** Function bta_dm_observe_cmpl_cb 4289 ** 4290 ** Description Callback for BLE Observe complete 4291 ** 4292 ** 4293 ** Returns void 4294 ** 4295 *******************************************************************************/ 4296 static void bta_dm_observe_cmpl_cb (void * p_result) 4297 { 4298 tBTA_DM_SEARCH data; 4299 4300 APPL_TRACE_DEBUG("bta_dm_observe_cmpl_cb"); 4301 4302 data.inq_cmpl.num_resps = ((tBTM_INQUIRY_CMPL *)p_result)->num_resp; 4303 if (bta_dm_search_cb.p_scan_cback) 4304 { 4305 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data); 4306 } 4307 } 4308 4309 #if (SMP_INCLUDED == TRUE) 4310 /******************************************************************************* 4311 ** 4312 ** Function bta_dm_ble_smp_cback 4313 ** 4314 ** Description Callback for BLE SMP 4315 ** 4316 ** 4317 ** Returns void 4318 ** 4319 *******************************************************************************/ 4320 static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_DATA *p_data) 4321 { 4322 tBTM_STATUS status = BTM_SUCCESS; 4323 tBTA_DM_SEC sec_event; 4324 char *p_name = NULL; 4325 4326 if (!bta_dm_cb.p_sec_cback) 4327 return BTM_NOT_AUTHORIZED; 4328 4329 memset(&sec_event, 0, sizeof(tBTA_DM_SEC)); 4330 switch (event) 4331 { 4332 case BTM_LE_IO_REQ_EVT: 4333 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE) 4334 4335 bta_dm_co_ble_io_req(bda, 4336 &p_data->io_req.io_cap, 4337 &p_data->io_req.oob_data, 4338 &p_data->io_req.auth_req, 4339 &p_data->io_req.max_key_size, 4340 &p_data->io_req.init_keys, 4341 &p_data->io_req.resp_keys); 4342 #endif 4343 APPL_TRACE_EVENT("io mitm: %d oob_data:%d", p_data->io_req.auth_req, p_data->io_req.oob_data); 4344 4345 break; 4346 4347 case BTM_LE_SEC_REQUEST_EVT: 4348 bdcpy(sec_event.ble_req.bd_addr, bda); 4349 p_name = BTM_SecReadDevName(bda); 4350 if (p_name != NULL) 4351 strlcpy((char*)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN); 4352 else 4353 sec_event.ble_req.bd_name[0] = 0; 4354 bta_dm_cb.p_sec_cback(BTA_DM_BLE_SEC_REQ_EVT, &sec_event); 4355 break; 4356 4357 case BTM_LE_KEY_NOTIF_EVT: 4358 bdcpy(sec_event.key_notif.bd_addr, bda); 4359 p_name = BTM_SecReadDevName(bda); 4360 if (p_name != NULL) 4361 strlcpy((char*)sec_event.key_notif.bd_name, p_name, BD_NAME_LEN); 4362 else 4363 sec_event.key_notif.bd_name[0] = 0; 4364 sec_event.key_notif.passkey = p_data->key_notif; 4365 bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_NOTIF_EVT, &sec_event); 4366 break; 4367 4368 case BTM_LE_KEY_REQ_EVT: 4369 bdcpy(sec_event.ble_req.bd_addr, bda); 4370 bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_REQ_EVT, &sec_event); 4371 break; 4372 4373 case BTM_LE_OOB_REQ_EVT: 4374 bdcpy(sec_event.ble_req.bd_addr, bda); 4375 bta_dm_cb.p_sec_cback(BTA_DM_BLE_OOB_REQ_EVT, &sec_event); 4376 break; 4377 4378 case BTM_LE_NC_REQ_EVT: 4379 bdcpy(sec_event.key_notif.bd_addr, bda); 4380 strlcpy((char*)sec_event.key_notif.bd_name, bta_dm_get_remname(), (BD_NAME_LEN)); 4381 sec_event.key_notif.passkey = p_data->key_notif; 4382 bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event); 4383 break; 4384 4385 case BTM_LE_KEY_EVT: 4386 bdcpy(sec_event.ble_key.bd_addr, bda); 4387 sec_event.ble_key.key_type = p_data->key.key_type; 4388 sec_event.ble_key.p_key_value = p_data->key.p_key_value; 4389 bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event); 4390 break; 4391 4392 case BTM_LE_COMPLT_EVT: 4393 bdcpy(sec_event.auth_cmpl.bd_addr, bda); 4394 #if BLE_INCLUDED == TRUE 4395 BTM_ReadDevInfo(bda, &sec_event.auth_cmpl.dev_type, &sec_event.auth_cmpl.addr_type); 4396 #endif 4397 p_name = BTM_SecReadDevName(bda); 4398 if (p_name != NULL) 4399 strlcpy((char*)sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN)); 4400 else 4401 sec_event.auth_cmpl.bd_name[0] = 0; 4402 4403 if (p_data->complt.reason != 0) 4404 { 4405 sec_event.auth_cmpl.fail_reason = BTA_DM_AUTH_CONVERT_SMP_CODE(((UINT8)p_data->complt.reason)); 4406 /* delete this device entry from Sec Dev DB */ 4407 bta_dm_remove_sec_dev_entry (bda); 4408 } 4409 else 4410 { 4411 sec_event.auth_cmpl.success = TRUE; 4412 if (!p_data->complt.smp_over_br) 4413 GATT_ConfigServiceChangeCCC(bda, TRUE, BT_TRANSPORT_LE); 4414 } 4415 4416 if (bta_dm_cb.p_sec_cback) 4417 { 4418 //bta_dm_cb.p_sec_cback(BTA_DM_AUTH_CMPL_EVT, &sec_event); 4419 bta_dm_cb.p_sec_cback(BTA_DM_BLE_AUTH_CMPL_EVT, &sec_event); 4420 } 4421 break; 4422 4423 default: 4424 status = BTM_NOT_AUTHORIZED; 4425 break; 4426 } 4427 return status; 4428 } 4429 #endif /* SMP_INCLUDED == TRUE */ 4430 4431 /******************************************************************************* 4432 ** 4433 ** Function bta_dm_ble_id_key_cback 4434 ** 4435 ** Description Callback for BLE local ID keys 4436 ** 4437 ** 4438 ** Returns void 4439 ** 4440 *******************************************************************************/ 4441 static void bta_dm_ble_id_key_cback (UINT8 key_type, tBTM_BLE_LOCAL_KEYS *p_key) 4442 { 4443 UINT8 evt; 4444 tBTA_DM_SEC dm_key; 4445 4446 switch (key_type) 4447 { 4448 case BTM_BLE_KEY_TYPE_ID: 4449 case BTM_BLE_KEY_TYPE_ER: 4450 if (bta_dm_cb.p_sec_cback) 4451 { 4452 memcpy(&dm_key.ble_id_keys, p_key, sizeof(tBTM_BLE_LOCAL_KEYS)); 4453 4454 evt = (key_type == BTM_BLE_KEY_TYPE_ID) ? BTA_DM_BLE_LOCAL_IR_EVT :\ 4455 BTA_DM_BLE_LOCAL_ER_EVT; 4456 bta_dm_cb.p_sec_cback(evt, &dm_key); 4457 } 4458 break; 4459 4460 default: 4461 APPL_TRACE_DEBUG("Unknown key type %d", key_type); 4462 break; 4463 } 4464 return; 4465 4466 } 4467 4468 /******************************************************************************* 4469 ** 4470 ** Function bta_dm_add_blekey 4471 ** 4472 ** Description This function adds an BLE Key to an security database entry. 4473 ** This function shall only be called AFTER BTA_DmAddBleDevice has been called. 4474 ** It is normally called during host startup to restore all required information 4475 ** stored in the NVRAM. 4476 ** 4477 ** Parameters: 4478 ** 4479 *******************************************************************************/ 4480 void bta_dm_add_blekey (tBTA_DM_MSG *p_data) 4481 { 4482 if (!BTM_SecAddBleKey (p_data->add_ble_key.bd_addr, 4483 (tBTM_LE_KEY_VALUE *)&p_data->add_ble_key.blekey, 4484 p_data->add_ble_key.key_type)) 4485 { 4486 APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Key for device %08x%04x", 4487 (p_data->add_ble_key.bd_addr[0]<<24)+(p_data->add_ble_key.bd_addr[1]<<16)+\ 4488 (p_data->add_ble_key.bd_addr[2]<<8)+p_data->add_ble_key.bd_addr[3], 4489 (p_data->add_ble_key.bd_addr[4]<<8)+p_data->add_ble_key.bd_addr[5]); 4490 } 4491 } 4492 4493 /******************************************************************************* 4494 ** 4495 ** Function bta_dm_add_ble_device 4496 ** 4497 ** Description This function adds an BLE device to an security database entry. 4498 ** It is normally called during host startup to restore all required information 4499 ** stored in the NVRAM. 4500 ** 4501 ** Parameters: 4502 ** 4503 *******************************************************************************/ 4504 void bta_dm_add_ble_device (tBTA_DM_MSG *p_data) 4505 { 4506 if (!BTM_SecAddBleDevice (p_data->add_ble_device.bd_addr, NULL, 4507 p_data->add_ble_device.dev_type , 4508 p_data->add_ble_device.addr_type)) 4509 { 4510 APPL_TRACE_ERROR ("BTA_DM: Error adding BLE Device for device %08x%04x", 4511 (p_data->add_ble_device.bd_addr[0]<<24)+(p_data->add_ble_device.bd_addr[1]<<16)+ \ 4512 (p_data->add_ble_device.bd_addr[2]<<8)+p_data->add_ble_device.bd_addr[3], 4513 (p_data->add_ble_device.bd_addr[4]<<8)+p_data->add_ble_device.bd_addr[5]); 4514 } 4515 } 4516 4517 /******************************************************************************* 4518 ** 4519 ** Function bta_dm_add_ble_device 4520 ** 4521 ** Description This function adds an BLE device to an security database entry. 4522 ** It is normally called during host startup to restore all required information 4523 ** stored in the NVRAM. 4524 ** 4525 ** Parameters: 4526 ** 4527 *******************************************************************************/ 4528 void bta_dm_ble_passkey_reply (tBTA_DM_MSG *p_data) 4529 { 4530 if (p_data->pin_reply.accept) 4531 { 4532 BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_SUCCESS, p_data->ble_passkey_reply.passkey); 4533 } 4534 else 4535 { 4536 BTM_BlePasskeyReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED, p_data->ble_passkey_reply.passkey); 4537 } 4538 4539 } 4540 4541 /******************************************************************************* 4542 ** 4543 ** Function bta_dm_ble_confirm_reply 4544 ** 4545 ** Description This is response to SM numeric comparison request submitted 4546 ** to application. 4547 ** 4548 ** Parameters: 4549 ** 4550 *******************************************************************************/ 4551 void bta_dm_ble_confirm_reply (tBTA_DM_MSG *p_data) 4552 { 4553 if (p_data->confirm.accept) 4554 { 4555 BTM_BleConfirmReply(p_data->confirm.bd_addr, BTM_SUCCESS); 4556 } 4557 else 4558 { 4559 BTM_BleConfirmReply(p_data->ble_passkey_reply.bd_addr, BTM_NOT_AUTHORIZED); 4560 } 4561 } 4562 4563 /******************************************************************************* 4564 ** 4565 ** Function bta_dm_security_grant 4566 ** 4567 ** Description This function grant SMP security request access. 4568 ** 4569 ** Parameters: 4570 ** 4571 *******************************************************************************/ 4572 void bta_dm_security_grant (tBTA_DM_MSG *p_data) 4573 { 4574 BTM_SecurityGrant(p_data->ble_sec_grant.bd_addr, p_data->ble_sec_grant.res); 4575 } 4576 4577 /******************************************************************************* 4578 ** 4579 ** Function bta_dm_ble_set_bg_conn_type 4580 ** 4581 ** Description This function set the BLE background connection type 4582 ** 4583 ** Parameters: 4584 ** 4585 *******************************************************************************/ 4586 void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data) 4587 { 4588 BTM_BleSetBgConnType(p_data->ble_set_bd_conn_type.bg_conn_type, 4589 p_data->ble_set_bd_conn_type.p_select_cback); 4590 } 4591 4592 /******************************************************************************* 4593 ** 4594 ** Function bta_dm_ble_set_conn_params 4595 ** 4596 ** Description This function set the preferred connection parameters. 4597 ** 4598 ** Parameters: 4599 ** 4600 *******************************************************************************/ 4601 void bta_dm_ble_set_conn_params (tBTA_DM_MSG *p_data) 4602 { 4603 BTM_BleSetPrefConnParams(p_data->ble_set_conn_params.peer_bda, 4604 p_data->ble_set_conn_params.conn_int_min, 4605 p_data->ble_set_conn_params.conn_int_max, 4606 p_data->ble_set_conn_params.slave_latency, 4607 p_data->ble_set_conn_params.supervision_tout); 4608 } 4609 4610 /******************************************************************************* 4611 ** 4612 ** Function bta_dm_ble_set_conn_scan_params 4613 ** 4614 ** Description This function sets BLE scan parameters. 4615 ** 4616 ** Parameters: 4617 ** 4618 *******************************************************************************/ 4619 void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data) 4620 { 4621 BTM_BleSetScanParams(p_data->ble_set_scan_params.client_if, 4622 p_data->ble_set_scan_params.scan_int, 4623 p_data->ble_set_scan_params.scan_window, 4624 p_data->ble_set_scan_params.scan_mode, 4625 p_data->ble_set_scan_params.scan_param_setup_cback); 4626 } 4627 4628 /******************************************************************************* 4629 ** 4630 ** Function bta_dm_ble_set_conn_scan_params 4631 ** 4632 ** Description This function set the preferred connection scan parameters. 4633 ** 4634 ** Parameters: 4635 ** 4636 *******************************************************************************/ 4637 void bta_dm_ble_set_conn_scan_params (tBTA_DM_MSG *p_data) 4638 { 4639 BTM_BleSetConnScanParams(p_data->ble_set_conn_scan_params.scan_int, 4640 p_data->ble_set_conn_scan_params.scan_window); 4641 } 4642 /******************************************************************************* 4643 ** 4644 ** Function bta_dm_ble_update_conn_params 4645 ** 4646 ** Description This function update LE connection parameters. 4647 ** 4648 ** Parameters: 4649 ** 4650 *******************************************************************************/ 4651 void bta_dm_ble_update_conn_params (tBTA_DM_MSG *p_data) 4652 { 4653 if (!L2CA_UpdateBleConnParams(p_data->ble_update_conn_params.bd_addr, 4654 p_data->ble_update_conn_params.min_int, 4655 p_data->ble_update_conn_params.max_int, 4656 p_data->ble_update_conn_params.latency, 4657 p_data->ble_update_conn_params.timeout)) 4658 { 4659 APPL_TRACE_ERROR("Update connection parameters failed!"); 4660 } 4661 } 4662 4663 #if BLE_PRIVACY_SPT == TRUE 4664 /******************************************************************************* 4665 ** 4666 ** Function bta_dm_ble_config_local_privacy 4667 ** 4668 ** Description This function set the local device LE privacy settings. 4669 ** 4670 ** Parameters: 4671 ** 4672 *******************************************************************************/ 4673 void bta_dm_ble_config_local_privacy (tBTA_DM_MSG *p_data) 4674 { 4675 BTM_BleConfigPrivacy (p_data->ble_local_privacy.privacy_enable); 4676 } 4677 #endif 4678 4679 /******************************************************************************* 4680 ** 4681 ** Function bta_dm_ble_observe 4682 ** 4683 ** Description This function set the preferred connection scan parameters. 4684 ** 4685 ** Parameters: 4686 ** 4687 *******************************************************************************/ 4688 void bta_dm_ble_observe (tBTA_DM_MSG *p_data) 4689 { 4690 tBTM_STATUS status; 4691 if (p_data->ble_observe.start) 4692 { 4693 /*Save the callback to be called when a scan results are available */ 4694 bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback; 4695 if ((status = BTM_BleObserve(TRUE, p_data->ble_observe.duration, 4696 bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb))!= BTM_CMD_STARTED) 4697 { 4698 tBTA_DM_SEARCH data; 4699 APPL_TRACE_WARNING(" %s BTM_BleObserve failed. status %d",__FUNCTION__,status); 4700 data.inq_cmpl.num_resps = 0; 4701 if (bta_dm_search_cb.p_scan_cback) 4702 { 4703 bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data); 4704 } 4705 } 4706 } 4707 else 4708 { 4709 bta_dm_search_cb.p_scan_cback = NULL; 4710 BTM_BleObserve(FALSE, 0, NULL,NULL ); 4711 } 4712 } 4713 /******************************************************************************* 4714 ** 4715 ** Function bta_dm_ble_set_adv_params 4716 ** 4717 ** Description This function set the adv parameters. 4718 ** 4719 ** Parameters: 4720 ** 4721 *******************************************************************************/ 4722 void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data) 4723 { 4724 BTM_BleSetAdvParams(p_data->ble_set_adv_params.adv_int_min, 4725 p_data->ble_set_adv_params.adv_int_max, 4726 p_data->ble_set_adv_params.p_dir_bda, 4727 BTA_DM_BLE_ADV_CHNL_MAP); 4728 } 4729 4730 /******************************************************************************* 4731 ** 4732 ** Function bta_dm_ble_set_adv_config 4733 ** 4734 ** Description This function set the customized ADV data configuration 4735 ** 4736 ** Parameters: 4737 ** 4738 *******************************************************************************/ 4739 void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data) 4740 { 4741 tBTA_STATUS status = BTA_FAILURE; 4742 4743 if (BTM_BleWriteAdvData(p_data->ble_set_adv_data.data_mask, 4744 (tBTM_BLE_ADV_DATA *)&p_data->ble_set_adv_data.adv_cfg) == BTM_SUCCESS) 4745 { 4746 status = BTA_SUCCESS; 4747 } 4748 4749 if (p_data->ble_set_adv_data.p_adv_data_cback) 4750 (*p_data->ble_set_adv_data.p_adv_data_cback)(status); 4751 } 4752 4753 /******************************************************************************* 4754 ** 4755 ** Function bta_dm_ble_set_scan_rsp 4756 ** 4757 ** Description This function set the customized ADV scan resp. configuration 4758 ** 4759 ** Parameters: 4760 ** 4761 *******************************************************************************/ 4762 void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data) 4763 { 4764 tBTA_STATUS status = BTA_FAILURE; 4765 4766 if(BTM_BleWriteScanRsp(p_data->ble_set_adv_data.data_mask, 4767 (tBTM_BLE_ADV_DATA *)&p_data->ble_set_adv_data.adv_cfg) == BTM_SUCCESS) 4768 { 4769 status = BTA_SUCCESS; 4770 } 4771 4772 if (p_data->ble_set_adv_data.p_adv_data_cback) 4773 (*p_data->ble_set_adv_data.p_adv_data_cback)(status); 4774 } 4775 4776 /******************************************************************************* 4777 ** 4778 ** Function bta_dm_ble_set_data_length 4779 ** 4780 ** Description This function set the maximum transmission packet size 4781 ** 4782 ** Parameters 4783 ** 4784 *******************************************************************************/ 4785 void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data) 4786 { 4787 if (BTM_SetBleDataLength(p_data->ble_set_data_length.remote_bda, 4788 p_data->ble_set_data_length.tx_data_length) != BTM_SUCCESS) 4789 { 4790 APPL_TRACE_ERROR("%s failed", __FUNCTION__); 4791 } 4792 } 4793 4794 /******************************************************************************* 4795 ** 4796 ** Function bta_dm_ble_broadcast 4797 ** 4798 ** Description Starts or stops LE broadcasts 4799 ** 4800 ** Parameters: 4801 ** 4802 *******************************************************************************/ 4803 void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data) 4804 { 4805 BTM_BleBroadcast(p_data->ble_observe.start); 4806 } 4807 4808 /******************************************************************************* 4809 ** 4810 ** Function bta_dm_ble_multi_adv_enb 4811 ** 4812 ** Description This function enables a single advertising instance 4813 ** 4814 ** Parameters: 4815 ** 4816 *******************************************************************************/ 4817 void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data) 4818 { 4819 tBTM_STATUS btm_status = 0; 4820 4821 bta_dm_cb.p_multi_adv_cback = p_data->ble_multi_adv_enb.p_cback; 4822 if(BTM_BleMaxMultiAdvInstanceCount() > 0 && NULL != p_data->ble_multi_adv_enb.p_ref) 4823 { 4824 btm_status = BTM_BleEnableAdvInstance((tBTM_BLE_ADV_PARAMS*) 4825 p_data->ble_multi_adv_enb.p_params, 4826 p_data->ble_multi_adv_enb.p_cback, 4827 p_data->ble_multi_adv_enb.p_ref); 4828 } 4829 4830 if(BTM_CMD_STARTED != btm_status) 4831 { 4832 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_ENB_EVT, 0xFF, 4833 p_data->ble_multi_adv_enb.p_ref, BTA_FAILURE); 4834 } 4835 } 4836 /******************************************************************************* 4837 ** 4838 ** Function bta_dm_ble_multi_adv_param_upd 4839 ** 4840 ** Description This function updates multiple advertising instance parameters 4841 ** 4842 ** Parameters: 4843 ** 4844 *******************************************************************************/ 4845 void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data) 4846 { 4847 tBTM_STATUS btm_status = 0; 4848 void *p_ref = NULL; 4849 4850 if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_param.inst_id > 0 4851 && p_data->ble_multi_adv_param.inst_id < BTM_BleMaxMultiAdvInstanceCount()) 4852 { 4853 btm_status = BTM_BleUpdateAdvInstParam(p_data->ble_multi_adv_param.inst_id, 4854 (tBTM_BLE_ADV_PARAMS*)p_data->ble_multi_adv_param.p_params); 4855 } 4856 4857 if(BTM_CMD_STARTED != btm_status) 4858 { 4859 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_param.inst_id); 4860 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_PARAM_EVT, 4861 p_data->ble_multi_adv_param.inst_id, p_ref, BTA_FAILURE); 4862 } 4863 } 4864 /******************************************************************************* 4865 ** 4866 ** Function bta_dm_ble_multi_adv_data 4867 ** 4868 ** Description This function write multiple advertising instance adv data 4869 ** or scan response data 4870 ** 4871 ** Parameters: 4872 ** 4873 *******************************************************************************/ 4874 void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data) 4875 { 4876 tBTM_STATUS btm_status = 0; 4877 void *p_ref = NULL; 4878 4879 if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_data.inst_id > 0 4880 && p_data->ble_multi_adv_data.inst_id < BTM_BleMaxMultiAdvInstanceCount()) 4881 { 4882 btm_status = BTM_BleCfgAdvInstData(p_data->ble_multi_adv_data.inst_id, 4883 p_data->ble_multi_adv_data.is_scan_rsp, 4884 p_data->ble_multi_adv_data.data_mask, 4885 (tBTM_BLE_ADV_DATA*)&p_data->ble_multi_adv_data.data); 4886 } 4887 4888 if(BTM_CMD_STARTED != btm_status) 4889 { 4890 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_data.inst_id); 4891 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DATA_EVT, 4892 p_data->ble_multi_adv_data.inst_id, p_ref, BTA_FAILURE); 4893 } 4894 4895 } 4896 /******************************************************************************* 4897 ** 4898 ** Function btm_dm_ble_multi_adv_disable 4899 ** 4900 ** Description This function disable a single adv instance 4901 ** 4902 ** Parameters: 4903 ** 4904 *******************************************************************************/ 4905 void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data) 4906 { 4907 tBTM_STATUS btm_status = 0; 4908 void *p_ref = NULL; 4909 4910 if(BTM_BleMaxMultiAdvInstanceCount() > 0 && p_data->ble_multi_adv_disable.inst_id > 0 4911 && p_data->ble_multi_adv_disable.inst_id < BTM_BleMaxMultiAdvInstanceCount()) 4912 { 4913 btm_status = BTM_BleDisableAdvInstance(p_data->ble_multi_adv_disable.inst_id); 4914 } 4915 4916 if(BTM_CMD_STARTED != btm_status) 4917 { 4918 p_ref = btm_ble_multi_adv_get_ref(p_data->ble_multi_adv_disable.inst_id); 4919 bta_dm_cb.p_multi_adv_cback(BTA_BLE_MULTI_ADV_DISABLE_EVT, 4920 p_data->ble_multi_adv_disable.inst_id, p_ref, BTA_FAILURE); 4921 } 4922 } 4923 4924 /******************************************************************************* 4925 ** 4926 ** Function bta_dm_ble_setup_storage 4927 ** 4928 ** Description This function configures up the storage parameters for ADV batch scanning 4929 ** 4930 ** Parameters: 4931 ** 4932 *******************************************************************************/ 4933 void bta_dm_ble_setup_storage (tBTA_DM_MSG *p_data) 4934 { 4935 tBTM_STATUS btm_status = 0; 4936 tBTM_BLE_VSC_CB cmn_ble_vsc_cb; 4937 4938 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); 4939 4940 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) 4941 { 4942 btm_status = BTM_BleSetStorageConfig(p_data->ble_set_storage.batch_scan_full_max, 4943 p_data->ble_set_storage.batch_scan_trunc_max, 4944 p_data->ble_set_storage.batch_scan_notify_threshold, 4945 p_data->ble_set_storage.p_setup_cback, 4946 p_data->ble_set_storage.p_thres_cback, 4947 p_data->ble_set_storage.p_read_rep_cback, 4948 p_data->ble_set_storage.ref_value); 4949 } 4950 4951 if(BTM_CMD_STARTED != btm_status) 4952 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_CFG_STRG_EVT, p_data->ble_set_storage.ref_value, 4953 btm_status); 4954 } 4955 4956 /******************************************************************************* 4957 ** 4958 ** Function bta_dm_ble_enable_batch_scan 4959 ** 4960 ** Description This function sets up the parameters and enables batch scan 4961 ** 4962 ** Parameters: 4963 ** 4964 *******************************************************************************/ 4965 void bta_dm_ble_enable_batch_scan (tBTA_DM_MSG *p_data) 4966 { 4967 tBTM_STATUS btm_status = 0; 4968 tBTM_BLE_VSC_CB cmn_ble_vsc_cb; 4969 4970 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); 4971 4972 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) 4973 { 4974 btm_status = BTM_BleEnableBatchScan(p_data->ble_enable_scan.scan_mode, 4975 p_data->ble_enable_scan.scan_int, 4976 p_data->ble_enable_scan.scan_window, 4977 p_data->ble_enable_scan.discard_rule, 4978 p_data->ble_enable_scan.addr_type, 4979 p_data->ble_enable_scan.ref_value); 4980 } 4981 4982 if(BTM_CMD_STARTED != btm_status) 4983 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_ENABLE_EVT, p_data->ble_enable_scan.ref_value, 4984 btm_status); 4985 } 4986 4987 /******************************************************************************* 4988 ** 4989 ** Function bta_dm_ble_disable_batch_scan 4990 ** 4991 ** Description This function disables the batch scan 4992 ** 4993 ** Parameters: 4994 ** 4995 *******************************************************************************/ 4996 void bta_dm_ble_disable_batch_scan (tBTA_DM_MSG *p_data) 4997 { 4998 UNUSED(p_data); 4999 tBTM_STATUS btm_status = 0; 5000 tBTM_BLE_VSC_CB cmn_ble_vsc_cb; 5001 5002 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); 5003 5004 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) 5005 { 5006 btm_status = BTM_BleDisableBatchScan(p_data->ble_disable_scan.ref_value); 5007 } 5008 5009 if(BTM_CMD_STARTED != btm_status) 5010 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_DISABLE_EVT, p_data->ble_enable_scan.ref_value, 5011 btm_status); 5012 } 5013 5014 /******************************************************************************* 5015 ** 5016 ** Function bta_dm_ble_read_scan_reports 5017 ** 5018 ** Description This function reads the batch scan reports 5019 ** 5020 ** Parameters: 5021 ** 5022 *******************************************************************************/ 5023 void bta_dm_ble_read_scan_reports(tBTA_DM_MSG *p_data) 5024 { 5025 tBTM_STATUS btm_status = 0; 5026 tBTM_BLE_VSC_CB cmn_ble_vsc_cb; 5027 5028 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); 5029 5030 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) 5031 { 5032 btm_status = BTM_BleReadScanReports(p_data->ble_read_reports.scan_type, 5033 p_data->ble_read_reports.ref_value); 5034 } 5035 5036 if(BTM_CMD_STARTED != btm_status) 5037 bta_ble_scan_setup_cb(BTM_BLE_BATCH_SCAN_READ_REPTS_EVT, p_data->ble_enable_scan.ref_value, 5038 btm_status); 5039 } 5040 5041 /******************************************************************************* 5042 ** 5043 ** Function bta_dm_ble_track_advertiser 5044 ** 5045 ** Description This function tracks the specific advertiser 5046 ** 5047 ** Parameters: 5048 ** 5049 *******************************************************************************/ 5050 void bta_dm_ble_track_advertiser(tBTA_DM_MSG *p_data) 5051 { 5052 tBTM_STATUS btm_status = 0; 5053 BD_ADDR bda; 5054 memset(&bda, 0 , sizeof(BD_ADDR)); 5055 tBTM_BLE_VSC_CB cmn_ble_vsc_cb; 5056 tBTA_DM_BLE_TRACK_ADV_DATA track_adv_data; 5057 5058 BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb); 5059 5060 if (0 != cmn_ble_vsc_cb.tot_scan_results_strg) 5061 { 5062 btm_status = BTM_BleTrackAdvertiser((tBTM_BLE_TRACK_ADV_CBACK *) 5063 p_data->ble_track_advert.p_track_adv_cback, 5064 p_data->ble_track_advert.ref_value); 5065 } 5066 5067 if(BTM_CMD_STARTED != btm_status) 5068 { 5069 memset(&track_adv_data, 0, sizeof(tBTA_DM_BLE_TRACK_ADV_DATA)); 5070 track_adv_data.advertiser_info_present = NO_ADV_INFO_PRESENT; /* Indicates failure */ 5071 track_adv_data.client_if = (UINT8)p_data->ble_track_advert.ref_value; 5072 p_data->ble_track_advert.p_track_adv_cback(&track_adv_data); 5073 } 5074 } 5075 5076 /******************************************************************************* 5077 ** 5078 ** Function bta_ble_scan_setup_cb 5079 ** 5080 ** Description Handle the setup callback from BTM layer and forward it to app layer 5081 ** 5082 ** Parameters: 5083 ** 5084 *******************************************************************************/ 5085 void bta_ble_scan_setup_cb(tBTM_BLE_BATCH_SCAN_EVT evt, tBTM_BLE_REF_VALUE ref_value, 5086 tBTM_STATUS status) 5087 { 5088 tBTA_BLE_BATCH_SCAN_EVT bta_evt = 0; 5089 5090 APPL_TRACE_DEBUG("bta_ble_scan_setup_cb : evt: %d, ref_value: %d, status:%d", evt, 5091 ref_value, status); 5092 5093 switch(evt) 5094 { 5095 case BTM_BLE_BATCH_SCAN_ENABLE_EVT: 5096 bta_evt = BTA_BLE_BATCH_SCAN_ENB_EVT; 5097 break; 5098 case BTM_BLE_BATCH_SCAN_CFG_STRG_EVT: 5099 bta_evt = BTA_BLE_BATCH_SCAN_CFG_STRG_EVT; 5100 break; 5101 case BTM_BLE_BATCH_SCAN_DISABLE_EVT: 5102 bta_evt = BTA_BLE_BATCH_SCAN_DIS_EVT; 5103 break; 5104 case BTM_BLE_BATCH_SCAN_PARAM_EVT: 5105 bta_evt = BTA_BLE_BATCH_SCAN_PARAM_EVT; 5106 break; 5107 default: 5108 break; 5109 } 5110 5111 if(NULL != bta_dm_cb.p_setup_cback) 5112 bta_dm_cb.p_setup_cback(bta_evt, ref_value, status); 5113 } 5114 5115 5116 #if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE 5117 /******************************************************************************* 5118 ** 5119 ** Function bta_ble_scan_pf_cmpl 5120 ** 5121 ** Description ADV payload filtering operation complete callback 5122 ** 5123 ** 5124 ** Returns TRUE if handled, otherwise FALSE. 5125 ** 5126 *******************************************************************************/ 5127 static void bta_ble_scan_cfg_cmpl(tBTM_BLE_PF_ACTION action, tBTM_BLE_SCAN_COND_OP cfg_op, 5128 tBTM_BLE_PF_AVBL_SPACE avbl_space, tBTM_STATUS status, 5129 tBTM_BLE_REF_VALUE ref_value) 5130 { 5131 tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE; 5132 5133 APPL_TRACE_DEBUG("bta_ble_scan_cfg_cmpl: %d, %d, %d, %d", action, cfg_op, avbl_space, status); 5134 5135 if(bta_dm_cb.p_scan_filt_cfg_cback) 5136 bta_dm_cb.p_scan_filt_cfg_cback(action, cfg_op, avbl_space, st, ref_value); 5137 } 5138 5139 /******************************************************************************* 5140 ** 5141 ** Function bta_dm_cfg_filter_cond 5142 ** 5143 ** Description This function configure adv payload filtering condition 5144 ** 5145 ** Parameters: 5146 ** 5147 *******************************************************************************/ 5148 void bta_dm_cfg_filter_cond (tBTA_DM_MSG *p_data) 5149 { 5150 tBTM_STATUS st = BTM_MODE_UNSUPPORTED; 5151 tBTA_STATUS status = BTA_FAILURE; 5152 5153 tBTM_BLE_VSC_CB cmn_vsc_cb; 5154 5155 APPL_TRACE_DEBUG("bta_dm_cfg_filter_cond"); 5156 BTM_BleGetVendorCapabilities(&cmn_vsc_cb); 5157 if(0 != cmn_vsc_cb.filter_support) 5158 { 5159 if ((st = BTM_BleCfgFilterCondition(p_data->ble_cfg_filter_cond.action, 5160 p_data->ble_cfg_filter_cond.cond_type, 5161 (tBTM_BLE_PF_FILT_INDEX)p_data->ble_cfg_filter_cond.filt_index, 5162 (tBTM_BLE_PF_COND_PARAM *)p_data->ble_cfg_filter_cond.p_cond_param, 5163 bta_ble_scan_cfg_cmpl, p_data->ble_cfg_filter_cond.ref_value)) 5164 == BTM_CMD_STARTED) 5165 { 5166 bta_dm_cb.p_scan_filt_cfg_cback = p_data->ble_cfg_filter_cond.p_filt_cfg_cback; 5167 return; 5168 } 5169 } 5170 5171 if (p_data->ble_cfg_filter_cond.p_filt_cfg_cback) 5172 p_data->ble_cfg_filter_cond.p_filt_cfg_cback(BTA_DM_BLE_PF_CONFIG_EVT, 5173 p_data->ble_cfg_filter_cond.cond_type, 0, status, 5174 p_data->ble_cfg_filter_cond.ref_value); 5175 return; 5176 } 5177 5178 /******************************************************************************* 5179 ** 5180 ** Function bta_dm_enable_scan_filter 5181 ** 5182 ** Description This function enable/disable adv payload filtering condition 5183 ** 5184 ** Parameters: 5185 ** 5186 *******************************************************************************/ 5187 void bta_dm_enable_scan_filter(tBTA_DM_MSG *p_data) 5188 { 5189 tBTM_STATUS st = BTM_MODE_UNSUPPORTED; 5190 tBTA_STATUS status = BTA_FAILURE; 5191 5192 tBTM_BLE_VSC_CB cmn_vsc_cb; 5193 APPL_TRACE_DEBUG("bta_dm_enable_scan_filter"); 5194 BTM_BleGetVendorCapabilities(&cmn_vsc_cb); 5195 5196 if(0 != cmn_vsc_cb.filter_support) 5197 { 5198 if((st = BTM_BleEnableDisableFilterFeature(p_data->ble_enable_scan_filt.action, 5199 p_data->ble_enable_scan_filt.p_filt_status_cback, 5200 (tBTM_BLE_REF_VALUE)p_data->ble_enable_scan_filt.ref_value)) == BTM_CMD_STARTED) 5201 bta_dm_cb.p_scan_filt_status_cback = p_data->ble_enable_scan_filt.p_filt_status_cback; 5202 return; 5203 } 5204 5205 if (p_data->ble_enable_scan_filt.p_filt_status_cback) 5206 p_data->ble_enable_scan_filt.p_filt_status_cback (BTA_DM_BLE_PF_ENABLE_EVT, 5207 p_data->ble_enable_scan_filt.ref_value, status); 5208 5209 } 5210 5211 /******************************************************************************* 5212 ** 5213 ** Function bta_dm_scan_filter_param_setup 5214 ** 5215 ** Description This function sets up scan filter params 5216 ** 5217 ** Parameters: 5218 ** 5219 *******************************************************************************/ 5220 void bta_dm_scan_filter_param_setup (tBTA_DM_MSG *p_data) 5221 { 5222 tBTM_STATUS st = BTM_MODE_UNSUPPORTED; 5223 tBTA_STATUS status = BTA_FAILURE; 5224 5225 tBTM_BLE_VSC_CB cmn_vsc_cb; 5226 5227 APPL_TRACE_DEBUG("bta_dm_scan_filter_param_setup"); 5228 BTM_BleGetVendorCapabilities(&cmn_vsc_cb); 5229 if(0 != cmn_vsc_cb.filter_support) 5230 { 5231 if ((st = BTM_BleAdvFilterParamSetup(p_data->ble_scan_filt_param_setup.action, 5232 p_data->ble_scan_filt_param_setup.filt_index, 5233 (tBTM_BLE_PF_FILT_PARAMS *)&p_data->ble_scan_filt_param_setup.filt_params, 5234 p_data->ble_scan_filt_param_setup.p_target, 5235 p_data->ble_scan_filt_param_setup.p_filt_param_cback, 5236 p_data->ble_scan_filt_param_setup.ref_value)) == BTM_CMD_STARTED) 5237 { 5238 bta_dm_cb.p_scan_filt_param_cback = p_data->ble_scan_filt_param_setup.p_filt_param_cback; 5239 return; 5240 } 5241 } 5242 5243 if (p_data->ble_scan_filt_param_setup.p_filt_param_cback) 5244 p_data->ble_scan_filt_param_setup.p_filt_param_cback (BTA_DM_BLE_PF_ENABLE_EVT, 0, 5245 p_data->ble_scan_filt_param_setup.ref_value, status); 5246 5247 return; 5248 } 5249 #endif 5250 5251 /******************************************************************************* 5252 ** 5253 ** Function bta_ble_enable_scan_cmpl 5254 ** 5255 ** Description ADV payload filtering enable / disable complete callback 5256 ** 5257 ** 5258 ** Returns None 5259 ** 5260 *******************************************************************************/ 5261 static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time, 5262 tBTM_BLE_RX_TIME_MS rx_time, 5263 tBTM_BLE_IDLE_TIME_MS idle_time, 5264 tBTM_BLE_ENERGY_USED energy_used, 5265 tBTM_STATUS status) 5266 { 5267 tBTA_STATUS st = (status == BTM_SUCCESS) ? BTA_SUCCESS: BTA_FAILURE; 5268 tBTA_DM_CONTRL_STATE ctrl_state = 0; 5269 5270 if (BTA_SUCCESS == st) 5271 ctrl_state = bta_dm_pm_obtain_controller_state(); 5272 5273 if (bta_dm_cb.p_energy_info_cback) 5274 bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, ctrl_state, st); 5275 } 5276 5277 /******************************************************************************* 5278 ** 5279 ** Function bta_dm_ble_get_energy_info 5280 ** 5281 ** Description This function obtains the energy info 5282 ** 5283 ** Parameters: 5284 ** 5285 *******************************************************************************/ 5286 void bta_dm_ble_get_energy_info(tBTA_DM_MSG *p_data) 5287 { 5288 tBTM_STATUS btm_status = 0; 5289 5290 bta_dm_cb.p_energy_info_cback = p_data->ble_energy_info.p_energy_info_cback; 5291 btm_status = BTM_BleGetEnergyInfo(bta_ble_energy_info_cmpl); 5292 if (BTM_CMD_STARTED != btm_status) 5293 bta_ble_energy_info_cmpl(0, 0, 0, 0, btm_status); 5294 } 5295 5296 #if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)) 5297 #ifndef BTA_DM_GATT_CLOSE_DELAY_TOUT 5298 #define BTA_DM_GATT_CLOSE_DELAY_TOUT 1000 5299 #endif 5300 5301 /******************************************************************************* 5302 ** 5303 ** Function bta_dm_gattc_register 5304 ** 5305 ** Description Register with GATTC in DM if BLE is needed. 5306 ** 5307 ** 5308 ** Returns void 5309 ** 5310 *******************************************************************************/ 5311 static void bta_dm_gattc_register(void) 5312 { 5313 tBT_UUID app_uuid = {LEN_UUID_128,{0}}; 5314 5315 if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF) 5316 { 5317 memset (&app_uuid.uu.uuid128, 0x87, LEN_UUID_128); 5318 BTA_GATTC_AppRegister(&app_uuid, bta_dm_gattc_callback); 5319 } 5320 } 5321 5322 /******************************************************************************* 5323 ** 5324 ** Function btm_dm_start_disc_gatt_services 5325 ** 5326 ** Description This function starts a GATT service search request. 5327 ** 5328 ** Parameters: 5329 ** 5330 *******************************************************************************/ 5331 static void btm_dm_start_disc_gatt_services (UINT16 conn_id) 5332 { 5333 tBT_UUID *p_uuid = bta_dm_search_cb.p_srvc_uuid + 5334 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search; 5335 5336 p_uuid = bta_dm_search_cb.p_srvc_uuid + 5337 bta_dm_search_cb.num_uuid - bta_dm_search_cb.uuid_to_search; 5338 5339 /* always search for all services */ 5340 BTA_GATTC_ServiceSearchRequest(conn_id, p_uuid); 5341 } 5342 5343 /******************************************************************************* 5344 ** 5345 ** Function bta_dm_gatt_disc_result 5346 ** 5347 ** Description This function process the GATT service search result. 5348 ** 5349 ** Parameters: 5350 ** 5351 *******************************************************************************/ 5352 static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id) 5353 { 5354 tBTA_DM_SEARCH result; 5355 5356 /* 5357 * This logic will not work for gatt case. We are checking against the bluetooth profiles here 5358 * just copy the GATTID in raw data field and send it across. 5359 */ 5360 5361 5362 if ( bta_dm_search_cb.ble_raw_used + sizeof(tBTA_GATT_ID) < bta_dm_search_cb.ble_raw_size ) 5363 { 5364 APPL_TRACE_DEBUG("ADDING BLE SERVICE uuid=0x%x, ble_ptr = 0x%x, ble_raw_used = 0x%x", 5365 service_id.uuid.uu.uuid16,bta_dm_search_cb.p_ble_rawdata,bta_dm_search_cb.ble_raw_used); 5366 5367 if(bta_dm_search_cb.p_ble_rawdata) 5368 { 5369 memcpy((bta_dm_search_cb.p_ble_rawdata + bta_dm_search_cb.ble_raw_used), &service_id, 5370 sizeof(service_id) ); 5371 5372 bta_dm_search_cb.ble_raw_used += sizeof(service_id); 5373 } 5374 else 5375 { 5376 APPL_TRACE_ERROR("p_ble_rawdata is NULL"); 5377 } 5378 5379 } 5380 else 5381 { 5382 APPL_TRACE_ERROR("%s out of room to accomodate more service ids ble_raw_size = %d ble_raw_used = %d", __FUNCTION__,bta_dm_search_cb.ble_raw_size, bta_dm_search_cb.ble_raw_used ); 5383 } 5384 5385 LOG_INFO(LOG_TAG, "%s service_id_uuid_len=%d ", __func__, service_id.uuid.len); 5386 if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) 5387 { 5388 5389 /* send result back to app now, one by one */ 5390 bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr); 5391 strlcpy((char*)result.disc_ble_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN); 5392 memcpy(&result.disc_ble_res.service, &service_id.uuid, sizeof(tBT_UUID)); 5393 5394 bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result); 5395 } 5396 } 5397 5398 /******************************************************************************* 5399 ** 5400 ** Function bta_dm_gatt_disc_complete 5401 ** 5402 ** Description This function process the GATT service search complete. 5403 ** 5404 ** Parameters: 5405 ** 5406 *******************************************************************************/ 5407 static void bta_dm_gatt_disc_complete(UINT16 conn_id, tBTA_GATT_STATUS status) 5408 { 5409 APPL_TRACE_DEBUG("%s conn_id = %d", __func__, conn_id); 5410 5411 if (bta_dm_search_cb.uuid_to_search > 0) 5412 bta_dm_search_cb.uuid_to_search --; 5413 5414 if (status == BTA_GATT_OK && bta_dm_search_cb.uuid_to_search > 0) { 5415 btm_dm_start_disc_gatt_services(conn_id); 5416 } else { 5417 tBTA_DM_MSG *p_msg = (tBTA_DM_MSG *)osi_malloc(sizeof(tBTA_DM_MSG)); 5418 5419 bta_dm_search_cb.uuid_to_search = 0; 5420 5421 /* no more services to be discovered */ 5422 p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT; 5423 p_msg->disc_result.result.disc_res.result = (status == BTA_GATT_OK) ? BTA_SUCCESS :BTA_FAILURE; 5424 APPL_TRACE_DEBUG("%s service found: 0x%08x", __func__, 5425 bta_dm_search_cb.services_found); 5426 p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found; 5427 p_msg->disc_result.result.disc_res.num_uuids = 0; 5428 p_msg->disc_result.result.disc_res.p_uuid_list = NULL; 5429 bdcpy(p_msg->disc_result.result.disc_res.bd_addr, 5430 bta_dm_search_cb.peer_bdaddr); 5431 strlcpy((char*)p_msg->disc_result.result.disc_res.bd_name, 5432 bta_dm_get_remname(), BD_NAME_LEN); 5433 5434 p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE; 5435 if (bta_dm_search_cb.ble_raw_used > 0) { 5436 p_msg->disc_result.result.disc_res.p_raw_data = 5437 osi_malloc(bta_dm_search_cb.ble_raw_used); 5438 5439 memcpy(p_msg->disc_result.result.disc_res.p_raw_data, 5440 bta_dm_search_cb.p_ble_rawdata, 5441 bta_dm_search_cb.ble_raw_used); 5442 5443 p_msg->disc_result.result.disc_res.raw_data_size = 5444 bta_dm_search_cb.ble_raw_used; 5445 } else { 5446 p_msg->disc_result.result.disc_res.p_raw_data = NULL; 5447 bta_dm_search_cb.p_ble_rawdata = 0; 5448 } 5449 5450 bta_sys_sendmsg(p_msg); 5451 5452 if (conn_id != BTA_GATT_INVALID_CONN_ID) 5453 { 5454 /* start a GATT channel close delay timer */ 5455 bta_sys_start_timer(bta_dm_search_cb.gatt_close_timer, 5456 BTA_DM_GATT_CLOSE_DELAY_TOUT, 5457 BTA_DM_DISC_CLOSE_TOUT_EVT, 0); 5458 bdcpy(bta_dm_search_cb.pending_close_bda, 5459 bta_dm_search_cb.peer_bdaddr); 5460 } 5461 bta_dm_search_cb.gatt_disc_active = FALSE; 5462 } 5463 } 5464 5465 /******************************************************************************* 5466 ** 5467 ** Function bta_dm_close_gatt_conn 5468 ** 5469 ** Description This function close the GATT connection after delay timeout. 5470 ** 5471 ** Parameters: 5472 ** 5473 *******************************************************************************/ 5474 void bta_dm_close_gatt_conn(tBTA_DM_MSG *p_data) 5475 { 5476 UNUSED(p_data); 5477 5478 if (bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID) 5479 BTA_GATTC_Close(bta_dm_search_cb.conn_id); 5480 5481 memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN); 5482 bta_dm_search_cb.conn_id = BTA_GATT_INVALID_CONN_ID; 5483 } 5484 /******************************************************************************* 5485 ** 5486 ** Function btm_dm_start_gatt_discovery 5487 ** 5488 ** Description This is GATT initiate the service search by open a GATT connection 5489 ** first. 5490 ** 5491 ** Parameters: 5492 ** 5493 *******************************************************************************/ 5494 void btm_dm_start_gatt_discovery (BD_ADDR bd_addr) 5495 { 5496 bta_dm_search_cb.gatt_disc_active = TRUE; 5497 5498 /* connection is already open */ 5499 if (bdcmp(bta_dm_search_cb.pending_close_bda, bd_addr) == 0 && 5500 bta_dm_search_cb.conn_id != BTA_GATT_INVALID_CONN_ID) 5501 { 5502 memset(bta_dm_search_cb.pending_close_bda, 0, BD_ADDR_LEN); 5503 alarm_cancel(bta_dm_search_cb.gatt_close_timer); 5504 btm_dm_start_disc_gatt_services(bta_dm_search_cb.conn_id); 5505 } 5506 else 5507 BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, TRUE, BTA_GATT_TRANSPORT_LE); 5508 } 5509 5510 /******************************************************************************* 5511 ** 5512 ** Function bta_dm_cancel_gatt_discovery 5513 ** 5514 ** Description This is GATT cancel the GATT service search. 5515 ** 5516 ** Parameters: 5517 ** 5518 *******************************************************************************/ 5519 static void bta_dm_cancel_gatt_discovery(BD_ADDR bd_addr) 5520 { 5521 if (bta_dm_search_cb.conn_id == BTA_GATT_INVALID_CONN_ID) 5522 { 5523 BTA_GATTC_CancelOpen(bta_dm_search_cb.client_if, bd_addr, TRUE); 5524 } 5525 5526 bta_dm_gatt_disc_complete(bta_dm_search_cb.conn_id, (tBTA_GATT_STATUS) BTA_GATT_ERROR); 5527 } 5528 5529 /******************************************************************************* 5530 ** 5531 ** Function bta_dm_proc_open_evt 5532 ** 5533 ** Description process BTA_GATTC_OPEN_EVT in DM. 5534 ** 5535 ** Parameters: 5536 ** 5537 *******************************************************************************/ 5538 void bta_dm_proc_open_evt(tBTA_GATTC_OPEN *p_data) 5539 { 5540 UINT8 *p1; 5541 UINT8 *p2; 5542 5543 p1 = bta_dm_search_cb.peer_bdaddr; 5544 p2 = p_data->remote_bda; 5545 5546 APPL_TRACE_DEBUG("DM Search state= %d search_cb.peer_dbaddr: [%08x%04x] connected_bda= [%08x%04x] ", 5547 bta_dm_search_cb.state, 5548 ((p1[0])<<24)+((p1[1])<<16)+((p1[2])<<8)+(p1[3]), 5549 ((p1[4])<<8)+ p1[5], 5550 ((p2[0])<<24)+((p2[1])<<16)+((p2[2])<<8)+(p2[3]), 5551 ((p2[4])<<8)+ p2[5]); 5552 5553 APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d" , 5554 p_data->conn_id, 5555 p_data->client_if, 5556 p_data->status); 5557 5558 bta_dm_search_cb.conn_id = p_data->conn_id; 5559 5560 if (p_data->status == BTA_GATT_OK) 5561 { 5562 btm_dm_start_disc_gatt_services(p_data->conn_id); 5563 } 5564 else 5565 { 5566 bta_dm_gatt_disc_complete(BTA_GATT_INVALID_CONN_ID, p_data->status); 5567 } 5568 } 5569 5570 /******************************************************************************* 5571 ** 5572 ** Function bta_dm_gattc_callback 5573 ** 5574 ** Description This is GATT client callback function used in DM. 5575 ** 5576 ** Parameters: 5577 ** 5578 *******************************************************************************/ 5579 static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC *p_data) 5580 { 5581 APPL_TRACE_DEBUG("bta_dm_gattc_callback event = %d", event); 5582 5583 switch (event) 5584 { 5585 case BTA_GATTC_REG_EVT: 5586 APPL_TRACE_DEBUG("BTA_GATTC_REG_EVT client_if = %d", p_data->reg_oper.client_if); 5587 if (p_data->reg_oper.status == BTA_GATT_OK) 5588 bta_dm_search_cb.client_if = p_data->reg_oper.client_if; 5589 else 5590 bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF; 5591 break; 5592 5593 case BTA_GATTC_OPEN_EVT: 5594 bta_dm_proc_open_evt(&p_data->open); 5595 break; 5596 5597 case BTA_GATTC_SEARCH_RES_EVT: 5598 bta_dm_gatt_disc_result(p_data->srvc_res.service_uuid); 5599 break; 5600 5601 case BTA_GATTC_SEARCH_CMPL_EVT: 5602 if ( bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) 5603 bta_dm_gatt_disc_complete(p_data->search_cmpl.conn_id, p_data->search_cmpl.status); 5604 break; 5605 5606 case BTA_GATTC_CLOSE_EVT: 5607 APPL_TRACE_DEBUG("BTA_GATTC_CLOSE_EVT reason = %d", p_data->close.reason); 5608 /* in case of disconnect before search is completed */ 5609 if ( (bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) && 5610 (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) && 5611 !memcmp(p_data->close.remote_bda, bta_dm_search_cb.peer_bdaddr, BD_ADDR_LEN)) 5612 { 5613 bta_dm_gatt_disc_complete((UINT16)BTA_GATT_INVALID_CONN_ID, (tBTA_GATT_STATUS) BTA_GATT_ERROR); 5614 } 5615 break; 5616 5617 default: 5618 break; 5619 } 5620 } 5621 5622 #endif /* BTA_GATT_INCLUDED */ 5623 5624 #if BLE_VND_INCLUDED == TRUE 5625 /******************************************************************************* 5626 ** 5627 ** Function bta_dm_ctrl_features_rd_cmpl_cback 5628 ** 5629 ** Description callback to handle controller feature read complete 5630 ** 5631 ** Parameters: 5632 ** 5633 *******************************************************************************/ 5634 static void bta_dm_ctrl_features_rd_cmpl_cback(tBTM_STATUS result) 5635 { 5636 APPL_TRACE_DEBUG("%s status = %d ", __FUNCTION__, result); 5637 if (result == BTM_SUCCESS) 5638 { 5639 if(bta_dm_cb.p_sec_cback) 5640 bta_dm_cb.p_sec_cback(BTA_DM_LE_FEATURES_READ, NULL); 5641 } 5642 else 5643 { 5644 APPL_TRACE_ERROR("%s Ctrl BLE feature read failed: status :%d",__FUNCTION__, result); 5645 } 5646 5647 } 5648 #endif /* BLE_VND_INCLUDED */ 5649 5650 #endif /* BLE_INCLUDED */ 5651