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