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 "bt_common.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 /*******************************************************************************
     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                           UINT8 pin_length)
     63 {
     64     BTM_TRACE_API("%s: link key type:%x", __func__, key_type);
     65 
     66     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
     67     if (!p_dev_rec)
     68     {
     69         p_dev_rec = btm_sec_allocate_dev_rec();
     70 
     71         memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
     72         p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
     73 
     74 #if BLE_INCLUDED == TRUE
     75         /* use default value for background connection params */
     76         /* update conn params, use default value for background connection params */
     77         memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS));
     78 #endif
     79     } else {
     80         /* "Bump" timestamp for existing record */
     81         p_dev_rec->timestamp = btm_cb.dev_rec_count++;
     82 
     83         /* TODO(eisenbach):
     84          * Small refactor, but leaving original logic for now.
     85          * On the surface, this does not make any sense at all. Why change the
     86          * bond state for an existing device here? This logic should be verified
     87          * as part of a larger refactor.
     88          */
     89         p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;
     90     }
     91 
     92     if (dev_class)
     93         memcpy (p_dev_rec->dev_class, dev_class, DEV_CLASS_LEN);
     94 
     95     memset(p_dev_rec->sec_bd_name, 0, sizeof(tBTM_BD_NAME));
     96 
     97     if (bd_name && bd_name[0])
     98     {
     99         p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
    100         strlcpy ((char *)p_dev_rec->sec_bd_name,
    101                  (char *)bd_name, BTM_MAX_REM_BD_NAME_LEN);
    102     }
    103 
    104     p_dev_rec->num_read_pages = 0;
    105     if (features)
    106     {
    107         BOOLEAN found = FALSE;
    108         memcpy (p_dev_rec->features, features, sizeof (p_dev_rec->features));
    109         for (int i = HCI_EXT_FEATURES_PAGE_MAX; !found && i >= 0; i--)
    110         {
    111             for (int j = 0; j < HCI_FEATURE_BYTES_PER_PAGE; j++)
    112             {
    113                 if (p_dev_rec->features[i][j] != 0)
    114                 {
    115                     found = TRUE;
    116                     p_dev_rec->num_read_pages = i + 1;
    117                     break;
    118                 }
    119             }
    120         }
    121     } else {
    122         memset (p_dev_rec->features, 0, sizeof (p_dev_rec->features));
    123     }
    124 
    125     BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
    126 
    127     if (link_key)
    128     {
    129         BTM_TRACE_EVENT ("%s: BDA: %02x:%02x:%02x:%02x:%02x:%02x", __func__,
    130                           bd_addr[0], bd_addr[1], bd_addr[2],
    131                           bd_addr[3], bd_addr[4], bd_addr[5]);
    132         p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN;
    133         memcpy (p_dev_rec->link_key, link_key, LINK_KEY_LEN);
    134         p_dev_rec->link_key_type = key_type;
    135         p_dev_rec->pin_code_length = pin_length;
    136 
    137         if (pin_length >= 16 ||
    138             key_type == BTM_LKEY_TYPE_AUTH_COMB ||
    139             key_type == BTM_LKEY_TYPE_AUTH_COMB_P_256) {
    140             // Set the flag if the link key was made by using either a 16 digit
    141             // pin or MITM.
    142             p_dev_rec->sec_flags |= BTM_SEC_16_DIGIT_PIN_AUTHED | BTM_SEC_LINK_KEY_AUTHED;
    143         }
    144     }
    145 
    146 #if defined(BTIF_MIXED_MODE_INCLUDED) && (BTIF_MIXED_MODE_INCLUDED == TRUE)
    147     if (key_type  < BTM_MAX_PRE_SM4_LKEY_TYPE)
    148         p_dev_rec->sm4 = BTM_SM4_KNOWN;
    149     else
    150         p_dev_rec->sm4 = BTM_SM4_TRUE;
    151 #endif
    152 
    153     p_dev_rec->rmt_io_caps = io_cap;
    154     p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR;
    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     if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) ||
    174         BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR))
    175     {
    176         BTM_TRACE_WARNING("%s FAILED: Cannot Delete when connection is active", __func__);
    177         return FALSE;
    178     }
    179 
    180     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(bd_addr);
    181     if (p_dev_rec != NULL)
    182     {
    183         btm_sec_free_dev(p_dev_rec);
    184         /* Tell controller to get rid of the link key, if it has one stored */
    185         BTM_DeleteStoredLinkKey (p_dev_rec->bd_addr, NULL);
    186     }
    187 
    188     return TRUE;
    189 }
    190 
    191 /*******************************************************************************
    192 **
    193 ** Function         BTM_SecClearSecurityFlags
    194 **
    195 ** Description      Reset the security flags (mark as not-paired) for a given
    196 **                  remove device.
    197 **
    198 *******************************************************************************/
    199 extern void BTM_SecClearSecurityFlags (BD_ADDR bd_addr)
    200 {
    201     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(bd_addr);
    202     if (p_dev_rec == NULL)
    203         return;
    204 
    205     p_dev_rec->sec_flags = 0;
    206     p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
    207     p_dev_rec->sm4 = BTM_SM4_UNKNOWN;
    208 }
    209 
    210 /*******************************************************************************
    211 **
    212 ** Function         BTM_SecReadDevName
    213 **
    214 ** Description      Looks for the device name in the security database for the
    215 **                  specified BD address.
    216 **
    217 ** Returns          Pointer to the name or NULL
    218 **
    219 *******************************************************************************/
    220 char *BTM_SecReadDevName (BD_ADDR bd_addr)
    221 {
    222     char *p_name = NULL;
    223     tBTM_SEC_DEV_REC *p_srec;
    224 
    225     if ((p_srec = btm_find_dev(bd_addr)) != NULL)
    226         p_name = (char *)p_srec->sec_bd_name;
    227 
    228     return(p_name);
    229 }
    230 
    231 bool is_bd_addr_equal(void *data, void *context)
    232 {
    233     tBTM_SEC_DEV_REC *p_dev_rec = data;
    234     BD_ADDR *bd_addr = context;
    235 
    236     if (!memcmp(p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN))
    237         return false;
    238 
    239     return true;
    240 }
    241 
    242 /*******************************************************************************
    243 **
    244 ** Function         btm_sec_alloc_dev
    245 **
    246 ** Description      Look for the record in the device database for the record
    247 **                  with specified address
    248 **
    249 ** Returns          Pointer to the record or NULL
    250 **
    251 *******************************************************************************/
    252 tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr)
    253 {
    254     tBTM_INQ_INFO    *p_inq_info;
    255     BTM_TRACE_EVENT ("btm_sec_alloc_dev");
    256 
    257     tBTM_SEC_DEV_REC *p_dev_rec = btm_sec_allocate_dev_rec();
    258 
    259     /* Check with the BT manager if details about remote device are known */
    260     /* outgoing connection */
    261     if ((p_inq_info = BTM_InqDbRead(bd_addr)) != NULL)
    262     {
    263         memcpy (p_dev_rec->dev_class, p_inq_info->results.dev_class, DEV_CLASS_LEN);
    264 
    265 #if BLE_INCLUDED == TRUE
    266         p_dev_rec->device_type = p_inq_info->results.device_type;
    267         p_dev_rec->ble.ble_addr_type = p_inq_info->results.ble_addr_type;
    268 #endif
    269     }
    270     else if (!memcmp (bd_addr, btm_cb.connecting_bda, BD_ADDR_LEN))
    271             memcpy (p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN);
    272 
    273 #if BLE_INCLUDED == TRUE
    274     /* update conn params, use default value for background connection params */
    275     memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS));
    276 #endif
    277 
    278     memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN);
    279 
    280 #if BLE_INCLUDED == TRUE
    281     p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_LE);
    282 #endif
    283     p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR);
    284 
    285     return(p_dev_rec);
    286 }
    287 
    288 
    289 /*******************************************************************************
    290 **
    291 ** Function         btm_sec_free_dev
    292 **
    293 ** Description      Mark device record as not used
    294 **
    295 *******************************************************************************/
    296 void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec)
    297 {
    298 #if BLE_INCLUDED == TRUE
    299     /* Clear out any saved BLE keys */
    300     btm_sec_clear_ble_keys (p_dev_rec);
    301 #endif
    302     list_remove(btm_cb.sec_dev_rec, p_dev_rec);
    303 }
    304 
    305 /*******************************************************************************
    306 **
    307 ** Function         btm_dev_support_switch
    308 **
    309 ** Description      This function is called by the L2CAP to check if remote
    310 **                  device supports role switch
    311 **
    312 ** Parameters:      bd_addr       - Address of the peer device
    313 **
    314 ** Returns          TRUE if device is known and role switch is supported
    315 **
    316 *******************************************************************************/
    317 BOOLEAN btm_dev_support_switch (BD_ADDR bd_addr)
    318 {
    319     tBTM_SEC_DEV_REC  *p_dev_rec;
    320     UINT8   xx;
    321     BOOLEAN feature_empty = TRUE;
    322 
    323 #if BTM_SCO_INCLUDED == TRUE
    324     /* Role switch is not allowed if a SCO is up */
    325     if (btm_is_sco_active_by_bdaddr(bd_addr))
    326         return(FALSE);
    327 #endif
    328     p_dev_rec = btm_find_dev (bd_addr);
    329     if (p_dev_rec && controller_get_interface()->supports_master_slave_role_switch())
    330     {
    331         if (HCI_SWITCH_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0]))
    332         {
    333             BTM_TRACE_DEBUG("btm_dev_support_switch return TRUE (feature found)");
    334             return (TRUE);
    335         }
    336 
    337         /* If the feature field is all zero, we never received them */
    338         for (xx = 0 ; xx < BD_FEATURES_LEN ; xx++)
    339         {
    340             if (p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0][xx] != 0x00)
    341             {
    342                 feature_empty = FALSE; /* at least one is != 0 */
    343                 break;
    344             }
    345         }
    346 
    347         /* If we don't know peer's capabilities, assume it supports Role-switch */
    348         if (feature_empty)
    349         {
    350             BTM_TRACE_DEBUG("btm_dev_support_switch return TRUE (feature empty)");
    351             return (TRUE);
    352         }
    353     }
    354 
    355     BTM_TRACE_DEBUG("btm_dev_support_switch return FALSE");
    356     return(FALSE);
    357 }
    358 
    359 bool is_handle_equal(void *data, void *context)
    360 {
    361     tBTM_SEC_DEV_REC *p_dev_rec = data;
    362     UINT16 *handle = context;
    363 
    364     if (p_dev_rec->hci_handle == *handle
    365 #if BLE_INCLUDED == TRUE
    366      || p_dev_rec->ble_hci_handle == *handle
    367 #endif
    368      )
    369         return false;
    370 
    371     return true;
    372 }
    373 
    374 /*******************************************************************************
    375 **
    376 ** Function         btm_find_dev_by_handle
    377 **
    378 ** Description      Look for the record in the device database for the record
    379 **                  with specified handle
    380 **
    381 ** Returns          Pointer to the record or NULL
    382 **
    383 *******************************************************************************/
    384 tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle)
    385 {
    386     list_node_t *n = list_foreach(btm_cb.sec_dev_rec, is_handle_equal, &handle);
    387     if (n)
    388         return list_node(n);
    389 
    390     return NULL;
    391 }
    392 
    393 bool is_address_equal(void *data, void *context)
    394 {
    395     tBTM_SEC_DEV_REC *p_dev_rec = data;
    396     BD_ADDR *bd_addr = context;
    397 
    398     if (!memcmp (p_dev_rec->bd_addr, *bd_addr, BD_ADDR_LEN))
    399         return false;
    400 #if BLE_INCLUDED == TRUE
    401     // If a LE random address is looking for device record
    402     if (!memcmp(p_dev_rec->ble.pseudo_addr, *bd_addr, BD_ADDR_LEN))
    403         return false;
    404 
    405     if (btm_ble_addr_resolvable(*bd_addr, p_dev_rec))
    406         return false;
    407 #endif
    408     return true;
    409 }
    410 
    411 /*******************************************************************************
    412 **
    413 ** Function         btm_find_dev
    414 **
    415 ** Description      Look for the record in the device database for the record
    416 **                  with specified BD address
    417 **
    418 ** Returns          Pointer to the record or NULL
    419 **
    420 *******************************************************************************/
    421 tBTM_SEC_DEV_REC *btm_find_dev(BD_ADDR bd_addr)
    422 {
    423     if (!bd_addr)
    424         return NULL;
    425 
    426     list_node_t *n = list_foreach(btm_cb.sec_dev_rec, is_address_equal, bd_addr);
    427     if (n)
    428         return list_node(n);
    429 
    430     return NULL;
    431 }
    432 
    433 /*******************************************************************************
    434 **
    435 ** Function         btm_consolidate_dev
    436 5**
    437 ** Description      combine security records if identified as same peer
    438 **
    439 ** Returns          none
    440 **
    441 *******************************************************************************/
    442 void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec)
    443 {
    444 #if BLE_INCLUDED == TRUE
    445     tBTM_SEC_DEV_REC temp_rec = *p_target_rec;
    446 
    447     BTM_TRACE_DEBUG("%s", __func__);
    448 
    449     list_node_t *end = list_end(btm_cb.sec_dev_rec);
    450     for (list_node_t *node = list_begin(btm_cb.sec_dev_rec); node != end; node = list_next(node)) {
    451         tBTM_SEC_DEV_REC *p_dev_rec = list_node(node);
    452 
    453         if (p_target_rec == p_dev_rec)
    454             continue;
    455 
    456         if (!memcmp (p_dev_rec->bd_addr, p_target_rec->bd_addr, BD_ADDR_LEN))
    457         {
    458             memcpy(p_target_rec, p_dev_rec, sizeof(tBTM_SEC_DEV_REC));
    459             p_target_rec->ble = temp_rec.ble;
    460             p_target_rec->ble_hci_handle = temp_rec.ble_hci_handle;
    461             p_target_rec->enc_key_size = temp_rec.enc_key_size;
    462             p_target_rec->conn_params = temp_rec.conn_params;
    463             p_target_rec->device_type |= temp_rec.device_type;
    464             p_target_rec->sec_flags |= temp_rec.sec_flags;
    465 
    466             p_target_rec->new_encryption_key_is_p256 = temp_rec.new_encryption_key_is_p256;
    467             p_target_rec->no_smp_on_br = temp_rec.no_smp_on_br;
    468             p_target_rec->bond_type = temp_rec.bond_type;
    469 
    470             /* remove the combined record */
    471             list_remove(btm_cb.sec_dev_rec, p_dev_rec);
    472             break;
    473         }
    474 
    475         /* an RPA device entry is a duplicate of the target record */
    476         if (btm_ble_addr_resolvable(p_dev_rec->bd_addr, p_target_rec))
    477         {
    478             if (memcmp(p_target_rec->ble.pseudo_addr, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0)
    479             {
    480                 p_target_rec->ble.ble_addr_type = p_dev_rec->ble.ble_addr_type;
    481                 p_target_rec->device_type |= p_dev_rec->device_type;
    482 
    483                 /* remove the combined record */
    484                 list_remove(btm_cb.sec_dev_rec, p_dev_rec);
    485             }
    486             break;
    487         }
    488     }
    489 #endif
    490 }
    491 
    492 /*******************************************************************************
    493 **
    494 ** Function         btm_find_or_alloc_dev
    495 **
    496 ** Description      Look for the record in the device database for the record
    497 **                  with specified BD address
    498 **
    499 ** Returns          Pointer to the record or NULL
    500 **
    501 *******************************************************************************/
    502 tBTM_SEC_DEV_REC *btm_find_or_alloc_dev (BD_ADDR bd_addr)
    503 {
    504     tBTM_SEC_DEV_REC *p_dev_rec;
    505     BTM_TRACE_EVENT ("btm_find_or_alloc_dev");
    506     if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
    507     {
    508 
    509         /* Allocate a new device record or reuse the oldest one */
    510         p_dev_rec = btm_sec_alloc_dev (bd_addr);
    511     }
    512     return(p_dev_rec);
    513 }
    514 
    515 /*******************************************************************************
    516 **
    517 ** Function         btm_find_oldest_dev_rec
    518 **
    519 ** Description      Locates the oldest device in use. It first looks for
    520 **                  the oldest non-paired device.  If all devices are paired it
    521 **                  returns the oldest paired device.
    522 **
    523 ** Returns          Pointer to the record or NULL
    524 **
    525 *******************************************************************************/
    526 static tBTM_SEC_DEV_REC* btm_find_oldest_dev_rec (void)
    527 {
    528     tBTM_SEC_DEV_REC *p_oldest = NULL;
    529     UINT32       ts_oldest = 0xFFFFFFFF;
    530     tBTM_SEC_DEV_REC *p_oldest_paired = NULL;
    531     UINT32       ts_oldest_paired = 0xFFFFFFFF;
    532 
    533     list_node_t *end = list_end(btm_cb.sec_dev_rec);
    534     for (list_node_t *node = list_begin(btm_cb.sec_dev_rec); node != end; node = list_next(node)) {
    535         tBTM_SEC_DEV_REC *p_dev_rec = list_node(node);
    536 
    537         if ((p_dev_rec->sec_flags & (BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LE_LINK_KEY_KNOWN)) == 0) {
    538             // Device is not paired
    539             if (p_dev_rec->timestamp < ts_oldest) {
    540                 p_oldest = p_dev_rec;
    541                 ts_oldest = p_dev_rec->timestamp;
    542             }
    543         } else {
    544             // Paired device
    545             if (p_dev_rec->timestamp < ts_oldest_paired) {
    546                 p_oldest_paired = p_dev_rec;
    547                 ts_oldest_paired = p_dev_rec->timestamp;
    548             }
    549         }
    550     }
    551 
    552     // If we did not find any non-paired devices, use the oldest paired one...
    553     if (ts_oldest == 0xFFFFFFFF)
    554         p_oldest = p_oldest_paired;
    555 
    556     return p_oldest;
    557 }
    558 
    559 /*******************************************************************************
    560 **
    561 ** Function         btm_sec_allocate_dev_rec
    562 **
    563 ** Description      Attempts to allocate a new device record. If we have
    564 **                  exceeded the maximum number of allowable records to
    565 **                  allocate, the oldest record will be deleted to make room
    566 **                  for the new record.
    567 **
    568 ** Returns          Pointer to the newly allocated record
    569 **
    570 *******************************************************************************/
    571 tBTM_SEC_DEV_REC* btm_sec_allocate_dev_rec(void)
    572 {
    573     tBTM_SEC_DEV_REC *p_dev_rec = NULL;
    574 
    575     if (list_length(btm_cb.sec_dev_rec) > BTM_SEC_MAX_DEVICE_RECORDS)
    576     {
    577         p_dev_rec = btm_find_oldest_dev_rec();
    578         list_remove(btm_cb.sec_dev_rec, p_dev_rec);
    579     }
    580 
    581     p_dev_rec = osi_calloc(sizeof(tBTM_SEC_DEV_REC));
    582     list_append(btm_cb.sec_dev_rec, p_dev_rec);
    583 
    584     // Initialize defaults
    585     p_dev_rec->sec_flags = BTM_SEC_IN_USE;
    586     p_dev_rec->bond_type = BOND_TYPE_UNKNOWN;
    587     p_dev_rec->timestamp = btm_cb.dev_rec_count++;
    588 
    589     return p_dev_rec;
    590 }
    591 
    592 /*******************************************************************************
    593 **
    594 ** Function         btm_get_bond_type_dev
    595 **
    596 ** Description      Get the bond type for a device in the device database
    597 **                  with specified BD address
    598 **
    599 ** Returns          The device bond type if known, otherwise BOND_TYPE_UNKNOWN
    600 **
    601 *******************************************************************************/
    602 tBTM_BOND_TYPE btm_get_bond_type_dev(BD_ADDR bd_addr)
    603 {
    604     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(bd_addr);
    605 
    606     if (p_dev_rec == NULL)
    607         return BOND_TYPE_UNKNOWN;
    608 
    609     return p_dev_rec->bond_type;
    610 }
    611 
    612 /*******************************************************************************
    613 **
    614 ** Function         btm_set_bond_type_dev
    615 **
    616 ** Description      Set the bond type for a device in the device database
    617 **                  with specified BD address
    618 **
    619 ** Returns          TRUE on success, otherwise FALSE
    620 **
    621 *******************************************************************************/
    622 BOOLEAN btm_set_bond_type_dev(BD_ADDR bd_addr, tBTM_BOND_TYPE bond_type)
    623 {
    624     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(bd_addr);
    625 
    626     if (p_dev_rec == NULL)
    627         return FALSE;
    628 
    629     p_dev_rec->bond_type = bond_type;
    630     return TRUE;
    631 }
    632