1 /******************************************************************************
2 *
3 * Copyright 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 "stack/btm/btm_dev.h"
26
27 #include <stddef.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "btm_api.h"
33 #include "btm_ble_int.h"
34 #include "device/include/controller.h"
35 #include "l2c_api.h"
36 #include "main/shim/btm_api.h"
37 #include "main/shim/dumpsys.h"
38 #include "main/shim/shim.h"
39 #include "osi/include/allocator.h"
40 #include "osi/include/compat.h"
41 #include "rust/src/connection/ffi/connection_shim.h"
42 #include "stack/include/acl_api.h"
43 #include "stack/include/bt_octets.h"
44 #include "types/raw_address.h"
45
46 extern tBTM_CB btm_cb;
47 void gatt_consolidate(const RawAddress& identity_addr, const RawAddress& rpa);
48
49 namespace {
50
51 constexpr char kBtmLogTag[] = "BOND";
52
53 }
54
55 /*******************************************************************************
56 *
57 * Function BTM_SecAddDevice
58 *
59 * Description Add/modify device. This function will be normally called
60 * during host startup to restore all required information
61 * stored in the NVRAM.
62 *
63 * Parameters: bd_addr - BD address of the peer
64 * dev_class - Device Class
65 * bd_name - Name of the peer device. NULL if unknown.
66 * features - Remote device's features (up to 3 pages).
67 * NULL if not known
68 * link_key - Connection link key. NULL if unknown.
69 *
70 * Returns true if added OK, else false
71 *
72 ******************************************************************************/
BTM_SecAddDevice(const RawAddress & bd_addr,DEV_CLASS dev_class,const BD_NAME & bd_name,uint8_t * features,LinkKey * p_link_key,uint8_t key_type,uint8_t pin_length)73 bool BTM_SecAddDevice(const RawAddress& bd_addr, DEV_CLASS dev_class,
74 const BD_NAME& bd_name, uint8_t* features,
75 LinkKey* p_link_key, uint8_t key_type,
76 uint8_t pin_length) {
77 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
78 if (!p_dev_rec) {
79 p_dev_rec = btm_sec_allocate_dev_rec();
80 LOG_DEBUG(
81 "Caching new record from config file device:%s link_key_type:%x "
82 "name:%s",
83 ADDRESS_TO_LOGGABLE_CSTR(bd_addr), key_type, bd_name);
84
85 p_dev_rec->bd_addr = bd_addr;
86 p_dev_rec->hci_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_BR_EDR);
87
88 /* use default value for background connection params */
89 /* update conn params, use default value for background connection params */
90 memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS));
91 } else {
92 LOG_DEBUG(
93 "Caching existing record from config file device:%s link_key_type:%x",
94 ADDRESS_TO_LOGGABLE_CSTR(bd_addr), key_type);
95
96 /* "Bump" timestamp for existing record */
97 p_dev_rec->timestamp = btm_cb.dev_rec_count++;
98
99 /* TODO(eisenbach):
100 * Small refactor, but leaving original logic for now.
101 * On the surface, this does not make any sense at all. Why change the
102 * bond state for an existing device here? This logic should be verified
103 * as part of a larger refactor.
104 */
105 p_dev_rec->bond_type = tBTM_SEC_DEV_REC::BOND_TYPE_UNKNOWN;
106 }
107
108 if (dev_class) memcpy(p_dev_rec->dev_class, dev_class, DEV_CLASS_LEN);
109
110 memset(p_dev_rec->sec_bd_name, 0, sizeof(tBTM_BD_NAME));
111
112 if (bd_name && bd_name[0]) {
113 LOG_DEBUG(" Remote name known for device:%s name:%s",
114 ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bd_name);
115 p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
116 strlcpy((char*)p_dev_rec->sec_bd_name, (char*)bd_name,
117 BTM_MAX_REM_BD_NAME_LEN + 1);
118 }
119
120 if (p_link_key) {
121 LOG_DEBUG(" Link key known for device:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr));
122 p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN;
123 p_dev_rec->link_key = *p_link_key;
124 p_dev_rec->link_key_type = key_type;
125 p_dev_rec->pin_code_length = pin_length;
126
127 if (pin_length >= 16 || key_type == BTM_LKEY_TYPE_AUTH_COMB ||
128 key_type == BTM_LKEY_TYPE_AUTH_COMB_P_256) {
129 // Set the flag if the link key was made by using either a 16 digit
130 // pin or MITM.
131 p_dev_rec->sec_flags |=
132 BTM_SEC_16_DIGIT_PIN_AUTHED | BTM_SEC_LINK_KEY_AUTHED;
133 }
134 }
135
136 p_dev_rec->rmt_io_caps = BTM_IO_CAP_OUT;
137 p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR;
138
139 return true;
140 }
141
wipe_secrets_and_remove(tBTM_SEC_DEV_REC * p_dev_rec)142 void wipe_secrets_and_remove(tBTM_SEC_DEV_REC* p_dev_rec) {
143 p_dev_rec->link_key.fill(0);
144 memset(&p_dev_rec->ble.keys, 0, sizeof(tBTM_SEC_BLE_KEYS));
145 list_remove(btm_cb.sec_dev_rec, p_dev_rec);
146 }
147
148 /** Removes the device from acceptlist */
149 void BTM_AcceptlistRemove(const RawAddress& address);
150
151 /** Free resources associated with the device associated with |bd_addr| address.
152 *
153 * *** WARNING ***
154 * tBTM_SEC_DEV_REC associated with bd_addr becomes invalid after this function
155 * is called, also any of it's fields. i.e. if you use p_dev_rec->bd_addr, it is
156 * no longer valid!
157 * *** WARNING ***
158 *
159 * Returns true if removed OK, false if not found or ACL link is active.
160 */
BTM_SecDeleteDevice(const RawAddress & bd_addr)161 bool BTM_SecDeleteDevice(const RawAddress& bd_addr) {
162 if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) ||
163 BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR)) {
164 LOG_WARN("%s FAILED: Cannot Delete when connection to %s is active",
165 __func__, ADDRESS_TO_LOGGABLE_CSTR(bd_addr));
166 return false;
167 }
168
169 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
170 if (p_dev_rec != NULL) {
171 RawAddress bda = p_dev_rec->bd_addr;
172
173 LOG_INFO("Remove device %s from filter accept list before delete record",
174 ADDRESS_TO_LOGGABLE_CSTR(bd_addr));
175 if (bluetooth::common::init_flags::
176 use_unified_connection_manager_is_enabled()) {
177 bluetooth::connection::GetConnectionManager()
178 .stop_all_connections_to_device(
179 bluetooth::connection::ResolveRawAddress(p_dev_rec->bd_addr));
180 } else {
181 BTM_AcceptlistRemove(p_dev_rec->bd_addr);
182 }
183
184 const auto device_type = p_dev_rec->device_type;
185 const auto bond_type = p_dev_rec->bond_type;
186
187 /* Clear out any saved BLE keys */
188 btm_sec_clear_ble_keys(p_dev_rec);
189 wipe_secrets_and_remove(p_dev_rec);
190 /* Tell controller to get rid of the link key, if it has one stored */
191 BTM_DeleteStoredLinkKey(&bda, NULL);
192 LOG_INFO("%s %s complete", __func__, ADDRESS_TO_LOGGABLE_CSTR(bd_addr));
193 BTM_LogHistory(kBtmLogTag, bd_addr, "Device removed",
194 base::StringPrintf("device_type:%s bond_type:%s",
195 DeviceTypeText(device_type).c_str(),
196 bond_type_text(bond_type).c_str()));
197 } else {
198 LOG_WARN("%s Unable to delete link key for unknown device %s", __func__,
199 ADDRESS_TO_LOGGABLE_CSTR(bd_addr));
200 }
201
202 return true;
203 }
204
205 /*******************************************************************************
206 *
207 * Function BTM_SecClearSecurityFlags
208 *
209 * Description Reset the security flags (mark as not-paired) for a given
210 * remove device.
211 *
212 ******************************************************************************/
BTM_SecClearSecurityFlags(const RawAddress & bd_addr)213 void BTM_SecClearSecurityFlags(const RawAddress& bd_addr) {
214 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
215 if (p_dev_rec == NULL) return;
216
217 p_dev_rec->sec_flags = 0;
218 p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
219 p_dev_rec->sm4 = BTM_SM4_UNKNOWN;
220 }
221
222 /*******************************************************************************
223 *
224 * Function BTM_SecReadDevName
225 *
226 * Description Looks for the device name in the security database for the
227 * specified BD address.
228 *
229 * Returns Pointer to the name or NULL
230 *
231 ******************************************************************************/
BTM_SecReadDevName(const RawAddress & bd_addr)232 char* BTM_SecReadDevName(const RawAddress& bd_addr) {
233 char* p_name = NULL;
234 tBTM_SEC_DEV_REC* p_srec;
235
236 p_srec = btm_find_dev(bd_addr);
237 if (p_srec != NULL) p_name = (char*)p_srec->sec_bd_name;
238
239 return (p_name);
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 ******************************************************************************/
btm_sec_alloc_dev(const RawAddress & bd_addr)252 tBTM_SEC_DEV_REC* btm_sec_alloc_dev(const RawAddress& bd_addr) {
253 tBTM_INQ_INFO* p_inq_info;
254
255 tBTM_SEC_DEV_REC* p_dev_rec = btm_sec_allocate_dev_rec();
256
257 LOG_DEBUG("Allocated device record bd_addr:%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr));
258
259 /* Check with the BT manager if details about remote device are known */
260 /* outgoing connection */
261 p_inq_info = BTM_InqDbRead(bd_addr);
262 if (p_inq_info != NULL) {
263 memcpy(p_dev_rec->dev_class, p_inq_info->results.dev_class, DEV_CLASS_LEN);
264
265 p_dev_rec->device_type = p_inq_info->results.device_type;
266 if (is_ble_addr_type_known(p_inq_info->results.ble_addr_type))
267 p_dev_rec->ble.SetAddressType(p_inq_info->results.ble_addr_type);
268 else
269 LOG_WARN(
270 "Please do not update device record from anonymous le advertisement");
271
272 } else if (bd_addr == btm_cb.connecting_bda)
273 memcpy(p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN);
274
275 /* update conn params, use default value for background connection params */
276 memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS));
277
278 p_dev_rec->bd_addr = bd_addr;
279
280 p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_LE);
281 p_dev_rec->hci_handle = BTM_GetHCIConnHandle(bd_addr, BT_TRANSPORT_BR_EDR);
282
283 return (p_dev_rec);
284 }
285
286 /*******************************************************************************
287 *
288 * Function btm_dev_support_role_switch
289 *
290 * Description This function is called by the L2CAP to check if remote
291 * device supports role switch
292 *
293 * Parameters: bd_addr - Address of the peer device
294 *
295 * Returns true if device is known and role switch is supported
296 * for the link.
297 *
298 ******************************************************************************/
btm_dev_support_role_switch(const RawAddress & bd_addr)299 bool btm_dev_support_role_switch(const RawAddress& bd_addr) {
300 if (BTM_IsScoActiveByBdaddr(bd_addr)) {
301 BTM_TRACE_DEBUG("%s Role switch is not allowed if a SCO is up", __func__);
302 return false;
303 }
304
305 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
306 if (p_dev_rec == nullptr) {
307 BTM_TRACE_DEBUG("%s Unknown address for role switch", __func__);
308 return false;
309 }
310
311 if (!controller_get_interface()->supports_central_peripheral_role_switch()) {
312 BTM_TRACE_DEBUG("%s Local controller does not support role switch",
313 __func__);
314 return false;
315 }
316
317 if (p_dev_rec->remote_supports_hci_role_switch) {
318 BTM_TRACE_DEBUG("%s Peer controller supports role switch", __func__);
319 return true;
320 }
321
322 if (!p_dev_rec->remote_feature_received) {
323 BTM_TRACE_DEBUG(
324 "%s Unknown peer capabilities, assuming peer supports role switch",
325 __func__);
326 return true;
327 }
328
329 BTM_TRACE_DEBUG("%s Peer controller does not support role switch", __func__);
330 return false;
331 }
332
is_handle_equal(void * data,void * context)333 bool is_handle_equal(void* data, void* context) {
334 tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(data);
335 uint16_t* handle = static_cast<uint16_t*>(context);
336
337 if (p_dev_rec->hci_handle == *handle || p_dev_rec->ble_hci_handle == *handle)
338 return false;
339
340 return true;
341 }
342
343 /*******************************************************************************
344 *
345 * Function btm_find_dev_by_handle
346 *
347 * Description Look for the record in the device database for the record
348 * with specified handle
349 *
350 * Returns Pointer to the record or NULL
351 *
352 ******************************************************************************/
btm_find_dev_by_handle(uint16_t handle)353 tBTM_SEC_DEV_REC* btm_find_dev_by_handle(uint16_t handle) {
354 list_node_t* n = list_foreach(btm_cb.sec_dev_rec, is_handle_equal, &handle);
355 if (n) return static_cast<tBTM_SEC_DEV_REC*>(list_node(n));
356
357 return NULL;
358 }
359
is_address_equal(void * data,void * context)360 bool is_address_equal(void* data, void* context) {
361 tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(data);
362 const RawAddress* bd_addr = ((RawAddress*)context);
363
364 if (p_dev_rec->bd_addr == *bd_addr) return false;
365 // If a LE random address is looking for device record
366 if (p_dev_rec->ble.pseudo_addr == *bd_addr) return false;
367
368 if (btm_ble_addr_resolvable(*bd_addr, p_dev_rec)) return false;
369 return true;
370 }
371
372 /*******************************************************************************
373 *
374 * Function btm_find_dev
375 *
376 * Description Look for the record in the device database for the record
377 * with specified BD address
378 *
379 * Returns Pointer to the record or NULL
380 *
381 ******************************************************************************/
btm_find_dev(const RawAddress & bd_addr)382 tBTM_SEC_DEV_REC* btm_find_dev(const RawAddress& bd_addr) {
383 if (btm_cb.sec_dev_rec == nullptr) return nullptr;
384
385 list_node_t* n =
386 list_foreach(btm_cb.sec_dev_rec, is_address_equal, (void*)&bd_addr);
387 if (n) return static_cast<tBTM_SEC_DEV_REC*>(list_node(n));
388
389 return NULL;
390 }
391
has_lenc_and_address_is_equal(void * data,void * context)392 static bool has_lenc_and_address_is_equal(void* data, void* context) {
393 tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(data);
394 if (!(p_dev_rec->ble.key_type & BTM_LE_KEY_LENC)) return true;
395
396 return is_address_equal(data, context);
397 }
398
399 /*******************************************************************************
400 *
401 * Function btm_find_dev_with_lenc
402 *
403 * Description Look for the record in the device database with LTK and
404 * specified BD address
405 *
406 * Returns Pointer to the record or NULL
407 *
408 ******************************************************************************/
btm_find_dev_with_lenc(const RawAddress & bd_addr)409 tBTM_SEC_DEV_REC* btm_find_dev_with_lenc(const RawAddress& bd_addr) {
410 if (btm_cb.sec_dev_rec == nullptr) return nullptr;
411
412 list_node_t* n = list_foreach(btm_cb.sec_dev_rec, has_lenc_and_address_is_equal,
413 (void*)&bd_addr);
414 if (n) return static_cast<tBTM_SEC_DEV_REC*>(list_node(n));
415
416 return NULL;
417 }
418 /*******************************************************************************
419 *
420 * Function btm_consolidate_dev
421 5**
422 * Description combine security records if identified as same peer
423 *
424 * Returns none
425 *
426 ******************************************************************************/
btm_consolidate_dev(tBTM_SEC_DEV_REC * p_target_rec)427 void btm_consolidate_dev(tBTM_SEC_DEV_REC* p_target_rec) {
428 tBTM_SEC_DEV_REC temp_rec = *p_target_rec;
429
430 BTM_TRACE_DEBUG("%s", __func__);
431
432 list_node_t* end = list_end(btm_cb.sec_dev_rec);
433 list_node_t* node = list_begin(btm_cb.sec_dev_rec);
434 while (node != end) {
435 tBTM_SEC_DEV_REC* p_dev_rec =
436 static_cast<tBTM_SEC_DEV_REC*>(list_node(node));
437
438 // we do list_remove in some cases, must grab next before removing
439 node = list_next(node);
440
441 if (p_target_rec == p_dev_rec) continue;
442
443 if (p_dev_rec->bd_addr == p_target_rec->bd_addr) {
444 memcpy(p_target_rec, p_dev_rec, sizeof(tBTM_SEC_DEV_REC));
445 p_target_rec->ble = temp_rec.ble;
446 p_target_rec->ble_hci_handle = temp_rec.ble_hci_handle;
447 p_target_rec->enc_key_size = temp_rec.enc_key_size;
448 p_target_rec->conn_params = temp_rec.conn_params;
449 p_target_rec->device_type |= temp_rec.device_type;
450 p_target_rec->sec_flags |= temp_rec.sec_flags;
451
452 p_target_rec->new_encryption_key_is_p256 =
453 temp_rec.new_encryption_key_is_p256;
454 p_target_rec->bond_type = temp_rec.bond_type;
455
456 /* remove the combined record */
457 wipe_secrets_and_remove(p_dev_rec);
458 // p_dev_rec gets freed in list_remove, we should not access it further
459 continue;
460 }
461
462 /* an RPA device entry is a duplicate of the target record */
463 if (btm_ble_addr_resolvable(p_dev_rec->bd_addr, p_target_rec)) {
464 if (p_target_rec->ble.pseudo_addr == p_dev_rec->bd_addr) {
465 p_target_rec->ble.SetAddressType(p_dev_rec->ble.AddressType());
466 p_target_rec->device_type |= p_dev_rec->device_type;
467
468 /* remove the combined record */
469 wipe_secrets_and_remove(p_dev_rec);
470 }
471 }
472 }
473 }
474
475 BTM_CONSOLIDATION_CB* btm_consolidate_cb = nullptr;
476
BTM_SetConsolidationCallback(BTM_CONSOLIDATION_CB * cb)477 void BTM_SetConsolidationCallback(BTM_CONSOLIDATION_CB* cb) {
478 btm_consolidate_cb = cb;
479 }
480
481 /* combine security records of established LE connections after Classic pairing
482 * succeeded. */
btm_dev_consolidate_existing_connections(const RawAddress & bd_addr)483 void btm_dev_consolidate_existing_connections(const RawAddress& bd_addr) {
484 tBTM_SEC_DEV_REC* p_target_rec = btm_find_dev(bd_addr);
485 if (!p_target_rec) {
486 LOG_ERROR("No security record for just bonded device!?!?");
487 return;
488 }
489
490 if (p_target_rec->ble_hci_handle != HCI_INVALID_HANDLE) {
491 LOG_INFO("Not consolidating - already have LE connection");
492 return;
493 }
494
495 LOG_INFO("%s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr));
496
497 list_node_t* end = list_end(btm_cb.sec_dev_rec);
498 list_node_t* node = list_begin(btm_cb.sec_dev_rec);
499 while (node != end) {
500 tBTM_SEC_DEV_REC* p_dev_rec =
501 static_cast<tBTM_SEC_DEV_REC*>(list_node(node));
502
503 // we do list_remove in some cases, must grab next before removing
504 node = list_next(node);
505
506 if (p_target_rec == p_dev_rec) continue;
507
508 /* an RPA device entry is a duplicate of the target record */
509 if (btm_ble_addr_resolvable(p_dev_rec->bd_addr, p_target_rec)) {
510 if (p_dev_rec->ble_hci_handle == HCI_INVALID_HANDLE) {
511 LOG_INFO("already disconnected - erasing entry %s",
512 ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr));
513 wipe_secrets_and_remove(p_dev_rec);
514 continue;
515 }
516
517 LOG_INFO(
518 "Found existing LE connection to just bonded device on %s handle 0x%04x",
519 ADDRESS_TO_LOGGABLE_CSTR(p_dev_rec->bd_addr), p_dev_rec->ble_hci_handle);
520
521 RawAddress ble_conn_addr = p_dev_rec->bd_addr;
522 p_target_rec->ble_hci_handle = p_dev_rec->ble_hci_handle;
523
524 /* remove the old LE record */
525 wipe_secrets_and_remove(p_dev_rec);
526
527 btm_acl_consolidate(bd_addr, ble_conn_addr);
528 L2CA_Consolidate(bd_addr, ble_conn_addr);
529 gatt_consolidate(bd_addr, ble_conn_addr);
530 if (btm_consolidate_cb) btm_consolidate_cb(bd_addr, ble_conn_addr);
531
532 /* To avoid race conditions between central/peripheral starting encryption
533 * at same time, initiate it just from central. */
534 if (L2CA_GetBleConnRole(ble_conn_addr) == HCI_ROLE_CENTRAL) {
535 LOG_INFO("Will encrypt existing connection");
536 BTM_SetEncryption(bd_addr, BT_TRANSPORT_LE, nullptr, nullptr,
537 BTM_BLE_SEC_ENCRYPT);
538 }
539 }
540 }
541 }
542
543 /*******************************************************************************
544 *
545 * Function btm_find_or_alloc_dev
546 *
547 * Description Look for the record in the device database for the record
548 * with specified BD address
549 *
550 * Returns Pointer to the record or NULL
551 *
552 ******************************************************************************/
btm_find_or_alloc_dev(const RawAddress & bd_addr)553 tBTM_SEC_DEV_REC* btm_find_or_alloc_dev(const RawAddress& bd_addr) {
554 tBTM_SEC_DEV_REC* p_dev_rec;
555 BTM_TRACE_EVENT("btm_find_or_alloc_dev");
556 p_dev_rec = btm_find_dev(bd_addr);
557 if (p_dev_rec == NULL) {
558 /* Allocate a new device record or reuse the oldest one */
559 p_dev_rec = btm_sec_alloc_dev(bd_addr);
560 }
561 return (p_dev_rec);
562 }
563
564 /*******************************************************************************
565 *
566 * Function btm_find_oldest_dev_rec
567 *
568 * Description Locates the oldest device in use. It first looks for
569 * the oldest non-paired device. If all devices are paired it
570 * returns the oldest paired device.
571 *
572 * Returns Pointer to the record or NULL
573 *
574 ******************************************************************************/
btm_find_oldest_dev_rec(void)575 static tBTM_SEC_DEV_REC* btm_find_oldest_dev_rec(void) {
576 tBTM_SEC_DEV_REC* p_oldest = NULL;
577 uint32_t ts_oldest = 0xFFFFFFFF;
578 tBTM_SEC_DEV_REC* p_oldest_paired = NULL;
579 uint32_t ts_oldest_paired = 0xFFFFFFFF;
580
581 list_node_t* end = list_end(btm_cb.sec_dev_rec);
582 for (list_node_t* node = list_begin(btm_cb.sec_dev_rec); node != end;
583 node = list_next(node)) {
584 tBTM_SEC_DEV_REC* p_dev_rec =
585 static_cast<tBTM_SEC_DEV_REC*>(list_node(node));
586
587 if ((p_dev_rec->sec_flags &
588 (BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LE_LINK_KEY_KNOWN)) == 0) {
589 // Device is not paired
590 if (p_dev_rec->timestamp < ts_oldest) {
591 p_oldest = p_dev_rec;
592 ts_oldest = p_dev_rec->timestamp;
593 }
594 } else {
595 // Paired device
596 if (p_dev_rec->timestamp < ts_oldest_paired) {
597 p_oldest_paired = p_dev_rec;
598 ts_oldest_paired = p_dev_rec->timestamp;
599 }
600 }
601 }
602
603 // If we did not find any non-paired devices, use the oldest paired one...
604 if (ts_oldest == 0xFFFFFFFF) p_oldest = p_oldest_paired;
605
606 return p_oldest;
607 }
608
609 /*******************************************************************************
610 *
611 * Function btm_sec_allocate_dev_rec
612 *
613 * Description Attempts to allocate a new device record. If we have
614 * exceeded the maximum number of allowable records to
615 * allocate, the oldest record will be deleted to make room
616 * for the new record.
617 *
618 * Returns Pointer to the newly allocated record
619 *
620 ******************************************************************************/
btm_sec_allocate_dev_rec(void)621 tBTM_SEC_DEV_REC* btm_sec_allocate_dev_rec(void) {
622 tBTM_SEC_DEV_REC* p_dev_rec = NULL;
623
624 if (list_length(btm_cb.sec_dev_rec) > BTM_SEC_MAX_DEVICE_RECORDS) {
625 p_dev_rec = btm_find_oldest_dev_rec();
626 wipe_secrets_and_remove(p_dev_rec);
627 }
628
629 p_dev_rec =
630 static_cast<tBTM_SEC_DEV_REC*>(osi_calloc(sizeof(tBTM_SEC_DEV_REC)));
631 list_append(btm_cb.sec_dev_rec, p_dev_rec);
632
633 // Initialize defaults
634 p_dev_rec->sec_flags = BTM_SEC_IN_USE;
635 p_dev_rec->bond_type = tBTM_SEC_DEV_REC::BOND_TYPE_UNKNOWN;
636 p_dev_rec->timestamp = btm_cb.dev_rec_count++;
637 p_dev_rec->rmt_io_caps = BTM_IO_CAP_UNKNOWN;
638 p_dev_rec->suggested_tx_octets = 0;
639
640 return p_dev_rec;
641 }
642
643 /*******************************************************************************
644 *
645 * Function btm_get_bond_type_dev
646 *
647 * Description Get the bond type for a device in the device database
648 * with specified BD address
649 *
650 * Returns The device bond type if known, otherwise BOND_TYPE_UNKNOWN
651 *
652 ******************************************************************************/
btm_get_bond_type_dev(const RawAddress & bd_addr)653 tBTM_SEC_DEV_REC::tBTM_BOND_TYPE btm_get_bond_type_dev(
654 const RawAddress& bd_addr) {
655 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
656
657 if (p_dev_rec == NULL) return tBTM_SEC_DEV_REC::BOND_TYPE_UNKNOWN;
658
659 return p_dev_rec->bond_type;
660 }
661
662 /*******************************************************************************
663 *
664 * Function btm_set_bond_type_dev
665 *
666 * Description Set the bond type for a device in the device database
667 * with specified BD address
668 *
669 * Returns true on success, otherwise false
670 *
671 ******************************************************************************/
btm_set_bond_type_dev(const RawAddress & bd_addr,tBTM_SEC_DEV_REC::tBTM_BOND_TYPE bond_type)672 bool btm_set_bond_type_dev(const RawAddress& bd_addr,
673 tBTM_SEC_DEV_REC::tBTM_BOND_TYPE bond_type) {
674 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
675
676 if (p_dev_rec == NULL) return false;
677
678 p_dev_rec->bond_type = bond_type;
679 return true;
680 }
681
682 /*******************************************************************************
683 *
684 * Function btm_get_sec_dev_rec
685 *
686 * Description Get security device records satisfying given filter
687 *
688 * Returns A vector containing pointers of security device records
689 *
690 ******************************************************************************/
btm_get_sec_dev_rec()691 std::vector<tBTM_SEC_DEV_REC*> btm_get_sec_dev_rec() {
692 std::vector<tBTM_SEC_DEV_REC*> result{};
693
694 list_node_t* end = list_end(btm_cb.sec_dev_rec);
695 for (list_node_t* node = list_begin(btm_cb.sec_dev_rec); node != end;
696 node = list_next(node)) {
697 tBTM_SEC_DEV_REC* p_dev_rec =
698 static_cast<tBTM_SEC_DEV_REC*>(list_node(node));
699 result.push_back(p_dev_rec);
700 }
701 return result;
702 }
703