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