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 *******************************************************************************/
BTM_SecAddDevice(BD_ADDR bd_addr,DEV_CLASS dev_class,BD_NAME bd_name,UINT8 * features,UINT32 trusted_mask[],LINK_KEY link_key,UINT8 key_type,tBTM_IO_CAP io_cap,UINT8 pin_length)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 *******************************************************************************/
BTM_SecDeleteDevice(BD_ADDR bd_addr)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 *******************************************************************************/
BTM_SecReadDevName(BD_ADDR bd_addr)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 *******************************************************************************/
btm_sec_alloc_dev(BD_ADDR bd_addr)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 *******************************************************************************/
btm_sec_free_dev(tBTM_SEC_DEV_REC * p_dev_rec)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 *******************************************************************************/
btm_dev_support_switch(BD_ADDR bd_addr)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 *******************************************************************************/
btm_find_dev_by_handle(UINT16 handle)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 *******************************************************************************/
btm_find_dev(BD_ADDR bd_addr)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 *******************************************************************************/
btm_consolidate_dev(tBTM_SEC_DEV_REC * p_target_rec)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 *******************************************************************************/
btm_find_or_alloc_dev(BD_ADDR bd_addr)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 *******************************************************************************/
btm_find_oldest_dev(void)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 *******************************************************************************/
btm_get_bond_type_dev(BD_ADDR bd_addr)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 *******************************************************************************/
btm_set_bond_type_dev(BD_ADDR bd_addr,tBTM_BOND_TYPE bond_type)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