1 /****************************************************************************** 2 * 3 * Copyright (C) 1999-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 functions for the Bluetooth Device Manager 22 * 23 ******************************************************************************/ 24 25 #include <stdlib.h> 26 #include <string.h> 27 #include <stdio.h> 28 #include <stddef.h> 29 30 #include "bt_types.h" 31 #include "gki.h" 32 #include "hcimsgs.h" 33 #include "btu.h" 34 #include "btm_api.h" 35 #include "btm_int.h" 36 #include "hcidefs.h" 37 #include "l2c_api.h" 38 static tBTM_SEC_DEV_REC *btm_find_oldest_dev (void); 39 40 /******************************************************************************* 41 ** 42 ** Function BTM_SecAddDevice 43 ** 44 ** Description Add/modify device. This function will be normally called 45 ** during host startup to restore all required information 46 ** stored in the NVRAM. 47 ** 48 ** Parameters: bd_addr - BD address of the peer 49 ** dev_class - Device Class 50 ** bd_name - Name of the peer device. NULL if unknown. 51 ** features - Remote device's features (up to 3 pages). NULL if not known 52 ** trusted_mask - Bitwise OR of services that do not 53 ** require authorization. (array of UINT32) 54 ** link_key - Connection link key. NULL if unknown. 55 ** 56 ** Returns TRUE if added OK, else FALSE 57 ** 58 *******************************************************************************/ 59 BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, 60 UINT8 *features, UINT32 trusted_mask[], 61 LINK_KEY link_key, UINT8 key_type, tBTM_IO_CAP io_cap) 62 { 63 tBTM_SEC_DEV_REC *p_dev_rec; 64 int i, j; 65 BOOLEAN found = FALSE; 66 67 p_dev_rec = btm_find_dev (bd_addr); 68 if (!p_dev_rec) 69 { 70 /* There is no device record, allocate one. 71 * If we can not find an empty spot for this one, let it fail. */ 72 for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++) 73 { 74 if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE)) 75 { 76 p_dev_rec = &btm_cb.sec_dev_rec[i]; 77 78 /* Mark this record as in use and initialize */ 79 memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC)); 80 p_dev_rec->sec_flags = BTM_SEC_IN_USE; 81 memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN); 82 p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr); 83 84 #if BLE_INCLUDED == TRUE 85 /* use default value for background connection params */ 86 /* update conn params, use default value for background connection params */ 87 memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS)); 88 #endif 89 break; 90 } 91 } 92 93 if (!p_dev_rec) 94 return(FALSE); 95 } 96 97 p_dev_rec->timestamp = btm_cb.dev_rec_count++; 98 99 if (dev_class) 100 memcpy (p_dev_rec->dev_class, dev_class, DEV_CLASS_LEN); 101 102 memset(p_dev_rec->sec_bd_name, 0, sizeof(tBTM_BD_NAME)); 103 104 if (bd_name && bd_name[0]) 105 { 106 p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN; 107 BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, sizeof (p_dev_rec->sec_bd_name), 108 (char *)bd_name, BTM_MAX_REM_BD_NAME_LEN); 109 } 110 111 p_dev_rec->num_read_pages = 0; 112 if (features) 113 { 114 memcpy (p_dev_rec->features, features, sizeof (p_dev_rec->features)); 115 for (i = HCI_EXT_FEATURES_PAGE_MAX; i >= 0; i--) 116 { 117 for (j = 0; j < HCI_FEATURE_BYTES_PER_PAGE; j++) 118 { 119 if (p_dev_rec->features[i][j] != 0) 120 { 121 found = TRUE; 122 break; 123 } 124 } 125 if (found) 126 { 127 p_dev_rec->num_read_pages = i + 1; 128 break; 129 } 130 } 131 } 132 else 133 memset (p_dev_rec->features, 0, sizeof (p_dev_rec->features)); 134 135 BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask); 136 137 if (link_key) 138 { 139 BTM_TRACE_EVENT6 ("BTM_SecAddDevice() BDA: %02x:%02x:%02x:%02x:%02x:%02x", 140 bd_addr[0], bd_addr[1], bd_addr[2], 141 bd_addr[3], bd_addr[4], bd_addr[5]); 142 p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN; 143 memcpy (p_dev_rec->link_key, link_key, LINK_KEY_LEN); 144 p_dev_rec->link_key_type = key_type; 145 } 146 147 #if defined(BTIF_MIXED_MODE_INCLUDED) && (BTIF_MIXED_MODE_INCLUDED == TRUE) 148 if (key_type < BTM_MAX_PRE_SM4_LKEY_TYPE) 149 p_dev_rec->sm4 = BTM_SM4_KNOWN; 150 else 151 p_dev_rec->sm4 = BTM_SM4_TRUE; 152 #endif 153 154 p_dev_rec->rmt_io_caps = io_cap; 155 156 return(TRUE); 157 } 158 159 160 /******************************************************************************* 161 ** 162 ** Function BTM_SecDeleteDevice 163 ** 164 ** Description Free resources associated with the device. 165 ** 166 ** Parameters: bd_addr - BD address of the peer 167 ** 168 ** Returns TRUE if removed OK, FALSE if not found or ACL link is active 169 ** 170 *******************************************************************************/ 171 BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr) 172 { 173 tBTM_SEC_DEV_REC *p_dev_rec; 174 175 if (BTM_IsAclConnectionUp(bd_addr)) 176 { 177 BTM_TRACE_WARNING0("BTM_SecDeleteDevice FAILED: Cannot Delete when connection is active"); 178 return(FALSE); 179 } 180 181 if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL) 182 return(FALSE); 183 184 btm_sec_free_dev (p_dev_rec); 185 186 /* Tell controller to get rid of the link key if it has one stored */ 187 BTM_DeleteStoredLinkKey (bd_addr, NULL); 188 189 return(TRUE); 190 } 191 192 /******************************************************************************* 193 ** 194 ** Function BTM_SecReadDevName 195 ** 196 ** Description Looks for the device name in the security database for the 197 ** specified BD address. 198 ** 199 ** Returns Pointer to the name or NULL 200 ** 201 *******************************************************************************/ 202 char *BTM_SecReadDevName (BD_ADDR bd_addr) 203 { 204 char *p_name = NULL; 205 tBTM_SEC_DEV_REC *p_srec; 206 207 if ((p_srec = btm_find_dev(bd_addr)) != NULL) 208 p_name = (char *)p_srec->sec_bd_name; 209 210 return(p_name); 211 } 212 213 /******************************************************************************* 214 ** 215 ** Function btm_sec_alloc_dev 216 ** 217 ** Description Look for the record in the device database for the record 218 ** with specified handle 219 ** 220 ** Returns Pointer to the record 221 ** 222 *******************************************************************************/ 223 tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr) 224 { 225 tBTM_SEC_DEV_REC *p_dev_rec = NULL; 226 tBTM_INQ_INFO *p_inq_info; 227 int i; 228 BTM_TRACE_EVENT0 ("btm_sec_alloc_dev"); 229 for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++) 230 { 231 if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE)) 232 { 233 p_dev_rec = &btm_cb.sec_dev_rec[i]; 234 break; 235 } 236 } 237 238 if (!p_dev_rec) 239 p_dev_rec = btm_find_oldest_dev(); 240 241 memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC)); 242 243 p_dev_rec->sec_flags = BTM_SEC_IN_USE; 244 245 /* Check with the BT manager if details about remote device are known */ 246 /* outgoing connection */ 247 if ((p_inq_info = BTM_InqDbRead(bd_addr)) != NULL) 248 { 249 memcpy (p_dev_rec->dev_class, p_inq_info->results.dev_class, DEV_CLASS_LEN); 250 251 #if BLE_INCLUDED == TRUE 252 p_dev_rec->device_type = p_inq_info->results.device_type; 253 p_dev_rec->ble.ble_addr_type = p_inq_info->results.ble_addr_type; 254 255 /* update conn params, use default value for background connection params */ 256 memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS)); 257 #endif 258 259 #if BTM_INQ_GET_REMOTE_NAME == TRUE 260 if (p_inq_info->remote_name_state == BTM_INQ_RMT_NAME_DONE) 261 { 262 BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, sizeof (p_dev_rec->sec_bd_name), 263 (char *)p_inq_info->remote_name, BTM_MAX_REM_BD_NAME_LEN); 264 p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN; 265 } 266 #endif 267 } 268 else 269 { 270 #if BLE_INCLUDED == TRUE 271 /* update conn params, use default value for background connection params */ 272 memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS)); 273 #endif 274 275 if (!memcmp (bd_addr, btm_cb.connecting_bda, BD_ADDR_LEN)) 276 memcpy (p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN); 277 } 278 279 memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN); 280 281 p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr); 282 p_dev_rec->timestamp = btm_cb.dev_rec_count++; 283 284 return(p_dev_rec); 285 } 286 287 288 /******************************************************************************* 289 ** 290 ** Function btm_sec_free_dev 291 ** 292 ** Description Mark device record as not used 293 ** 294 *******************************************************************************/ 295 void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec) 296 { 297 p_dev_rec->sec_flags = 0; 298 299 #if BLE_INCLUDED == TRUE 300 /* Clear out any saved BLE keys */ 301 btm_sec_clear_ble_keys (p_dev_rec); 302 #endif 303 304 305 } 306 307 /******************************************************************************* 308 ** 309 ** Function btm_dev_support_switch 310 ** 311 ** Description This function is called by the L2CAP to check if remote 312 ** device supports role switch 313 ** 314 ** Parameters: bd_addr - Address of the peer device 315 ** 316 ** Returns TRUE if device is known and role switch is supported 317 ** 318 *******************************************************************************/ 319 BOOLEAN btm_dev_support_switch (BD_ADDR bd_addr) 320 { 321 tBTM_SEC_DEV_REC *p_dev_rec; 322 UINT8 xx; 323 BOOLEAN feature_empty = TRUE; 324 325 #if BTM_SCO_INCLUDED == TRUE 326 /* Role switch is not allowed if a SCO is up */ 327 if (btm_is_sco_active_by_bdaddr(bd_addr)) 328 return(FALSE); 329 #endif 330 p_dev_rec = btm_find_dev (bd_addr); 331 if (p_dev_rec && HCI_SWITCH_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0])) 332 { 333 if (HCI_SWITCH_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0])) 334 { 335 BTM_TRACE_DEBUG0("btm_dev_support_switch return TRUE (feature found)"); 336 return (TRUE); 337 } 338 339 /* If the feature field is all zero, we never received them */ 340 for (xx = 0 ; xx < BD_FEATURES_LEN ; xx++) 341 { 342 if (p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0][xx] != 0x00) 343 { 344 feature_empty = FALSE; /* at least one is != 0 */ 345 break; 346 } 347 } 348 349 /* If we don't know peer's capabilities, assume it supports Role-switch */ 350 if (feature_empty) 351 { 352 BTM_TRACE_DEBUG0("btm_dev_support_switch return TRUE (feature empty)"); 353 return (TRUE); 354 } 355 } 356 357 BTM_TRACE_DEBUG0("btm_dev_support_switch return FALSE"); 358 return(FALSE); 359 } 360 361 /******************************************************************************* 362 ** 363 ** Function btm_find_dev_by_handle 364 ** 365 ** Description Look for the record in the device database for the record 366 ** with specified handle 367 ** 368 ** Returns Pointer to the record or NULL 369 ** 370 *******************************************************************************/ 371 tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle) 372 { 373 tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; 374 int i; 375 376 for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) 377 { 378 if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) 379 && (p_dev_rec->hci_handle == handle)) 380 return(p_dev_rec); 381 } 382 return(NULL); 383 } 384 385 /******************************************************************************* 386 ** 387 ** Function btm_find_dev 388 ** 389 ** Description Look for the record in the device database for the record 390 ** with specified BD address 391 ** 392 ** Returns Pointer to the record or NULL 393 ** 394 *******************************************************************************/ 395 tBTM_SEC_DEV_REC *btm_find_dev (BD_ADDR bd_addr) 396 { 397 tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; 398 int i; 399 400 if (bd_addr) 401 { 402 for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) 403 { 404 if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) 405 && (!memcmp (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN))) 406 return(p_dev_rec); 407 } 408 } 409 return(NULL); 410 } 411 412 /******************************************************************************* 413 ** 414 ** Function btm_find_or_alloc_dev 415 ** 416 ** Description Look for the record in the device database for the record 417 ** with specified BD address 418 ** 419 ** Returns Pointer to the record or NULL 420 ** 421 *******************************************************************************/ 422 tBTM_SEC_DEV_REC *btm_find_or_alloc_dev (BD_ADDR bd_addr) 423 { 424 tBTM_SEC_DEV_REC *p_dev_rec; 425 BTM_TRACE_EVENT0 ("btm_find_or_alloc_dev"); 426 if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL) 427 { 428 429 /* Allocate a new device record or reuse the oldest one */ 430 p_dev_rec = btm_sec_alloc_dev (bd_addr); 431 } 432 return(p_dev_rec); 433 } 434 435 /******************************************************************************* 436 ** 437 ** Function btm_find_oldest_dev 438 ** 439 ** Description Locates the oldest device in use. It first looks for 440 ** the oldest non-paired device. If all devices are paired it 441 ** deletes the oldest paired device. 442 ** 443 ** Returns Pointer to the record 444 ** 445 *******************************************************************************/ 446 tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) 447 { 448 tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; 449 tBTM_SEC_DEV_REC *p_oldest = p_dev_rec; 450 UINT32 ot = 0xFFFFFFFF; 451 int i; 452 453 /* First look for the non-paired devices for the oldest entry */ 454 for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) 455 { 456 if (((p_dev_rec->sec_flags & BTM_SEC_IN_USE) == 0) 457 || ((p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) != 0)) 458 continue; /* Device is paired so skip it */ 459 460 if (p_dev_rec->timestamp < ot) 461 { 462 p_oldest = p_dev_rec; 463 ot = p_dev_rec->timestamp; 464 } 465 } 466 467 if (ot != 0xFFFFFFFF) 468 return(p_oldest); 469 470 /* All devices are paired; find the oldest */ 471 p_dev_rec = &btm_cb.sec_dev_rec[0]; 472 for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) 473 { 474 if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) == 0) 475 continue; 476 477 if (p_dev_rec->timestamp < ot) 478 { 479 p_oldest = p_dev_rec; 480 ot = p_dev_rec->timestamp; 481 } 482 } 483 return(p_oldest); 484 } 485 486 487