Home | History | Annotate | Download | only in btm
      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 "device/include/controller.h"
     32 #include "gki.h"
     33 #include "hcimsgs.h"
     34 #include "btu.h"
     35 #include "btm_api.h"
     36 #include "btm_int.h"
     37 #include "hcidefs.h"
     38 #include "l2c_api.h"
     39 
     40 static tBTM_SEC_DEV_REC *btm_find_oldest_dev (void);
     41 
     42 /*******************************************************************************
     43 **
     44 ** Function         BTM_SecAddDevice
     45 **
     46 ** Description      Add/modify device.  This function will be normally called
     47 **                  during host startup to restore all required information
     48 **                  stored in the NVRAM.
     49 **
     50 ** Parameters:      bd_addr          - BD address of the peer
     51 **                  dev_class        - Device Class
     52 **                  bd_name          - Name of the peer device.  NULL if unknown.
     53 **                  features         - Remote device's features (up to 3 pages). NULL if not known
     54 **                  trusted_mask     - Bitwise OR of services that do not
     55 **                                     require authorization. (array of UINT32)
     56 **                  link_key         - Connection link key. NULL if unknown.
     57 **
     58 ** Returns          TRUE if added OK, else FALSE
     59 **
     60 *******************************************************************************/
     61 BOOLEAN BTM_SecAddDevice (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name,
     62                           UINT8 *features, UINT32 trusted_mask[],
     63                           LINK_KEY link_key, UINT8 key_type, tBTM_IO_CAP io_cap,
     64                           UINT8 pin_length)
     65 {
     66     tBTM_SEC_DEV_REC  *p_dev_rec;
     67     int               i, j;
     68     BOOLEAN           found = FALSE;
     69 
     70     BTM_TRACE_API("%s, link key type:%x", __FUNCTION__,key_type);
     71     p_dev_rec = btm_find_dev (bd_addr);
     72     if (!p_dev_rec)
     73     {
     74         /* There is no device record, allocate one.
     75          * If we can not find an empty spot for this one, let it fail. */
     76         for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++)
     77         {
     78             if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE))
     79             {
     80                 p_dev_rec = &btm_cb.sec_dev_rec[i];
     81 
     82                 /* Mark this record as in use and initialize */
     83                 memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC));
     84                 p_dev_rec->sec_flags = BTM_SEC_IN_USE;
     85                 memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
     86                 p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
     87 
     88 #if BLE_INCLUDED == TRUE
     89                 /* use default value for background connection params */
     90                 /* update conn params, use default value for background connection params */
     91                 memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS));
     92 #endif
     93                 break;
     94             }
     95         }
     96 
     97         if (!p_dev_rec)
     98             return(FALSE);
     99     }
    100 
    101     p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;           /* Default value */
    102     p_dev_rec->timestamp = btm_cb.dev_rec_count++;
    103 
    104     if (dev_class)
    105         memcpy (p_dev_rec->dev_class, dev_class, DEV_CLASS_LEN);
    106 
    107     memset(p_dev_rec->sec_bd_name, 0, sizeof(tBTM_BD_NAME));
    108 
    109     if (bd_name && bd_name[0])
    110     {
    111         p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
    112         BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, sizeof (p_dev_rec->sec_bd_name),
    113             (char *)bd_name, BTM_MAX_REM_BD_NAME_LEN);
    114     }
    115 
    116     p_dev_rec->num_read_pages = 0;
    117     if (features)
    118     {
    119         memcpy (p_dev_rec->features, features, sizeof (p_dev_rec->features));
    120         for (i = HCI_EXT_FEATURES_PAGE_MAX; i >= 0; i--)
    121         {
    122             for (j = 0; j < HCI_FEATURE_BYTES_PER_PAGE; j++)
    123             {
    124                 if (p_dev_rec->features[i][j] != 0)
    125                 {
    126                     found = TRUE;
    127                     break;
    128                 }
    129             }
    130             if (found)
    131             {
    132                 p_dev_rec->num_read_pages = i + 1;
    133                 break;
    134             }
    135         }
    136     }
    137     else
    138         memset (p_dev_rec->features, 0, sizeof (p_dev_rec->features));
    139 
    140     BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
    141 
    142     if (link_key)
    143     {
    144         BTM_TRACE_EVENT ("BTM_SecAddDevice()  BDA: %02x:%02x:%02x:%02x:%02x:%02x",
    145                           bd_addr[0], bd_addr[1], bd_addr[2],
    146                           bd_addr[3], bd_addr[4], bd_addr[5]);
    147         p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN;
    148         memcpy (p_dev_rec->link_key, link_key, LINK_KEY_LEN);
    149         p_dev_rec->link_key_type = key_type;
    150         p_dev_rec->pin_code_length = pin_length;
    151 
    152         if (pin_length >= 16 ||
    153             key_type == BTM_LKEY_TYPE_AUTH_COMB ||
    154             key_type == BTM_LKEY_TYPE_AUTH_COMB_P_256) {
    155             // Set the fiag if the link key was made by using either a 16 digit
    156             // pin or MITM.
    157             p_dev_rec->sec_flags |= BTM_SEC_16_DIGIT_PIN_AUTHED;
    158         }
    159     }
    160 
    161 #if defined(BTIF_MIXED_MODE_INCLUDED) && (BTIF_MIXED_MODE_INCLUDED == TRUE)
    162     if (key_type  < BTM_MAX_PRE_SM4_LKEY_TYPE)
    163         p_dev_rec->sm4 = BTM_SM4_KNOWN;
    164     else
    165         p_dev_rec->sm4 = BTM_SM4_TRUE;
    166 #endif
    167 
    168     p_dev_rec->rmt_io_caps = io_cap;
    169     p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR;
    170 
    171     return(TRUE);
    172 }
    173 
    174 
    175 /*******************************************************************************
    176 **
    177 ** Function         BTM_SecDeleteDevice
    178 **
    179 ** Description      Free resources associated with the device.
    180 **
    181 ** Parameters:      bd_addr          - BD address of the peer
    182 **
    183 ** Returns          TRUE if removed OK, FALSE if not found or ACL link is active
    184 **
    185 *******************************************************************************/
    186 BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr)
    187 {
    188     tBTM_SEC_DEV_REC *p_dev_rec;
    189 
    190     if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) ||
    191         BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR))
    192     {
    193         BTM_TRACE_WARNING("%s FAILED: Cannot Delete when connection is active", __func__);
    194         return FALSE;
    195     }
    196 
    197     if ((p_dev_rec = btm_find_dev(bd_addr)) != NULL)
    198     {
    199         btm_sec_free_dev(p_dev_rec);
    200         /* Tell controller to get rid of the link key, if it has one stored */
    201         BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL);
    202     }
    203 
    204     return TRUE;
    205 }
    206 
    207 /*******************************************************************************
    208 **
    209 ** Function         BTM_SecReadDevName
    210 **
    211 ** Description      Looks for the device name in the security database for the
    212 **                  specified BD address.
    213 **
    214 ** Returns          Pointer to the name or NULL
    215 **
    216 *******************************************************************************/
    217 char *BTM_SecReadDevName (BD_ADDR bd_addr)
    218 {
    219     char *p_name = NULL;
    220     tBTM_SEC_DEV_REC *p_srec;
    221 
    222     if ((p_srec = btm_find_dev(bd_addr)) != NULL)
    223         p_name = (char *)p_srec->sec_bd_name;
    224 
    225     return(p_name);
    226 }
    227 
    228 /*******************************************************************************
    229 **
    230 ** Function         btm_sec_alloc_dev
    231 **
    232 ** Description      Look for the record in the device database for the record
    233 **                  with specified address
    234 **
    235 ** Returns          Pointer to the record or NULL
    236 **
    237 *******************************************************************************/
    238 tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr)
    239 {
    240     tBTM_SEC_DEV_REC *p_dev_rec = NULL;
    241     tBTM_INQ_INFO    *p_inq_info;
    242     int               i;
    243     DEV_CLASS         old_cod;
    244     int               i_new_entry = BTM_SEC_MAX_DEVICE_RECORDS;
    245     int               i_old_entry = BTM_SEC_MAX_DEVICE_RECORDS;
    246     BTM_TRACE_EVENT ("btm_sec_alloc_dev");
    247 
    248     for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++)
    249     {
    250         /* look for old entry where device details are present */
    251         if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE) &&
    252              (!memcmp (btm_cb.sec_dev_rec[i].bd_addr, bd_addr, BD_ADDR_LEN)))
    253         {
    254             i_old_entry = i;
    255             BTM_TRACE_EVENT ("btm_sec_alloc_dev  old device found");
    256             break;
    257         }
    258     }
    259 
    260     for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++)
    261     {
    262         if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE))
    263         {
    264             i_new_entry = i;
    265             break;
    266         }
    267     }
    268 
    269     if (i_new_entry == BTM_SEC_MAX_DEVICE_RECORDS) {
    270         p_dev_rec = btm_find_oldest_dev();
    271     }
    272     else {
    273         /* if the old device entry not present go with
    274             new entry */
    275         if(i_old_entry == BTM_SEC_MAX_DEVICE_RECORDS) {
    276             p_dev_rec = &btm_cb.sec_dev_rec[i_new_entry];
    277         }
    278         else {
    279             p_dev_rec = &btm_cb.sec_dev_rec[i_old_entry];
    280             memcpy (old_cod, p_dev_rec->dev_class, DEV_CLASS_LEN);
    281         }
    282     }
    283     memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC));
    284 
    285     /* Retain the old COD for device */
    286     if(i_old_entry != BTM_SEC_MAX_DEVICE_RECORDS) {
    287         BTM_TRACE_EVENT ("btm_sec_alloc_dev restoring cod ");
    288         memcpy (p_dev_rec->dev_class, old_cod, DEV_CLASS_LEN);
    289 
    290     }
    291 
    292     p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;           /* Default value */
    293     p_dev_rec->sec_flags = BTM_SEC_IN_USE;
    294 
    295     /* Check with the BT manager if details about remote device are known */
    296     /* outgoing connection */
    297     if ((p_inq_info = BTM_InqDbRead(bd_addr)) != NULL)
    298     {
    299         memcpy (p_dev_rec->dev_class, p_inq_info->results.dev_class, DEV_CLASS_LEN);
    300 
    301 #if BLE_INCLUDED == TRUE
    302         p_dev_rec->device_type = p_inq_info->results.device_type;
    303         p_dev_rec->ble.ble_addr_type = p_inq_info->results.ble_addr_type;
    304 
    305         /* update conn params, use default value for background connection params */
    306         memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS));
    307 #endif
    308     }
    309     else
    310     {
    311 #if BLE_INCLUDED == TRUE
    312         /* update conn params, use default value for background connection params */
    313         memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS));
    314 #endif
    315 
    316         if (!memcmp (bd_addr, btm_cb.connecting_bda, BD_ADDR_LEN))
    317             memcpy (p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN);
    318     }
    319 
    320     memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
    321 
    322 #if BLE_INCLUDED == TRUE
    323     p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_LE);
    324 #endif
    325     p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
    326     p_dev_rec->timestamp = btm_cb.dev_rec_count++;
    327 
    328     return(p_dev_rec);
    329 }
    330 
    331 
    332 /*******************************************************************************
    333 **
    334 ** Function         btm_sec_free_dev
    335 **
    336 ** Description      Mark device record as not used
    337 **
    338 *******************************************************************************/
    339 void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec)
    340 {
    341     p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;
    342     p_dev_rec->sec_flags = 0;
    343 
    344 #if BLE_INCLUDED == TRUE
    345     /* Clear out any saved BLE keys */
    346     btm_sec_clear_ble_keys (p_dev_rec);
    347 #endif
    348 
    349 
    350 }
    351 
    352 /*******************************************************************************
    353 **
    354 ** Function         btm_dev_support_switch
    355 **
    356 ** Description      This function is called by the L2CAP to check if remote
    357 **                  device supports role switch
    358 **
    359 ** Parameters:      bd_addr       - Address of the peer device
    360 **
    361 ** Returns          TRUE if device is known and role switch is supported
    362 **
    363 *******************************************************************************/
    364 BOOLEAN btm_dev_support_switch (BD_ADDR bd_addr)
    365 {
    366     tBTM_SEC_DEV_REC  *p_dev_rec;
    367     UINT8   xx;
    368     BOOLEAN feature_empty = TRUE;
    369 
    370 #if BTM_SCO_INCLUDED == TRUE
    371     /* Role switch is not allowed if a SCO is up */
    372     if (btm_is_sco_active_by_bdaddr(bd_addr))
    373         return(FALSE);
    374 #endif
    375     p_dev_rec = btm_find_dev (bd_addr);
    376     if (p_dev_rec && controller_get_interface()->supports_master_slave_role_switch())
    377     {
    378         if (HCI_SWITCH_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0]))
    379         {
    380             BTM_TRACE_DEBUG("btm_dev_support_switch return TRUE (feature found)");
    381             return (TRUE);
    382         }
    383 
    384         /* If the feature field is all zero, we never received them */
    385         for (xx = 0 ; xx < BD_FEATURES_LEN ; xx++)
    386         {
    387             if (p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0][xx] != 0x00)
    388             {
    389                 feature_empty = FALSE; /* at least one is != 0 */
    390                 break;
    391             }
    392         }
    393 
    394         /* If we don't know peer's capabilities, assume it supports Role-switch */
    395         if (feature_empty)
    396         {
    397             BTM_TRACE_DEBUG("btm_dev_support_switch return TRUE (feature empty)");
    398             return (TRUE);
    399         }
    400     }
    401 
    402     BTM_TRACE_DEBUG("btm_dev_support_switch return FALSE");
    403     return(FALSE);
    404 }
    405 
    406 /*******************************************************************************
    407 **
    408 ** Function         btm_find_dev_by_handle
    409 **
    410 ** Description      Look for the record in the device database for the record
    411 **                  with specified handle
    412 **
    413 ** Returns          Pointer to the record or NULL
    414 **
    415 *******************************************************************************/
    416 tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle)
    417 {
    418     tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
    419     int i;
    420 
    421     for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
    422     {
    423         if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
    424             && ((p_dev_rec->hci_handle == handle)
    425 #if BLE_INCLUDED == TRUE
    426             ||(p_dev_rec->ble_hci_handle == handle)
    427 #endif
    428                 ))
    429             return(p_dev_rec);
    430     }
    431     return(NULL);
    432 }
    433 
    434 /*******************************************************************************
    435 **
    436 ** Function         btm_find_dev
    437 **
    438 ** Description      Look for the record in the device database for the record
    439 **                  with specified BD address
    440 **
    441 ** Returns          Pointer to the record or NULL
    442 **
    443 *******************************************************************************/
    444 tBTM_SEC_DEV_REC *btm_find_dev(BD_ADDR bd_addr)
    445 {
    446     tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
    447 
    448     if (bd_addr)
    449     {
    450         for (uint8_t i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
    451         {
    452             if (p_dev_rec->sec_flags & BTM_SEC_IN_USE)
    453             {
    454                 if (!memcmp (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN))
    455                     return(p_dev_rec);
    456 
    457 #if BLE_INCLUDED == TRUE
    458                 // If a LE random address is looking for device record
    459                 if (!memcmp(p_dev_rec->ble.pseudo_addr, bd_addr, BD_ADDR_LEN))
    460                     return (p_dev_rec);
    461 
    462                 if (btm_ble_addr_resolvable(bd_addr, p_dev_rec))
    463                     return(p_dev_rec);
    464 #endif
    465             }
    466         }
    467     }
    468     return(NULL);
    469 }
    470 
    471 /*******************************************************************************
    472 **
    473 ** Function         btm_consolidate_dev
    474 **
    475 ** Description      combine security records if identified as same peer
    476 **
    477 ** Returns          none
    478 **
    479 *******************************************************************************/
    480 void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec)
    481 {
    482 #if BLE_INCLUDED == TRUE
    483     tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
    484     tBTM_SEC_DEV_REC temp_rec = *p_target_rec;
    485     BD_ADDR dummy_bda = {0};
    486 
    487     BTM_TRACE_DEBUG("%s", __func__);
    488 
    489     for (uint8_t i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
    490     {
    491         if (p_target_rec!= p_dev_rec && p_dev_rec->sec_flags & BTM_SEC_IN_USE)
    492         {
    493             if (!memcmp (p_dev_rec->bd_addr, p_target_rec->bd_addr, BD_ADDR_LEN))
    494             {
    495                 memcpy(p_target_rec, p_dev_rec, sizeof(tBTM_SEC_DEV_REC));
    496                 p_target_rec->ble = temp_rec.ble;
    497                 p_target_rec->ble_hci_handle = temp_rec.ble_hci_handle;
    498                 p_target_rec->enc_key_size = temp_rec.enc_key_size;
    499                 p_target_rec->conn_params = temp_rec.conn_params;
    500                 p_target_rec->device_type |= temp_rec.device_type;
    501                 p_target_rec->sec_flags |= temp_rec.sec_flags;
    502 
    503                 p_target_rec->new_encryption_key_is_p256 = temp_rec.new_encryption_key_is_p256;
    504                 p_target_rec->no_smp_on_br = temp_rec.no_smp_on_br;
    505                 p_target_rec->bond_type = temp_rec.bond_type;
    506                 /* mark the combined record as unused */
    507                 p_dev_rec->sec_flags &= ~BTM_SEC_IN_USE;
    508                 p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;
    509                 break;
    510             }
    511 
    512             /* an RPA device entry is a duplicate of the target record */
    513             if (btm_ble_addr_resolvable(p_dev_rec->bd_addr, p_target_rec))
    514             {
    515                 if (memcmp(p_target_rec->ble.pseudo_addr, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0)
    516                 {
    517                     p_target_rec->ble.ble_addr_type = p_dev_rec->ble.ble_addr_type;
    518                     p_target_rec->device_type |= p_dev_rec->device_type;
    519                     p_dev_rec->sec_flags &= ~BTM_SEC_IN_USE;
    520                     p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;
    521                 }
    522                 break;
    523             }
    524         }
    525     }
    526 #endif
    527 }
    528 
    529 /*******************************************************************************
    530 **
    531 ** Function         btm_find_or_alloc_dev
    532 **
    533 ** Description      Look for the record in the device database for the record
    534 **                  with specified BD address
    535 **
    536 ** Returns          Pointer to the record or NULL
    537 **
    538 *******************************************************************************/
    539 tBTM_SEC_DEV_REC *btm_find_or_alloc_dev (BD_ADDR bd_addr)
    540 {
    541     tBTM_SEC_DEV_REC *p_dev_rec;
    542     BTM_TRACE_EVENT ("btm_find_or_alloc_dev");
    543     if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
    544     {
    545 
    546         /* Allocate a new device record or reuse the oldest one */
    547         p_dev_rec = btm_sec_alloc_dev (bd_addr);
    548     }
    549     return(p_dev_rec);
    550 }
    551 
    552 /*******************************************************************************
    553 **
    554 ** Function         btm_find_oldest_dev
    555 **
    556 ** Description      Locates the oldest device in use. It first looks for
    557 **                  the oldest non-paired device.  If all devices are paired it
    558 **                  deletes the oldest paired device.
    559 **
    560 ** Returns          Pointer to the record or NULL
    561 **
    562 *******************************************************************************/
    563 tBTM_SEC_DEV_REC *btm_find_oldest_dev (void)
    564 {
    565     tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
    566     tBTM_SEC_DEV_REC *p_oldest = p_dev_rec;
    567     UINT32       ot = 0xFFFFFFFF;
    568     int i;
    569 
    570     /* First look for the non-paired devices for the oldest entry */
    571     for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
    572     {
    573         if (((p_dev_rec->sec_flags & BTM_SEC_IN_USE) == 0)
    574             || ((p_dev_rec->sec_flags & (BTM_SEC_LINK_KEY_KNOWN |BTM_SEC_LE_LINK_KEY_KNOWN)) != 0))
    575             continue; /* Device is paired so skip it */
    576 
    577         if (p_dev_rec->timestamp < ot)
    578         {
    579             p_oldest = p_dev_rec;
    580             ot       = p_dev_rec->timestamp;
    581         }
    582     }
    583 
    584     if (ot != 0xFFFFFFFF)
    585         return(p_oldest);
    586 
    587     /* All devices are paired; find the oldest */
    588     p_dev_rec = &btm_cb.sec_dev_rec[0];
    589     for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
    590     {
    591         if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) == 0)
    592             continue;
    593 
    594         if (p_dev_rec->timestamp < ot)
    595         {
    596             p_oldest = p_dev_rec;
    597             ot       = p_dev_rec->timestamp;
    598         }
    599     }
    600     return(p_oldest);
    601 }
    602 
    603 /*******************************************************************************
    604 **
    605 ** Function         btm_get_bond_type_dev
    606 **
    607 ** Description      Get the bond type for a device in the device database
    608 **                  with specified BD address
    609 **
    610 ** Returns          The device bond type if known, otherwise BOND_TYPE_UNKNOWN
    611 **
    612 *******************************************************************************/
    613 tBTM_BOND_TYPE btm_get_bond_type_dev(BD_ADDR bd_addr)
    614 {
    615     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(bd_addr);
    616 
    617     if (p_dev_rec == NULL)
    618         return BOND_TYPE_UNKNOWN;
    619 
    620     return p_dev_rec->bond_type;
    621 }
    622 
    623 /*******************************************************************************
    624 **
    625 ** Function         btm_set_bond_type_dev
    626 **
    627 ** Description      Set the bond type for a device in the device database
    628 **                  with specified BD address
    629 **
    630 ** Returns          TRUE on success, otherwise FALSE
    631 **
    632 *******************************************************************************/
    633 BOOLEAN btm_set_bond_type_dev(BD_ADDR bd_addr, tBTM_BOND_TYPE bond_type)
    634 {
    635     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(bd_addr);
    636 
    637     if (p_dev_rec == NULL)
    638         return FALSE;
    639 
    640     p_dev_rec->bond_type = bond_type;
    641     return TRUE;
    642 }
    643