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