| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 "gki.h" |
| 32 | #include "hcimsgs.h" |
| 33 | #include "btu.h" |
| 34 | #include "btm_api.h" |
| 35 | #include "btm_int.h" |
| 36 | #include "hcidefs.h" |
| 37 | #include "l2c_api.h" |
| 38 | static tBTM_SEC_DEV_REC *btm_find_oldest_dev (void); |
| 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. |
| Andre Eisenbach | 3aa6054 | 2013-03-22 18:00:51 -0700 | [diff] [blame] | 51 | ** features - Remote device's features (up to 3 pages). NULL if not known |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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, |
| Andre Eisenbach | 3aa6054 | 2013-03-22 18:00:51 -0700 | [diff] [blame] | 60 | UINT8 *features, UINT32 trusted_mask[], |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 61 | LINK_KEY link_key, UINT8 key_type, tBTM_IO_CAP io_cap) |
| 62 | { |
| 63 | tBTM_SEC_DEV_REC *p_dev_rec; |
| Andre Eisenbach | 3aa6054 | 2013-03-22 18:00:51 -0700 | [diff] [blame] | 64 | int i, j; |
| 65 | BOOLEAN found = FALSE; |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 66 | |
| Sharvil Nanavati | 83c5256 | 2014-05-04 00:46:57 -0700 | [diff] [blame] | 67 | BTM_TRACE_API("%s, link key type:%x", __FUNCTION__,key_type); |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 68 | p_dev_rec = btm_find_dev (bd_addr); |
| 69 | if (!p_dev_rec) |
| 70 | { |
| 71 | /* There is no device record, allocate one. |
| 72 | * If we can not find an empty spot for this one, let it fail. */ |
| 73 | for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++) |
| 74 | { |
| 75 | if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE)) |
| 76 | { |
| 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); |
| Ganesh Ganapathi Batta | 8fe5887 | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 83 | p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR); |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 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 | p_dev_rec->timestamp = btm_cb.dev_rec_count++; |
| 99 | |
| 100 | if (dev_class) |
| 101 | memcpy (p_dev_rec->dev_class, dev_class, DEV_CLASS_LEN); |
| 102 | |
| 103 | memset(p_dev_rec->sec_bd_name, 0, sizeof(tBTM_BD_NAME)); |
| 104 | |
| 105 | if (bd_name && bd_name[0]) |
| 106 | { |
| 107 | p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN; |
| 108 | BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, sizeof (p_dev_rec->sec_bd_name), |
| 109 | (char *)bd_name, BTM_MAX_REM_BD_NAME_LEN); |
| 110 | } |
| 111 | |
| Andre Eisenbach | 3aa6054 | 2013-03-22 18:00:51 -0700 | [diff] [blame] | 112 | p_dev_rec->num_read_pages = 0; |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 113 | if (features) |
| Andre Eisenbach | 3aa6054 | 2013-03-22 18:00:51 -0700 | [diff] [blame] | 114 | { |
| 115 | memcpy (p_dev_rec->features, features, sizeof (p_dev_rec->features)); |
| 116 | for (i = HCI_EXT_FEATURES_PAGE_MAX; i >= 0; i--) |
| 117 | { |
| 118 | for (j = 0; j < HCI_FEATURE_BYTES_PER_PAGE; j++) |
| 119 | { |
| 120 | if (p_dev_rec->features[i][j] != 0) |
| 121 | { |
| 122 | found = TRUE; |
| 123 | break; |
| 124 | } |
| 125 | } |
| 126 | if (found) |
| 127 | { |
| 128 | p_dev_rec->num_read_pages = i + 1; |
| 129 | break; |
| 130 | } |
| 131 | } |
| 132 | } |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 133 | else |
| Andre Eisenbach | 3aa6054 | 2013-03-22 18:00:51 -0700 | [diff] [blame] | 134 | memset (p_dev_rec->features, 0, sizeof (p_dev_rec->features)); |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 135 | |
| 136 | BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask); |
| 137 | |
| 138 | if (link_key) |
| 139 | { |
| Sharvil Nanavati | 83c5256 | 2014-05-04 00:46:57 -0700 | [diff] [blame] | 140 | BTM_TRACE_EVENT ("BTM_SecAddDevice() BDA: %02x:%02x:%02x:%02x:%02x:%02x", |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 141 | bd_addr[0], bd_addr[1], bd_addr[2], |
| 142 | bd_addr[3], bd_addr[4], bd_addr[5]); |
| 143 | p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN; |
| 144 | memcpy (p_dev_rec->link_key, link_key, LINK_KEY_LEN); |
| 145 | p_dev_rec->link_key_type = key_type; |
| 146 | } |
| 147 | |
| 148 | #if defined(BTIF_MIXED_MODE_INCLUDED) && (BTIF_MIXED_MODE_INCLUDED == TRUE) |
| Ganesh Ganapathi Batta | ead3cde | 2013-02-05 15:22:31 -0800 | [diff] [blame] | 149 | if (key_type < BTM_MAX_PRE_SM4_LKEY_TYPE) |
| 150 | p_dev_rec->sm4 = BTM_SM4_KNOWN; |
| 151 | else |
| 152 | p_dev_rec->sm4 = BTM_SM4_TRUE; |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 153 | #endif |
| 154 | |
| 155 | p_dev_rec->rmt_io_caps = io_cap; |
| 156 | |
| 157 | return(TRUE); |
| 158 | } |
| 159 | |
| 160 | |
| 161 | /******************************************************************************* |
| 162 | ** |
| 163 | ** Function BTM_SecDeleteDevice |
| 164 | ** |
| 165 | ** Description Free resources associated with the device. |
| 166 | ** |
| 167 | ** Parameters: bd_addr - BD address of the peer |
| 168 | ** |
| 169 | ** Returns TRUE if removed OK, FALSE if not found or ACL link is active |
| 170 | ** |
| 171 | *******************************************************************************/ |
| 172 | BOOLEAN BTM_SecDeleteDevice (BD_ADDR bd_addr) |
| 173 | { |
| 174 | tBTM_SEC_DEV_REC *p_dev_rec; |
| 175 | |
| Ganesh Ganapathi Batta | 8fe5887 | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 176 | if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE) || BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR)) |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 177 | { |
| Sharvil Nanavati | 83c5256 | 2014-05-04 00:46:57 -0700 | [diff] [blame] | 178 | BTM_TRACE_WARNING("BTM_SecDeleteDevice FAILED: Cannot Delete when connection is active"); |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 179 | return(FALSE); |
| 180 | } |
| 181 | |
| 182 | if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL) |
| 183 | return(FALSE); |
| 184 | |
| 185 | btm_sec_free_dev (p_dev_rec); |
| 186 | |
| 187 | /* Tell controller to get rid of the link key if it has one stored */ |
| 188 | BTM_DeleteStoredLinkKey (bd_addr, NULL); |
| 189 | |
| 190 | return(TRUE); |
| 191 | } |
| 192 | |
| 193 | /******************************************************************************* |
| 194 | ** |
| 195 | ** Function BTM_SecReadDevName |
| 196 | ** |
| 197 | ** Description Looks for the device name in the security database for the |
| 198 | ** specified BD address. |
| 199 | ** |
| 200 | ** Returns Pointer to the name or NULL |
| 201 | ** |
| 202 | *******************************************************************************/ |
| 203 | char *BTM_SecReadDevName (BD_ADDR bd_addr) |
| 204 | { |
| 205 | char *p_name = NULL; |
| 206 | tBTM_SEC_DEV_REC *p_srec; |
| 207 | |
| 208 | if ((p_srec = btm_find_dev(bd_addr)) != NULL) |
| 209 | p_name = (char *)p_srec->sec_bd_name; |
| 210 | |
| 211 | return(p_name); |
| 212 | } |
| 213 | |
| 214 | /******************************************************************************* |
| 215 | ** |
| 216 | ** Function btm_sec_alloc_dev |
| 217 | ** |
| 218 | ** Description Look for the record in the device database for the record |
| Ganesh Ganapathi Batta | 8fe5887 | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 219 | ** with specified address |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 220 | ** |
| Ganesh Ganapathi Batta | 8fe5887 | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 221 | ** Returns Pointer to the record or NULL |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 222 | ** |
| 223 | *******************************************************************************/ |
| 224 | tBTM_SEC_DEV_REC *btm_sec_alloc_dev (BD_ADDR bd_addr) |
| 225 | { |
| 226 | tBTM_SEC_DEV_REC *p_dev_rec = NULL; |
| 227 | tBTM_INQ_INFO *p_inq_info; |
| 228 | int i; |
| Sharvil Nanavati | 83c5256 | 2014-05-04 00:46:57 -0700 | [diff] [blame] | 229 | BTM_TRACE_EVENT ("btm_sec_alloc_dev"); |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 230 | for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++) |
| 231 | { |
| 232 | if (!(btm_cb.sec_dev_rec[i].sec_flags & BTM_SEC_IN_USE)) |
| 233 | { |
| 234 | p_dev_rec = &btm_cb.sec_dev_rec[i]; |
| 235 | break; |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | if (!p_dev_rec) |
| 240 | p_dev_rec = btm_find_oldest_dev(); |
| 241 | |
| 242 | memset (p_dev_rec, 0, sizeof (tBTM_SEC_DEV_REC)); |
| 243 | |
| 244 | p_dev_rec->sec_flags = BTM_SEC_IN_USE; |
| 245 | |
| 246 | /* Check with the BT manager if details about remote device are known */ |
| 247 | /* outgoing connection */ |
| 248 | if ((p_inq_info = BTM_InqDbRead(bd_addr)) != NULL) |
| 249 | { |
| 250 | memcpy (p_dev_rec->dev_class, p_inq_info->results.dev_class, DEV_CLASS_LEN); |
| 251 | |
| 252 | #if BLE_INCLUDED == TRUE |
| 253 | p_dev_rec->device_type = p_inq_info->results.device_type; |
| 254 | p_dev_rec->ble.ble_addr_type = p_inq_info->results.ble_addr_type; |
| 255 | |
| 256 | /* update conn params, use default value for background connection params */ |
| 257 | memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS)); |
| 258 | #endif |
| 259 | |
| 260 | #if BTM_INQ_GET_REMOTE_NAME == TRUE |
| 261 | if (p_inq_info->remote_name_state == BTM_INQ_RMT_NAME_DONE) |
| 262 | { |
| 263 | BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, sizeof (p_dev_rec->sec_bd_name), |
| 264 | (char *)p_inq_info->remote_name, BTM_MAX_REM_BD_NAME_LEN); |
| 265 | p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN; |
| 266 | } |
| 267 | #endif |
| 268 | } |
| 269 | else |
| 270 | { |
| 271 | #if BLE_INCLUDED == TRUE |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 272 | /* update conn params, use default value for background connection params */ |
| 273 | memset(&p_dev_rec->conn_params, 0xff, sizeof(tBTM_LE_CONN_PRAMS)); |
| 274 | #endif |
| 275 | |
| 276 | if (!memcmp (bd_addr, btm_cb.connecting_bda, BD_ADDR_LEN)) |
| 277 | memcpy (p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN); |
| 278 | } |
| 279 | |
| 280 | memcpy (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN); |
| 281 | |
| Ganesh Ganapathi Batta | 8fe5887 | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 282 | #if BLE_INCLUDED == TRUE |
| 283 | p_dev_rec->ble_hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_LE); |
| 284 | #endif |
| 285 | p_dev_rec->hci_handle = BTM_GetHCIConnHandle (bd_addr, BT_TRANSPORT_BR_EDR); |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 286 | p_dev_rec->timestamp = btm_cb.dev_rec_count++; |
| 287 | |
| 288 | return(p_dev_rec); |
| 289 | } |
| 290 | |
| 291 | |
| 292 | /******************************************************************************* |
| 293 | ** |
| 294 | ** Function btm_sec_free_dev |
| 295 | ** |
| 296 | ** Description Mark device record as not used |
| 297 | ** |
| 298 | *******************************************************************************/ |
| 299 | void btm_sec_free_dev (tBTM_SEC_DEV_REC *p_dev_rec) |
| 300 | { |
| 301 | p_dev_rec->sec_flags = 0; |
| 302 | |
| 303 | #if BLE_INCLUDED == TRUE |
| 304 | /* Clear out any saved BLE keys */ |
| 305 | btm_sec_clear_ble_keys (p_dev_rec); |
| 306 | #endif |
| 307 | |
| 308 | |
| 309 | } |
| 310 | |
| 311 | /******************************************************************************* |
| 312 | ** |
| 313 | ** Function btm_dev_support_switch |
| 314 | ** |
| 315 | ** Description This function is called by the L2CAP to check if remote |
| 316 | ** device supports role switch |
| 317 | ** |
| 318 | ** Parameters: bd_addr - Address of the peer device |
| 319 | ** |
| 320 | ** Returns TRUE if device is known and role switch is supported |
| 321 | ** |
| 322 | *******************************************************************************/ |
| 323 | BOOLEAN btm_dev_support_switch (BD_ADDR bd_addr) |
| 324 | { |
| 325 | tBTM_SEC_DEV_REC *p_dev_rec; |
| 326 | UINT8 xx; |
| 327 | BOOLEAN feature_empty = TRUE; |
| 328 | |
| 329 | #if BTM_SCO_INCLUDED == TRUE |
| 330 | /* Role switch is not allowed if a SCO is up */ |
| 331 | if (btm_is_sco_active_by_bdaddr(bd_addr)) |
| 332 | return(FALSE); |
| 333 | #endif |
| 334 | p_dev_rec = btm_find_dev (bd_addr); |
| Andre Eisenbach | 3aa6054 | 2013-03-22 18:00:51 -0700 | [diff] [blame] | 335 | if (p_dev_rec && HCI_SWITCH_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0])) |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 336 | { |
| Andre Eisenbach | 3aa6054 | 2013-03-22 18:00:51 -0700 | [diff] [blame] | 337 | if (HCI_SWITCH_SUPPORTED(p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0])) |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 338 | { |
| Sharvil Nanavati | 83c5256 | 2014-05-04 00:46:57 -0700 | [diff] [blame] | 339 | BTM_TRACE_DEBUG("btm_dev_support_switch return TRUE (feature found)"); |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 340 | return (TRUE); |
| 341 | } |
| 342 | |
| 343 | /* If the feature field is all zero, we never received them */ |
| 344 | for (xx = 0 ; xx < BD_FEATURES_LEN ; xx++) |
| 345 | { |
| Andre Eisenbach | 3aa6054 | 2013-03-22 18:00:51 -0700 | [diff] [blame] | 346 | if (p_dev_rec->features[HCI_EXT_FEATURES_PAGE_0][xx] != 0x00) |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 347 | { |
| 348 | feature_empty = FALSE; /* at least one is != 0 */ |
| 349 | break; |
| 350 | } |
| 351 | } |
| 352 | |
| 353 | /* If we don't know peer's capabilities, assume it supports Role-switch */ |
| 354 | if (feature_empty) |
| 355 | { |
| Sharvil Nanavati | 83c5256 | 2014-05-04 00:46:57 -0700 | [diff] [blame] | 356 | BTM_TRACE_DEBUG("btm_dev_support_switch return TRUE (feature empty)"); |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 357 | return (TRUE); |
| 358 | } |
| 359 | } |
| 360 | |
| Sharvil Nanavati | 83c5256 | 2014-05-04 00:46:57 -0700 | [diff] [blame] | 361 | BTM_TRACE_DEBUG("btm_dev_support_switch return FALSE"); |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 362 | return(FALSE); |
| 363 | } |
| 364 | |
| 365 | /******************************************************************************* |
| 366 | ** |
| 367 | ** Function btm_find_dev_by_handle |
| 368 | ** |
| 369 | ** Description Look for the record in the device database for the record |
| 370 | ** with specified handle |
| 371 | ** |
| 372 | ** Returns Pointer to the record or NULL |
| 373 | ** |
| 374 | *******************************************************************************/ |
| 375 | tBTM_SEC_DEV_REC *btm_find_dev_by_handle (UINT16 handle) |
| 376 | { |
| 377 | tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; |
| 378 | int i; |
| 379 | |
| 380 | for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) |
| 381 | { |
| 382 | if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) |
| Ganesh Ganapathi Batta | 8fe5887 | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 383 | && ((p_dev_rec->hci_handle == handle) |
| 384 | #if BLE_INCLUDED == TRUE |
| 385 | ||(p_dev_rec->ble_hci_handle == handle) |
| 386 | #endif |
| 387 | )) |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 388 | return(p_dev_rec); |
| 389 | } |
| 390 | return(NULL); |
| 391 | } |
| 392 | |
| 393 | /******************************************************************************* |
| 394 | ** |
| 395 | ** Function btm_find_dev |
| 396 | ** |
| 397 | ** Description Look for the record in the device database for the record |
| 398 | ** with specified BD address |
| 399 | ** |
| 400 | ** Returns Pointer to the record or NULL |
| 401 | ** |
| 402 | *******************************************************************************/ |
| 403 | tBTM_SEC_DEV_REC *btm_find_dev (BD_ADDR bd_addr) |
| 404 | { |
| 405 | tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; |
| 406 | int i; |
| 407 | |
| 408 | if (bd_addr) |
| 409 | { |
| 410 | for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) |
| 411 | { |
| 412 | if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) |
| 413 | && (!memcmp (p_dev_rec->bd_addr, bd_addr, BD_ADDR_LEN))) |
| 414 | return(p_dev_rec); |
| 415 | } |
| 416 | } |
| 417 | return(NULL); |
| 418 | } |
| 419 | |
| 420 | /******************************************************************************* |
| 421 | ** |
| 422 | ** Function btm_find_or_alloc_dev |
| 423 | ** |
| 424 | ** Description Look for the record in the device database for the record |
| 425 | ** with specified BD address |
| 426 | ** |
| 427 | ** Returns Pointer to the record or NULL |
| 428 | ** |
| 429 | *******************************************************************************/ |
| 430 | tBTM_SEC_DEV_REC *btm_find_or_alloc_dev (BD_ADDR bd_addr) |
| 431 | { |
| 432 | tBTM_SEC_DEV_REC *p_dev_rec; |
| Sharvil Nanavati | 83c5256 | 2014-05-04 00:46:57 -0700 | [diff] [blame] | 433 | BTM_TRACE_EVENT ("btm_find_or_alloc_dev"); |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 434 | if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL) |
| 435 | { |
| 436 | |
| 437 | /* Allocate a new device record or reuse the oldest one */ |
| 438 | p_dev_rec = btm_sec_alloc_dev (bd_addr); |
| 439 | } |
| 440 | return(p_dev_rec); |
| 441 | } |
| 442 | |
| 443 | /******************************************************************************* |
| 444 | ** |
| 445 | ** Function btm_find_oldest_dev |
| 446 | ** |
| 447 | ** Description Locates the oldest device in use. It first looks for |
| 448 | ** the oldest non-paired device. If all devices are paired it |
| 449 | ** deletes the oldest paired device. |
| 450 | ** |
| Ganesh Ganapathi Batta | 8fe5887 | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 451 | ** Returns Pointer to the record or NULL |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 452 | ** |
| 453 | *******************************************************************************/ |
| 454 | tBTM_SEC_DEV_REC *btm_find_oldest_dev (void) |
| 455 | { |
| 456 | tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0]; |
| 457 | tBTM_SEC_DEV_REC *p_oldest = p_dev_rec; |
| 458 | UINT32 ot = 0xFFFFFFFF; |
| 459 | int i; |
| 460 | |
| 461 | /* First look for the non-paired devices for the oldest entry */ |
| 462 | for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) |
| 463 | { |
| 464 | if (((p_dev_rec->sec_flags & BTM_SEC_IN_USE) == 0) |
| Ganesh Ganapathi Batta | 8fe5887 | 2014-04-16 16:50:09 -0700 | [diff] [blame] | 465 | || ((p_dev_rec->sec_flags & (BTM_SEC_LINK_KEY_KNOWN |BTM_SEC_LE_LINK_KEY_KNOWN)) != 0)) |
| The Android Open Source Project | 5738f83 | 2012-12-12 16:00:35 -0800 | [diff] [blame] | 466 | continue; /* Device is paired so skip it */ |
| 467 | |
| 468 | if (p_dev_rec->timestamp < ot) |
| 469 | { |
| 470 | p_oldest = p_dev_rec; |
| 471 | ot = p_dev_rec->timestamp; |
| 472 | } |
| 473 | } |
| 474 | |
| 475 | if (ot != 0xFFFFFFFF) |
| 476 | return(p_oldest); |
| 477 | |
| 478 | /* All devices are paired; find the oldest */ |
| 479 | p_dev_rec = &btm_cb.sec_dev_rec[0]; |
| 480 | for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++) |
| 481 | { |
| 482 | if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE) == 0) |
| 483 | continue; |
| 484 | |
| 485 | if (p_dev_rec->timestamp < ot) |
| 486 | { |
| 487 | p_oldest = p_dev_rec; |
| 488 | ot = p_dev_rec->timestamp; |
| 489 | } |
| 490 | } |
| 491 | return(p_oldest); |
| 492 | } |
| 493 | |
| 494 | |