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