blob: 7aab0a95af69405c6bfa15506dfee978b3f8801d [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
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 Security Manager
22 *
23 ******************************************************************************/
24
25#include <string.h>
26#include "bt_types.h"
27#include "hcimsgs.h"
28#include "btu.h"
29#include "btm_int.h"
30#include "l2c_int.h"
Mike J. Chen5cd8bff2014-01-31 18:16:59 -080031#include "bt_utils.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080032
33#if (BT_USE_TRACES == TRUE && BT_TRACE_VERBOSE == FALSE)
34/* needed for sprintf() */
35#include <stdio.h>
36#endif
37
38#if BLE_INCLUDED == TRUE
39 #include "gatt_int.h"
40#endif
41
42#define BTM_SEC_MAX_COLLISION_DELAY (GKI_SECS_TO_TICKS(5))
43
44#ifdef APPL_AUTH_WRITE_EXCEPTION
45BOOLEAN (APPL_AUTH_WRITE_EXCEPTION)(BD_ADDR bd_addr);
46#endif
47
Andre Eisenbach6975b4d2013-08-05 16:55:38 -070048
49/********************************************************************************
50** L O C A L F U N C T I O N P R O T O T Y P E S *
51*********************************************************************************/
The Android Open Source Project5738f832012-12-12 16:00:35 -080052static tBTM_SEC_SERV_REC *btm_sec_find_first_serv (BOOLEAN is_originator, UINT16 psm);
53static tBTM_SEC_SERV_REC *btm_sec_find_next_serv (tBTM_SEC_SERV_REC *p_cur);
54static tBTM_SEC_SERV_REC *btm_sec_find_mx_serv (UINT8 is_originator, UINT16 psm,
55 UINT32 mx_proto_id,
56 UINT32 mx_chan_id);
57
58static tBTM_STATUS btm_sec_execute_procedure (tBTM_SEC_DEV_REC *p_dev_rec);
59static BOOLEAN btm_sec_start_get_name (tBTM_SEC_DEV_REC *p_dev_rec);
60static BOOLEAN btm_sec_start_authentication (tBTM_SEC_DEV_REC *p_dev_rec);
61static BOOLEAN btm_sec_start_encryption (tBTM_SEC_DEV_REC *p_dev_rec);
62static void btm_sec_collision_timeout (TIMER_LIST_ENT *p_tle);
63static void btm_restore_mode(void);
64static void btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle);
65static tBTM_STATUS btm_sec_dd_create_conn (tBTM_SEC_DEV_REC *p_dev_rec);
66static void btm_sec_change_pairing_state (tBTM_PAIRING_STATE new_state);
67
68#if (BT_USE_TRACES == TRUE)
69static char *btm_pair_state_descr (tBTM_PAIRING_STATE state);
70#endif
71
72static void btm_sec_check_pending_reqs(void);
73static BOOLEAN btm_sec_queue_mx_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_orig,
74 UINT32 mx_proto_id, UINT32 mx_chan_id,
75 tBTM_SEC_CALLBACK *p_callback, void *p_ref_data);
76static void btm_sec_bond_cancel_complete (void);
77static void btm_send_link_key_notif (tBTM_SEC_DEV_REC *p_dev_rec);
78static BOOLEAN btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC *p_dev_rec);
79
80static UINT8 btm_sec_start_authorization (tBTM_SEC_DEV_REC *p_dev_rec);
81BOOLEAN btm_sec_are_all_trusted(UINT32 p_mask[]);
82
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -070083static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason, UINT16 conn_handle);
84UINT8 btm_sec_start_role_switch (tBTM_SEC_DEV_REC *p_dev_rec);
The Android Open Source Project5738f832012-12-12 16:00:35 -080085tBTM_SEC_DEV_REC *btm_sec_find_dev_by_sec_state (UINT8 state);
86
87static BOOLEAN btm_sec_set_security_level ( CONNECTION_TYPE conn_type, char *p_name, UINT8 service_id,
88 UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id,
89 UINT32 mx_chan_id);
90
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -070091static BOOLEAN btm_dev_authenticated(tBTM_SEC_DEV_REC *p_dev_rec);
92static BOOLEAN btm_dev_encrypted(tBTM_SEC_DEV_REC *p_dev_rec);
93static BOOLEAN btm_dev_authorized(tBTM_SEC_DEV_REC *p_dev_rec);
94static BOOLEAN btm_serv_trusted(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_SEC_SERV_REC *p_serv_rec);
95
The Android Open Source Project5738f832012-12-12 16:00:35 -080096/* TRUE - authenticated link key is possible */
97static const BOOLEAN btm_sec_io_map [BTM_IO_CAP_MAX][BTM_IO_CAP_MAX] =
98{
99 /* OUT, IO, IN, NONE */
100/* OUT */ {FALSE, FALSE, TRUE, FALSE},
101/* IO */ {FALSE, TRUE, TRUE, FALSE},
102/* IN */ {TRUE, TRUE, TRUE, FALSE},
103/* NONE */ {FALSE, FALSE, FALSE, FALSE}
104};
105/* BTM_IO_CAP_OUT 0 DisplayOnly */
106/* BTM_IO_CAP_IO 1 DisplayYesNo */
107/* BTM_IO_CAP_IN 2 KeyboardOnly */
108/* BTM_IO_CAP_NONE 3 NoInputNoOutput */
109
110/*******************************************************************************
111**
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700112** Function btm_dev_authenticated
113**
114** Description check device is authenticated
115**
116** Returns BOOLEAN TRUE or FALSE
117**
118*******************************************************************************/
119static BOOLEAN btm_dev_authenticated (tBTM_SEC_DEV_REC *p_dev_rec)
120{
121 if(p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED)
122 {
123 return(TRUE);
124 }
125 return(FALSE);
126}
127
128/*******************************************************************************
129**
130** Function btm_dev_encrypted
131**
132** Description check device is encrypted
133**
134** Returns BOOLEAN TRUE or FALSE
135**
136*******************************************************************************/
137static BOOLEAN btm_dev_encrypted (tBTM_SEC_DEV_REC *p_dev_rec)
138{
139 if(p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)
140 {
141 return(TRUE);
142 }
143 return(FALSE);
144}
145
146/*******************************************************************************
147**
148** Function btm_dev_authorized
149**
150** Description check device is authorized
151**
152** Returns BOOLEAN TRUE or FALSE
153**
154*******************************************************************************/
155static BOOLEAN btm_dev_authorized (tBTM_SEC_DEV_REC *p_dev_rec)
156{
157 if(p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED)
158 {
159 return(TRUE);
160 }
161 return(FALSE);
162}
163
164/*******************************************************************************
165**
166** Function btm_serv_trusted
167**
168** Description check service is trusted
169**
170** Returns BOOLEAN TRUE or FALSE
171**
172*******************************************************************************/
173static BOOLEAN btm_serv_trusted(tBTM_SEC_DEV_REC *p_dev_rec, tBTM_SEC_SERV_REC *p_serv_rec)
174{
175 if(BTM_SEC_IS_SERVICE_TRUSTED(p_dev_rec->trusted_mask, p_serv_rec->service_id))
176 {
177 return(TRUE);
178 }
179 return(FALSE);
180}
181
182/*******************************************************************************
183**
The Android Open Source Project5738f832012-12-12 16:00:35 -0800184** Function BTM_SecRegister
185**
186** Description Application manager calls this function to register for
187** security services. There can be one and only one application
188** saving link keys. BTM allows only first registration.
189**
190** Returns TRUE if registered OK, else FALSE
191**
192*******************************************************************************/
193BOOLEAN BTM_SecRegister (tBTM_APPL_INFO *p_cb_info)
194{
195#if BLE_INCLUDED == TRUE
196 BT_OCTET16 temp_value = {0};
197#endif
198
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700199 BTM_TRACE_EVENT ("BTM_Sec: application registered");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800200
201#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
The Android Open Source Project5738f832012-12-12 16:00:35 -0800202 if (p_cb_info->p_le_callback)
203 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700204 BTM_TRACE_ERROR ("BTM_SecRegister:p_cb_info->p_le_callback == 0x%x ", p_cb_info->p_le_callback);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700205
206 if (p_cb_info->p_le_callback)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800207 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700208 #if SMP_INCLUDED == TRUE
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700209 BTM_TRACE_EVENT ("BTM_Sec: SMP_Register( btm_proc_smp_cback )");
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700210 SMP_Register(btm_proc_smp_cback);
211 #endif
212 /* if no IR is loaded, need to regenerate all the keys */
213 if (memcmp(btm_cb.devcb.id_keys.ir, &temp_value, sizeof(BT_OCTET16)) == 0)
214 {
215 btm_ble_reset_id();
216 }
217 }
218 else
219 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700220 BTM_TRACE_ERROR ("BTM_SecRegister:p_cb_info->p_le_callback == NULL ");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800221 }
222 }
The Android Open Source Project5738f832012-12-12 16:00:35 -0800223#endif
224
The Android Open Source Project5738f832012-12-12 16:00:35 -0800225 btm_cb.api = *p_cb_info;
226#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700227 BTM_TRACE_ERROR ("BTM_SecRegister: btm_cb.api.p_le_callback = 0x%x ", btm_cb.api.p_le_callback);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800228#endif
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700229 BTM_TRACE_EVENT ("BTM_Sec: application registered");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800230 return(TRUE);
231}
232
233
234/*******************************************************************************
235**
236** Function BTM_SecRegisterLinkKeyNotificationCallback
237**
238** Description Application manager calls this function to register for
239** link key notification. When there is nobody registered
240** we should avoid changing link key
241**
242** Returns TRUE if registered OK, else FALSE
243**
244*******************************************************************************/
245BOOLEAN BTM_SecRegisterLinkKeyNotificationCallback (tBTM_LINK_KEY_CALLBACK *p_callback)
246{
247 btm_cb.api.p_link_key_callback = p_callback;
248 return(TRUE);
249}
250
251
252/*******************************************************************************
253**
254** Function BTM_SecAddRmtNameNotifyCallback
255**
256** Description Any profile can register to be notified when name of the
257** remote device is resolved.
258**
259** Returns TRUE if registered OK, else FALSE
260**
261*******************************************************************************/
262BOOLEAN BTM_SecAddRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback)
263{
264 int i;
265
266 for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++)
267 {
268 if (btm_cb.p_rmt_name_callback[i] == NULL)
269 {
270 btm_cb.p_rmt_name_callback[i] = p_callback;
271 return(TRUE);
272 }
273 }
274
275 return(FALSE);
276}
277
278
279/*******************************************************************************
280**
281** Function BTM_SecDeleteRmtNameNotifyCallback
282**
283** Description Any profile can deregister notification when a new Link Key
284** is generated per connection.
285**
286** Returns TRUE if OK, else FALSE
287**
288*******************************************************************************/
289BOOLEAN BTM_SecDeleteRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback)
290{
291 int i;
292
293 for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++)
294 {
295 if (btm_cb.p_rmt_name_callback[i] == p_callback)
296 {
297 btm_cb.p_rmt_name_callback[i] = NULL;
298 return(TRUE);
299 }
300 }
301
302 return(FALSE);
303}
304
305
306/*******************************************************************************
307**
308** Function BTM_SecSetConnectFilterCallback
309**
310** Description Host can register to be asked whenever a HCI connection
311** request is received. In the registered function host
312** suppose to check connectibility filters. Yes/No result
313** should be returned syncronously
314**
315** Returns void
316**
317*******************************************************************************/
318void BTM_SecSetConnectFilterCallback (tBTM_FILTER_CB *p_callback)
319{
320 btm_cb.p_conn_filter_cb = p_callback;
321}
322
323/*******************************************************************************
324**
325** Function BTM_GetSecurityMode
326**
327** Description Get security mode for the device
328**
329** Returns void
330**
331*******************************************************************************/
332UINT8 BTM_GetSecurityMode (void)
333{
334 return(btm_cb.security_mode);
335}
336
337/*******************************************************************************
338**
339** Function BTM_GetSecurityFlags
340**
341** Description Get security flags for the device
342**
343** Returns BOOLEAN TRUE or FALSE is device found
344**
345*******************************************************************************/
346BOOLEAN BTM_GetSecurityFlags (BD_ADDR bd_addr, UINT8 * p_sec_flags)
347{
348 tBTM_SEC_DEV_REC *p_dev_rec;
349
350 if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
351 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700352 *p_sec_flags = (UINT8) p_dev_rec->sec_flags;
353 return(TRUE);
354 }
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700355 BTM_TRACE_ERROR ("BTM_GetSecurityFlags false");
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -0700356 return(FALSE);
357}
358
359/*******************************************************************************
360**
361** Function BTM_GetSecurityFlagsByTransport
362**
363** Description Get security flags for the device on a particular transport
364**
365** Returns BOOLEAN TRUE or FALSE is device found
366**
367*******************************************************************************/
368BOOLEAN BTM_GetSecurityFlagsByTransport (BD_ADDR bd_addr, UINT8 * p_sec_flags,
369 tBT_TRANSPORT transport)
370{
371 tBTM_SEC_DEV_REC *p_dev_rec;
372
373 if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
374 {
375 if (transport == BT_TRANSPORT_BR_EDR)
376 *p_sec_flags = (UINT8) p_dev_rec->sec_flags;
377 else
378 *p_sec_flags = (UINT8) (p_dev_rec->sec_flags >> 8);
379
The Android Open Source Project5738f832012-12-12 16:00:35 -0800380 return(TRUE);
381 }
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700382 BTM_TRACE_ERROR ("BTM_GetSecurityFlags false");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800383 return(FALSE);
384}
385
386/*******************************************************************************
387**
388** Function BTM_SetSecurityMode
389**
390** Description Set security mode for the device
391**
392** Returns void
393**
394*******************************************************************************/
395void BTM_SetSecurityMode (UINT8 security_mode)
396{
397 UINT8 old_mode = btm_cb.security_mode;
398
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800399 UINT8 sp_mode = HCI_SP_MODE_ENABLED;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800400 UINT8 sp_debug_mode = HCI_SPD_MODE_DISABLED;
401
402 switch (security_mode)
403 {
404#if (BTM_PRE_LISBON_INCLUDED == TRUE)
405 case BTM_SEC_MODE_NONE:
406 case BTM_SEC_MODE_SERVICE:
407 case BTM_SEC_MODE_LINK:
408 break;
409#endif
410
411 case BTM_SEC_MODE_SP_DEBUG:
412 sp_debug_mode = HCI_SPD_MODE_ENABLED;
413 break;
414 case BTM_SEC_MODE_SP:
415 /* the default is enabled */
416 break;
417 default:
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700418 BTM_TRACE_ERROR ("BTM_SetSecurityMode: unknown mode:%d", security_mode);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800419 return;
420 }
421 btm_cb.security_mode = security_mode;
422
Andre Eisenbach3aa60542013-03-22 18:00:51 -0700423 if (HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
The Android Open Source Project5738f832012-12-12 16:00:35 -0800424 {
425 /* Lisbon devices and only use BTM_SEC_MODE_SP */
426 btm_cb.security_mode = BTM_SEC_MODE_SP;
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700427 BTM_TRACE_DEBUG("BTM_SetSecurityMode: SP:%d, debug:%d", sp_mode, sp_debug_mode);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800428 btsnd_hcic_write_simple_pairing_mode(sp_mode);
429 btsnd_hcic_write_simp_pair_debug_mode(sp_debug_mode);
430 return;
431 }
432
433 /* must be a pre-Lisbon device */
434#if (BTM_PRE_LISBON_INCLUDED == TRUE)
435 /* If previously security mode was Link Level and now lesser notify */
436 /* controller not to perform authentication, encryption on startup */
437 if ((old_mode == BTM_SEC_MODE_LINK)
438 && ( security_mode != BTM_SEC_MODE_LINK))
439 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700440 BTM_TRACE_DEBUG("BTM_SetSecurityMode: Authen Enable -> FALSE");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800441 btsnd_hcic_write_auth_enable (FALSE);
442 btsnd_hcic_write_encr_mode (HCI_ENCRYPT_MODE_DISABLED);
443 }
444
445 /* If previously security is increased to Link Level notify */
446 /* controller to perform authentication, encryption on startup */
447 if ((old_mode != BTM_SEC_MODE_LINK)
448 && ( security_mode == BTM_SEC_MODE_LINK))
449 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700450 BTM_TRACE_DEBUG("BTM_SetSecurityMode: Authen Enable -> TRUE");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800451 btsnd_hcic_write_auth_enable (TRUE);
452 btsnd_hcic_write_encr_mode (HCI_ENCRYPT_MODE_POINT_TO_POINT);
453 }
454#endif /* BTM_PRE_LISBON_INCLUDED == TRUE */
455}
456
457/*******************************************************************************
458**
459** Function BTM_SetPinType
460**
461** Description Set PIN type for the device.
462**
463** Returns void
464**
465*******************************************************************************/
466void BTM_SetPinType (UINT8 pin_type, PIN_CODE pin_code, UINT8 pin_code_len)
467{
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700468 BTM_TRACE_API ("BTM_SetPinType: pin type %d [variable-0, fixed-1], code %s, length %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800469 pin_type, (char *) pin_code, pin_code_len);
470
471 /* If device is not up security mode will be set as a part of startup */
472 if ( (btm_cb.cfg.pin_type != pin_type)
473 && (btm_cb.devcb.state > BTM_DEV_STATE_WAIT_AFTER_RESET) )
474 {
475 btsnd_hcic_write_pin_type (pin_type);
476 }
477
478 btm_cb.cfg.pin_type = pin_type;
479 btm_cb.cfg.pin_code_len = pin_code_len;
480 memcpy (btm_cb.cfg.pin_code, pin_code, pin_code_len);
481}
482
483/*******************************************************************************
484**
485** Function BTM_SetPairableMode
486**
487** Description Enable or disable pairing
488**
489** Parameters allow_pairing - (TRUE or FALSE) whether or not the device
490** allows pairing.
491** connect_only_paired - (TRUE or FALSE) whether or not to
492** only allow paired devices to connect.
493**
494** Returns void
495**
496*******************************************************************************/
497void BTM_SetPairableMode (BOOLEAN allow_pairing, BOOLEAN connect_only_paired)
498{
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700499 BTM_TRACE_API ("BTM_SetPairableMode() allow_pairing: %u connect_only_paired: %u", allow_pairing, connect_only_paired);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800500
501 btm_cb.pairing_disabled = !allow_pairing;
502 btm_cb.connect_only_paired = connect_only_paired;
503}
504
505
506#define BTM_NO_AVAIL_SEC_SERVICES ((UINT16) 0xffff)
507
508/*******************************************************************************
509**
510** Function BTM_SetUCDSecurityLevel
511**
512** Description Register UCD service security level with Security Manager
513**
514** Parameters: is_originator - TRUE if originating the connection, FALSE if not
515** p_name - Name of the service relevant only if
516** authorization will show this name to user. ignored
517** if BTM_SEC_SERVICE_NAME_LEN is 0.
518** service_id - service ID for the service passed to authorization callback
519** sec_level - bit mask of the security features
520** psm - L2CAP PSM
521** mx_proto_id - protocol ID of multiplexing proto below
522** mx_chan_id - channel ID of multiplexing proto below
523**
524** Returns TRUE if registered OK, else FALSE
525**
526*******************************************************************************/
527BOOLEAN BTM_SetUCDSecurityLevel (BOOLEAN is_originator, char *p_name, UINT8 service_id,
528 UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id,
529 UINT32 mx_chan_id)
530{
531#if (L2CAP_UCD_INCLUDED == TRUE)
532 CONNECTION_TYPE conn_type;
533
534 if (is_originator)
535 conn_type = CONNLESS_ORIG;
536 else
537 conn_type = CONNLESS_TERM;
538
539 return(btm_sec_set_security_level (conn_type, p_name, service_id,
540 sec_level, psm, mx_proto_id, mx_chan_id));
541#else
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800542 UNUSED(is_originator);
543 UNUSED(p_name);
544 UNUSED(service_id);
545 UNUSED(sec_level);
546 UNUSED(psm);
547 UNUSED(mx_proto_id);
548 UNUSED(mx_chan_id);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800549 return FALSE;
550#endif
551}
552
553/*******************************************************************************
554**
555** Function BTM_SetSecurityLevel
556**
557** Description Register service security level with Security Manager
558**
559** Parameters: is_originator - TRUE if originating the connection, FALSE if not
560** p_name - Name of the service relevant only if
561** authorization will show this name to user. ignored
562** if BTM_SEC_SERVICE_NAME_LEN is 0.
563** service_id - service ID for the service passed to authorization callback
564** sec_level - bit mask of the security features
565** psm - L2CAP PSM
566** mx_proto_id - protocol ID of multiplexing proto below
567** mx_chan_id - channel ID of multiplexing proto below
568**
569** Returns TRUE if registered OK, else FALSE
570**
571*******************************************************************************/
572BOOLEAN BTM_SetSecurityLevel (BOOLEAN is_originator, char *p_name, UINT8 service_id,
573 UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id,
574 UINT32 mx_chan_id)
575{
576#if (L2CAP_UCD_INCLUDED == TRUE)
577 CONNECTION_TYPE conn_type;
578
579 if (is_originator)
580 conn_type = CONN_ORIENT_ORIG;
581 else
582 conn_type = CONN_ORIENT_TERM;
583
584 return(btm_sec_set_security_level (conn_type, p_name, service_id,
585 sec_level, psm, mx_proto_id, mx_chan_id));
586#else
587 return(btm_sec_set_security_level (is_originator, p_name, service_id,
588 sec_level, psm, mx_proto_id, mx_chan_id));
589#endif
590}
591
592/*******************************************************************************
593**
594** Function btm_sec_set_security_level
595**
596** Description Register service security level with Security Manager
597**
598** Parameters: conn_type - TRUE if originating the connection, FALSE if not
599** p_name - Name of the service relevant only if
600** authorization will show this name to user. ignored
601** if BTM_SEC_SERVICE_NAME_LEN is 0.
602** service_id - service ID for the service passed to authorization callback
603** sec_level - bit mask of the security features
604** psm - L2CAP PSM
605** mx_proto_id - protocol ID of multiplexing proto below
606** mx_chan_id - channel ID of multiplexing proto below
607**
608** Returns TRUE if registered OK, else FALSE
609**
610*******************************************************************************/
611static BOOLEAN btm_sec_set_security_level (CONNECTION_TYPE conn_type, char *p_name, UINT8 service_id,
612 UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id,
613 UINT32 mx_chan_id)
614{
615 tBTM_SEC_SERV_REC *p_srec;
616 UINT16 index;
617 UINT16 first_unused_record = BTM_NO_AVAIL_SEC_SERVICES;
618 BOOLEAN record_allocated = FALSE;
619 BOOLEAN is_originator;
620#if (L2CAP_UCD_INCLUDED == TRUE)
621 BOOLEAN is_ucd;
622
623 if (conn_type & CONNECTION_TYPE_ORIG_MASK)
624 is_originator = TRUE;
625 else
626 is_originator = FALSE;
627
628 if (conn_type & CONNECTION_TYPE_CONNLESS_MASK )
629 {
630 is_ucd = TRUE;
631 }
632 else
633 {
634 is_ucd = FALSE;
635 }
636#else
637 is_originator = conn_type;
638#endif
639
640 /* See if the record can be reused (same service name, psm, mx_proto_id,
641 service_id, and mx_chan_id), or obtain the next unused record */
642
643 p_srec = &btm_cb.sec_serv_rec[0];
644
645
646 for (index = 0; index < BTM_SEC_MAX_SERVICE_RECORDS; index++, p_srec++)
647 {
648 /* Check if there is already a record for this service */
649 if (p_srec->security_flags & BTM_SEC_IN_USE)
650 {
651#if BTM_SEC_SERVICE_NAME_LEN > 0
652 if (p_srec->psm == psm &&
653 p_srec->mx_proto_id == mx_proto_id &&
654 service_id == p_srec->service_id &&
655 (!strncmp (p_name, (char *) p_srec->orig_service_name,
656 BTM_SEC_SERVICE_NAME_LEN) ||
657 !strncmp (p_name, (char *) p_srec->term_service_name,
658 BTM_SEC_SERVICE_NAME_LEN)))
659#else
660 if (p_srec->psm == psm &&
661 p_srec->mx_proto_id == mx_proto_id &&
662 service_id == p_srec->service_id)
663#endif
664 {
665 record_allocated = TRUE;
666 break;
667 }
668 }
669 /* Mark the first available service record */
670 else if (!record_allocated)
671 {
672 memset (p_srec, 0, sizeof(tBTM_SEC_SERV_REC));
673 record_allocated = TRUE;
674 first_unused_record = index;
675 }
676 }
677
678 if (!record_allocated)
679 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700680 BTM_TRACE_WARNING("BTM_SEC_REG: Out of Service Records (%d)", BTM_SEC_MAX_SERVICE_RECORDS);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800681 return(record_allocated);
682 }
683
684 /* Process the request if service record is valid */
685 /* If a duplicate service wasn't found, use the first available */
686 if (index >= BTM_SEC_MAX_SERVICE_RECORDS)
687 {
688 index = first_unused_record;
689 p_srec = &btm_cb.sec_serv_rec[index];
690 }
691
692 p_srec->psm = psm;
693 p_srec->service_id = service_id;
694 p_srec->mx_proto_id = mx_proto_id;
695
696 if (is_originator)
697 {
698 p_srec->orig_mx_chan_id = mx_chan_id;
699#if BTM_SEC_SERVICE_NAME_LEN > 0
700 BCM_STRNCPY_S ((char *)p_srec->orig_service_name, sizeof(p_srec->orig_service_name), p_name, BTM_SEC_SERVICE_NAME_LEN);
701#endif
702 /* clear out the old setting, just in case it exists */
703#if (L2CAP_UCD_INCLUDED == TRUE)
704 if ( is_ucd )
705 {
706 p_srec->ucd_security_flags &=
707 ~(BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_ENCRYPT | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_MITM |
708 BTM_SEC_FORCE_MASTER | BTM_SEC_ATTEMPT_MASTER | BTM_SEC_FORCE_SLAVE | BTM_SEC_ATTEMPT_SLAVE);
709 }
710 else
711#endif
712 {
713 p_srec->security_flags &=
714 ~(BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_ENCRYPT | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_MITM |
715 BTM_SEC_FORCE_MASTER | BTM_SEC_ATTEMPT_MASTER | BTM_SEC_FORCE_SLAVE | BTM_SEC_ATTEMPT_SLAVE);
716 }
717
718 /* Parameter validation. Originator should not set requirements for incoming connections */
719 sec_level &= ~(BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_ENCRYPT | BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_MITM);
720
721 if (btm_cb.security_mode == BTM_SEC_MODE_SP)
722 {
723 if (sec_level & BTM_SEC_OUT_AUTHENTICATE)
724 sec_level |= BTM_SEC_OUT_MITM;
725 }
726
727 /* Make sure the authenticate bit is set, when encrypt bit is set */
728 if (sec_level & BTM_SEC_OUT_ENCRYPT)
729 sec_level |= BTM_SEC_OUT_AUTHENTICATE;
730
731 /* outgoing connections usually set the security level right before
732 * the connection is initiated.
733 * set it to be the outgoing service */
734#if (L2CAP_UCD_INCLUDED == TRUE)
735 if ( is_ucd == FALSE )
736#endif
737 {
738 btm_cb.p_out_serv = p_srec;
739 }
740 }
741 else
742 {
743 p_srec->term_mx_chan_id = mx_chan_id;
744#if BTM_SEC_SERVICE_NAME_LEN > 0
745 BCM_STRNCPY_S ((char *)p_srec->term_service_name, sizeof(p_srec->term_service_name), p_name, BTM_SEC_SERVICE_NAME_LEN);
746#endif
747 /* clear out the old setting, just in case it exists */
748#if (L2CAP_UCD_INCLUDED == TRUE)
749 if ( is_ucd )
750 {
751 p_srec->ucd_security_flags &=
752 ~(BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_ENCRYPT | BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_MITM |
753 BTM_SEC_FORCE_MASTER | BTM_SEC_ATTEMPT_MASTER | BTM_SEC_FORCE_SLAVE | BTM_SEC_ATTEMPT_SLAVE);
754 }
755 else
756#endif
757 {
758 p_srec->security_flags &=
759 ~(BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_ENCRYPT | BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_MITM |
760 BTM_SEC_FORCE_MASTER | BTM_SEC_ATTEMPT_MASTER | BTM_SEC_FORCE_SLAVE | BTM_SEC_ATTEMPT_SLAVE);
761 }
762
763 /* Parameter validation. Acceptor should not set requirements for outgoing connections */
764 sec_level &= ~(BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_ENCRYPT | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_MITM);
765
766 if (btm_cb.security_mode == BTM_SEC_MODE_SP)
767 {
768 if (sec_level & BTM_SEC_IN_AUTHENTICATE)
769 sec_level |= BTM_SEC_IN_MITM;
770 }
771
772 /* Make sure the authenticate bit is set, when encrypt bit is set */
773 if (sec_level & BTM_SEC_IN_ENCRYPT)
774 sec_level |= BTM_SEC_IN_AUTHENTICATE;
775 }
776
777#if (L2CAP_UCD_INCLUDED == TRUE)
778 if ( is_ucd )
779 {
780 p_srec->security_flags |= (UINT16)(BTM_SEC_IN_USE);
781 p_srec->ucd_security_flags |= (UINT16)(sec_level | BTM_SEC_IN_USE);
782 }
783 else
784 {
785 p_srec->security_flags |= (UINT16)(sec_level | BTM_SEC_IN_USE);
786 }
787
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700788 BTM_TRACE_API("BTM_SEC_REG[%d]: id %d, conn_type 0x%x, psm 0x%04x, proto_id %d, chan_id %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800789 index, service_id, conn_type, psm, mx_proto_id, mx_chan_id);
790
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700791 BTM_TRACE_API(" : security_flags: 0x%04x, ucd_security_flags: 0x%04x",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800792 p_srec->security_flags, p_srec->ucd_security_flags);
793
794#if BTM_SEC_SERVICE_NAME_LEN > 0
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700795 BTM_TRACE_API(" : service name [%s] (up to %d chars saved)",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800796 p_name, BTM_SEC_SERVICE_NAME_LEN);
797#endif
798#else
799 p_srec->security_flags |= (UINT16)(sec_level | BTM_SEC_IN_USE);
800
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700801 BTM_TRACE_API("BTM_SEC_REG[%d]: id %d, is_orig %d, psm 0x%04x, proto_id %d, chan_id %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800802 index, service_id, is_originator, psm, mx_proto_id, mx_chan_id);
803
804#if BTM_SEC_SERVICE_NAME_LEN > 0
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700805 BTM_TRACE_API(" : sec: 0x%x, service name [%s] (up to %d chars saved)",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800806 p_srec->security_flags, p_name, BTM_SEC_SERVICE_NAME_LEN);
807#endif
808#endif
809
810
811 return(record_allocated);
812}
813
814/*******************************************************************************
815**
816** Function BTM_SecClrService
817**
818** Description Removes specified service record(s) from the security database.
819** All service records with the specified name are removed.
820** Typically used only by devices with limited RAM so that it can
821** reuse an old security service record.
822**
823** Note: Unpredictable results may occur if a service is cleared
824** that is still in use by an application/profile.
825**
826** Parameters Service ID - Id of the service to remove. ('0' removes all service
827** records (except SDP).
828**
829** Returns Number of records that were freed.
830**
831*******************************************************************************/
832UINT8 BTM_SecClrService (UINT8 service_id)
833{
834 tBTM_SEC_SERV_REC *p_srec = &btm_cb.sec_serv_rec[0];
835 UINT8 num_freed = 0;
836 int i;
837
838 for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_srec++)
839 {
840 /* Delete services with specified name (if in use and not SDP) */
841 if ((p_srec->security_flags & BTM_SEC_IN_USE) && (p_srec->psm != BT_PSM_SDP) &&
842 (!service_id || (service_id == p_srec->service_id)))
843 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700844 BTM_TRACE_API("BTM_SEC_CLR[%d]: id %d", i, service_id);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800845 p_srec->security_flags = 0;
846#if (L2CAP_UCD_INCLUDED == TRUE)
847 p_srec->ucd_security_flags = 0;
848#endif
849 num_freed++;
850 }
851 }
852
853 return(num_freed);
854}
855
856/*******************************************************************************
857**
858** Function btm_sec_clr_service_by_psm
859**
860** Description Removes specified service record from the security database.
861** All service records with the specified psm are removed.
862** Typically used by L2CAP to free up the service record used
863** by dynamic PSM clients when the channel is closed.
864** The given psm must be a virtual psm.
865**
866** Parameters Service ID - Id of the service to remove. ('0' removes all service
867** records (except SDP).
868**
869** Returns Number of records that were freed.
870**
871*******************************************************************************/
872UINT8 btm_sec_clr_service_by_psm (UINT16 psm)
873{
874 tBTM_SEC_SERV_REC *p_srec = &btm_cb.sec_serv_rec[0];
875 UINT8 num_freed = 0;
876 int i;
877
878 for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_srec++)
879 {
880 /* Delete services with specified name (if in use and not SDP) */
881 if ((p_srec->security_flags & BTM_SEC_IN_USE) && (p_srec->psm == psm) )
882 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700883 BTM_TRACE_API("BTM_SEC_CLR[%d]: id %d ", i, p_srec->service_id);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800884 p_srec->security_flags = 0;
885 num_freed++;
886 }
887 }
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700888 BTM_TRACE_API("btm_sec_clr_service_by_psm psm:0x%x num_freed:%d", psm, num_freed);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800889
890 return(num_freed);
891}
892
893/*******************************************************************************
894**
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800895** Function btm_sec_clr_temp_auth_service
896**
897** Description Removes specified device record's temporary authorization
898** flag from the security database.
899**
900** Parameters Device address to be cleared
901**
902** Returns void.
903**
904*******************************************************************************/
905void btm_sec_clr_temp_auth_service (BD_ADDR bda)
906{
907 tBTM_SEC_DEV_REC *p_dev_rec;
908
909 if ((p_dev_rec = btm_find_dev (bda)) == NULL)
910 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700911 BTM_TRACE_WARNING ("btm_sec_clr_temp_auth_service() - no dev CB");
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800912 return;
913 }
914
915 /* Reset the temporary authorized flag so that next time (untrusted) service is accessed autorization will take place */
916 if (p_dev_rec->last_author_service_id != BTM_SEC_NO_LAST_SERVICE_ID && p_dev_rec->p_cur_service)
917 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700918 BTM_TRACE_DEBUG ("btm_sec_clr_auth_service_by_psm [clearing device: %02x:%02x:%02x:%02x:%02x:%02x]",
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -0800919 bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
920
921 p_dev_rec->last_author_service_id = BTM_SEC_NO_LAST_SERVICE_ID;
922 }
923}
924
925/*******************************************************************************
926**
927**
The Android Open Source Project5738f832012-12-12 16:00:35 -0800928** Function BTM_SecClrUCDService
929**
930** Description
931**
932** Parameters Service ID - Id of the service to remove.
933** ('0' removes all service records )
934**
935** Returns Number of records that were cleared.
936**
937*******************************************************************************/
938UINT8 BTM_SecClrUCDService (UINT8 service_id)
939{
940#if (L2CAP_UCD_INCLUDED == TRUE)
941 tBTM_SEC_SERV_REC *p_srec = &btm_cb.sec_serv_rec[0];
942 UINT8 num_cleared = 0;
943 int i;
944
945 for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_srec++)
946 {
947 /* Delete services with specified name (if in use and not SDP) */
948 if ((p_srec->security_flags & BTM_SEC_IN_USE) &&
949 (!service_id || (service_id == (UINT32)p_srec->service_id)))
950 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700951 BTM_TRACE_API("BTM_UCD_SEC_CLR[%d]: id %d", i, service_id);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800952 p_srec->ucd_security_flags = 0;
953 num_cleared++;
954 }
955 }
956
957 return(num_cleared);
958#else
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800959 UNUSED(service_id);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800960 return(0);
961#endif
962}
963
964/*******************************************************************************
965**
966** Function BTM_PINCodeReply
967**
968** Description This function is called after Security Manager submitted
969** PIN code request to the UI.
970**
971** Parameters: bd_addr - Address of the device for which PIN was requested
972** res - result of the operation BTM_SUCCESS if success
973** pin_len - length in bytes of the PIN Code
974** p_pin - pointer to array with the PIN Code
975** trusted_mask - bitwise OR of trusted services (array of UINT32)
976**
977*******************************************************************************/
978void BTM_PINCodeReply (BD_ADDR bd_addr, UINT8 res, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
979{
980 tBTM_SEC_DEV_REC *p_dev_rec;
981
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700982 BTM_TRACE_API ("BTM_PINCodeReply(): PairState: %s PairFlags: 0x%02x PinLen:%d Result:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800983 btm_pair_state_descr(btm_cb.pairing_state), btm_cb.pairing_flags, pin_len, res);
984
985 /* If timeout already expired or has been canceled, ignore the reply */
986 if (btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_LOCAL_PIN)
987 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700988 BTM_TRACE_WARNING ("BTM_PINCodeReply() - Wrong State: %d", btm_cb.pairing_state);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800989 return;
990 }
991
992 if (memcmp (bd_addr, btm_cb.pairing_bda, BD_ADDR_LEN) != 0)
993 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -0700994 BTM_TRACE_ERROR ("BTM_PINCodeReply() - Wrong BD Addr");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800995 return;
996 }
997
998 if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
999 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001000 BTM_TRACE_ERROR ("BTM_PINCodeReply() - no dev CB");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001001 return;
1002 }
1003
1004 if ( (pin_len > PIN_CODE_LEN) || (pin_len == 0) || (p_pin == NULL) )
1005 res = BTM_ILLEGAL_VALUE;
1006
1007 if (res != BTM_SUCCESS)
1008 {
1009 /* if peer started dd OR we started dd and pre-fetch pin was not used send negative reply */
1010 if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PEER_STARTED_DD) ||
1011 ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) &&
1012 (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE)) )
1013 {
1014 /* use BTM_PAIR_STATE_WAIT_AUTH_COMPLETE to report authentication failed event */
1015 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
1016 btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
1017
1018 btsnd_hcic_pin_code_neg_reply (bd_addr);
1019 }
1020 else
1021 {
1022 p_dev_rec->security_required = BTM_SEC_NONE;
1023 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
1024 }
1025 return;
1026 }
1027 if (trusted_mask)
1028 BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
1029 p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
1030
1031 if ( (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
1032 && (p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE)
1033 && (btm_cb.security_mode_changed == FALSE) )
1034 {
1035 /* This is start of the dedicated bonding if local device is 2.0 */
1036 btm_cb.pin_code_len = pin_len;
1037 memcpy (btm_cb.pin_code, p_pin, pin_len);
1038
1039 btm_cb.security_mode_changed = TRUE;
1040#ifdef APPL_AUTH_WRITE_EXCEPTION
1041 if(!(APPL_AUTH_WRITE_EXCEPTION)(p_dev_rec->bd_addr))
1042#endif
1043 btsnd_hcic_write_auth_enable (TRUE);
1044
1045 btm_cb.acl_disc_reason = 0xff ;
1046
1047 /* if we rejected incoming connection request, we have to wait HCI_Connection_Complete event */
1048 /* before originating */
1049 if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT)
1050 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001051 BTM_TRACE_WARNING ("BTM_PINCodeReply(): waiting HCI_Connection_Complete after rejected incoming connection");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001052 /* we change state little bit early so btm_sec_connected() will originate connection */
1053 /* when existing ACL link is down completely */
1054 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
1055 }
1056 /* if we already accepted incoming connection from pairing device */
1057 else if (p_dev_rec->sm4 & BTM_SM4_CONN_PEND)
1058 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001059 BTM_TRACE_WARNING ("BTM_PINCodeReply(): link is connecting so wait pin code request from peer");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001060 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
1061 }
1062 else if (btm_sec_dd_create_conn(p_dev_rec) != BTM_CMD_STARTED)
1063 {
1064 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
1065 p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED;
1066
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001067 if (btm_cb.api.p_auth_complete_callback)
1068 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
The Android Open Source Project5738f832012-12-12 16:00:35 -08001069 p_dev_rec->sec_bd_name, HCI_ERR_AUTH_FAILURE);
1070 }
1071 return;
1072 }
1073
1074 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
1075 btm_cb.acl_disc_reason = HCI_SUCCESS;
1076
1077#ifdef PORCHE_PAIRING_CONFLICT
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001078 BTM_TRACE_EVENT("BTM_PINCodeReply(): Saving pin_len: %d btm_cb.pin_code_len: %d", pin_len, btm_cb.pin_code_len);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001079 /* if this was not pre-fetched, save the PIN */
1080 if (btm_cb.pin_code_len == 0)
1081 memcpy (btm_cb.pin_code, p_pin, pin_len);
1082 btm_cb.pin_code_len_saved = pin_len;
1083#endif
1084 btsnd_hcic_pin_code_req_reply (bd_addr, pin_len, p_pin);
1085}
1086
1087
1088/*******************************************************************************
1089**
1090** Function BTM_DeviceAuthorized
1091**
1092** Description This function is called after Security Manager submitted
1093** authorization request to the UI.
1094**
1095** Parameters: bd_addr - Address of the device for which PIN was requested
1096** res - result of the operation BTM_SUCCESS if success
1097**
1098*******************************************************************************/
1099void BTM_DeviceAuthorized (BD_ADDR bd_addr, UINT8 res, UINT32 trusted_mask[])
1100{
1101 tBTM_SEC_DEV_REC *p_dev_rec;
1102
1103 if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
1104 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001105 BTM_TRACE_WARNING ("Security Manager: Attempting Authorization of Unknown Device Address [%02x%02x%02x%02x%02x%02x]",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001106 bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
1107 return;
1108 }
1109
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001110 BTM_TRACE_EVENT ("Security Manager: authorized status:%d State:%d Trusted:%08x %08x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001111 res, (p_dev_rec) ? p_dev_rec->sec_state : 0, trusted_mask[0], trusted_mask[1]);
1112
1113 if (res == BTM_SUCCESS)
1114 {
1115 p_dev_rec->sec_flags |= BTM_SEC_AUTHORIZED;
1116 if (trusted_mask)
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001117 {
The Android Open Source Project5738f832012-12-12 16:00:35 -08001118 BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001119 }
1120
1121 /* Save the currently authorized service in case we are asked again
1122 by another multiplexer layer */
1123 if (!p_dev_rec->is_originator)
1124 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001125 BTM_TRACE_DEBUG("BTM_DeviceAuthorized: Setting last_author_service_id to %d",
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001126 p_dev_rec->p_cur_service->service_id);
1127 p_dev_rec->last_author_service_id = p_dev_rec->p_cur_service->service_id;
1128 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001129 }
1130
1131 if (p_dev_rec->sec_state != BTM_SEC_STATE_AUTHORIZING)
1132 return;
1133
1134 p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
1135
1136 if (res != BTM_SUCCESS)
1137 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001138 btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001139 return;
1140 }
1141
1142 if ((res = (UINT8)btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
1143 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001144 btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001145 }
1146}
1147
The Android Open Source Project5738f832012-12-12 16:00:35 -08001148/*******************************************************************************
1149**
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001150** Function btm_sec_bond_by_transport
The Android Open Source Project5738f832012-12-12 16:00:35 -08001151**
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001152** Description this is the bond function that will start either SSP or SMP.
The Android Open Source Project5738f832012-12-12 16:00:35 -08001153**
1154** Parameters: bd_addr - Address of the device to bond
1155** pin_len - length in bytes of the PIN Code
1156** p_pin - pointer to array with the PIN Code
1157** trusted_mask - bitwise OR of trusted services (array of UINT32)
1158**
1159** Note: After 2.1 parameters are not used and preserved here not to change API
1160*******************************************************************************/
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001161tBTM_STATUS btm_sec_bond_by_transport (BD_ADDR bd_addr, tBT_TRANSPORT transport,
1162 UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
The Android Open Source Project5738f832012-12-12 16:00:35 -08001163{
1164 tBTM_SEC_DEV_REC *p_dev_rec;
1165 tBTM_STATUS status;
Andre Eisenbach3aa60542013-03-22 18:00:51 -07001166 UINT8 *p_features;
1167 UINT8 ii;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001168 tACL_CONN *p= btm_bda_to_acl(bd_addr, transport);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001169 BTM_TRACE_API ("btm_sec_bond_by_transport BDA: %02x:%02x:%02x:%02x:%02x:%02x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001170 bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
1171
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001172 BTM_TRACE_DEBUG("btm_sec_bond_by_transport: Transport used %d" , transport);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001173
1174
The Android Open Source Project5738f832012-12-12 16:00:35 -08001175 /* Other security process is in progress */
1176 if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
1177 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001178 BTM_TRACE_ERROR ("BTM_SecBond: already busy in state: %s", btm_pair_state_descr(btm_cb.pairing_state));
The Android Open Source Project5738f832012-12-12 16:00:35 -08001179 return(BTM_WRONG_MODE);
1180 }
1181
Andre Eisenbach6975b4d2013-08-05 16:55:38 -07001182 if ((p_dev_rec = btm_find_or_alloc_dev (bd_addr)) == NULL)
1183 {
1184 return(BTM_NO_RESOURCES);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001185 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001186
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001187 BTM_TRACE_DEBUG ("before update sec_flags=0x%x", p_dev_rec->sec_flags);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001188
The Android Open Source Project5738f832012-12-12 16:00:35 -08001189 /* Finished if connection is active and already paired */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001190 if ( ((p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE) && transport == BT_TRANSPORT_BR_EDR
1191 && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))
1192#if (BLE_INCLUDED == TRUE)
1193 ||((p_dev_rec->ble_hci_handle != BTM_SEC_INVALID_HANDLE) && transport == BT_TRANSPORT_LE
1194 && (p_dev_rec->sec_flags & BTM_SEC_LE_AUTHENTICATED))
1195#endif
1196
1197 )
The Android Open Source Project5738f832012-12-12 16:00:35 -08001198 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001199 BTM_TRACE_WARNING("BTM_SecBond -> Already Paired");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001200 return(BTM_SUCCESS);
1201 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001202
1203 /* Tell controller to get rid of the link key if it has one stored */
1204 if ((BTM_DeleteStoredLinkKey (bd_addr, NULL)) != BTM_SUCCESS)
1205 return(BTM_NO_RESOURCES);
1206
1207 /* Save the PIN code if we got a valid one */
1208 if (p_pin && (pin_len <= PIN_CODE_LEN) && (pin_len != 0))
1209 {
1210 btm_cb.pin_code_len = pin_len;
1211 memcpy (btm_cb.pin_code, p_pin, PIN_CODE_LEN);
1212 }
1213
1214 memcpy (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN);
1215
1216 btm_cb.pairing_flags = BTM_PAIR_FLAGS_WE_STARTED_DD;
1217
1218 p_dev_rec->security_required = BTM_SEC_OUT_AUTHENTICATE;
1219 p_dev_rec->is_originator = TRUE;
1220 if (trusted_mask)
1221 BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
1222
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001223#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
1224 if (transport == BT_TRANSPORT_LE)
1225 {
1226 p_dev_rec->sec_flags &= ~ BTM_SEC_LE_MASK;
1227
1228 if (SMP_Pair(bd_addr) == SMP_STARTED)
1229 {
1230 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_LE_ACTIVE;
1231 p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
1232 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
1233 return BTM_CMD_STARTED;
1234 }
1235
1236 btm_cb.pairing_flags = 0;
1237 return(BTM_NO_RESOURCES);
1238 }
1239#endif
1240
Andre Eisenbach6975b4d2013-08-05 16:55:38 -07001241 p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED
The Android Open Source Project5738f832012-12-12 16:00:35 -08001242 | BTM_SEC_ROLE_SWITCHED | BTM_SEC_LINK_KEY_AUTHED);
1243
The Android Open Source Project5738f832012-12-12 16:00:35 -08001244
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001245 BTM_TRACE_DEBUG ("after update sec_flags=0x%x", p_dev_rec->sec_flags);
Andre Eisenbach3aa60542013-03-22 18:00:51 -07001246 if (!HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
The Android Open Source Project5738f832012-12-12 16:00:35 -08001247 {
1248 /* The special case when we authenticate keyboard. Set pin type to fixed */
1249 /* It would be probably better to do it from the application, but it is */
1250 /* complicated */
1251 if (((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) == BTM_COD_MAJOR_PERIPHERAL)
1252 && (p_dev_rec->dev_class[2] & BTM_COD_MINOR_KEYBOARD)
1253 && (btm_cb.cfg.pin_type != HCI_PIN_TYPE_FIXED))
1254 {
1255 btm_cb.pin_type_changed = TRUE;
1256 btsnd_hcic_write_pin_type (HCI_PIN_TYPE_FIXED);
1257 }
1258 }
1259
Andre Eisenbach3aa60542013-03-22 18:00:51 -07001260 for (ii = 0; ii <= HCI_EXT_FEATURES_PAGE_MAX; ii++)
1261 {
1262 p_features = p_dev_rec->features[ii];
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001263 BTM_TRACE_EVENT(" remote_features page[%1d] = %02x-%02x-%02x-%02x",
Andre Eisenbach3aa60542013-03-22 18:00:51 -07001264 ii, p_features[0], p_features[1], p_features[2], p_features[3]);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001265 BTM_TRACE_EVENT(" %02x-%02x-%02x-%02x",
Andre Eisenbach3aa60542013-03-22 18:00:51 -07001266 p_features[4], p_features[5], p_features[6], p_features[7]);
1267 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001268
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001269 BTM_TRACE_EVENT ("BTM_SecBond: Remote sm4: 0x%x HCI Handle: 0x%04x", p_dev_rec->sm4, p_dev_rec->hci_handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001270
1271#if BTM_SEC_FORCE_RNR_FOR_DBOND == TRUE
1272 p_dev_rec->sec_flags &= ~BTM_SEC_NAME_KNOWN;
1273#endif
1274
1275 /* If connection already exists... */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001276 if (p && p->hci_handle != BTM_SEC_INVALID_HANDLE)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001277 {
1278 if (!btm_sec_start_authentication (p_dev_rec))
1279 return(BTM_NO_RESOURCES);
1280
1281 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
1282
1283 /* Mark lcb as bonding */
1284 l2cu_update_lcb_4_bonding (bd_addr, TRUE);
1285 return(BTM_CMD_STARTED);
1286 }
1287
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001288 BTM_TRACE_DEBUG ("sec mode: %d sm4:x%x", btm_cb.security_mode, p_dev_rec->sm4);
Andre Eisenbach3aa60542013-03-22 18:00:51 -07001289 if (!HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0])
The Android Open Source Project5738f832012-12-12 16:00:35 -08001290 || (p_dev_rec->sm4 == BTM_SM4_KNOWN))
1291 {
1292 if ( btm_sec_check_prefetch_pin (p_dev_rec) )
1293 return(BTM_CMD_STARTED);
1294 }
1295 if (BTM_SEC_MODE_SP == btm_cb.security_mode && BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4))
1296 {
1297 /* local is 2.1 and peer is unknown */
1298 if ((p_dev_rec->sm4 & BTM_SM4_CONN_PEND) == 0)
1299 {
1300 /* we are not accepting connection request from peer
1301 * -> RNR (to learn if peer is 2.1)
1302 * RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */
1303 btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001304 BTM_ReadRemoteDeviceName(bd_addr, NULL, BT_TRANSPORT_BR_EDR);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001305 }
1306 else
1307 {
1308 /* We are accepting connection request from peer */
1309 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
1310 }
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001311 BTM_TRACE_DEBUG ("State:%s sm4: 0x%x sec_state:%d",
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001312 btm_pair_state_descr (btm_cb.pairing_state), p_dev_rec->sm4, p_dev_rec->sec_state);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001313 return BTM_CMD_STARTED;
1314 }
1315
1316 /* both local and peer are 2.1 */
1317 status = btm_sec_dd_create_conn(p_dev_rec);
1318
1319 if (status != BTM_CMD_STARTED)
1320 {
1321 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
1322 }
1323
1324 return status;
1325}
1326
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001327/*******************************************************************************
1328**
1329** Function BTM_SecBondByTransport
1330**
1331** Description This function is called to perform bonding with peer device.
1332** If the connection is already up, but not secure, pairing
1333** is attempted. If already paired BTM_SUCCESS is returned.
1334**
1335** Parameters: bd_addr - Address of the device to bond
1336** transport - doing SSP over BR/EDR or SMP over LE
1337** pin_len - length in bytes of the PIN Code
1338** p_pin - pointer to array with the PIN Code
1339** trusted_mask - bitwise OR of trusted services (array of UINT32)
1340**
1341** Note: After 2.1 parameters are not used and preserved here not to change API
1342*******************************************************************************/
1343tBTM_STATUS BTM_SecBondByTransport (BD_ADDR bd_addr, tBT_TRANSPORT transport,
1344 UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
1345{
1346#if SMP_INCLUDED == TRUE
1347 tBT_DEVICE_TYPE dev_type;
1348 tBLE_ADDR_TYPE addr_type;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001349
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001350 BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type);
1351 /* LE device, do SMP pairing */
1352 if ((transport == BT_TRANSPORT_LE && (dev_type & BT_DEVICE_TYPE_BLE) == 0) ||
1353 (transport == BT_TRANSPORT_BR_EDR && (dev_type & BT_DEVICE_TYPE_BREDR) == 0))
1354 {
1355 return BTM_ILLEGAL_ACTION;
1356 }
1357#endif
1358 return btm_sec_bond_by_transport(bd_addr, transport, pin_len, p_pin, trusted_mask);
1359}
1360
1361/*******************************************************************************
1362**
1363** Function BTM_SecBond
1364**
1365** Description This function is called to perform bonding with peer device.
1366** If the connection is already up, but not secure, pairing
1367** is attempted. If already paired BTM_SUCCESS is returned.
1368**
1369** Parameters: bd_addr - Address of the device to bond
1370** pin_len - length in bytes of the PIN Code
1371** p_pin - pointer to array with the PIN Code
1372** trusted_mask - bitwise OR of trusted services (array of UINT32)
1373**
1374** Note: After 2.1 parameters are not used and preserved here not to change API
1375*******************************************************************************/
1376tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
1377{
1378 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
1379#if BLE_INCLUDED == TRUE
1380 if (BTM_UseLeLink(bd_addr))
1381 transport = BT_TRANSPORT_LE;
1382#endif
1383 return btm_sec_bond_by_transport(bd_addr, transport, pin_len, p_pin, trusted_mask);
1384}
The Android Open Source Project5738f832012-12-12 16:00:35 -08001385/*******************************************************************************
1386**
1387** Function BTM_SecBondCancel
1388**
1389** Description This function is called to cancel ongoing bonding process
1390** with peer device.
1391**
1392** Parameters: bd_addr - Address of the peer device
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001393** transport - FALSE for BR/EDR link; TRUE for LE link
The Android Open Source Project5738f832012-12-12 16:00:35 -08001394**
1395*******************************************************************************/
1396tBTM_STATUS BTM_SecBondCancel (BD_ADDR bd_addr)
1397{
1398 tBTM_SEC_DEV_REC *p_dev_rec;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001399
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001400 BTM_TRACE_API ("BTM_SecBondCancel() State: %s flags:0x%x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001401 btm_pair_state_descr (btm_cb.pairing_state), btm_cb.pairing_flags);
1402
1403 if (((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
1404 || (memcmp (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN) != 0) )
1405 return BTM_UNKNOWN_ADDR;
1406
1407#if SMP_INCLUDED == TRUE
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001408 if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_LE_ACTIVE)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001409 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001410 if (p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001411 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001412 BTM_TRACE_DEBUG ("Cancel LE pairing");
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001413 if (SMP_PairCancel(bd_addr))
1414 {
1415 return BTM_CMD_STARTED;
1416 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001417 }
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001418 return BTM_WRONG_MODE;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001419 }
1420
1421#endif
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001422 BTM_TRACE_DEBUG ("hci_handle:0x%x sec_state:%d", p_dev_rec->hci_handle, p_dev_rec->sec_state );
The Android Open Source Project5738f832012-12-12 16:00:35 -08001423 if (BTM_PAIR_STATE_WAIT_LOCAL_PIN == btm_cb.pairing_state &&
1424 BTM_PAIR_FLAGS_WE_STARTED_DD & btm_cb.pairing_flags)
1425 {
1426 /* pre-fetching pin for dedicated bonding */
1427 btm_sec_bond_cancel_complete();
1428 return BTM_SUCCESS;
1429 }
1430
1431 /* If this BDA is in a bonding procedure */
1432 if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
1433 && (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD))
1434 {
1435 /* If the HCI link is up */
1436 if (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
1437 {
1438 /* If some other thread disconnecting, we do not send second command */
1439 if (p_dev_rec->sec_state == BTM_SEC_STATE_DISCONNECTING)
1440 return(BTM_CMD_STARTED);
1441
1442 /* If the HCI link was set up by Bonding process */
1443 if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001444 return btm_sec_send_hci_disconnect(p_dev_rec, HCI_ERR_PEER_USER, p_dev_rec->hci_handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001445 else
1446 l2cu_update_lcb_4_bonding(bd_addr, FALSE);
1447
1448 return BTM_NOT_AUTHORIZED;
1449 }
1450 else /*HCI link is not up */
1451 {
1452 /* If the HCI link creation was started by Bonding process */
1453 if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE)
1454 {
1455 if (btsnd_hcic_create_conn_cancel(bd_addr))
1456 return BTM_CMD_STARTED;
1457
1458 return BTM_NO_RESOURCES;
1459 }
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001460 if (btm_cb.pairing_state == BTM_PAIR_STATE_GET_REM_NAME)
1461 {
1462 BTM_CancelRemoteDeviceName();
1463 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_WE_CANCEL_DD;
1464 return BTM_CMD_STARTED;
1465 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08001466 return BTM_NOT_AUTHORIZED;
1467 }
1468 }
1469
1470 return BTM_WRONG_MODE;
1471}
1472
1473/*******************************************************************************
1474**
1475** Function BTM_SecUseMasterLinkKey
1476**
1477** Description This function is called to tell master of the piconet to
1478** switch to master link key
1479**
1480** Parameters: use_master_key - If true Master Link Key shoul be used
1481**
1482*******************************************************************************/
1483tBTM_STATUS BTM_SecUseMasterLinkKey (BOOLEAN use_master_key)
1484{
1485 return(btsnd_hcic_master_link_key (use_master_key) ? BTM_SUCCESS :
1486 BTM_NO_RESOURCES);
1487}
1488
1489/*******************************************************************************
1490**
1491** Function BTM_SetMasterKeyCompCback
1492**
1493** Description This function is called to register for the master key complete
1494** status event.
1495**
1496** Parameters: mkey_cback - callback registered with the security manager
1497**
1498*******************************************************************************/
1499void BTM_SetMasterKeyCompCback( tBTM_MKEY_CALLBACK *mkey_cback )
1500{
1501 btm_cb.mkey_cback = mkey_cback;
1502}
1503
1504/*******************************************************************************
1505**
1506** Function BTM_SecGetDeviceLinkKey
1507**
1508** Description This function is called to obtain link key for the device
1509** it returns BTM_SUCCESS if link key is available, or
1510** BTM_UNKNOWN_ADDR if Security Manager does not know about
1511** the device or device record does not contain link key info
1512**
1513** Parameters: bd_addr - Address of the device
1514** link_key - Link Key is copied into this array
1515**
1516*******************************************************************************/
1517tBTM_STATUS BTM_SecGetDeviceLinkKey (BD_ADDR bd_addr, LINK_KEY link_key)
1518{
1519 tBTM_SEC_DEV_REC *p_dev_rec;
1520
1521 if (((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
1522 && (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN))
1523 {
1524 memcpy (link_key, p_dev_rec->link_key, LINK_KEY_LEN);
1525 return(BTM_SUCCESS);
1526 }
1527 return(BTM_UNKNOWN_ADDR);
1528}
1529
1530
1531/*******************************************************************************
1532**
1533** Function BTM_SetEncryption
1534**
1535** Description This function is called to ensure that connection is
1536** encrypted. Should be called only on an open connection.
1537** Typically only needed for connections that first want to
1538** bring up unencrypted links, then later encrypt them.
1539**
1540** Parameters: bd_addr - Address of the peer device
1541** p_callback - Pointer to callback function called if
1542** this function returns PENDING after required
1543** procedures are completed. Can be set to NULL
1544** if status is not desired.
1545** p_ref_data - pointer to any data the caller wishes to receive
1546** in the callback function upon completion.
1547* can be set to NULL if not used.
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001548** transport - TRUE to encryption the link over LE trasnport
1549** or FALSE for BR/EDR trasnport
The Android Open Source Project5738f832012-12-12 16:00:35 -08001550**
1551** Returns BTM_SUCCESS - already encrypted
1552** BTM_PENDING - command will be returned in the callback
1553** BTM_WRONG_MODE- connection not up.
1554** BTM_BUSY - security procedures are currently active
1555** BTM_MODE_UNSUPPORTED - if security manager not linked in.
1556**
1557*******************************************************************************/
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001558tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBT_TRANSPORT transport, tBTM_SEC_CBACK *p_callback,
The Android Open Source Project5738f832012-12-12 16:00:35 -08001559 void *p_ref_data)
1560{
1561 tBTM_SEC_DEV_REC *p_dev_rec;
1562 tBTM_STATUS rc;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001563#if BLE_INCLUDED == TRUE
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001564 tACL_CONN *p = btm_bda_to_acl(bd_addr, transport);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001565#endif
1566
1567 p_dev_rec = btm_find_dev (bd_addr);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001568
1569 if (!p_dev_rec ||
1570 (transport == BT_TRANSPORT_BR_EDR && p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE)
1571#if BLE_INCLUDED == TRUE
1572 || (transport == BT_TRANSPORT_LE && p_dev_rec->ble_hci_handle == BTM_SEC_INVALID_HANDLE)
1573#endif
1574 )
The Android Open Source Project5738f832012-12-12 16:00:35 -08001575 {
1576 /* Connection should be up and runnning */
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001577 BTM_TRACE_WARNING ("Security Manager: BTM_SetEncryption not connected");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001578
1579 if (p_callback)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001580 (*p_callback) (bd_addr, transport, p_ref_data, BTM_WRONG_MODE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001581
1582 return(BTM_WRONG_MODE);
1583 }
1584
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001585 if ((transport == BT_TRANSPORT_BR_EDR &&
1586 (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))
1587#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
1588 || (transport == BT_TRANSPORT_LE &&
1589 (p_dev_rec->sec_flags & BTM_SEC_LE_ENCRYPTED))
The Android Open Source Project5738f832012-12-12 16:00:35 -08001590#endif
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001591 )
The Android Open Source Project5738f832012-12-12 16:00:35 -08001592 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001593 BTM_TRACE_EVENT ("Security Manager: BTM_SetEncryption already encrypted");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001594
1595 if (p_callback)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001596 (*p_callback) (bd_addr, transport, p_ref_data, BTM_SUCCESS);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001597
1598 return(BTM_SUCCESS);
1599 }
1600
1601 if (p_dev_rec->p_callback)
1602 {
1603 /* Connection should be up and runnning */
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001604 BTM_TRACE_WARNING ("Security Manager: BTM_SetEncryption busy");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001605
1606 if (p_callback)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001607 (*p_callback) (bd_addr, transport, p_ref_data, BTM_BUSY);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001608
1609 return(BTM_BUSY);
1610 }
1611
1612 p_dev_rec->p_callback = p_callback;
1613 p_dev_rec->p_ref_data = p_ref_data;
1614 p_dev_rec->security_required |= (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT);
1615 p_dev_rec->is_originator = FALSE;
1616
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001617 BTM_TRACE_API ("Security Manager: BTM_SetEncryption Handle:%d State:%d Flags:0x%x Required:0x%x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001618 p_dev_rec->hci_handle, p_dev_rec->sec_state, p_dev_rec->sec_flags,
1619 p_dev_rec->security_required);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001620
The Android Open Source Project5738f832012-12-12 16:00:35 -08001621#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001622 if (transport == BT_TRANSPORT_LE)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001623 {
1624 rc = btm_ble_set_encryption(bd_addr, p_ref_data, p->link_role);
1625 }
1626 else
1627#endif
1628
1629 rc = btm_sec_execute_procedure (p_dev_rec);
1630
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001631 if (rc != BTM_CMD_STARTED && rc != BTM_BUSY)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001632 {
1633 if (p_callback)
1634 {
1635 p_dev_rec->p_callback = NULL;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001636 (*p_callback) (bd_addr, transport, p_dev_rec->p_ref_data, rc);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001637 }
1638 }
1639 return(rc);
1640}
1641
1642/*******************************************************************************
1643 * disconnect the ACL link, if it's not done yet.
1644*******************************************************************************/
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001645static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason, UINT16 conn_handle)
The Android Open Source Project5738f832012-12-12 16:00:35 -08001646{
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001647 UINT8 old_state = p_dev_rec->sec_state;
1648 tBTM_STATUS status = BTM_CMD_STARTED;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001649
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001650 BTM_TRACE_EVENT ("btm_sec_send_hci_disconnect: handle:0x%x, reason=0x%x",
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001651 conn_handle, reason);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001652
1653 /* if some other thread disconnecting, we do not send second command */
1654 if (BTM_SEC_STATE_DISCONNECTING != old_state)
1655 {
1656 p_dev_rec->sec_state = BTM_SEC_STATE_DISCONNECTING;
1657
1658#if BTM_DISC_DURING_RS == TRUE
1659 /* If a Role Switch is in progress, delay the HCI Disconnect to avoid controller problem (4329B1) */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001660 if (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING &&
1661 p_dev_rec->hci_handle == conn_handle)
1662
The Android Open Source Project5738f832012-12-12 16:00:35 -08001663 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001664 BTM_TRACE_DEBUG("RS in progress - Set DISC Pending flag in btm_sec_send_hci_disconnect to delay disconnect");
The Android Open Source Project5738f832012-12-12 16:00:35 -08001665 p_dev_rec->rs_disc_pending = BTM_SEC_DISC_PENDING;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001666 status = BTM_SUCCESS;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001667 }
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001668 else
The Android Open Source Project5738f832012-12-12 16:00:35 -08001669#endif
1670 /* Tear down the HCI link */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001671 if (!btsnd_hcic_disconnect (conn_handle, reason))
The Android Open Source Project5738f832012-12-12 16:00:35 -08001672 {
1673 /* could not send disconnect. restore old state */
1674 p_dev_rec->sec_state = old_state;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001675 status = BTM_NO_RESOURCES;
The Android Open Source Project5738f832012-12-12 16:00:35 -08001676 }
1677 }
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08001678 return (status);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001679}
1680
1681/*******************************************************************************
1682**
1683** Function BTM_ConfirmReqReply
1684**
1685** Description This function is called to confirm the numeric value for
1686** Simple Pairing in response to BTM_SP_CFM_REQ_EVT
1687**
1688** Parameters: res - result of the operation BTM_SUCCESS if success
1689** bd_addr - Address of the peer device
1690**
1691*******************************************************************************/
1692void BTM_ConfirmReqReply(tBTM_STATUS res, BD_ADDR bd_addr)
1693{
1694 tBTM_SEC_DEV_REC *p_dev_rec;
1695
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001696 BTM_TRACE_EVENT ("BTM_ConfirmReqReply() State: %s Res: %u",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001697 btm_pair_state_descr(btm_cb.pairing_state), res);
1698
1699 /* If timeout already expired or has been canceled, ignore the reply */
1700 if ( (btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM)
1701 || (memcmp (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN) != 0) )
1702 return;
1703
1704 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
1705
1706 if ( (res == BTM_SUCCESS) || (res == BTM_SUCCESS_NO_SECURITY) )
1707 {
1708 btm_cb.acl_disc_reason = HCI_SUCCESS;
1709
1710 if (res == BTM_SUCCESS)
1711 {
1712 if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
1713 p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
1714 }
1715
1716 btsnd_hcic_user_conf_reply (bd_addr, TRUE);
1717 }
1718 else
1719 {
1720 /* Report authentication failed event from state BTM_PAIR_STATE_WAIT_AUTH_COMPLETE */
1721 btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
1722 btsnd_hcic_user_conf_reply (bd_addr, FALSE);
1723 }
1724}
1725
1726/*******************************************************************************
1727**
1728** Function BTM_PasskeyReqReply
1729**
1730** Description This function is called to provide the passkey for
1731** Simple Pairing in response to BTM_SP_KEY_REQ_EVT
1732**
1733** Parameters: res - result of the operation BTM_SUCCESS if success
1734** bd_addr - Address of the peer device
1735** passkey - numeric value in the range of
1736** BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
1737**
1738*******************************************************************************/
1739#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
1740void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr, UINT32 passkey)
1741{
1742 tBTM_SEC_DEV_REC *p_dev_rec;
1743
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001744 BTM_TRACE_API ("BTM_PasskeyReqReply: State: %s res:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001745 btm_pair_state_descr(btm_cb.pairing_state), res);
1746
1747 if ( (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE)
1748 || (memcmp (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN) != 0) )
1749 {
1750 return;
1751 }
1752
1753 /* If timeout already expired or has been canceled, ignore the reply */
1754 if ( (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_AUTH_COMPLETE) && (res != BTM_SUCCESS) )
1755 {
1756 if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
1757 {
1758 btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
1759
1760 if (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07001761 btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08001762 else
1763 BTM_SecBondCancel(bd_addr);
1764
1765 p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_AUTHED | BTM_SEC_LINK_KEY_KNOWN);
1766
1767 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
1768 return;
1769 }
1770 }
1771 else if (btm_cb.pairing_state != BTM_PAIR_STATE_KEY_ENTRY)
1772 return;
1773
1774 if (passkey > BTM_MAX_PASSKEY_VAL)
1775 res = BTM_ILLEGAL_VALUE;
1776
1777 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
1778
1779 if (res != BTM_SUCCESS)
1780 {
1781 /* use BTM_PAIR_STATE_WAIT_AUTH_COMPLETE to report authentication failed event */
1782 btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
1783 btsnd_hcic_user_passkey_neg_reply (bd_addr);
1784 }
1785 else
1786 {
1787 btm_cb.acl_disc_reason = HCI_SUCCESS;
1788 btsnd_hcic_user_passkey_reply (bd_addr, passkey);
1789 }
1790}
1791#endif
1792
1793/*******************************************************************************
1794**
1795** Function BTM_SendKeypressNotif
1796**
1797** Description This function is used during the passkey entry model
1798** by a device with KeyboardOnly IO capabilities
1799** (very likely to be a HID Device).
1800** It is called by a HID Device to inform the remote device when
1801** a key has been entered or erased.
1802**
1803** Parameters: bd_addr - Address of the peer device
1804** type - notification type
1805**
1806*******************************************************************************/
1807#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
1808void BTM_SendKeypressNotif(BD_ADDR bd_addr, tBTM_SP_KEY_TYPE type)
1809{
1810 /* This API only make sense between PASSKEY_REQ and SP complete */
1811 if (btm_cb.pairing_state == BTM_PAIR_STATE_KEY_ENTRY)
1812 btsnd_hcic_send_keypress_notif (bd_addr, type);
1813}
1814#endif
1815
1816#if BTM_OOB_INCLUDED == TRUE
1817/*******************************************************************************
1818**
1819** Function BTM_IoCapRsp
1820**
1821** Description This function is called in response to BTM_SP_IO_REQ_EVT
1822** When the event data io_req.oob_data is set to BTM_OOB_UNKNOWN
1823** by the tBTM_SP_CALLBACK implementation, this function is
1824** called to provide the actual response
1825**
1826** Parameters: bd_addr - Address of the peer device
1827** io_cap - The IO capability of local device.
1828** oob - BTM_OOB_NONE or BTM_OOB_PRESENT.
1829** auth_req- MITM protection required or not.
1830**
1831*******************************************************************************/
1832void BTM_IoCapRsp(BD_ADDR bd_addr, tBTM_IO_CAP io_cap, tBTM_OOB_DATA oob, tBTM_AUTH_REQ auth_req)
1833{
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001834 BTM_TRACE_EVENT ("BTM_IoCapRsp: state: %s oob: %d io_cap: %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001835 btm_pair_state_descr(btm_cb.pairing_state), oob, io_cap);
1836
1837 if ( (btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS)
1838 || (memcmp (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN) != 0) )
1839 return;
1840
1841 if (oob < BTM_OOB_UNKNOWN && io_cap < BTM_IO_CAP_MAX)
1842 {
1843 btm_cb.devcb.loc_auth_req = auth_req;
1844 btm_cb.devcb.loc_io_caps = io_cap;
1845
1846 if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
1847 auth_req = (BTM_AUTH_DD_BOND | (auth_req&BTM_AUTH_YN_BIT));
1848
1849 btsnd_hcic_io_cap_req_reply (bd_addr, io_cap, oob, auth_req);
1850 }
1851}
1852
1853/*******************************************************************************
1854**
1855** Function BTM_ReadLocalOobData
1856**
1857** Description This function is called to read the local OOB data from
1858** LM
1859**
1860*******************************************************************************/
1861tBTM_STATUS BTM_ReadLocalOobData(void)
1862{
1863 tBTM_STATUS status = BTM_SUCCESS;
1864
1865 if (btsnd_hcic_read_local_oob_data() == FALSE)
1866 status = BTM_NO_RESOURCES;
1867
1868 return status;
1869}
1870
1871/*******************************************************************************
1872**
1873** Function BTM_RemoteOobDataReply
1874**
1875** Description This function is called to provide the remote OOB data for
1876** Simple Pairing in response to BTM_SP_RMT_OOB_EVT
1877**
1878** Parameters: bd_addr - Address of the peer device
1879** c - simple pairing Hash C.
1880** r - simple pairing Randomizer C.
1881**
1882*******************************************************************************/
1883void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr, BT_OCTET16 c, BT_OCTET16 r)
1884{
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07001885 BTM_TRACE_EVENT ("BTM_RemoteOobDataReply(): State: %s res:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08001886 btm_pair_state_descr(btm_cb.pairing_state), res);
1887
1888 /* If timeout already expired or has been canceled, ignore the reply */
1889 if (btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP)
1890 return;
1891
1892 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
1893
1894 if (res != BTM_SUCCESS)
1895 {
1896 /* use BTM_PAIR_STATE_WAIT_AUTH_COMPLETE to report authentication failed event */
1897 btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
1898 btsnd_hcic_rem_oob_neg_reply (bd_addr);
1899 }
1900 else
1901 {
1902 btm_cb.acl_disc_reason = HCI_SUCCESS;
1903 btsnd_hcic_rem_oob_reply (bd_addr, c, r);
1904 }
1905}
1906
1907/*******************************************************************************
1908**
1909** Function BTM_BuildOobData
1910**
1911** Description This function is called to build the OOB data payload to
1912** be sent over OOB (non-Bluetooth) link
1913**
1914** Parameters: p_data - the location for OOB data
1915** max_len - p_data size.
1916** c - simple pairing Hash C.
1917** r - simple pairing Randomizer C.
1918** name_len- 0, local device name would not be included.
1919** otherwise, the local device name is included for
1920** up to this specified length
1921**
1922** Returns Number of bytes in p_data.
1923**
1924*******************************************************************************/
1925UINT16 BTM_BuildOobData(UINT8 *p_data, UINT16 max_len, BT_OCTET16 c,
1926 BT_OCTET16 r, UINT8 name_len)
1927{
1928 UINT8 *p = p_data;
1929 UINT16 len = 0;
1930 UINT16 delta;
1931#if BTM_MAX_LOC_BD_NAME_LEN > 0
1932 UINT16 name_size;
1933 UINT8 name_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE;
1934#endif
1935
1936 if (p_data && max_len >= BTM_OOB_MANDATORY_SIZE)
1937 {
1938 /* add mandatory part */
1939 UINT16_TO_STREAM(p, len);
1940 BDADDR_TO_STREAM(p, btm_cb.devcb.local_addr);
1941
1942 len = BTM_OOB_MANDATORY_SIZE;
1943 max_len -= len;
1944
1945 /* now optional part */
1946
1947 /* add Hash C */
1948 delta = BTM_OOB_HASH_C_SIZE + 2;
1949 if (max_len >= delta)
1950 {
1951 *p++ = BTM_OOB_HASH_C_SIZE + 1;
1952 *p++ = BTM_EIR_OOB_SSP_HASH_C_TYPE;
1953 ARRAY_TO_STREAM(p, c, BTM_OOB_HASH_C_SIZE);
1954 len += delta;
1955 max_len -= delta;
1956 }
1957
1958 /* add Rand R */
1959 delta = BTM_OOB_RAND_R_SIZE + 2;
1960 if (max_len >= delta)
1961 {
1962 *p++ = BTM_OOB_RAND_R_SIZE + 1;
1963 *p++ = BTM_EIR_OOB_SSP_RAND_R_TYPE;
1964 ARRAY_TO_STREAM(p, r, BTM_OOB_RAND_R_SIZE);
1965 len += delta;
1966 max_len -= delta;
1967 }
1968
1969 /* add class of device */
1970 delta = BTM_OOB_COD_SIZE + 2;
1971 if (max_len >= delta)
1972 {
1973 *p++ = BTM_OOB_COD_SIZE + 1;
1974 *p++ = BTM_EIR_OOB_COD_TYPE;
1975 DEVCLASS_TO_STREAM(p, btm_cb.devcb.dev_class);
1976 len += delta;
1977 max_len -= delta;
1978 }
1979#if BTM_MAX_LOC_BD_NAME_LEN > 0
1980 name_size = name_len;
1981 if (name_size > strlen(btm_cb.cfg.bd_name))
1982 {
1983 name_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
1984 name_size = (UINT16)strlen(btm_cb.cfg.bd_name);
1985 }
1986 delta = name_size + 2;
1987 if (max_len >= delta)
1988 {
1989 *p++ = name_size + 1;
1990 *p++ = name_type;
1991 ARRAY_TO_STREAM (p, btm_cb.cfg.bd_name, name_size);
1992 len += delta;
1993 max_len -= delta;
1994 }
1995#endif
1996 /* update len */
1997 p = p_data;
1998 UINT16_TO_STREAM(p, len);
1999 }
2000 return len;
2001}
2002
2003/*******************************************************************************
2004**
2005** Function BTM_ReadOobData
2006**
2007** Description This function is called to parse the OOB data payload
2008** received over OOB (non-Bluetooth) link
2009**
2010** Parameters: p_data - the location for OOB data
2011** eir_tag - The associated EIR tag to read the data.
2012** *p_len(output) - the length of the data with the given tag.
2013**
2014** Returns the beginning of the data with the given tag.
2015** NULL, if the tag is not found.
2016**
2017*******************************************************************************/
2018UINT8 * BTM_ReadOobData(UINT8 *p_data, UINT8 eir_tag, UINT8 *p_len)
2019{
2020 UINT8 *p = p_data;
2021 UINT16 max_len;
2022 UINT8 len, type;
2023 UINT8 *p_ret = NULL;
2024 UINT8 ret_len = 0;
2025
2026 if (p_data)
2027 {
2028 STREAM_TO_UINT16(max_len, p);
2029 if (max_len >= BTM_OOB_MANDATORY_SIZE)
2030 {
2031 if (BTM_EIR_OOB_BD_ADDR_TYPE == eir_tag)
2032 {
2033 p_ret = p; /* the location for bd_addr */
2034 ret_len = BTM_OOB_BD_ADDR_SIZE;
2035 }
2036 else
2037 {
2038 p += BD_ADDR_LEN;
2039 max_len -= BTM_OOB_MANDATORY_SIZE;
2040 /* now the optional data in EIR format */
2041 while (max_len > 0)
2042 {
2043 len = *p++; /* tag data len + 1 */
2044 type = *p++;
2045 if (eir_tag == type)
2046 {
2047 p_ret = p;
2048 ret_len = len - 1;
2049 break;
2050 }
2051 /* the data size of this tag is len + 1 (tag data len + 2) */
2052 if (max_len > len)
2053 {
2054 max_len -= len;
2055 max_len--;
2056 len--;
2057 p += len;
2058 }
2059 else
2060 max_len = 0;
2061 }
2062 }
2063 }
2064 }
2065
2066 if (p_len)
2067 *p_len = ret_len;
2068
2069 return p_ret;
2070}
2071#endif
2072
2073/*******************************************************************************
2074**
2075** Function BTM_SetOutService
2076**
2077** Description This function is called to set the service for
2078** outgoing connections.
2079**
2080** If the profile/application calls BTM_SetSecurityLevel
2081** before initiating a connection, this function does not
2082** need to be called.
2083**
2084** Returns void
2085**
2086*******************************************************************************/
2087void BTM_SetOutService(BD_ADDR bd_addr, UINT8 service_id, UINT32 mx_chan_id)
2088{
2089 tBTM_SEC_DEV_REC *p_dev_rec;
2090 tBTM_SEC_SERV_REC *p_serv_rec = &btm_cb.sec_serv_rec[0];
2091 int i;
2092
2093 btm_cb.p_out_serv = p_serv_rec;
2094 p_dev_rec = btm_find_dev (bd_addr);
2095
2096 for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_serv_rec++)
2097 {
2098 if ((p_serv_rec->security_flags & BTM_SEC_IN_USE)
2099 && (p_serv_rec->service_id == service_id)
2100 && (p_serv_rec->orig_mx_chan_id == mx_chan_id))
2101 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002102 BTM_TRACE_API("BTM_SetOutService p_out_serv id %d, psm 0x%04x, proto_id %d, chan_id %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002103 p_serv_rec->service_id, p_serv_rec->psm, p_serv_rec->mx_proto_id, p_serv_rec->orig_mx_chan_id);
2104 btm_cb.p_out_serv = p_serv_rec;
2105 if (p_dev_rec)
2106 p_dev_rec->p_cur_service = p_serv_rec;
2107 break;
2108 }
2109 }
2110}
2111
2112/************************************************************************
2113** I N T E R N A L F U N C T I O N S
2114*************************************************************************/
2115/*******************************************************************************
2116**
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002117** Function btm_sec_is_upgrade_possible
2118**
2119** Description This function returns TRUE if the existing link key
2120** can be upgraded or if the link key does not exist.
2121**
2122** Returns BOOLEAN
2123**
2124*******************************************************************************/
2125static BOOLEAN btm_sec_is_upgrade_possible(tBTM_SEC_DEV_REC *p_dev_rec, BOOLEAN is_originator)
2126{
2127 UINT16 mtm_check = is_originator ? BTM_SEC_OUT_MITM : BTM_SEC_IN_MITM;
2128 BOOLEAN is_possible = TRUE;
2129
2130 if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)
2131 {
2132 is_possible = FALSE;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002133 if(p_dev_rec->p_cur_service)
2134 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002135 BTM_TRACE_DEBUG ("btm_sec_is_upgrade_possible id:%d, link_key_typet:%d, rmt_io_caps:%d, chk flags:x%x, flags:x%x",
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002136 p_dev_rec->p_cur_service->service_id, p_dev_rec->link_key_type, p_dev_rec->rmt_io_caps,
2137 mtm_check, p_dev_rec->p_cur_service->security_flags);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002138 }
2139 else
2140 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002141 BTM_TRACE_DEBUG ("btm_sec_is_upgrade_possible link_key_typet:%d, rmt_io_caps:%d, chk flags:x%x, ",
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002142 p_dev_rec->link_key_type, p_dev_rec->rmt_io_caps, mtm_check);
2143 }
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002144 /* Already have a link key to the connected peer. Is the link key secure enough?
2145 ** Is a link key upgrade even possible?
2146 */
2147 if ((p_dev_rec->security_required & mtm_check) /* needs MITM */
2148 && (p_dev_rec->link_key_type == BTM_LKEY_TYPE_UNAUTH_COMB) /* has unauthenticated link key */
2149 && (p_dev_rec->rmt_io_caps < BTM_IO_CAP_MAX) /* a valid peer IO cap */
2150 && (btm_sec_io_map[p_dev_rec->rmt_io_caps][btm_cb.devcb.loc_io_caps])) /* authenticated link key is possible */
2151 {
2152 /* upgrade is possible: check if the application wants the upgrade.
2153 * If the application is configured to use a global MITM flag,
2154 * it probably would not want to upgrade the link key based on the security level database */
2155 is_possible = TRUE;
2156 }
2157 }
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002158 BTM_TRACE_DEBUG ("btm_sec_is_upgrade_possible is_possible:%d sec_flags:0x%x", is_possible, p_dev_rec->sec_flags);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002159 return is_possible;
2160}
2161
2162/*******************************************************************************
2163**
The Android Open Source Project5738f832012-12-12 16:00:35 -08002164** Function btm_sec_check_upgrade
2165**
2166** Description This function is called to check if the existing link key
2167** needs to be upgraded.
2168**
2169** Returns void
2170**
2171*******************************************************************************/
2172static void btm_sec_check_upgrade(tBTM_SEC_DEV_REC *p_dev_rec, BOOLEAN is_originator)
2173{
2174 tBTM_SP_UPGRADE evt_data;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002175
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002176 BTM_TRACE_DEBUG ("btm_sec_check_upgrade...");
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002177
2178 /* Only check if link key already exists */
2179 if (!(p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN))
2180 return;
2181 if (btm_sec_is_upgrade_possible (p_dev_rec, is_originator) == TRUE)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002182 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002183 BTM_TRACE_DEBUG ("need upgrade!! sec_flags:0x%x", p_dev_rec->sec_flags);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002184 /* upgrade is possible: check if the application wants the upgrade.
2185 * If the application is configured to use a global MITM flag,
2186 * it probably would not want to upgrade the link key based on the security level database */
2187 memcpy (evt_data.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
2188 evt_data.upgrade = TRUE;
2189 if (btm_cb.api.p_sp_callback)
2190 (*btm_cb.api.p_sp_callback) (BTM_SP_UPGRADE_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002191
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002192 BTM_TRACE_DEBUG ("evt_data.upgrade:0x%x", evt_data.upgrade);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002193 if (evt_data.upgrade)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002194 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002195 /* if the application confirms the upgrade, set the upgrade bit */
2196 p_dev_rec->sm4 |= BTM_SM4_UPGRADE;
The Android Open Source Project5738f832012-12-12 16:00:35 -08002197
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002198 /* Clear the link key known to go through authentication/pairing again */
2199 p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED);
2200 p_dev_rec->sec_flags &= ~BTM_SEC_AUTHENTICATED;
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002201 BTM_TRACE_DEBUG ("sec_flags:0x%x", p_dev_rec->sec_flags);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002202 }
2203 }
2204}
2205
2206/*******************************************************************************
2207**
2208** Function btm_sec_l2cap_access_req
2209**
2210** Description This function is called by the L2CAP to grant permission to
2211** establish L2CAP connection to or from the peer device.
2212**
2213** Parameters: bd_addr - Address of the peer device
2214** psm - L2CAP PSM
2215** is_originator - TRUE if protocol above L2CAP originates
2216** connection
2217** p_callback - Pointer to callback function called if
2218** this function returns PENDING after required
2219** procedures are complete. MUST NOT BE NULL.
2220**
2221** Returns tBTM_STATUS
2222**
2223*******************************************************************************/
2224#define BTM_SEC_OUT_FLAGS (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT | BTM_SEC_OUT_AUTHORIZE)
2225#define BTM_SEC_IN_FLAGS (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT | BTM_SEC_IN_AUTHORIZE)
2226
2227tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle,
2228 CONNECTION_TYPE conn_type,
2229 tBTM_SEC_CALLBACK *p_callback,
2230 void *p_ref_data)
2231{
2232 tBTM_SEC_DEV_REC *p_dev_rec;
2233 tBTM_SEC_SERV_REC *p_serv_rec;
2234 UINT16 security_required;
2235 UINT16 old_security_required;
2236 BOOLEAN old_is_originator;
2237 tBTM_STATUS rc = BTM_SUCCESS;
2238 BOOLEAN chk_acp_auth_done = FALSE;
2239 BOOLEAN is_originator;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002240 BOOLEAN transport = FALSE; /* should check PSM range in LE connection oriented L2CAP connection */
The Android Open Source Project5738f832012-12-12 16:00:35 -08002241
2242#if (L2CAP_UCD_INCLUDED == TRUE)
2243 if (conn_type & CONNECTION_TYPE_ORIG_MASK)
2244 is_originator = TRUE;
2245 else
2246 is_originator = FALSE;
2247
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002248 BTM_TRACE_DEBUG ("btm_sec_l2cap_access_req conn_type:0x%x, 0x%x", conn_type, p_ref_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002249#else
2250 is_originator = conn_type;
2251
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002252 BTM_TRACE_DEBUG ("btm_sec_l2cap_access_req is_originator:%d, 0x%x", is_originator, p_ref_data);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002253#endif
2254
2255 /* Find or get oldest record */
2256 p_dev_rec = btm_find_or_alloc_dev (bd_addr);
2257
2258 p_dev_rec->hci_handle = handle;
2259
2260 /* Find the service record for the PSM */
2261 p_serv_rec = btm_sec_find_first_serv (conn_type, psm);
2262
2263 /* If there is no application registered with this PSM do not allow connection */
2264 if (!p_serv_rec)
2265 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002266 BTM_TRACE_WARNING ("btm_sec_l2cap_access_req() PSM:%d no application registerd", psm);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002267
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002268 (*p_callback) (bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002269
2270 return(BTM_MODE_UNSUPPORTED);
2271 }
2272
2273 /* SDP connection we will always let through */
2274 if (BT_PSM_SDP == psm)
2275 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002276 (*p_callback) (bd_addr,transport, p_ref_data, BTM_SUCCESS_NO_SECURITY);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002277
2278 return(BTM_SUCCESS);
2279 }
2280#if (L2CAP_UCD_INCLUDED == TRUE)
2281 if ( conn_type & CONNECTION_TYPE_CONNLESS_MASK )
2282 {
2283 security_required = p_serv_rec->ucd_security_flags;
2284
2285 rc = BTM_CMD_STARTED;
2286 if (is_originator)
2287 {
2288 if (((security_required & BTM_SEC_OUT_FLAGS) == 0) ||
2289 ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
2290 ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) ||
2291 ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_FLAGS) && (p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED))) )
2292 {
2293 rc = BTM_SUCCESS;
2294 }
2295 }
2296 else
2297 {
2298 if (((security_required & BTM_SEC_IN_FLAGS) == 0) ||
2299 ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
2300 ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) ||
2301 ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_FLAGS) && (p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED))) )
2302 {
2303 rc = BTM_SUCCESS;
2304 }
2305 }
2306
2307 if (rc == BTM_SUCCESS)
2308 {
2309 if (p_callback)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002310 (*p_callback) (bd_addr, transport, (void *)p_ref_data, BTM_SUCCESS);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002311
2312 return(BTM_SUCCESS);
2313 }
2314 }
2315 else
2316#endif
2317 {
2318 security_required = p_serv_rec->security_flags;
2319 }
2320
2321 /* there are some devices (moto KRZR) which connects to several services at the same time */
2322 /* we will process one after another */
2323 if ( (p_dev_rec->p_callback) || (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) )
2324 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002325 BTM_TRACE_EVENT ("btm_sec_l2cap_access_req() - busy - PSM:%d delayed state: %s mode:%d, sm4:0x%x",
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002326 psm, btm_pair_state_descr(btm_cb.pairing_state), btm_cb.security_mode, p_dev_rec->sm4);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002327 BTM_TRACE_EVENT ("security_flags:x%x, sec_flags:x%x", security_required, p_dev_rec->sec_flags);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002328 rc = BTM_CMD_STARTED;
2329 if ((BTM_SEC_MODE_SP != btm_cb.security_mode)
2330 || ((BTM_SEC_MODE_SP == btm_cb.security_mode) && (BTM_SM4_KNOWN == p_dev_rec->sm4))
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002331 || (BTM_SEC_IS_SM4(p_dev_rec->sm4) && (btm_sec_is_upgrade_possible(p_dev_rec, is_originator) == FALSE))
The Android Open Source Project5738f832012-12-12 16:00:35 -08002332 )
2333 {
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002334 /* legacy mode - local is legacy or local is lisbon/peer is legacy
2335 * or SM4 with no possibility of link key upgrade */
The Android Open Source Project5738f832012-12-12 16:00:35 -08002336 if (is_originator)
2337 {
2338 if (((security_required & BTM_SEC_OUT_FLAGS) == 0) ||
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002339 ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec))) ||
2340 ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && btm_dev_encrypted(p_dev_rec))) ||
2341 ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_FLAGS) && btm_dev_authorized(p_dev_rec) && btm_dev_encrypted(p_dev_rec))) )
The Android Open Source Project5738f832012-12-12 16:00:35 -08002342 {
2343 rc = BTM_SUCCESS;
2344 }
2345 }
2346 else
2347 {
2348 if (((security_required & BTM_SEC_IN_FLAGS) == 0) ||
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002349 (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec)) ||
2350 (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && btm_dev_encrypted(p_dev_rec)) ||
2351 (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHORIZE) && (btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))) ||
2352 (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_AUTHORIZE)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)) && btm_dev_authenticated(p_dev_rec))) ||
2353 (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_ENCRYPT | BTM_SEC_IN_AUTHORIZE)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)) && btm_dev_encrypted(p_dev_rec))) ||
2354 (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_FLAGS) && btm_dev_encrypted(p_dev_rec) && (btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))))
The Android Open Source Project5738f832012-12-12 16:00:35 -08002355 {
2356 rc = BTM_SUCCESS;
2357 }
2358 }
2359
2360 if (rc == BTM_SUCCESS)
2361 {
2362 if (p_callback)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002363 (*p_callback) (bd_addr, transport, (void *)p_ref_data, BTM_SUCCESS);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002364
2365 return(BTM_SUCCESS);
2366 }
2367 }
2368
2369 btm_cb.sec_req_pending = TRUE;
2370 return(BTM_CMD_STARTED);
2371 }
2372
2373 /* Save pointer to service record */
2374 p_dev_rec->p_cur_service = p_serv_rec;
2375
2376
2377 /* mess /w security_required in btm_sec_l2cap_access_req for Lisbon */
2378 if (btm_cb.security_mode == BTM_SEC_MODE_SP)
2379 {
2380 if (is_originator)
2381 {
2382 if (BTM_SEC_IS_SM4(p_dev_rec->sm4))
2383 {
2384 /* SM4 to SM4 -> always authenticate & encrypt */
2385 security_required |= (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT);
2386 }
2387 else
2388 {
2389 if ( !(BTM_SM4_KNOWN & p_dev_rec->sm4))
2390 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002391 BTM_TRACE_DEBUG ("remote features unknown!!sec_flags:0x%x", p_dev_rec->sec_flags);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002392 /* the remote features are not known yet */
2393 p_dev_rec->sm4 |= BTM_SM4_REQ_PEND;
2394
2395 return(BTM_CMD_STARTED);
2396 }
2397 }
2398 }
2399 else
2400 {
2401 /* responder */
2402 if (BTM_SEC_IS_SM4(p_dev_rec->sm4))
2403 {
2404 /* SM4 to SM4: the acceptor needs to make sure the authentication is already done */
2405 chk_acp_auth_done = TRUE;
2406 /* SM4 to SM4 -> always authenticate & encrypt */
2407 security_required |= (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT);
2408 }
2409 else
2410 {
2411 if ( !(BTM_SM4_KNOWN & p_dev_rec->sm4))
2412 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002413 BTM_TRACE_DEBUG ("(rsp) remote features unknown!!sec_flags:0x%x", p_dev_rec->sec_flags);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002414 /* the remote features are not known yet */
2415 p_dev_rec->sm4 |= BTM_SM4_REQ_PEND;
2416
2417 return(BTM_CMD_STARTED);
2418 }
2419 }
2420 }
2421 }
2422
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002423 BTM_TRACE_DEBUG ("btm_sec_l2cap_access_req() sm4:0x%x, sec_flags:0x%x, security_required:0x%x chk:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002424 p_dev_rec->sm4, p_dev_rec->sec_flags, security_required, chk_acp_auth_done);
2425
2426 old_security_required = p_dev_rec->security_required;
2427 old_is_originator = p_dev_rec->is_originator;
2428 p_dev_rec->security_required = security_required;
2429 p_dev_rec->p_ref_data = p_ref_data;
2430 p_dev_rec->is_originator = is_originator;
2431
2432#if (L2CAP_UCD_INCLUDED == TRUE)
2433 if ( conn_type & CONNECTION_TYPE_CONNLESS_MASK )
2434 p_dev_rec->is_ucd = TRUE;
2435 else
2436 p_dev_rec->is_ucd = FALSE;
2437#endif
2438
2439 /* If there are multiple service records used through the same PSM */
2440 /* leave security decision for the multiplexor on the top */
2441#if (L2CAP_UCD_INCLUDED == TRUE)
2442 if (((btm_sec_find_next_serv (p_serv_rec)) != NULL)
2443 &&(!( conn_type & CONNECTION_TYPE_CONNLESS_MASK ))) /* if not UCD */
2444#else
2445 if ((btm_sec_find_next_serv (p_serv_rec)) != NULL)
2446#endif
2447 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002448 BTM_TRACE_DEBUG ("no next_serv sm4:0x%x, chk:%d", p_dev_rec->sm4, chk_acp_auth_done);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002449 if (!BTM_SEC_IS_SM4(p_dev_rec->sm4))
2450 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002451 BTM_TRACE_EVENT ("Security Manager: l2cap_access_req PSM:%d postponed for multiplexer", psm);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002452 /* pre-Lisbon: restore the old settings */
2453 p_dev_rec->security_required = old_security_required;
2454 p_dev_rec->is_originator = old_is_originator;
2455
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002456 (*p_callback) (bd_addr, transport, p_ref_data, BTM_SUCCESS);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002457
2458 return(BTM_SUCCESS);
2459 }
2460 }
2461
2462 /* if the originator is using dynamic PSM in legacy mode, do not start any security process now.
2463 * The layer above L2CAP needs to carry out the security requirement after L2CAP connect response is received*/
2464 if (is_originator && (btm_cb.security_mode != BTM_SEC_MODE_SP || !BTM_SEC_IS_SM4(p_dev_rec->sm4)) && (psm >= 0x1001))
2465 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002466 BTM_TRACE_EVENT ("dynamic PSM:0x%x in legacy mode - postponed for upper layer", psm);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002467 /* restore the old settings */
2468 p_dev_rec->security_required = old_security_required;
2469 p_dev_rec->is_originator = old_is_originator;
2470
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002471 (*p_callback) (bd_addr, transport, p_ref_data, BTM_SUCCESS);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002472
2473 return(BTM_SUCCESS);
2474 }
2475
2476 if (chk_acp_auth_done)
2477 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002478 BTM_TRACE_DEBUG ("(SM4 to SM4) btm_sec_l2cap_access_req rspd. authenticated: x%x, enc: x%x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002479 (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED), (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED));
2480 /* SM4, but we do not know for sure which level of security we need.
2481 * as long as we have a link key, it's OK */
2482 if ((0 == (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))
2483 ||(0 == (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)))
2484 {
2485 rc = BTM_DELAY_CHECK;
2486 /*
2487 2046 may report HCI_Encryption_Change and L2C Connection Request out of sequence
2488 because of data path issues. Delay this disconnect a little bit
2489 */
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002490 BTM_TRACE_ERROR ("peer should have initiated security process by now (SM4 to SM4)");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002491 p_dev_rec->p_callback = p_callback;
2492 p_dev_rec->sec_state = BTM_SEC_STATE_DELAY_FOR_ENC;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002493 (*p_callback) (bd_addr, transport, p_ref_data, rc);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002494
Hemant Gupta5aec4862013-12-19 20:37:16 +05302495 return(BTM_CMD_STARTED);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002496 }
2497 }
2498
2499 p_dev_rec->p_callback = p_callback;
2500
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002501 if (p_dev_rec->last_author_service_id == BTM_SEC_NO_LAST_SERVICE_ID
2502 || p_dev_rec->last_author_service_id != p_dev_rec->p_cur_service->service_id)
2503 {
2504 /* Although authentication and encryption are per connection
2505 ** authorization is per access request. For example when serial connection
2506 ** is up and authorized and client requests to read file (access to other
2507 ** scn), we need to request user's permission again.
2508 */
2509 p_dev_rec->sec_flags &= ~BTM_SEC_AUTHORIZED;
2510 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002511
2512 if (BTM_SEC_IS_SM4(p_dev_rec->sm4))
2513 {
2514 /* If we already have a link key to the connected peer, is the link key secure enough ? */
2515 btm_sec_check_upgrade(p_dev_rec, is_originator);
2516 }
2517
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002518 BTM_TRACE_EVENT ("Security Manager: l2cap_access_req PSM:%d Handle:%d State:%d Flags:0x%x Required:0x%x Service ID:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002519 psm, handle, p_dev_rec->sec_state, p_dev_rec->sec_flags, p_dev_rec->security_required, p_dev_rec->p_cur_service->service_id);
2520
2521 if ((rc = btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
2522 {
2523 p_dev_rec->p_callback = NULL;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002524 (*p_callback) (bd_addr, transport, p_dev_rec->p_ref_data, (UINT8)rc);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002525 }
2526
2527 return(rc);
2528}
2529
2530/*******************************************************************************
2531**
2532** Function btm_sec_mx_access_request
2533**
2534** Description This function is called by all Multiplexing Protocols during
2535** establishing connection to or from peer device to grant
2536** permission to establish application connection.
2537**
2538** Parameters: bd_addr - Address of the peer device
2539** psm - L2CAP PSM
2540** is_originator - TRUE if protocol above L2CAP originates
2541** connection
2542** mx_proto_id - protocol ID of the multiplexer
2543** mx_chan_id - multiplexer channel to reach application
2544** p_callback - Pointer to callback function called if
2545** this function returns PENDING after required
2546** procedures are completed
2547** p_ref_data - Pointer to any reference data needed by the
2548** the callback function.
2549**
2550** Returns BTM_CMD_STARTED
2551**
2552*******************************************************************************/
2553tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_originator,
2554 UINT32 mx_proto_id, UINT32 mx_chan_id,
2555 tBTM_SEC_CALLBACK *p_callback, void *p_ref_data)
2556
2557{
2558 tBTM_SEC_DEV_REC *p_dev_rec;
2559 tBTM_SEC_SERV_REC *p_serv_rec;
2560 tBTM_STATUS rc;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002561 UINT16 security_required;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002562 BOOLEAN transport = FALSE;/* should check PSM range in LE connection oriented L2CAP connection */
The Android Open Source Project5738f832012-12-12 16:00:35 -08002563
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002564 BTM_TRACE_DEBUG ("btm_sec_mx_access_request is_originator:%d", is_originator);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002565 /* Find or get oldest record */
2566 p_dev_rec = btm_find_or_alloc_dev (bd_addr);
2567
2568 /* Find the service record for the PSM */
2569 p_serv_rec = btm_sec_find_mx_serv (is_originator, psm, mx_proto_id, mx_chan_id);
2570
2571 /* If there is no application registered with this PSM do not allow connection */
2572 if (!p_serv_rec)
2573 {
2574 if (p_callback)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002575 (*p_callback) (bd_addr, transport, p_ref_data, BTM_MODE_UNSUPPORTED);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002576
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002577 BTM_TRACE_ERROR ("Security Manager: MX service not found PSM:%d Proto:%d SCN:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002578 psm, mx_proto_id, mx_chan_id);
2579 return BTM_NO_RESOURCES;
2580 }
2581
2582 /* there are some devices (moto phone) which connects to several services at the same time */
2583 /* we will process one after another */
2584 if ( (p_dev_rec->p_callback) || (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) )
2585 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002586 BTM_TRACE_EVENT ("btm_sec_mx_access_request service PSM:%d Proto:%d SCN:%d delayed state: %s",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002587 psm, mx_proto_id, mx_chan_id, btm_pair_state_descr(btm_cb.pairing_state));
2588
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002589 rc = BTM_CMD_STARTED;
2590 security_required = p_serv_rec->security_flags;
2591 if ((BTM_SEC_MODE_SP != btm_cb.security_mode)
2592 || ((BTM_SEC_MODE_SP == btm_cb.security_mode) && (BTM_SM4_KNOWN == p_dev_rec->sm4))
2593 || (BTM_SEC_IS_SM4(p_dev_rec->sm4) && (btm_sec_is_upgrade_possible(p_dev_rec, is_originator) == FALSE))
2594 )
2595 {
2596 /* legacy mode - local is legacy or local is lisbon/peer is legacy
2597 * or SM4 with no possibility of link key upgrade */
2598 if (is_originator)
2599 {
2600 if (((security_required & BTM_SEC_OUT_FLAGS) == 0) ||
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002601 ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec))) ||
2602 ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && btm_dev_encrypted(p_dev_rec)))
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002603 )
2604 {
2605 rc = BTM_SUCCESS;
2606 }
2607 }
2608 else
2609 {
2610 if (((security_required & BTM_SEC_IN_FLAGS) == 0) ||
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002611 ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && btm_dev_authenticated(p_dev_rec))) ||
2612 (((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHORIZE) && (btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))) ||
2613 (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_AUTHENTICATE)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec)) && btm_dev_authenticated(p_dev_rec))) ||
2614 (((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_ENCRYPT)) && ((btm_dev_authorized(p_dev_rec)||btm_serv_trusted(p_dev_rec, p_serv_rec))&& btm_dev_encrypted(p_dev_rec))) ||
2615 ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && btm_dev_encrypted(p_dev_rec)))
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002616 )
2617 {
2618 rc = BTM_SUCCESS;
2619 }
2620 }
2621 }
2622 if (rc == BTM_CMD_STARTED)
2623 {
2624 btm_sec_queue_mx_request (bd_addr, psm, is_originator, mx_proto_id, mx_chan_id, p_callback, p_ref_data);
2625 return rc;
2626 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08002627 }
2628
2629 p_dev_rec->p_cur_service = p_serv_rec;
2630 p_dev_rec->security_required = p_serv_rec->security_flags;
2631
2632 if (BTM_SEC_MODE_SP == btm_cb.security_mode)
2633 {
2634 if (BTM_SEC_IS_SM4(p_dev_rec->sm4))
2635 {
2636 /* If we already have a link key, check if that link key is good enough */
2637 btm_sec_check_upgrade(p_dev_rec, is_originator);
2638 }
2639 }
2640
2641 p_dev_rec->is_originator = is_originator;
2642 p_dev_rec->p_callback = p_callback;
2643 p_dev_rec->p_ref_data = p_ref_data;
2644
2645 /* Although authentication and encryption are per connection */
2646 /* authorization is per access request. For example when serial connection */
2647 /* is up and authorized and client requests to read file (access to other */
2648 /* scn, we need to request user's permission again. */
2649 p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED);
2650
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002651 BTM_TRACE_EVENT ("Security Manager: mx_access_req proto_id:%d chan_id:%d State:%d Flags:0x%x Required:0x%x Service ID:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002652 mx_proto_id, mx_chan_id, p_dev_rec->sec_state, p_dev_rec->sec_flags, p_dev_rec->security_required, p_dev_rec->p_cur_service->service_id);
2653
2654 if ((rc = btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
2655 {
2656 if (p_callback)
2657 {
2658 p_dev_rec->p_callback = NULL;
2659
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002660 (*p_callback) (bd_addr,transport, p_ref_data, (UINT8)rc);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002661 }
2662 }
2663
2664 return rc;
2665}
2666
2667/*******************************************************************************
2668**
2669** Function btm_sec_conn_req
2670**
2671** Description This function is when the peer device is requesting
2672** connection
2673**
2674** Returns void
2675**
2676*******************************************************************************/
2677void btm_sec_conn_req (UINT8 *bda, UINT8 *dc)
2678{
2679 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda);
2680
2681 /* Some device may request a connection before we are done with the HCI_Reset sequence */
2682 if (btm_cb.devcb.state != BTM_DEV_STATE_READY)
2683 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002684 BTM_TRACE_EVENT ("Security Manager: connect request when device not ready");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002685 btsnd_hcic_reject_conn (bda, HCI_ERR_HOST_REJECT_DEVICE);
2686 return;
2687 }
2688
2689 /* Security guys wants us not to allow connection from not paired devices */
2690
2691 /* Check if connection is allowed for only paired devices */
2692 if (btm_cb.connect_only_paired)
2693 {
2694 if (!p_dev_rec || !(p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED))
2695 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002696 BTM_TRACE_EVENT ("Security Manager: connect request from non-paired device");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002697 btsnd_hcic_reject_conn (bda, HCI_ERR_HOST_REJECT_DEVICE);
2698 return;
2699 }
2700 }
2701
2702#if BTM_ALLOW_CONN_IF_NONDISCOVER == FALSE
2703 /* If non-discoverable, only allow known devices to connect */
2704 if (btm_cb.btm_inq_vars.discoverable_mode == BTM_NON_DISCOVERABLE)
2705 {
2706 if (!p_dev_rec)
2707 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002708 BTM_TRACE_EVENT ("Security Manager: connect request from not paired device");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002709 btsnd_hcic_reject_conn (bda, HCI_ERR_HOST_REJECT_DEVICE);
2710 return;
2711 }
2712 }
2713#endif
2714
2715 /* Host can be registered to verify comming BDA or DC */
2716 if (btm_cb.p_conn_filter_cb)
2717 {
2718 if (!(* btm_cb.p_conn_filter_cb) (bda, dc))
2719 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002720 BTM_TRACE_EVENT ("Security Manager: connect request did not pass filter");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002721
2722 /* incomming call did not pass connection filters. Reject */
2723 btsnd_hcic_reject_conn (bda, HCI_ERR_HOST_REJECT_DEVICE);
2724 return;
2725 }
2726 }
2727
2728 if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
2729 &&(btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
2730 &&(!memcmp (btm_cb.pairing_bda, bda, BD_ADDR_LEN)))
2731 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002732 BTM_TRACE_EVENT ("Security Manager: reject connect request from bonding device");
The Android Open Source Project5738f832012-12-12 16:00:35 -08002733
2734 /* incoming connection from bonding device is rejected */
2735 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_REJECTED_CONNECT;
2736 btsnd_hcic_reject_conn (bda, HCI_ERR_HOST_REJECT_DEVICE);
2737 return;
2738 }
2739
2740 /* Host is not interested or approved connection. Save BDA and DC and */
2741 /* pass request to L2CAP */
2742 memcpy (btm_cb.connecting_bda, bda, BD_ADDR_LEN);
2743 memcpy (btm_cb.connecting_dc, dc, DEV_CLASS_LEN);
2744
2745 if (l2c_link_hci_conn_req (bda))
2746 {
2747 if (!p_dev_rec)
2748 {
2749 /* accept the connection -> allocate a device record */
2750 p_dev_rec = btm_sec_alloc_dev (bda);
2751 }
2752 if (p_dev_rec)
2753 {
2754 p_dev_rec->sm4 |= BTM_SM4_CONN_PEND;
2755 }
2756 }
2757}
2758
2759/*******************************************************************************
2760**
2761** Function btm_sec_bond_cancel_complete
2762**
2763** Description This function is called to report bond cancel complete
2764** event.
2765**
2766** Returns void
2767**
2768*******************************************************************************/
2769static void btm_sec_bond_cancel_complete (void)
2770{
2771 tBTM_SEC_DEV_REC *p_dev_rec;
2772
2773 if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE) ||
2774 (BTM_PAIR_STATE_WAIT_LOCAL_PIN == btm_cb.pairing_state &&
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08002775 BTM_PAIR_FLAGS_WE_STARTED_DD & btm_cb.pairing_flags) ||
2776 (btm_cb.pairing_state == BTM_PAIR_STATE_GET_REM_NAME &&
2777 BTM_PAIR_FLAGS_WE_CANCEL_DD & btm_cb.pairing_flags))
The Android Open Source Project5738f832012-12-12 16:00:35 -08002778 {
2779 /* for dedicated bonding in legacy mode, authentication happens at "link level"
2780 * btm_sec_connected is called with failed status.
2781 * In theory, the code that handles is_pairing_device/TRUE should clean out security related code.
2782 * However, this function may clean out the security related flags and btm_sec_connected would not know
2783 * this function also needs to do proper clean up.
2784 */
2785 if ((p_dev_rec = btm_find_dev (btm_cb.pairing_bda)) != NULL)
2786 p_dev_rec->security_required = BTM_SEC_NONE;
2787 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
2788
2789 /* Notify application that the cancel succeeded */
2790 if (btm_cb.api.p_bond_cancel_cmpl_callback)
2791 btm_cb.api.p_bond_cancel_cmpl_callback(BTM_SUCCESS);
2792 }
2793}
2794
2795/*******************************************************************************
2796**
2797** Function btm_create_conn_cancel_complete
2798**
2799** Description This function is called when the command complete message
2800** is received from the HCI for the create connection cancel
2801** command.
2802**
2803** Returns void
2804**
2805*******************************************************************************/
2806void btm_create_conn_cancel_complete (UINT8 *p)
2807{
2808 UINT8 status;
2809
2810 STREAM_TO_UINT8 (status, p);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002811 BTM_TRACE_EVENT ("btm_create_conn_cancel_complete(): in State: %s status:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002812 btm_pair_state_descr(btm_cb.pairing_state), status);
2813
2814 /* if the create conn cancel cmd was issued by the bond cancel,
2815 ** the application needs to be notified that bond cancel succeeded
2816 */
2817 switch (status)
2818 {
2819 case HCI_SUCCESS:
2820 btm_sec_bond_cancel_complete();
2821 break;
2822 case HCI_ERR_CONNECTION_EXISTS:
2823 case HCI_ERR_NO_CONNECTION:
2824 default:
2825 /* Notify application of the error */
2826 if (btm_cb.api.p_bond_cancel_cmpl_callback)
2827 btm_cb.api.p_bond_cancel_cmpl_callback(BTM_ERR_PROCESSING);
2828 break;
2829 }
2830}
2831
2832/*******************************************************************************
2833**
2834** Function btm_sec_check_pending_reqs
2835**
2836** Description This function is called at the end of the security procedure
2837** to let L2CAP and RFCOMM know to re-submit any pending requests
2838**
2839** Returns void
2840**
2841*******************************************************************************/
2842void btm_sec_check_pending_reqs (void)
2843{
2844 tBTM_SEC_QUEUE_ENTRY *p_e;
2845 BUFFER_Q bq;
2846
2847 if (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE)
2848 {
2849 /* First, resubmit L2CAP requests */
2850 if (btm_cb.sec_req_pending)
2851 {
2852 btm_cb.sec_req_pending = FALSE;
2853 l2cu_resubmit_pending_sec_req (NULL);
2854 }
2855
2856 /* Now, re-submit anything in the mux queue */
2857 bq = btm_cb.sec_pending_q;
2858
2859 GKI_init_q (&btm_cb.sec_pending_q);
2860
2861 while ((p_e = (tBTM_SEC_QUEUE_ENTRY *)GKI_dequeue (&bq)) != NULL)
2862 {
2863 /* Check that the ACL is still up before starting security procedures */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002864 if (btm_bda_to_acl(p_e->bd_addr, BT_TRANSPORT_BR_EDR) != NULL)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002865 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002866 BTM_TRACE_EVENT ("btm_sec_check_pending_reqs() submitting PSM: 0x%04x Is_Orig: %u mx_proto_id: %u mx_chan_id: %u",
The Android Open Source Project5738f832012-12-12 16:00:35 -08002867 p_e->psm, p_e->is_orig, p_e->mx_proto_id, p_e->mx_chan_id);
2868
2869 btm_sec_mx_access_request (p_e->bd_addr, p_e->psm, p_e->is_orig,
2870 p_e->mx_proto_id, p_e->mx_chan_id,
2871 p_e->p_callback, p_e->p_ref_data);
2872 }
2873
2874 GKI_freebuf (p_e);
2875 }
2876 }
2877}
2878
2879/*******************************************************************************
2880**
2881** Function btm_sec_init
2882**
2883** Description This function is on the SEC startup
2884**
2885** Returns void
2886**
2887*******************************************************************************/
2888void btm_sec_init (UINT8 sec_mode)
2889{
2890#if 0 /* cleared in btm_init; put back in if calling from anywhere else! */
2891 int i;
2892
2893 memset (btm_cb.sec_serv_rec, 0, sizeof (btm_cb.sec_serv_rec));
2894 memset (btm_cb.sec_dev_rec, 0, sizeof (btm_cb.sec_dev_rec));
2895 memset (&btm_cb.pairing_tle, 0, sizeof(TIMER_LIST_ENT));
2896
2897#endif
2898 btm_cb.security_mode = sec_mode;
2899 memset (btm_cb.pairing_bda, 0xff, BD_ADDR_LEN);
2900 btm_cb.max_collision_delay = BTM_SEC_MAX_COLLISION_DELAY;
2901}
2902
2903/*******************************************************************************
2904**
2905** Function btm_sec_device_down
2906**
2907** Description This function should be called when device is disabled or
2908** turned off
2909**
2910** Returns void
2911**
2912*******************************************************************************/
2913void btm_sec_device_down (void)
2914{
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002915 BTM_TRACE_EVENT ("btm_sec_device_down() State: %s", btm_pair_state_descr(btm_cb.pairing_state));
The Android Open Source Project5738f832012-12-12 16:00:35 -08002916
2917 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
2918}
2919
2920/*******************************************************************************
2921**
2922** Function btm_sec_dev_reset
2923**
2924** Description This function should be called after device reset
2925**
2926** Returns void
2927**
2928*******************************************************************************/
2929void btm_sec_dev_reset (void)
2930{
2931#if (BTM_PRE_LISBON_INCLUDED == TRUE)
2932 if (btm_cb.security_mode == BTM_SEC_MODE_LINK)
2933 {
2934 btsnd_hcic_write_auth_enable (TRUE);
2935 btsnd_hcic_write_encr_mode (HCI_ENCRYPT_MODE_POINT_TO_POINT);
2936 }
2937#endif
2938#if (BTM_PRE_LISBON_INCLUDED == TRUE)
2939 else
2940#endif
Andre Eisenbach3aa60542013-03-22 18:00:51 -07002941 /* btm_sec_dev_reset() is only called from btm_decode_ext_features_page(...)
The Android Open Source Project5738f832012-12-12 16:00:35 -08002942 * right now. */
Andre Eisenbach3aa60542013-03-22 18:00:51 -07002943 if (HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
The Android Open Source Project5738f832012-12-12 16:00:35 -08002944 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002945 btsnd_hcic_write_simple_pairing_mode(HCI_SP_MODE_ENABLED);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002946#if BLE_INCLUDED == TRUE
2947 btsnd_hcic_set_event_mask(LOCAL_BR_EDR_CONTROLLER_ID,
2948 (UINT8 *)HCI_DUMO_EVENT_MASK_EXT);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07002949
2950 btsnd_hcic_ble_set_evt_mask((UINT8 *)HCI_BLE_EVENT_MASK_DEF);
2951
The Android Open Source Project5738f832012-12-12 16:00:35 -08002952#else
2953 btsnd_hcic_set_event_mask(LOCAL_BR_EDR_CONTROLLER_ID,
2954 (UINT8 *)HCI_LISBON_EVENT_MASK_EXT);
2955#endif
2956 /* set the default IO capabilities */
2957 btm_cb.devcb.loc_io_caps = BTM_LOCAL_IO_CAPS;
2958 /* add mx service to use no security */
2959#if (RFCOMM_INCLUDED == TRUE)
2960 BTM_SetSecurityLevel(FALSE, "RFC_MUX", BTM_SEC_SERVICE_RFC_MUX,
2961 BTM_SEC_NONE, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, 0);
2962#endif
2963 }
2964 else
2965 {
2966 btm_cb.security_mode = BTM_SEC_MODE_SERVICE;
2967 }
2968
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07002969 BTM_TRACE_DEBUG ("btm_sec_dev_reset sec mode: %d", btm_cb.security_mode);
The Android Open Source Project5738f832012-12-12 16:00:35 -08002970}
2971
2972/*******************************************************************************
2973**
2974** Function btm_sec_abort_access_req
2975**
2976** Description This function is called by the L2CAP or RFCOMM to abort
2977** the pending operation.
2978**
2979** Parameters: bd_addr - Address of the peer device
2980**
2981** Returns void
2982**
2983*******************************************************************************/
2984void btm_sec_abort_access_req (BD_ADDR bd_addr)
2985{
2986 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
2987
2988 if (!p_dev_rec)
2989 return;
2990
2991 if (btm_cb.api.p_abort_callback)
2992 (*btm_cb.api.p_abort_callback)(bd_addr, p_dev_rec->dev_class, p_dev_rec->sec_bd_name);
2993
2994 if ((p_dev_rec->sec_state != BTM_SEC_STATE_AUTHORIZING)
2995 && (p_dev_rec->sec_state != BTM_SEC_STATE_AUTHENTICATING))
2996 return;
2997
2998 p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
2999 p_dev_rec->p_callback = NULL;
3000}
3001
3002/*******************************************************************************
3003**
3004** Function btm_sec_dd_create_conn
3005**
3006** Description This function is called to create the ACL connection for
3007** the dedicated boding process
3008**
3009** Returns void
3010**
3011*******************************************************************************/
3012static tBTM_STATUS btm_sec_dd_create_conn (tBTM_SEC_DEV_REC *p_dev_rec)
3013{
3014 tL2C_LCB *p_lcb;
3015
3016 /* Make sure an L2cap link control block is available */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07003017 if ((p_lcb = l2cu_allocate_lcb (p_dev_rec->bd_addr, TRUE, BT_TRANSPORT_BR_EDR)) == NULL)
The Android Open Source Project5738f832012-12-12 16:00:35 -08003018 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003019 BTM_TRACE_WARNING ("Security Manager: failed allocate LCB [%02x%02x%02x%02x%02x%02x]",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003020 p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
3021 p_dev_rec->bd_addr[3], p_dev_rec->bd_addr[4], p_dev_rec->bd_addr[5]);
3022
3023 return(BTM_NO_RESOURCES);
3024 }
3025
3026 /* set up the control block to indicated dedicated bonding */
3027 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_DISC_WHEN_DONE;
3028
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07003029 if (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE)
The Android Open Source Project5738f832012-12-12 16:00:35 -08003030 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003031 BTM_TRACE_WARNING ("Security Manager: failed create [%02x%02x%02x%02x%02x%02x]",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003032 p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
3033 p_dev_rec->bd_addr[3], p_dev_rec->bd_addr[4], p_dev_rec->bd_addr[5]);
3034
3035 l2cu_release_lcb(p_lcb);
3036 return(BTM_NO_RESOURCES);
3037 }
3038
3039#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
3040 btm_acl_update_busy_level (BTM_BLI_PAGE_EVT);
3041#endif
3042
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003043 BTM_TRACE_DEBUG ("Security Manager: btm_sec_dd_create_conn [%02x%02x%02x%02x%02x%02x]",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003044 p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
3045 p_dev_rec->bd_addr[3], p_dev_rec->bd_addr[4], p_dev_rec->bd_addr[5]);
3046
3047 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
3048
3049 return(BTM_CMD_STARTED);
3050}
3051
3052/*******************************************************************************
3053**
3054** Function btm_sec_rmt_name_request_complete
3055**
3056** Description This function is called when remote name was obtained from
3057** the peer device
3058**
3059** Returns void
3060**
3061*******************************************************************************/
3062void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT8 status)
3063{
3064 tBTM_SEC_DEV_REC *p_dev_rec;
3065 int i;
3066 DEV_CLASS dev_class;
3067 UINT8 old_sec_state;
3068
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003069 BTM_TRACE_EVENT ("btm_sec_rmt_name_request_complete");
The Android Open Source Project5738f832012-12-12 16:00:35 -08003070 if (((p_bd_addr == NULL) && !BTM_ACL_IS_CONNECTED(btm_cb.connecting_bda))
3071 || ((p_bd_addr != NULL) && !BTM_ACL_IS_CONNECTED(p_bd_addr)))
3072 {
3073 btm_acl_resubmit_page();
3074 }
3075
3076 /* If remote name request failed, p_bd_addr is null and we need to search */
3077 /* based on state assuming that we are doing 1 at a time */
3078 if (p_bd_addr)
3079 p_dev_rec = btm_find_dev (p_bd_addr);
3080 else
3081 {
3082 p_dev_rec = &btm_cb.sec_dev_rec[0];
3083
3084 for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
3085 {
3086 if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
3087 && (p_dev_rec->sec_state == BTM_SEC_STATE_GETTING_NAME))
3088 {
3089 p_bd_addr = p_dev_rec->bd_addr;
3090 break;
3091 }
3092 }
3093
3094 if (i == BTM_SEC_MAX_DEVICE_RECORDS)
3095 p_dev_rec = NULL;
3096 }
3097
3098
3099 /* Commenting out trace due to obf/compilation problems.
3100 */
3101#if (BT_USE_TRACES == TRUE)
3102 if (!p_bd_name)
3103 p_bd_name = (UINT8 *)"";
3104
3105 if (p_dev_rec)
3106 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003107 BTM_TRACE_EVENT ("Security Manager: rmt_name_complete PairState: %s RemName: %s status: %d State:%d p_dev_rec: 0x%08x ",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003108 btm_pair_state_descr (btm_cb.pairing_state), p_bd_name,
3109 status, p_dev_rec->sec_state, p_dev_rec);
3110 }
3111 else
3112 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003113 BTM_TRACE_EVENT ("Security Manager: rmt_name_complete PairState: %s RemName: %s status: %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003114 btm_pair_state_descr (btm_cb.pairing_state), p_bd_name,
3115 status);
3116 }
3117#endif
3118
3119 if (p_dev_rec)
3120 {
3121 old_sec_state = p_dev_rec->sec_state;
3122 if (status == HCI_SUCCESS)
3123 {
3124 BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, sizeof (p_dev_rec->sec_bd_name), (char *)p_bd_name, BTM_MAX_REM_BD_NAME_LEN);
3125 p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003126 BTM_TRACE_EVENT ("setting BTM_SEC_NAME_KNOWN sec_flags:0x%x", p_dev_rec->sec_flags);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003127 }
3128 else
3129 {
3130 /* Notify all clients waiting for name to be resolved even if it failed so clients can continue */
3131 p_dev_rec->sec_bd_name[0] = 0;
3132 }
3133
3134 if (p_dev_rec->sec_state == BTM_SEC_STATE_GETTING_NAME)
3135 p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
3136
3137 /* Notify all clients waiting for name to be resolved */
3138 for (i = 0;i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++)
3139 {
Hemant Gupta831423e2014-01-08 12:42:13 +05303140 if (btm_cb.p_rmt_name_callback[i] && p_bd_addr)
The Android Open Source Project5738f832012-12-12 16:00:35 -08003141 (*btm_cb.p_rmt_name_callback[i])(p_bd_addr, p_dev_rec->dev_class,
3142 p_dev_rec->sec_bd_name);
3143 }
3144 }
3145 else
3146 {
3147 dev_class[0] = 0;
3148 dev_class[1] = 0;
3149 dev_class[2] = 0;
3150
3151 /* Notify all clients waiting for name to be resolved even if not found so clients can continue */
3152 for (i = 0;i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++)
3153 {
Hemant Gupta831423e2014-01-08 12:42:13 +05303154 if (btm_cb.p_rmt_name_callback[i] && p_bd_addr)
The Android Open Source Project5738f832012-12-12 16:00:35 -08003155 (*btm_cb.p_rmt_name_callback[i])(p_bd_addr, dev_class, (UINT8 *)"");
3156 }
3157
3158 return;
3159 }
3160
3161 /* If we were delaying asking UI for a PIN because name was not resolved, ask now */
3162 if ( (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_LOCAL_PIN) && p_bd_addr
3163 && (memcmp (btm_cb.pairing_bda, p_bd_addr, BD_ADDR_LEN) == 0) )
3164 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003165 BTM_TRACE_EVENT ("btm_sec_rmt_name_request_complete() delayed pin now being requested flags:0x%x, (p_pin_callback=0x%p)", btm_cb.pairing_flags, btm_cb.api.p_pin_callback);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003166
3167 if (((btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) == 0) &&
3168 ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0) &&
3169 btm_cb.api.p_pin_callback)
3170 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003171 BTM_TRACE_EVENT ("btm_sec_rmt_name_request_complete() calling pin_callback");
The Android Open Source Project5738f832012-12-12 16:00:35 -08003172 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
3173 (*btm_cb.api.p_pin_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, p_bd_name);
3174 }
3175
3176 /* Set the same state again to force the timer to be restarted */
3177 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_PIN);
3178 return;
3179 }
3180
3181 /* Check if we were delaying bonding because name was not resolved */
3182 if ( btm_cb.pairing_state == BTM_PAIR_STATE_GET_REM_NAME)
3183 {
3184 if (p_bd_addr && memcmp (btm_cb.pairing_bda, p_bd_addr, BD_ADDR_LEN) == 0)
3185 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003186 BTM_TRACE_EVENT ("btm_sec_rmt_name_request_complete() continue bonding sm4: 0x%04x, status:0x%x", p_dev_rec->sm4, status);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08003187 if(btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_CANCEL_DD)
3188 {
3189 btm_sec_bond_cancel_complete();
3190 return;
3191 }
3192
The Android Open Source Project5738f832012-12-12 16:00:35 -08003193 if (status != HCI_SUCCESS)
3194 {
3195 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
3196
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07003197 if (btm_cb.api.p_auth_complete_callback)
3198 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
3199 p_dev_rec->sec_bd_name, status);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003200 return;
3201 }
3202
3203 /* if peer is very old legacy devices, HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT is not reported */
3204 if (BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4))
3205 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07003206 /* set the KNOWN flag only if BTM_PAIR_FLAGS_REJECTED_CONNECT is not set.*/
3207 /* If it is set, there may be a race condition */
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003208 BTM_TRACE_DEBUG ("btm_sec_rmt_name_request_complete IS_SM4_UNKNOWN Flags:0x%04x",
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07003209 btm_cb.pairing_flags);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003210 if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT) == 0)
3211 {
3212 p_dev_rec->sm4 |= BTM_SM4_KNOWN;
3213 }
3214 }
3215
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003216 BTM_TRACE_DEBUG("%s, SM4 Value: %x, Legacy:%d,IS SM4:%d, Unknown:%d",__FUNCTION__,
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07003217 p_dev_rec->sm4, BTM_SEC_IS_SM4_LEGACY(p_dev_rec->sm4),
3218 BTM_SEC_IS_SM4(p_dev_rec->sm4),BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4));
3219
The Android Open Source Project5738f832012-12-12 16:00:35 -08003220 /* BT 2.1 or carkit, bring up the connection to force the peer to request PIN.
3221 ** Else prefetch (btm_sec_check_prefetch_pin will do the prefetching if needed)
3222 */
3223 if ((p_dev_rec->sm4 != BTM_SM4_KNOWN) || !btm_sec_check_prefetch_pin(p_dev_rec))
3224 {
3225 /* if we rejected incoming connection request, we have to wait HCI_Connection_Complete event */
3226 /* before originating */
3227 if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT)
3228 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003229 BTM_TRACE_WARNING ("btm_sec_rmt_name_request_complete: waiting HCI_Connection_Complete after rejecting connection");
The Android Open Source Project5738f832012-12-12 16:00:35 -08003230 }
3231 /* Both we and the peer are 2.1 - continue to create connection */
3232 else if (btm_sec_dd_create_conn(p_dev_rec) != BTM_CMD_STARTED)
3233 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003234 BTM_TRACE_WARNING ("btm_sec_rmt_name_request_complete: failed to start connection");
The Android Open Source Project5738f832012-12-12 16:00:35 -08003235
3236 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
3237
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07003238 if (btm_cb.api.p_auth_complete_callback)
The Android Open Source Project5738f832012-12-12 16:00:35 -08003239 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
3240 p_dev_rec->sec_bd_name, HCI_ERR_MEMORY_FULL);
3241 }
3242 }
3243 return;
3244 }
3245 else
3246 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003247 BTM_TRACE_WARNING ("btm_sec_rmt_name_request_complete: wrong BDA, retry with pairing BDA");
The Android Open Source Project5738f832012-12-12 16:00:35 -08003248
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07003249 BTM_ReadRemoteDeviceName (btm_cb.pairing_bda, NULL, BT_TRANSPORT_BR_EDR);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003250 return;
3251 }
3252 }
3253
3254 /* check if we were delaying link_key_callback because name was not resolved */
3255 if (p_dev_rec->link_key_not_sent)
3256 {
3257 /* If HCI connection complete has not arrived, wait for it */
3258 if (p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE)
3259 return;
3260
3261 p_dev_rec->link_key_not_sent = FALSE;
3262 btm_send_link_key_notif(p_dev_rec);
3263
3264 /* If its not us who perform authentication, we should tell stackserver */
3265 /* that some authentication has been completed */
3266 /* This is required when different entities receive link notification and auth complete */
3267 if (!(p_dev_rec->security_required & BTM_SEC_OUT_AUTHENTICATE))
3268 {
3269 if (btm_cb.api.p_auth_complete_callback)
3270 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
3271 p_dev_rec->dev_class,
3272 p_dev_rec->sec_bd_name, HCI_SUCCESS);
3273
3274 }
3275 }
3276
3277 /* If this is a bonding procedure can disconnect the link now */
3278 if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
3279 && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))
3280 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003281 BTM_TRACE_WARNING ("btm_sec_rmt_name_request_complete (none/ce)");
The Android Open Source Project5738f832012-12-12 16:00:35 -08003282 p_dev_rec->security_required &= ~(BTM_SEC_OUT_AUTHENTICATE);
3283 l2cu_start_post_bond_timer(p_dev_rec->hci_handle);
3284 return;
3285 }
3286
3287 if (old_sec_state != BTM_SEC_STATE_GETTING_NAME)
3288 return;
3289
3290 /* If get name failed, notify the waiting layer */
3291 if (status != HCI_SUCCESS)
3292 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07003293 btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003294 return;
3295 }
3296
3297 if (p_dev_rec->sm4 & BTM_SM4_REQ_PEND)
3298 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003299 BTM_TRACE_EVENT ("waiting for remote features!!");
The Android Open Source Project5738f832012-12-12 16:00:35 -08003300 return;
3301 }
3302
3303 /* Remote Name succeeded, execute the next security procedure, if any */
3304 status = (UINT8)btm_sec_execute_procedure (p_dev_rec);
3305
3306 /* If result is pending reply from the user or from the device is pending */
3307 if (status == BTM_CMD_STARTED)
3308 return;
3309
3310 /* There is no next procedure or start of procedure failed, notify the waiting layer */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07003311 btm_sec_dev_rec_cback_event (p_dev_rec, status, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003312}
3313
3314/*******************************************************************************
3315**
3316** Function btm_sec_rmt_host_support_feat_evt
3317**
3318** Description This function is called when the
3319** HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT is received
3320**
3321** Returns void
3322**
3323*******************************************************************************/
3324void btm_sec_rmt_host_support_feat_evt (UINT8 *p)
3325{
3326 tBTM_SEC_DEV_REC *p_dev_rec;
3327 BD_ADDR bd_addr; /* peer address */
3328 BD_FEATURES features;
3329
3330 STREAM_TO_BDADDR (bd_addr, p);
3331 p_dev_rec = btm_find_or_alloc_dev (bd_addr);
3332
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003333 BTM_TRACE_EVENT ("btm_sec_rmt_host_support_feat_evt sm4: 0x%x p[0]: 0x%x", p_dev_rec->sm4, p[0]);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003334
3335 if (BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4))
3336 {
3337 p_dev_rec->sm4 = BTM_SM4_KNOWN;
Andre Eisenbach3aa60542013-03-22 18:00:51 -07003338 STREAM_TO_ARRAY(features, p, HCI_FEATURE_BYTES_PER_PAGE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003339 if (HCI_SSP_HOST_SUPPORTED(features))
3340 {
3341 p_dev_rec->sm4 = BTM_SM4_TRUE;
3342 }
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003343 BTM_TRACE_EVENT ("btm_sec_rmt_host_support_feat_evt sm4: 0x%x features[0]: 0x%x", p_dev_rec->sm4, features[0]);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003344 }
3345}
3346
3347/*******************************************************************************
3348**
3349** Function btm_io_capabilities_req
3350**
3351** Description This function is called when LM request for the IO
3352** capability of the local device and
3353** if the OOB data is present for the device in the event
3354**
3355** Returns void
3356**
3357*******************************************************************************/
3358void btm_io_capabilities_req (UINT8 *p)
3359{
3360 tBTM_SP_IO_REQ evt_data;
3361 UINT8 err_code = 0;
3362 tBTM_SEC_DEV_REC *p_dev_rec;
3363 BOOLEAN is_orig = TRUE;
3364 UINT8 callback_rc = BTM_SUCCESS;
3365
3366 STREAM_TO_BDADDR (evt_data.bd_addr, p);
3367
3368 /* setup the default response according to compile options */
3369 /* assume that the local IO capability does not change
3370 * loc_io_caps is initialized with the default value */
3371 evt_data.io_cap = btm_cb.devcb.loc_io_caps;
3372 evt_data.oob_data = BTM_OOB_NONE;
3373 evt_data.auth_req = BTM_DEFAULT_AUTH_REQ;
3374
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003375 BTM_TRACE_EVENT ("btm_io_capabilities_req() State: %s", btm_pair_state_descr(btm_cb.pairing_state));
The Android Open Source Project5738f832012-12-12 16:00:35 -08003376
3377 p_dev_rec = btm_find_or_alloc_dev (evt_data.bd_addr);
3378 p_dev_rec->sm4 |= BTM_SM4_TRUE;
3379
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003380 BTM_TRACE_EVENT ("btm_io_capabilities_req() State: %s Flags: 0x%04x p_cur_service: 0x%08x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003381 btm_pair_state_descr(btm_cb.pairing_state), btm_cb.pairing_flags, p_dev_rec->p_cur_service);
3382
3383 if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
3384 {
3385 if (btm_cb.pairing_state == BTM_PAIR_STATE_INCOMING_SSP)
3386 {
3387 /* received IO capability response already-> not the originator of SSP */
3388 is_orig = FALSE;
3389
3390 if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_PEER_STARTED_DD)
3391 evt_data.auth_req = BTM_DEFAULT_DD_AUTH_REQ;
3392 }
3393 /* security is already in progress */
3394 else if (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_PIN_REQ)
3395 {
3396/* coverity[uninit_use_in_call]
3397Event uninit_use_in_call: Using uninitialized element of array "evt_data.bd_addr" in call to function "memcmp"
3398False-positive: evt_data.bd_addr is set at the beginning with: STREAM_TO_BDADDR (evt_data.bd_addr, p);
3399*/
3400 if (memcmp (evt_data.bd_addr, btm_cb.pairing_bda, BD_ADDR_LEN))
3401 {
3402 /* and it's not the device in bonding -> reject it */
3403 err_code = HCI_ERR_HOST_BUSY_PAIRING;
3404 }
3405 else
3406 {
3407 /* local device initiated dedicated bonding */
3408 evt_data.auth_req = BTM_DEFAULT_DD_AUTH_REQ;
3409 }
3410 }
3411 else
3412 {
3413 err_code = HCI_ERR_HOST_BUSY_PAIRING;
3414 }
3415 }
3416
3417 /* paring is not allowed */
3418 if (btm_cb.pairing_disabled)
3419 err_code = HCI_ERR_PAIRING_NOT_ALLOWED;
3420
3421 if (err_code != 0)
3422 {
3423/* coverity[uninit_use_in_call]
3424Event uninit_use_in_call: Using uninitialized element of array "evt_data.bd_addr" in call to function "memcmp"
3425False-positive: evt_data.bd_addr is set at the beginning with: STREAM_TO_BDADDR (evt_data.bd_addr, p);
3426*/
3427 btsnd_hcic_io_cap_req_neg_reply(evt_data.bd_addr, err_code);
3428 return;
3429 }
3430
3431 evt_data.is_orig = is_orig;
3432
3433 if (is_orig)
3434 {
3435 /* local device initiated the pairing non-bonding -> use p_cur_service */
3436 if (!(btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) &&
3437 p_dev_rec->p_cur_service &&
3438 (p_dev_rec->p_cur_service->security_flags & BTM_SEC_OUT_AUTHENTICATE))
3439 {
3440 evt_data.auth_req = (p_dev_rec->p_cur_service->security_flags & BTM_SEC_OUT_MITM) ? BTM_AUTH_SP_YES : BTM_AUTH_SP_NO;
3441 }
3442 }
3443
3444 /* Notify L2CAP to increase timeout */
3445 l2c_pin_code_request (evt_data.bd_addr);
3446
3447 memcpy (btm_cb.pairing_bda, evt_data.bd_addr, BD_ADDR_LEN);
3448
3449/* coverity[uninit_use_in_call]
3450Event uninit_use_in_call: Using uninitialized element of array "evt_data.bd_addr" in call to function "memcmp"
3451False-positive: False-positive: evt_data.bd_addr is set at the beginning with: STREAM_TO_BDADDR (evt_data.bd_addr, p);
3452*/
3453 if (!memcmp (evt_data.bd_addr, btm_cb.connecting_bda, BD_ADDR_LEN))
3454 memcpy (p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN);
3455
3456 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS);
3457
3458 callback_rc = BTM_SUCCESS;
3459 if (p_dev_rec->sm4 & BTM_SM4_UPGRADE)
3460 {
3461 p_dev_rec->sm4 &= ~BTM_SM4_UPGRADE;
3462
3463 /* link key upgrade: always use SPGB_YES - assuming we want to save the link key */
3464 evt_data.auth_req = BTM_AUTH_SPGB_YES;
3465 }
3466 else if (btm_cb.api.p_sp_callback)
3467 {
3468 /* the callback function implementation may change the IO capability... */
3469 callback_rc = (*btm_cb.api.p_sp_callback) (BTM_SP_IO_REQ_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
3470 }
3471
3472#if BTM_OOB_INCLUDED == TRUE
3473 if ((callback_rc == BTM_SUCCESS) || (BTM_OOB_UNKNOWN != evt_data.oob_data))
3474#else
3475 if (callback_rc == BTM_SUCCESS)
3476#endif
3477 {
3478 if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD))
3479 {
3480 evt_data.auth_req = (BTM_AUTH_DD_BOND | (evt_data.auth_req & BTM_AUTH_YN_BIT));
3481 }
3482
3483 /* if the user does not indicate "reply later" by setting the oob_data to unknown
3484 * send the response right now. Save the current IO capability in the control block */
3485 btm_cb.devcb.loc_auth_req = evt_data.auth_req;
3486 btm_cb.devcb.loc_io_caps = evt_data.io_cap;
3487
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003488 BTM_TRACE_EVENT ("btm_io_capabilities_req: State: %s IO_CAP:%d oob_data:%d auth_req:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003489 btm_pair_state_descr(btm_cb.pairing_state), evt_data.io_cap,
3490 evt_data.oob_data, evt_data.auth_req);
3491
3492 btsnd_hcic_io_cap_req_reply(evt_data.bd_addr, evt_data.io_cap,
3493 evt_data.oob_data, evt_data.auth_req);
3494 }
3495}
3496
3497/*******************************************************************************
3498**
3499** Function btm_io_capabilities_rsp
3500**
3501** Description This function is called when the IO capability of the
3502** specified device is received
3503**
3504** Returns void
3505**
3506*******************************************************************************/
3507void btm_io_capabilities_rsp (UINT8 *p)
3508{
3509 tBTM_SEC_DEV_REC *p_dev_rec;
3510 tBTM_SP_IO_RSP evt_data;
3511
3512 STREAM_TO_BDADDR (evt_data.bd_addr, p);
3513 STREAM_TO_UINT8 (evt_data.io_cap, p);
3514 STREAM_TO_UINT8 (evt_data.oob_data, p);
3515 STREAM_TO_UINT8 (evt_data.auth_req, p);
3516
3517 /* Allocate a new device record or reuse the oldest one */
3518 p_dev_rec = btm_find_or_alloc_dev (evt_data.bd_addr);
3519
3520 /* If no security is in progress, this indicates incoming security */
3521 if (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE)
3522 {
3523 memcpy (btm_cb.pairing_bda, evt_data.bd_addr, BD_ADDR_LEN);
3524
3525 btm_sec_change_pairing_state (BTM_PAIR_STATE_INCOMING_SSP);
3526
3527 /* Make sure we reset the trusted mask to help against attacks */
3528 BTM_SEC_CLR_TRUSTED_DEVICE(p_dev_rec->trusted_mask);
3529
3530 /* work around for FW bug */
3531 btm_inq_stop_on_ssp();
3532 }
3533
3534 /* Notify L2CAP to increase timeout */
3535 l2c_pin_code_request (evt_data.bd_addr);
3536
3537 /* We must have a device record here.
3538 * Use the connecting device's CoD for the connection */
3539/* coverity[uninit_use_in_call]
3540Event uninit_use_in_call: Using uninitialized element of array "evt_data.bd_addr" in call to function "memcmp"
3541FALSE-POSITIVE error from Coverity test-tool. evt_data.bd_addr is set at the beginning with: STREAM_TO_BDADDR (evt_data.bd_addr, p);
3542*/
3543 if (!memcmp (evt_data.bd_addr, btm_cb.connecting_bda, BD_ADDR_LEN))
3544 memcpy (p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN);
3545
3546 /* peer sets dedicated bonding bit and we did not initiate dedicated bonding */
3547 if (btm_cb.pairing_state == BTM_PAIR_STATE_INCOMING_SSP /* peer initiated bonding */
3548 && (evt_data.auth_req & BTM_AUTH_DD_BOND) ) /* and dedicated bonding bit is set */
3549 {
3550 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PEER_STARTED_DD;
3551 }
3552
3553 /* save the IO capability in the device record */
3554 p_dev_rec->rmt_io_caps = evt_data.io_cap;
3555 p_dev_rec->rmt_auth_req = evt_data.auth_req;
3556
3557 if (btm_cb.api.p_sp_callback)
3558 (*btm_cb.api.p_sp_callback) (BTM_SP_IO_RSP_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
3559}
3560
3561/*******************************************************************************
3562**
3563** Function btm_proc_sp_req_evt
3564**
3565** Description This function is called to process/report
3566** HCI_USER_CONFIRMATION_REQUEST_EVT
3567** or HCI_USER_PASSKEY_REQUEST_EVT
3568** or HCI_USER_PASSKEY_NOTIFY_EVT
3569**
3570** Returns void
3571**
3572*******************************************************************************/
3573void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
3574{
3575 tBTM_STATUS status = BTM_ERR_PROCESSING;
3576 tBTM_SP_EVT_DATA evt_data;
3577 UINT8 *p_bda = evt_data.cfm_req.bd_addr;
3578 tBTM_SEC_DEV_REC *p_dev_rec;
3579
3580 /* All events start with bd_addr */
3581 STREAM_TO_BDADDR (p_bda, p);
3582
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003583 BTM_TRACE_EVENT ("btm_proc_sp_req_evt() BDA: %08x%04x event: 0x%x, State: %s",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003584 (p_bda[0]<<24) + (p_bda[1]<<16) + (p_bda[2]<<8) + p_bda[3], (p_bda[4] << 8) + p_bda[5],
3585 event, btm_pair_state_descr(btm_cb.pairing_state));
3586
3587 if ( ((p_dev_rec = btm_find_dev (p_bda)) != NULL)
3588 && (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
3589 && (memcmp (btm_cb.pairing_bda, p_bda, BD_ADDR_LEN) == 0) )
3590 {
3591 memcpy (evt_data.cfm_req.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
3592 memcpy (evt_data.cfm_req.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN);
3593
3594 BCM_STRNCPY_S ((char *)evt_data.cfm_req.bd_name, sizeof(evt_data.cfm_req.bd_name), (char *)p_dev_rec->sec_bd_name, BTM_MAX_REM_BD_NAME_LEN);
3595
3596 switch (event)
3597 {
3598 case BTM_SP_CFM_REQ_EVT:
3599 /* Numeric confirmation. Need user to conf the passkey */
3600 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM);
3601
3602 /* The device record must be allocated in the "IO cap exchange" step */
3603 STREAM_TO_UINT32 (evt_data.cfm_req.num_val, p);
3604
3605 evt_data.cfm_req.just_works = TRUE;
3606
3607 /* process user confirm req in association with the auth_req param */
3608#if (BTM_LOCAL_IO_CAPS == BTM_IO_CAP_IO)
3609 if ( (p_dev_rec->rmt_io_caps == BTM_IO_CAP_IO)
3610 && (btm_cb.devcb.loc_io_caps == BTM_IO_CAP_IO)
3611 && ((p_dev_rec->rmt_auth_req & BTM_AUTH_SP_YES) || (btm_cb.devcb.loc_auth_req & BTM_AUTH_SP_YES)) )
3612 {
3613 /* Both devices are DisplayYesNo and one or both devices want to authenticate
3614 -> use authenticated link key */
3615 evt_data.cfm_req.just_works = FALSE;
3616 }
3617#endif
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003618 BTM_TRACE_DEBUG ("btm_proc_sp_req_evt() just_works:%d, io loc:%d, rmt:%d, auth loc:%d, rmt:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003619 evt_data.cfm_req.just_works, btm_cb.devcb.loc_io_caps, p_dev_rec->rmt_io_caps,
3620 btm_cb.devcb.loc_auth_req, p_dev_rec->rmt_auth_req);
3621
3622 evt_data.cfm_req.loc_auth_req = btm_cb.devcb.loc_auth_req;
3623 evt_data.cfm_req.rmt_auth_req = p_dev_rec->rmt_auth_req;
3624 evt_data.cfm_req.loc_io_caps = btm_cb.devcb.loc_io_caps;
3625 evt_data.cfm_req.rmt_io_caps = p_dev_rec->rmt_io_caps;
3626 break;
3627
3628 case BTM_SP_KEY_NOTIF_EVT:
3629 /* Passkey notification (other side is a keyboard) */
3630 STREAM_TO_UINT32 (evt_data.key_notif.passkey, p);
3631
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003632 BTM_TRACE_DEBUG ("BTM_SP_KEY_NOTIF_EVT: passkey: %u", evt_data.key_notif.passkey);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003633
3634 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
3635 break;
3636
3637#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
3638 case BTM_SP_KEY_REQ_EVT:
3639 /* HCI_USER_PASSKEY_REQUEST_EVT */
3640 btm_sec_change_pairing_state (BTM_PAIR_STATE_KEY_ENTRY);
3641 break;
3642#endif
3643 }
3644
3645 if (btm_cb.api.p_sp_callback)
3646 {
3647 status = (*btm_cb.api.p_sp_callback) (event, (tBTM_SP_EVT_DATA *)&evt_data);
3648 if (status != BTM_NOT_AUTHORIZED)
3649 {
3650 return;
3651 }
3652 /* else BTM_NOT_AUTHORIZED means when the app wants to reject the req right now */
3653 }
3654 else if ( (event == BTM_SP_CFM_REQ_EVT) && (evt_data.cfm_req.just_works == TRUE) )
3655 {
3656 /* automatically reply with just works if no sp_cback */
3657 status = BTM_SUCCESS;
3658 }
3659
3660 if (event == BTM_SP_CFM_REQ_EVT)
3661 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003662 BTM_TRACE_DEBUG ("calling BTM_ConfirmReqReply with status: %d", status);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003663 BTM_ConfirmReqReply (status, p_bda);
3664 }
3665#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
3666 else if (event == BTM_SP_KEY_REQ_EVT)
3667 {
3668 BTM_PasskeyReqReply(status, p_bda, 0);
3669 }
3670#endif
3671 return;
3672 }
3673
3674 /* Something bad. we can only fail this connection */
3675 btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
3676
3677 if (BTM_SP_CFM_REQ_EVT == event)
3678 {
3679 btsnd_hcic_user_conf_reply (p_bda, FALSE);
3680 }
3681 else if (BTM_SP_KEY_NOTIF_EVT == event)
3682 {
3683 /* do nothing -> it very unlikely to happen.
3684 This event is most likely to be received by a HID host when it first connects to a HID device.
3685 Usually the Host initiated the connection in this case.
3686 On Mobile platforms, if there's a security process happening,
3687 the host probably can not initiate another connection.
3688 BTW (PC) is another story. */
3689 if (NULL != (p_dev_rec = btm_find_dev (p_bda)) )
3690 {
3691 btm_sec_disconnect (p_dev_rec->hci_handle, HCI_ERR_AUTH_FAILURE);
3692 }
3693 }
3694#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
3695 else
3696 {
3697 btsnd_hcic_user_passkey_neg_reply(p_bda);
3698 }
3699#endif
3700}
3701
3702/*******************************************************************************
3703**
3704** Function btm_keypress_notif_evt
3705**
3706** Description This function is called when a key press notification is
3707** received
3708**
3709** Returns void
3710**
3711*******************************************************************************/
3712void btm_keypress_notif_evt (UINT8 *p)
3713{
3714 tBTM_SP_KEYPRESS evt_data;
3715 UINT8 *p_bda;
3716
3717 /* parse & report BTM_SP_KEYPRESS_EVT */
3718 if (btm_cb.api.p_sp_callback)
3719 {
3720 p_bda = evt_data.bd_addr;
3721
3722 STREAM_TO_BDADDR (p_bda, p);
3723 evt_data.notif_type = *p;
3724
3725 (*btm_cb.api.p_sp_callback) (BTM_SP_KEYPRESS_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
3726 }
3727}
3728
3729/*******************************************************************************
3730**
3731** Function btm_simple_pair_complete
3732**
3733** Description This function is called when simple pairing process is
3734** complete
3735**
3736** Returns void
3737**
3738*******************************************************************************/
3739void btm_simple_pair_complete (UINT8 *p)
3740{
3741 tBTM_SP_COMPLT evt_data;
3742 tBTM_SEC_DEV_REC *p_dev_rec;
3743 UINT8 status;
3744 BOOLEAN disc = FALSE;
3745
3746 status = *p++;
3747 STREAM_TO_BDADDR (evt_data.bd_addr, p);
3748
3749 if ((p_dev_rec = btm_find_dev (evt_data.bd_addr)) == NULL)
3750 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003751 BTM_TRACE_ERROR ("btm_simple_pair_complete() with unknown BDA: %08x%04x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003752 (evt_data.bd_addr[0]<<24) + (evt_data.bd_addr[1]<<16) + (evt_data.bd_addr[2]<<8) + evt_data.bd_addr[3],
3753 (evt_data.bd_addr[4] << 8) + evt_data.bd_addr[5]);
3754 return;
3755 }
3756
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003757 BTM_TRACE_EVENT ("btm_simple_pair_complete() Pair State: %s Status:%d sec_state: %u",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003758 btm_pair_state_descr(btm_cb.pairing_state), status, p_dev_rec->sec_state);
3759
3760 evt_data.status = BTM_ERR_PROCESSING;
3761 if (status == HCI_SUCCESS)
3762 {
3763 evt_data.status = BTM_SUCCESS;
3764 p_dev_rec->sec_flags |= BTM_SEC_AUTHENTICATED;
3765 }
3766 else
3767 {
3768 if (status == HCI_ERR_PAIRING_NOT_ALLOWED)
3769 {
3770 /* The test spec wants the peer device to get this failure code. */
3771 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_DISCONNECT);
3772
3773 /* Change the timer to 1 second */
3774 btu_start_timer (&btm_cb.pairing_tle, BTU_TTYPE_USER_FUNC, BT_1SEC_TIMEOUT);
3775 }
3776 else if (memcmp (btm_cb.pairing_bda, evt_data.bd_addr, BD_ADDR_LEN) == 0)
3777 {
3778 /* stop the timer */
3779 btu_stop_timer (&btm_cb.pairing_tle);
3780
3781 if (p_dev_rec->sec_state != BTM_SEC_STATE_AUTHENTICATING)
3782 {
3783 /* the initiating side: will receive auth complete event. disconnect ACL at that time */
3784 disc = TRUE;
3785 }
3786 }
3787 else
3788 disc = TRUE;
3789 }
3790
3791 /* Let the pairing state stay active, p_auth_complete_callback will report the failure */
3792 memcpy (evt_data.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
3793 memcpy (evt_data.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN);
3794
3795 if (btm_cb.api.p_sp_callback)
3796 (*btm_cb.api.p_sp_callback) (BTM_SP_COMPLT_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
3797
3798 if (disc)
3799 {
3800 /* simple pairing failed */
Hemant Guptadb9ad592014-04-18 15:04:43 +05303801 /* Avoid sending disconnect on HCI_ERR_PEER_USER */
3802 if ((status != HCI_ERR_PEER_USER) && (status != HCI_ERR_CONN_CAUSE_LOCAL_HOST))
3803 {
3804 btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle);
3805 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08003806 }
3807}
3808
3809#if BTM_OOB_INCLUDED == TRUE
3810/*******************************************************************************
3811**
3812** Function btm_rem_oob_req
3813**
3814** Description This function is called to process/report
3815** HCI_REMOTE_OOB_DATA_REQUEST_EVT
3816**
3817** Returns void
3818**
3819*******************************************************************************/
3820void btm_rem_oob_req (UINT8 *p)
3821{
3822 UINT8 *p_bda;
3823 tBTM_SP_RMT_OOB evt_data;
3824 tBTM_SEC_DEV_REC *p_dev_rec;
3825 BT_OCTET16 c;
3826 BT_OCTET16 r;
3827
3828 p_bda = evt_data.bd_addr;
3829
3830 STREAM_TO_BDADDR (p_bda, p);
3831
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003832 BTM_TRACE_EVENT ("btm_rem_oob_req() BDA: %02x:%02x:%02x:%02x:%02x:%02x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003833 p_bda[0], p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]);
3834
3835 if ( (NULL != (p_dev_rec = btm_find_dev (p_bda))) &&
3836 btm_cb.api.p_sp_callback)
3837 {
3838 memcpy (evt_data.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
3839 memcpy (evt_data.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN);
3840 BCM_STRNCPY_S((char *)evt_data.bd_name, sizeof(evt_data.bd_name), (char *)p_dev_rec->sec_bd_name, BTM_MAX_REM_BD_NAME_LEN+1);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08003841 evt_data.bd_name[BTM_MAX_REM_BD_NAME_LEN] = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08003842
3843 btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP);
3844 if ((*btm_cb.api.p_sp_callback) (BTM_SP_RMT_OOB_EVT, (tBTM_SP_EVT_DATA *)&evt_data) == BTM_NOT_AUTHORIZED)
3845 {
3846 BTM_RemoteOobDataReply(TRUE, p_bda, c, r);
3847 }
3848 return;
3849 }
3850
3851 /* something bad. we can only fail this connection */
3852 btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
3853 btsnd_hcic_rem_oob_neg_reply (p_bda);
3854}
3855
3856/*******************************************************************************
3857**
3858** Function btm_read_local_oob_complete
3859**
3860** Description This function is called when read local oob data is
3861** completed by the LM
3862**
3863** Returns void
3864**
3865*******************************************************************************/
3866void btm_read_local_oob_complete (UINT8 *p)
3867{
3868 tBTM_SP_LOC_OOB evt_data;
3869 UINT8 status = *p++;
3870
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003871 BTM_TRACE_EVENT ("btm_read_local_oob_complete:%d", status);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003872 if (status == HCI_SUCCESS)
3873 {
3874 evt_data.status = BTM_SUCCESS;
3875 STREAM_TO_ARRAY16(evt_data.c, p);
3876 STREAM_TO_ARRAY16(evt_data.r, p);
3877 }
3878 else
3879 evt_data.status = BTM_ERR_PROCESSING;
3880
3881 if (btm_cb.api.p_sp_callback)
3882 (*btm_cb.api.p_sp_callback) (BTM_SP_LOC_OOB_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
3883}
3884#endif /* BTM_OOB_INCLUDED */
3885
3886/*******************************************************************************
3887**
3888** Function btm_sec_auth_collision
3889**
3890** Description This function is called when authentication or encryption
3891** needs to be retried at a later time.
3892**
3893** Returns void
3894**
3895*******************************************************************************/
3896static void btm_sec_auth_collision (UINT16 handle)
3897{
3898 tBTM_SEC_DEV_REC *p_dev_rec;
3899
3900 if (!btm_cb.collision_start_time)
3901 btm_cb.collision_start_time = GKI_get_tick_count ();
3902
3903 if ((GKI_get_tick_count () - btm_cb.collision_start_time) < btm_cb.max_collision_delay)
3904 {
3905 if (handle == BTM_SEC_INVALID_HANDLE)
3906 {
3907 if ((p_dev_rec = btm_sec_find_dev_by_sec_state (BTM_SEC_STATE_AUTHENTICATING)) == NULL)
3908 p_dev_rec = btm_sec_find_dev_by_sec_state (BTM_SEC_STATE_ENCRYPTING);
3909 }
3910 else
3911 p_dev_rec = btm_find_dev_by_handle (handle);
3912
3913 if (p_dev_rec != NULL)
3914 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003915 BTM_TRACE_DEBUG ("btm_sec_auth_collision: state %d (retrying in a moment...)", p_dev_rec->sec_state);
The Android Open Source Project5738f832012-12-12 16:00:35 -08003916 /* We will restart authentication after timeout */
3917 if (p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING || p_dev_rec->sec_state == BTM_SEC_STATE_ENCRYPTING)
3918 p_dev_rec->sec_state = 0;
3919
3920 btm_cb.p_collided_dev_rec = p_dev_rec;
3921 btm_cb.sec_collision_tle.param = (UINT32) btm_sec_collision_timeout;
3922 btu_start_timer (&btm_cb.sec_collision_tle, BTU_TTYPE_USER_FUNC, BT_1SEC_TIMEOUT);
3923 }
3924 }
3925}
3926
3927/*******************************************************************************
3928**
3929** Function btm_sec_auth_complete
3930**
3931** Description This function is when authentication of the connection is
3932** completed by the LM
3933**
3934** Returns void
3935**
3936*******************************************************************************/
3937void btm_sec_auth_complete (UINT16 handle, UINT8 status)
3938{
3939 UINT8 old_sm4;
3940 tBTM_PAIRING_STATE old_state = btm_cb.pairing_state;
3941 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
3942 BOOLEAN are_bonding = FALSE;
3943
3944 /* Commenting out trace due to obf/compilation problems.
3945 */
3946#if (BT_USE_TRACES == TRUE)
3947 if (p_dev_rec)
3948 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003949 BTM_TRACE_EVENT ("Security Manager: auth_complete PairState: %s handle:%u status:%d dev->sec_state: %u Bda:%08x, RName:%s",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003950 btm_pair_state_descr (btm_cb.pairing_state),
3951 handle, status,
3952 p_dev_rec->sec_state,
3953 (p_dev_rec->bd_addr[2]<<24)+(p_dev_rec->bd_addr[3]<<16)+(p_dev_rec->bd_addr[4]<<8)+p_dev_rec->bd_addr[5],
3954 p_dev_rec->sec_bd_name);
3955 }
3956 else
3957 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07003958 BTM_TRACE_EVENT ("Security Manager: auth_complete PairState: %s handle:%u status:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08003959 btm_pair_state_descr (btm_cb.pairing_state),
3960 handle, status);
3961 }
3962#endif
3963
3964 /* For transaction collision we need to wait and repeat. There is no need */
3965 /* for random timeout because only slave should receive the result */
3966 if ((status == HCI_ERR_LMP_ERR_TRANS_COLLISION) || (status == HCI_ERR_DIFF_TRANSACTION_COLLISION))
3967 {
3968 btm_sec_auth_collision(handle);
3969 return;
3970 }
3971 btm_cb.collision_start_time = 0;
3972
3973 btm_restore_mode();
3974
3975 /* Check if connection was made just to do bonding. If we authenticate
3976 the connection that is up, this is the last event received.
3977 */
3978 if (p_dev_rec
3979 && (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
3980 && !(btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE))
3981 {
3982 p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
3983
3984 l2cu_start_post_bond_timer (p_dev_rec->hci_handle);
3985 }
3986
3987 if (!p_dev_rec)
3988 return;
3989
3990 /* keep the old sm4 flag and clear the retry bit in control block */
3991 old_sm4 = p_dev_rec->sm4;
3992 p_dev_rec->sm4 &= ~BTM_SM4_RETRY;
3993
3994 if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
3995 && (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
3996 && (memcmp (p_dev_rec->bd_addr, btm_cb.pairing_bda, BD_ADDR_LEN) == 0) )
3997 are_bonding = TRUE;
3998
3999 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4000
4001 if (p_dev_rec->sec_state != BTM_SEC_STATE_AUTHENTICATING)
4002 {
4003 if ( (btm_cb.api.p_auth_complete_callback && status != HCI_SUCCESS)
4004 && (old_state != BTM_PAIR_STATE_IDLE) )
4005 {
4006 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
4007 p_dev_rec->dev_class,
4008 p_dev_rec->sec_bd_name, status);
4009 }
4010 return;
4011 }
4012
4013 /* There can be a race condition, when we are starting authentication and
4014 ** the peer device is doing encryption.
4015 ** If first we receive encryption change up, then initiated authentication
4016 ** can not be performed. According to the spec we can not do authentication
4017 ** on the encrypted link, so device is correct.
4018 */
4019 if ((status == HCI_ERR_COMMAND_DISALLOWED)
4020 && ((p_dev_rec->sec_flags & (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED)) ==
4021 (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED)))
4022 {
4023 status = HCI_SUCCESS;
4024 }
4025 /* Currently we do not notify user if it is a keyboard which connects */
4026 /* User probably Disabled the keyboard while it was asleap. Let her try */
4027 if (btm_cb.api.p_auth_complete_callback)
4028 {
4029 /* report the suthentication status */
4030 if (old_state != BTM_PAIR_STATE_IDLE)
4031 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
4032 p_dev_rec->dev_class,
4033 p_dev_rec->sec_bd_name, status);
4034 }
4035
4036 p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
4037
4038 /* If this is a bonding procedure can disconnect the link now */
4039 if (are_bonding)
4040 {
4041 p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
4042
4043 if (status != HCI_SUCCESS)
Hemant Guptadb9ad592014-04-18 15:04:43 +05304044 {
4045 if(((status != HCI_ERR_PEER_USER) && (status != HCI_ERR_CONN_CAUSE_LOCAL_HOST)))
4046 btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_PEER_USER, p_dev_rec->hci_handle);
4047 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08004048 else
4049 l2cu_start_post_bond_timer (p_dev_rec->hci_handle);
4050
4051 return;
4052 }
4053
4054 /* If authentication failed, notify the waiting layer */
4055 if (status != HCI_SUCCESS)
4056 {
4057 if ((old_sm4 & BTM_SM4_RETRY) == 0)
4058 {
4059 /* allow retry only once */
4060 if (status == HCI_ERR_LMP_ERR_TRANS_COLLISION)
4061 {
4062 /* not retried yet. set the retry bit */
4063 p_dev_rec->sm4 |= BTM_SM4_RETRY;
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004064 BTM_TRACE_DEBUG ("Collision retry sm4:x%x sec_flags:0x%x", p_dev_rec->sm4, p_dev_rec->sec_flags);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004065 }
4066 /* this retry for missing key is for Lisbon or later only.
4067 * Legacy device do not need this. the controller will drive the retry automatically */
4068 else if (HCI_ERR_KEY_MISSING == status && BTM_SEC_IS_SM4(p_dev_rec->sm4))
4069 {
4070 /* not retried yet. set the retry bit */
4071 p_dev_rec->sm4 |= BTM_SM4_RETRY;
4072 p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN;
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004073 BTM_TRACE_DEBUG ("Retry for missing key sm4:x%x sec_flags:0x%x", p_dev_rec->sm4, p_dev_rec->sec_flags);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004074
4075 /* With BRCM controller, we do not need to delete the stored link key in controller.
4076 If the stack may sit on top of other controller, we may need this
4077 BTM_DeleteStoredLinkKey (bd_addr, NULL); */
4078 }
4079
4080 if (p_dev_rec->sm4 & BTM_SM4_RETRY)
4081 {
4082 btm_sec_execute_procedure (p_dev_rec);
4083 return;
4084 }
4085 }
4086
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004087 btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004088
4089 if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE)
4090 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004091 btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004092 }
4093 return;
4094 }
4095
4096 p_dev_rec->sec_flags |= BTM_SEC_AUTHENTICATED;
4097
4098 /* Authentication succeeded, execute the next security procedure, if any */
4099 status = btm_sec_execute_procedure (p_dev_rec);
4100
4101 /* If there is no next procedure, or procedure failed to start, notify the caller */
4102 if (status != BTM_CMD_STARTED)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004103 btm_sec_dev_rec_cback_event (p_dev_rec, status, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004104}
4105
4106/*******************************************************************************
4107**
4108** Function btm_sec_mkey_comp_event
4109**
4110** Description This function is when encryption of the connection is
4111** completed by the LM
4112**
4113** Returns void
4114**
4115*******************************************************************************/
4116void btm_sec_mkey_comp_event (UINT16 handle, UINT8 status, UINT8 key_flg)
4117{
4118 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
4119 UINT8 bd_addr[BD_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} ;
4120
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004121 BTM_TRACE_EVENT ("Security Manager: mkey comp status:%d State:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08004122 status, (p_dev_rec) ? p_dev_rec->sec_state : 0);
4123
4124 /* If encryption setup failed, notify the waiting layer */
4125 /* There is no next procedure or start of procedure failed, notify the waiting layer */
4126 if (btm_cb.mkey_cback)
4127 {
4128 if (!p_dev_rec)
4129 (btm_cb.mkey_cback)(bd_addr, status, key_flg );
4130 else
4131 (btm_cb.mkey_cback)(p_dev_rec->bd_addr, status, key_flg );
4132 }
4133}
4134
4135/*******************************************************************************
4136**
4137** Function btm_sec_encrypt_change
4138**
4139** Description This function is when encryption of the connection is
4140** completed by the LM
4141**
4142** Returns void
4143**
4144*******************************************************************************/
4145void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
4146{
4147 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08004148#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004149 tACL_CONN *p_acl = NULL;
4150 UINT8 acl_idx = btm_handle_to_acl_index(handle);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08004151#endif
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004152 BTM_TRACE_EVENT ("Security Manager: encrypt_change status:%d State:%d, encr_enable = %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08004153 status, (p_dev_rec) ? p_dev_rec->sec_state : 0, encr_enable);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004154 BTM_TRACE_DEBUG ("before update p_dev_rec->sec_flags=0x%x", (p_dev_rec) ? p_dev_rec->sec_flags : 0 );
The Android Open Source Project5738f832012-12-12 16:00:35 -08004155
4156 /* For transaction collision we need to wait and repeat. There is no need */
4157 /* for random timeout because only slave should receive the result */
4158 if ((status == HCI_ERR_LMP_ERR_TRANS_COLLISION) || (status == HCI_ERR_DIFF_TRANSACTION_COLLISION))
4159 {
4160 btm_sec_auth_collision(handle);
4161 return;
4162 }
4163 btm_cb.collision_start_time = 0;
4164
4165 if (!p_dev_rec)
4166 return;
4167
4168 if ((status == HCI_SUCCESS) && encr_enable)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004169 {
4170 if (p_dev_rec->hci_handle == handle)
4171 p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED);
4172 else
4173 p_dev_rec->sec_flags |= (BTM_SEC_LE_AUTHENTICATED | BTM_SEC_LE_ENCRYPTED);
4174 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08004175
4176 /* It is possible that we decrypted the link to perform role switch */
4177 /* mark link not to be encrypted, so that when we execute security next time it will kick in again */
4178 if ((status == HCI_SUCCESS) && !encr_enable)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004179 {
4180 if (p_dev_rec->hci_handle == handle)
4181 p_dev_rec->sec_flags &= ~BTM_SEC_ENCRYPTED;
4182 else
4183 p_dev_rec->sec_flags &= ~BTM_SEC_LE_ENCRYPTED;
4184 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08004185
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004186 BTM_TRACE_DEBUG ("after update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags );
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08004187
The Android Open Source Project5738f832012-12-12 16:00:35 -08004188#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004189 if (acl_idx != MAX_L2CAP_LINKS )
4190 p_acl = &btm_cb.acl_db[acl_idx];
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08004191
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004192 if (p_acl && p_acl->transport == BT_TRANSPORT_LE)
The Android Open Source Project5738f832012-12-12 16:00:35 -08004193 {
4194 btm_ble_link_encrypted(p_dev_rec->bd_addr, encr_enable);
4195 return;
4196 }
4197 else
4198 /* BR/EDR connection, update the encryption key size to be 16 as always */
4199 p_dev_rec->enc_key_size = 16;
4200#endif
4201
4202 /* If this encryption was started by peer do not need to do anything */
4203 if (p_dev_rec->sec_state != BTM_SEC_STATE_ENCRYPTING)
4204 {
4205 if (BTM_SEC_STATE_DELAY_FOR_ENC == p_dev_rec->sec_state)
4206 {
4207 p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
4208 p_dev_rec->p_callback = NULL;
4209 l2cu_resubmit_pending_sec_req (p_dev_rec->bd_addr);
4210 }
4211 return;
4212 }
4213
4214 p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
4215
4216 /* If encryption setup failed, notify the waiting layer */
4217 if (status != HCI_SUCCESS)
4218 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004219 btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004220 return;
4221 }
4222
4223 /* Encryption setup succeeded, execute the next security procedure, if any */
4224 status = (UINT8)btm_sec_execute_procedure (p_dev_rec);
4225
4226 /* If there is no next procedure, or procedure failed to start, notify the caller */
4227 if (status != BTM_CMD_STARTED)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004228 btm_sec_dev_rec_cback_event (p_dev_rec, status, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004229}
4230
4231/*******************************************************************************
4232**
4233** Function btm_sec_create_conn
4234**
4235** Description This function records current role and forwards request to
4236** HCI
4237**
4238** Returns void
4239**
4240*******************************************************************************/
4241BOOLEAN btm_sec_create_conn (BD_ADDR bda, UINT16 packet_types,
4242 UINT8 page_scan_rep_mode, UINT8 page_scan_mode,
4243 UINT16 clock_offset, UINT8 allow_switch)
4244{
4245 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bda);
4246
4247 memcpy (btm_cb.connecting_bda, p_dev_rec->bd_addr, BD_ADDR_LEN);
4248 memcpy (btm_cb.connecting_dc, p_dev_rec->dev_class, DEV_CLASS_LEN);
4249
4250 btm_cb.acl_disc_reason = 0xff ;
4251
4252 p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
4253 p_dev_rec->role_master = TRUE;
4254
4255 /* If any SCO link up, do not allow a switch */
4256 if (BTM_GetNumScoLinks() != 0)
4257 allow_switch = HCI_CR_CONN_NOT_ALLOW_SWITCH;
4258
4259 return(btsnd_hcic_create_conn (bda, packet_types, page_scan_rep_mode,
4260 page_scan_mode, clock_offset, allow_switch));
4261}
4262
4263/*******************************************************************************
4264**
4265** Function btm_sec_connect_after_reject_timeout
4266**
4267** Description Connection for bonding could not start because of the collision
4268** Initiate outgoing connection
4269**
4270** Returns Pointer to the TLE struct
4271**
4272*******************************************************************************/
4273static void btm_sec_connect_after_reject_timeout (TIMER_LIST_ENT *p_tle)
4274{
4275 tBTM_SEC_DEV_REC *p_dev_rec = btm_cb.p_collided_dev_rec;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08004276 UNUSED(p_tle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004277
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004278 BTM_TRACE_EVENT ("btm_sec_connect_after_reject_timeout()");
The Android Open Source Project5738f832012-12-12 16:00:35 -08004279 btm_cb.sec_collision_tle.param = 0;
4280 btm_cb.p_collided_dev_rec = 0;
4281
4282 if (btm_sec_dd_create_conn(p_dev_rec) != BTM_CMD_STARTED)
4283 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004284 BTM_TRACE_WARNING ("Security Manager: btm_sec_connect_after_reject_timeout: failed to start connection");
The Android Open Source Project5738f832012-12-12 16:00:35 -08004285
4286 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4287
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004288 if (btm_cb.api.p_auth_complete_callback)
The Android Open Source Project5738f832012-12-12 16:00:35 -08004289 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
4290 p_dev_rec->sec_bd_name, HCI_ERR_MEMORY_FULL);
4291 }
4292}
4293
4294/*******************************************************************************
4295**
4296** Function btm_sec_connected
4297**
4298** Description This function is when a connection to the peer device is
4299** establsihed
4300**
4301** Returns void
4302**
4303*******************************************************************************/
4304void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
4305{
4306 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda);
4307 UINT8 res;
4308 BOOLEAN is_pairing_device = FALSE;
4309 tACL_CONN *p_acl_cb;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004310 UINT8 bit_shift = 0;
The Android Open Source Project5738f832012-12-12 16:00:35 -08004311
4312 btm_acl_resubmit_page();
4313
4314 /* Commenting out trace due to obf/compilation problems.
4315 */
4316#if (BT_USE_TRACES == TRUE)
4317 if (p_dev_rec)
4318 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004319 BTM_TRACE_EVENT ("Security Manager: btm_sec_connected in state: %s handle:%d status:%d enc_mode:%d bda:%x RName:%s",
The Android Open Source Project5738f832012-12-12 16:00:35 -08004320 btm_pair_state_descr(btm_cb.pairing_state), handle, status, enc_mode,
4321 (bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5],
4322 p_dev_rec->sec_bd_name);
4323 }
4324 else
4325 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004326 BTM_TRACE_EVENT ("Security Manager: btm_sec_connected in state: %s handle:%d status:%d enc_mode:%d bda:%x ",
The Android Open Source Project5738f832012-12-12 16:00:35 -08004327 btm_pair_state_descr(btm_cb.pairing_state), handle, status, enc_mode,
4328 (bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5]);
4329 }
4330#endif
4331
4332 if (!p_dev_rec)
4333 {
4334 /* There is no device record for new connection. Allocate one */
4335 if (status == HCI_SUCCESS)
4336 {
4337 p_dev_rec = btm_sec_alloc_dev (bda);
4338 }
4339 else
4340 {
4341 /* can not find the device record and the status is error,
4342 * just ignore it */
4343 return;
4344 }
4345 }
4346 else /* Update the timestamp for this device */
4347 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004348
4349#if BLE_INCLUDED == TRUE
4350 bit_shift = (handle == p_dev_rec->ble_hci_handle) ? 8 :0;
4351#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -08004352 p_dev_rec->timestamp = btm_cb.dev_rec_count++;
4353 if (p_dev_rec->sm4 & BTM_SM4_CONN_PEND)
4354 {
4355 /* tell L2CAP it's a bonding connection. */
4356 if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
4357 && (memcmp (btm_cb.pairing_bda, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0)
4358 && (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) )
4359 {
4360 /* if incoming connection failed while pairing, then try to connect and continue */
4361 /* Motorola S9 disconnects without asking pin code */
4362 if ((status != HCI_SUCCESS)&&(btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_PIN_REQ))
4363 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004364 BTM_TRACE_WARNING ("Security Manager: btm_sec_connected: incoming connection failed without asking PIN");
The Android Open Source Project5738f832012-12-12 16:00:35 -08004365
4366 p_dev_rec->sm4 &= ~BTM_SM4_CONN_PEND;
4367 if (p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN)
4368 {
4369 /* Start timer with 0 to initiate connection with new LCB */
4370 /* because L2CAP will delete current LCB with this event */
4371 btm_cb.p_collided_dev_rec = p_dev_rec;
4372 btm_cb.sec_collision_tle.param = (UINT32) btm_sec_connect_after_reject_timeout;
4373 btu_start_timer (&btm_cb.sec_collision_tle, BTU_TTYPE_USER_FUNC, 0);
4374 }
4375 else
4376 {
4377 btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004378 BTM_ReadRemoteDeviceName(p_dev_rec->bd_addr, NULL, BT_TRANSPORT_BR_EDR);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004379 }
4380#if BTM_DISC_DURING_RS == TRUE
4381 p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
4382#endif
4383 return;
4384 }
4385 else
4386 {
4387 l2cu_update_lcb_4_bonding(p_dev_rec->bd_addr, TRUE);
4388 }
4389 }
4390 /* always clear the pending flag */
4391 p_dev_rec->sm4 &= ~BTM_SM4_CONN_PEND;
4392 }
4393 }
4394
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004395#if BLE_INCLUDED == TRUE
4396 p_dev_rec->device_type |= BT_DEVICE_TYPE_BREDR;
4397#endif
4398
The Android Open Source Project5738f832012-12-12 16:00:35 -08004399#if BTM_DISC_DURING_RS == TRUE
4400 p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
4401#endif
4402
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08004403 p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
4404
The Android Open Source Project5738f832012-12-12 16:00:35 -08004405 if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
4406 && (memcmp (btm_cb.pairing_bda, bda, BD_ADDR_LEN) == 0) )
4407 {
4408 /* if we rejected incoming connection from bonding device */
4409 if ((status == HCI_ERR_HOST_REJECT_DEVICE)
4410 &&(btm_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT))
4411 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004412 BTM_TRACE_WARNING ("Security Manager: btm_sec_connected: HCI_Conn_Comp Flags:0x%04x, sm4: 0x%x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08004413 btm_cb.pairing_flags, p_dev_rec->sm4);
4414
4415 btm_cb.pairing_flags &= ~BTM_PAIR_FLAGS_REJECTED_CONNECT;
4416 if (BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4))
4417 {
4418 /* Try again: RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */
4419 btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004420 BTM_ReadRemoteDeviceName(bda, NULL, BT_TRANSPORT_BR_EDR);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004421 return;
4422 }
4423
4424 /* if we already have pin code */
4425 if (btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_LOCAL_PIN)
4426 {
4427 /* Start timer with 0 to initiate connection with new LCB */
4428 /* because L2CAP will delete current LCB with this event */
4429 btm_cb.p_collided_dev_rec = p_dev_rec;
4430 btm_cb.sec_collision_tle.param = (UINT32) btm_sec_connect_after_reject_timeout;
4431 btu_start_timer (&btm_cb.sec_collision_tle, BTU_TTYPE_USER_FUNC, 0);
4432 }
4433
4434 return;
4435 }
4436 /* wait for incoming connection without resetting pairing state */
4437 else if (status == HCI_ERR_CONNECTION_EXISTS)
4438 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004439 BTM_TRACE_WARNING ("Security Manager: btm_sec_connected: Wait for incoming connection");
The Android Open Source Project5738f832012-12-12 16:00:35 -08004440 return;
4441 }
4442
4443 is_pairing_device = TRUE;
4444 }
4445
4446 /* If connection was made to do bonding restore link security if changed */
4447 btm_restore_mode();
4448
4449 /* if connection fails during pin request, notify application */
4450 if (status != HCI_SUCCESS)
4451 {
4452 /* If connection failed because of during pairing, need to tell user */
4453 if (is_pairing_device)
4454 {
4455 p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004456 p_dev_rec->sec_flags &= ~((BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED) << bit_shift);
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004457 BTM_TRACE_DEBUG ("security_required:%x ", p_dev_rec->security_required );
The Android Open Source Project5738f832012-12-12 16:00:35 -08004458
4459 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4460
4461 /* We need to notify host that the key is not known any more */
4462 if (btm_cb.api.p_auth_complete_callback)
4463 {
4464 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
4465 p_dev_rec->dev_class,
4466 p_dev_rec->sec_bd_name, status);
4467 }
4468 }
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004469 /*
4470 Do not send authentication failure, if following conditions hold good
4471 1. BTM Sec Pairing state is idle
4472 2. Link key for the remote device is present.
4473 3. Remote is SSP capable.
4474 */
4475 else if ((p_dev_rec->link_key_type <= BTM_LKEY_TYPE_REMOTE_UNIT) &&
4476 (((status == HCI_ERR_AUTH_FAILURE) ||
The Android Open Source Project5738f832012-12-12 16:00:35 -08004477 (status == HCI_ERR_KEY_MISSING) ||
4478 (status == HCI_ERR_HOST_REJECT_SECURITY) ||
4479 (status == HCI_ERR_PAIRING_NOT_ALLOWED) ||
4480 (status == HCI_ERR_UNIT_KEY_USED) ||
4481 (status == HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED) ||
4482 (status == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE) ||
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004483 (status == HCI_ERR_REPEATED_ATTEMPTS))))
The Android Open Source Project5738f832012-12-12 16:00:35 -08004484 {
4485 p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004486 p_dev_rec->sec_flags &= ~ (BTM_SEC_LE_LINK_KEY_KNOWN << bit_shift);
4487
4488
4489#ifdef BRCM_NOT_4_BTE
4490 /* If we rejected pairing, pass this special result code */
4491 if (btm_cb.acl_disc_reason == HCI_ERR_HOST_REJECT_SECURITY)
4492 {
4493 status = HCI_ERR_HOST_REJECT_SECURITY;
4494 }
4495#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -08004496
4497 /* We need to notify host that the key is not known any more */
4498 if (btm_cb.api.p_auth_complete_callback)
4499 {
4500 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
4501 p_dev_rec->dev_class,
4502 p_dev_rec->sec_bd_name, status);
4503 }
4504 }
4505
4506 if (status == HCI_ERR_CONNECTION_TOUT || status == HCI_ERR_LMP_RESPONSE_TIMEOUT ||
4507 status == HCI_ERR_UNSPECIFIED || status == HCI_ERR_PAGE_TIMEOUT)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004508 btm_sec_dev_rec_cback_event (p_dev_rec, BTM_DEVICE_TIMEOUT, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004509 else
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004510 btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004511
4512 return;
4513 }
4514
4515 /* If initiated dedicated bonding, return the link key now, and initiate disconnect */
4516 /* If dedicated bonding, and we now have a link key, we are all done */
4517 if ( is_pairing_device
4518 && (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) )
4519 {
4520 if (p_dev_rec->link_key_not_sent)
4521 {
4522 p_dev_rec->link_key_not_sent = FALSE;
4523 btm_send_link_key_notif(p_dev_rec);
4524 }
4525
4526 p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
4527
4528 /* remember flag before it is initialized */
4529 if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
4530 res = TRUE;
4531 else
4532 res = FALSE;
4533
4534 if (btm_cb.api.p_auth_complete_callback)
4535 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
4536 p_dev_rec->dev_class,
4537 p_dev_rec->sec_bd_name, HCI_SUCCESS);
4538
4539 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4540
4541 if ( res )
4542 {
4543 /* Let l2cap start bond timer */
4544 l2cu_update_lcb_4_bonding (p_dev_rec->bd_addr, TRUE);
4545 }
4546
4547 return;
4548 }
4549
4550 p_dev_rec->hci_handle = handle;
4551
4552 /* role may not be correct here, it will be updated by l2cap, but we need to */
4553 /* notify btm_acl that link is up, so starting of rmt name request will not */
4554 /* set paging flag up */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004555 p_acl_cb = btm_bda_to_acl(bda, BT_TRANSPORT_BR_EDR);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004556 if (p_acl_cb)
4557 {
4558 /* whatever is in btm_establish_continue() without reporting the BTM_BL_CONN_EVT event */
4559#if (!defined(BTM_BYPASS_EXTRA_ACL_SETUP) || BTM_BYPASS_EXTRA_ACL_SETUP == FALSE)
4560 /* For now there are a some devices that do not like sending */
4561 /* commands events and data at the same time. */
4562 /* Set the packet types to the default allowed by the device */
4563 btm_set_packet_types (p_acl_cb, btm_cb.btm_acl_pkt_types_supported);
4564
4565 if (btm_cb.btm_def_link_policy)
4566 BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy);
4567#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -08004568 }
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004569 btm_acl_created (bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, handle, HCI_ROLE_SLAVE, BT_TRANSPORT_BR_EDR);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004570
4571 /* Initialize security flags. We need to do that because some */
4572 /* authorization complete could have come after the connection is dropped */
4573 /* and that would set wrong flag that link has been authorized already */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004574 p_dev_rec->sec_flags &= ~((BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED |
4575 BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED) << bit_shift);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004576
4577 if (enc_mode != HCI_ENCRYPT_MODE_DISABLED)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004578 p_dev_rec->sec_flags |= ((BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED) << bit_shift);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004579
4580 if (btm_cb.security_mode == BTM_SEC_MODE_LINK)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004581 p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED << bit_shift);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004582
4583 p_dev_rec->link_key_changed = FALSE;
4584
4585 /* After connection is established we perform security if we do not know */
4586 /* the name, or if we are originator because some procedure can have */
4587 /* been scheduled while connection was down */
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004588 BTM_TRACE_DEBUG ("is_originator:%d ", p_dev_rec->is_originator);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004589 if (!(p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN) || p_dev_rec->is_originator)
4590 {
4591 if ((res = btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004592 btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004593 }
4594 return;
4595}
4596
4597/*******************************************************************************
4598**
4599** Function btm_sec_role_changed
4600**
4601** Description This function is colled when controller reports role
4602** changed, or failed command status for Role Change request
4603**
4604** Returns void
4605**
4606*******************************************************************************/
4607void btm_sec_role_changed (void *p_ref_data)
4608{
4609 tBTM_SEC_DEV_REC *p_dev_rec = (tBTM_SEC_DEV_REC *)p_ref_data;
4610 UINT8 res;
4611
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004612 BTM_TRACE_EVENT ("Security Manager: role changed");
The Android Open Source Project5738f832012-12-12 16:00:35 -08004613
4614 /* If this role switch was started by peer do not need to do anything */
4615 if (p_dev_rec->sec_state != BTM_SEC_STATE_SWITCHING_ROLE)
4616 return;
4617
4618 /* If serurity required was to FORCE switch and it failed, notify the waiting layer */
4619 if (((p_dev_rec->security_required & BTM_SEC_FORCE_MASTER) && !p_dev_rec->role_master)
4620 || ((p_dev_rec->security_required & BTM_SEC_FORCE_SLAVE) && p_dev_rec->role_master))
4621 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004622 btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004623 return;
4624 }
4625
4626 p_dev_rec->sec_flags |= BTM_SEC_ROLE_SWITCHED;
4627
4628 p_dev_rec->security_required &= ~(BTM_SEC_FORCE_MASTER | BTM_SEC_ATTEMPT_MASTER |
4629 BTM_SEC_FORCE_SLAVE | BTM_SEC_ATTEMPT_SLAVE);
4630
4631 p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
4632
4633 if ((res = (UINT8)btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
4634 {
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004635 btm_sec_dev_rec_cback_event (p_dev_rec, res, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004636 }
4637}
4638
4639/*******************************************************************************
4640**
4641** Function btm_sec_disconnect
4642**
4643** Description This function is called to disconnect HCI link
4644**
4645** Returns btm status
4646**
4647*******************************************************************************/
4648tBTM_STATUS btm_sec_disconnect (UINT16 handle, UINT8 reason)
4649{
4650 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
4651
4652 /* In some weird race condition we may not have a record */
4653 if (!p_dev_rec)
4654 {
4655 btsnd_hcic_disconnect (handle, reason);
4656 return(BTM_SUCCESS);
4657 }
4658
4659 /* If we are in the process of bonding we need to tell client that auth failed */
4660 if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
4661 && (memcmp (btm_cb.pairing_bda, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0)
4662 && (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) )
4663 {
4664 /* we are currently doing bonding. Link will be disconnected when done */
4665 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_DISC_WHEN_DONE;
4666 return(BTM_BUSY);
4667 }
4668
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004669 return(btm_sec_send_hci_disconnect(p_dev_rec, reason, handle));
The Android Open Source Project5738f832012-12-12 16:00:35 -08004670}
4671
4672/*******************************************************************************
4673**
4674** Function btm_sec_disconnected
4675**
4676** Description This function is when a connection to the peer device is
4677** dropped
4678**
4679** Returns void
4680**
4681*******************************************************************************/
4682void btm_sec_disconnected (UINT16 handle, UINT8 reason)
4683{
4684 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
4685 UINT8 old_pairing_flags = btm_cb.pairing_flags;
4686 int result = HCI_ERR_AUTH_FAILURE;
Andre Eisenbachca22ac42013-02-13 17:02:11 +09004687 tBTM_SEC_CALLBACK *p_callback = NULL;
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004688 tBT_TRANSPORT transport = BT_TRANSPORT_BR_EDR;
The Android Open Source Project5738f832012-12-12 16:00:35 -08004689
4690 /* If page was delayed for disc complete, can do it now */
4691 btm_cb.discing = FALSE;
4692
4693 btm_acl_resubmit_page();
4694
4695 if (!p_dev_rec)
4696 return;
4697
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004698 transport = (handle == p_dev_rec->hci_handle) ? BT_TRANSPORT_BR_EDR: BT_TRANSPORT_LE;
4699
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08004700 p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
4701
The Android Open Source Project5738f832012-12-12 16:00:35 -08004702#if BTM_DISC_DURING_RS == TRUE
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004703 BTM_TRACE_ERROR("btm_sec_disconnected - Clearing Pending flag");
The Android Open Source Project5738f832012-12-12 16:00:35 -08004704 p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING; /* reset flag */
4705#endif
4706
4707 /* clear unused flags */
4708 p_dev_rec->sm4 &= BTM_SM4_TRUE;
4709
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004710 BTM_TRACE_EVENT("btm_sec_disconnected() sec_req:x%x State: %s reason:%d bda:%04x%08x RName:%s",
The Android Open Source Project5738f832012-12-12 16:00:35 -08004711 p_dev_rec->security_required, btm_pair_state_descr(btm_cb.pairing_state), reason, (p_dev_rec->bd_addr[0]<<8)+p_dev_rec->bd_addr[1],
4712 (p_dev_rec->bd_addr[2]<<24)+(p_dev_rec->bd_addr[3]<<16)+(p_dev_rec->bd_addr[4]<<8)+p_dev_rec->bd_addr[5], p_dev_rec->sec_bd_name);
4713
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004714 BTM_TRACE_EVENT("before Update sec_flags=0x%x", p_dev_rec->sec_flags);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004715
4716 /* If we are in the process of bonding we need to tell client that auth failed */
4717 if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
4718 && (memcmp (btm_cb.pairing_bda, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0))
4719 {
4720 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4721 p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN;
4722 if (btm_cb.api.p_auth_complete_callback)
4723 {
4724 /* If the disconnection reason is REPEATED_ATTEMPTS,
4725 send this error message to complete callback function
4726 to display the error message of Repeated attempts.
4727 All others, send HCI_ERR_AUTH_FAILURE. */
4728 if (reason == HCI_ERR_REPEATED_ATTEMPTS)
4729 {
4730 result = HCI_ERR_REPEATED_ATTEMPTS;
4731 }
4732 else if (old_pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
4733 {
4734 result = HCI_ERR_HOST_REJECT_SECURITY;
4735 }
4736 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
4737 p_dev_rec->sec_bd_name, result);
4738 }
4739 }
4740
The Android Open Source Project5738f832012-12-12 16:00:35 -08004741#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
4742 p_dev_rec->enc_key_size = 0;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08004743 btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, p_dev_rec->bd_addr, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004744 /* see sec_flags processing in btm_acl_removed */
The Android Open Source Project5738f832012-12-12 16:00:35 -08004745
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004746 if (transport == BT_TRANSPORT_LE)
4747 {
4748 p_dev_rec->ble_hci_handle = BTM_SEC_INVALID_HANDLE;
4749 p_dev_rec->sec_flags &= ~(BTM_SEC_LE_AUTHENTICATED|BTM_SEC_LE_ENCRYPTED);
4750 }
4751 else
4752#endif
4753 {
4754 p_dev_rec->hci_handle = BTM_SEC_INVALID_HANDLE;
4755 p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
4756 }
4757
4758 p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
The Android Open Source Project5738f832012-12-12 16:00:35 -08004759 p_dev_rec->security_required = BTM_SEC_NONE;
Andre Eisenbachca22ac42013-02-13 17:02:11 +09004760
4761 p_callback = p_dev_rec->p_callback;
4762
4763 /* if security is pending, send callback to clean up the security state */
4764 if(p_callback)
4765 {
4766 p_dev_rec->p_callback = NULL; /* when the peer device time out the authentication before
4767 we do, this call back must be reset here */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07004768 (*p_callback) (p_dev_rec->bd_addr, transport, p_dev_rec->p_ref_data, BTM_ERR_PROCESSING);
Andre Eisenbachca22ac42013-02-13 17:02:11 +09004769 }
4770
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004771 BTM_TRACE_EVENT("after Update sec_flags=0x%x", p_dev_rec->sec_flags);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004772}
4773
4774/*******************************************************************************
4775**
4776** Function btm_sec_link_key_notification
4777**
4778** Description This function is called when a new connection link key is
4779** generated
4780**
4781** Returns Pointer to the record or NULL
4782**
4783*******************************************************************************/
4784void btm_sec_link_key_notification (UINT8 *p_bda, UINT8 *p_link_key, UINT8 key_type)
4785{
4786 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_bda);
4787 BOOLEAN we_are_bonding = FALSE;
4788
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004789 BTM_TRACE_EVENT ("btm_sec_link_key_notification() BDA:%04x%08x, TYPE: %d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08004790 (p_bda[0]<<8)+p_bda[1], (p_bda[2]<<24)+(p_bda[3]<<16)+(p_bda[4]<<8)+p_bda[5],
4791 key_type);
4792
4793 /* If connection was made to do bonding restore link security if changed */
4794 btm_restore_mode();
4795
4796 /* Override the key type if version is pre-1.1 */
4797 if (btm_cb.devcb.local_version.hci_version < HCI_VERSION_1_1)
4798 p_dev_rec->link_key_type = BTM_LKEY_TYPE_IGNORE;
4799 if (key_type != BTM_LKEY_TYPE_CHANGED_COMB)
4800 p_dev_rec->link_key_type = key_type;
4801
4802 p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08004803#if (BLE_INCLUDED == TRUE)
4804 /* BR/EDR connection, update the encryption key size to be 16 as always */
4805 p_dev_rec->enc_key_size = 16;
4806#endif
The Android Open Source Project5738f832012-12-12 16:00:35 -08004807 memcpy (p_dev_rec->link_key, p_link_key, LINK_KEY_LEN);
4808
4809 if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
4810 && (memcmp (btm_cb.pairing_bda, p_bda, BD_ADDR_LEN) == 0) )
4811 {
4812 if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
4813 we_are_bonding = TRUE;
4814 else
4815 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4816 }
4817
4818 /* If name is not known at this point delay calling callback until the name is */
4819 /* resolved. Unless it is a HID Device and we really need to send all link keys. */
4820 if ((!(p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN)
4821 && ((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) != BTM_COD_MAJOR_PERIPHERAL)) )
4822 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004823 BTM_TRACE_EVENT ("btm_sec_link_key_notification() Delayed BDA: %08x%04x Type:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08004824 (p_bda[0]<<24) + (p_bda[1]<<16) + (p_bda[2]<<8) + p_bda[3], (p_bda[4] << 8) + p_bda[5], key_type);
4825
4826 p_dev_rec->link_key_not_sent = TRUE;
4827
4828 /* If it is for bonding nothing else will follow, so we need to start name resolution */
4829 if (we_are_bonding)
4830 {
4831 if (!(btsnd_hcic_rmt_name_req (p_bda, HCI_PAGE_SCAN_REP_MODE_R1, HCI_MANDATARY_PAGE_SCAN_MODE, 0)))
4832 btm_inq_rmt_name_failed();
4833 }
4834
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004835 BTM_TRACE_EVENT ("rmt_io_caps:%d, sec_flags:x%x, dev_class[1]:x%02x", p_dev_rec->rmt_io_caps, p_dev_rec->sec_flags, p_dev_rec->dev_class[1])
The Android Open Source Project5738f832012-12-12 16:00:35 -08004836 return;
4837 }
4838
4839 /* If its not us who perform authentication, we should tell stackserver */
4840 /* that some authentication has been completed */
4841 /* This is required when different entities receive link notification and auth complete */
4842 if (!(p_dev_rec->security_required & BTM_SEC_OUT_AUTHENTICATE))
4843 {
4844 if (btm_cb.api.p_auth_complete_callback)
4845 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
4846 p_dev_rec->sec_bd_name, HCI_SUCCESS);
4847 }
4848
4849 /* We will save link key only if the user authorized it - BTE report link key in all cases */
4850#ifdef BRCM_NONE_BTE
4851 if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED)
4852#endif
4853 {
4854 if (btm_cb.api.p_link_key_callback)
4855 {
4856 (*btm_cb.api.p_link_key_callback) (p_bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name,
4857 p_link_key, p_dev_rec->link_key_type);
4858 }
4859 }
4860}
4861
4862/*******************************************************************************
4863**
4864** Function btm_sec_link_key_request
4865**
4866** Description This function is called when controller requests link key
4867**
4868** Returns Pointer to the record or NULL
4869**
4870*******************************************************************************/
4871void btm_sec_link_key_request (UINT8 *p_bda)
4872{
4873 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_bda);
4874
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004875 BTM_TRACE_EVENT ("btm_sec_link_key_request() BDA: %02x:%02x:%02x:%02x:%02x:%02x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08004876 p_bda[0], p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]);
4877
Hemant Guptab81d7292014-03-17 15:07:01 +05304878 if( (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_PIN_REQ) &&
4879 (btm_cb.collision_start_time != 0) &&
4880 (memcmp (btm_cb.p_collided_dev_rec->bd_addr, p_bda, BD_ADDR_LEN) == 0) )
4881 {
4882 BTM_TRACE_EVENT ("btm_sec_link_key_request() rejecting link key req "
4883 "State: %d START_TIMEOUT : %d",
4884 btm_cb.pairing_state, btm_cb.collision_start_time);
4885 btsnd_hcic_link_key_neg_reply (p_bda);
4886 return;
4887 }
The Android Open Source Project5738f832012-12-12 16:00:35 -08004888 if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)
4889 {
4890 btsnd_hcic_link_key_req_reply (p_bda, p_dev_rec->link_key);
4891 return;
4892 }
4893
4894 /* Notify L2CAP to increase timeout */
4895 l2c_pin_code_request (p_bda);
4896
4897 /* Only ask the host for a key if this guy is not already bonding */
4898 if ( (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE)
4899 || (memcmp (p_bda, btm_cb.pairing_bda, BD_ADDR_LEN) != 0) )
4900 {
4901 if (btm_cb.api.p_link_key_req_callback)
4902 {
4903 if ((*btm_cb.api.p_link_key_req_callback)(p_bda, p_dev_rec->link_key) == BTM_SUCCESS)
4904 {
4905 btsnd_hcic_link_key_req_reply (p_bda, p_dev_rec->link_key);
4906 return;
4907 }
4908 }
4909 }
4910
4911 /* The link key is not in the database and it is not known to the manager */
4912 btsnd_hcic_link_key_neg_reply (p_bda);
4913}
4914
4915/*******************************************************************************
4916**
4917** Function btm_sec_pairing_timeout
4918**
4919** Description This function is called when host does not provide PIN
4920** within requested time
4921**
4922** Returns Pointer to the TLE struct
4923**
4924*******************************************************************************/
4925static void btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle)
4926{
4927 tBTM_CB *p_cb = &btm_cb;
4928 tBTM_SEC_DEV_REC *p_dev_rec;
4929#if BTM_OOB_INCLUDED == TRUE
4930#if (BTM_LOCAL_IO_CAPS == BTM_IO_CAP_NONE)
4931 tBTM_AUTH_REQ auth_req = BTM_AUTH_AP_NO;
4932#else
4933 tBTM_AUTH_REQ auth_req = BTM_AUTH_AP_YES;
4934#endif
4935#endif
4936 UINT8 name[2];
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08004937 UNUSED(p_tle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08004938
4939 p_cb->pairing_tle.param = 0;
4940/* Coverity: FALSE-POSITIVE error from Coverity tool. Please do NOT remove following comment. */
4941/* coverity[UNUSED_VALUE] pointer p_dev_rec is actually used several times... This is a Coverity false-positive, i.e. a fake issue.
4942*/
4943 p_dev_rec = btm_find_dev (p_cb->pairing_bda);
4944
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07004945 BTM_TRACE_EVENT ("btm_sec_pairing_timeout() State: %s Flags: %u",
The Android Open Source Project5738f832012-12-12 16:00:35 -08004946 btm_pair_state_descr(p_cb->pairing_state), p_cb->pairing_flags);
4947
4948 switch (p_cb->pairing_state)
4949 {
4950 case BTM_PAIR_STATE_WAIT_PIN_REQ:
4951 btm_sec_bond_cancel_complete();
4952 break;
4953
4954 case BTM_PAIR_STATE_WAIT_LOCAL_PIN:
4955 if ( (btm_cb.pairing_flags & BTM_PAIR_FLAGS_PRE_FETCH_PIN) == 0)
4956 btsnd_hcic_pin_code_neg_reply (p_cb->pairing_bda);
4957 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4958 /* We need to notify the UI that no longer need the PIN */
4959 if (btm_cb.api.p_auth_complete_callback)
4960 {
4961 if (p_dev_rec == NULL)
4962 {
4963 name[0] = 0;
4964 (*btm_cb.api.p_auth_complete_callback) (p_cb->pairing_bda,
4965 NULL,
4966 name, HCI_ERR_CONNECTION_TOUT);
4967 }
4968 else
4969 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
4970 p_dev_rec->dev_class,
4971 p_dev_rec->sec_bd_name, HCI_ERR_CONNECTION_TOUT);
4972 }
4973 break;
4974
4975 case BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM:
4976 btsnd_hcic_user_conf_reply (p_cb->pairing_bda, FALSE);
4977 /* btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); */
4978 break;
4979
4980#if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
4981 case BTM_PAIR_STATE_KEY_ENTRY:
4982 btsnd_hcic_user_passkey_neg_reply(p_cb->pairing_bda);
4983 /* btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); */
4984 break;
4985#endif /* !BTM_IO_CAP_NONE */
4986
4987#if BTM_OOB_INCLUDED == TRUE
4988 case BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS:
4989 if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
4990 auth_req |= BTM_AUTH_DD_BOND;
4991
4992 btsnd_hcic_io_cap_req_reply (p_cb->pairing_bda, btm_cb.devcb.loc_io_caps,
4993 BTM_OOB_NONE, auth_req);
4994 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4995 break;
4996
4997 case BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP:
4998 btsnd_hcic_rem_oob_neg_reply (p_cb->pairing_bda);
4999 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
5000 break;
5001#endif /* BTM_OOB_INCLUDED */
5002
5003 case BTM_PAIR_STATE_WAIT_DISCONNECT:
5004 /* simple pairing failed. Started a 1-sec timer at simple pairing complete.
5005 * now it's time to tear down the ACL link*/
5006 if (p_dev_rec == NULL)
5007 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005008 BTM_TRACE_ERROR ("btm_sec_pairing_timeout() BTM_PAIR_STATE_WAIT_DISCONNECT unknown BDA: %08x%04x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08005009 (p_cb->pairing_bda[0]<<24) + (p_cb->pairing_bda[1]<<16) + (p_cb->pairing_bda[2]<<8) + p_cb->pairing_bda[3],
5010 (p_cb->pairing_bda[4] << 8) + p_cb->pairing_bda[5]);
5011 break;
5012 }
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07005013 btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE, p_dev_rec->hci_handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08005014 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
5015 break;
5016
5017 case BTM_PAIR_STATE_WAIT_AUTH_COMPLETE:
5018 /* We need to notify the UI that timeout has happened while waiting for authentication*/
5019 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
5020 if (btm_cb.api.p_auth_complete_callback)
5021 {
5022 if (p_dev_rec == NULL)
5023 {
5024 name[0] = 0;
5025 (*btm_cb.api.p_auth_complete_callback) (p_cb->pairing_bda,
5026 NULL,
5027 name, HCI_ERR_CONNECTION_TOUT);
5028 }
5029 else
5030 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
5031 p_dev_rec->dev_class,
5032 p_dev_rec->sec_bd_name, HCI_ERR_CONNECTION_TOUT);
5033 }
5034 break;
5035
5036 default:
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005037 BTM_TRACE_WARNING ("btm_sec_pairing_timeout() not processed state: %s", btm_pair_state_descr(btm_cb.pairing_state));
The Android Open Source Project5738f832012-12-12 16:00:35 -08005038 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
5039 break;
5040 }
5041}
5042
5043/*******************************************************************************
5044**
5045** Function btm_sec_pin_code_request
5046**
5047** Description This function is called when controller requests PIN code
5048**
5049** Returns Pointer to the record or NULL
5050**
5051*******************************************************************************/
5052void btm_sec_pin_code_request (UINT8 *p_bda)
5053{
5054 tBTM_SEC_DEV_REC *p_dev_rec;
5055 tBTM_CB *p_cb = &btm_cb;
5056
Shobek Sam Attupurath57bda502013-04-17 16:08:17 +05305057#ifdef PORCHE_PAIRING_CONFLICT
5058 UINT8 default_pin_code_len = 4;
5059 PIN_CODE default_pin_code = {0x30, 0x30, 0x30, 0x30};
5060#endif
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005061 BTM_TRACE_EVENT ("btm_sec_pin_code_request() State: %s, BDA:%04x%08x",
The Android Open Source Project5738f832012-12-12 16:00:35 -08005062 btm_pair_state_descr(btm_cb.pairing_state),
5063 (p_bda[0]<<8)+p_bda[1], (p_bda[2]<<24)+(p_bda[3]<<16)+(p_bda[4]<<8)+p_bda[5] );
5064
5065 if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
5066 {
5067 if ( (memcmp (p_bda, btm_cb.pairing_bda, BD_ADDR_LEN) == 0) &&
5068 (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_AUTH_COMPLETE) )
5069 {
5070 /* fake this out - porshe carkit issue - */
5071// btm_cb.pairing_state = BTM_PAIR_STATE_IDLE;
5072 if(! btm_cb.pin_code_len_saved)
5073 {
5074 btsnd_hcic_pin_code_neg_reply (p_bda);
5075 return;
5076 }
5077 else
5078 {
5079 btsnd_hcic_pin_code_req_reply (p_bda, btm_cb.pin_code_len_saved, p_cb->pin_code);
5080 return;
5081 }
5082 }
5083 else if ((btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_PIN_REQ)
5084 || memcmp (p_bda, btm_cb.pairing_bda, BD_ADDR_LEN) != 0)
5085 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005086 BTM_TRACE_WARNING ("btm_sec_pin_code_request() rejected - state: %s",
The Android Open Source Project5738f832012-12-12 16:00:35 -08005087 btm_pair_state_descr(btm_cb.pairing_state));
5088
5089#ifdef PORCHE_PAIRING_CONFLICT
5090 /* reply pin code again due to counter in_rand when local initiates pairing */
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005091 BTM_TRACE_EVENT ("btm_sec_pin_code_request from remote dev. for local initiated pairing");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005092 if(! btm_cb.pin_code_len_saved)
5093 {
Shobek Sam Attupurath57bda502013-04-17 16:08:17 +05305094 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
5095 btsnd_hcic_pin_code_req_reply (p_bda, default_pin_code_len, default_pin_code);
The Android Open Source Project5738f832012-12-12 16:00:35 -08005096 }
5097 else
5098 {
5099 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
5100 btsnd_hcic_pin_code_req_reply (p_bda, btm_cb.pin_code_len_saved, p_cb->pin_code);
5101 }
5102#else
5103 btsnd_hcic_pin_code_neg_reply (p_bda);
5104#endif
5105 return;
5106 }
5107 }
5108
5109 p_dev_rec = btm_find_or_alloc_dev (p_bda);
5110 /* received PIN code request. must be non-sm4 */
5111 p_dev_rec->sm4 = BTM_SM4_KNOWN;
5112
5113 if (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE)
5114 {
5115 memcpy (btm_cb.pairing_bda, p_bda, BD_ADDR_LEN);
5116
5117 btm_cb.pairing_flags = BTM_PAIR_FLAGS_PEER_STARTED_DD;
5118 /* Make sure we reset the trusted mask to help against attacks */
5119 BTM_SEC_CLR_TRUSTED_DEVICE(p_dev_rec->trusted_mask);
5120 }
5121
5122 if (!p_cb->pairing_disabled && (p_cb->cfg.pin_type == HCI_PIN_TYPE_FIXED))
5123 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005124 BTM_TRACE_EVENT ("btm_sec_pin_code_request fixed pin replying");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005125 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
5126 btsnd_hcic_pin_code_req_reply (p_bda, p_cb->cfg.pin_code_len, p_cb->cfg.pin_code);
5127 return;
5128 }
5129
5130 /* Use the connecting device's CoD for the connection */
5131 if ( (!memcmp (p_bda, p_cb->connecting_bda, BD_ADDR_LEN))
5132 && (p_cb->connecting_dc[0] || p_cb->connecting_dc[1] || p_cb->connecting_dc[2]) )
5133 memcpy (p_dev_rec->dev_class, p_cb->connecting_dc, DEV_CLASS_LEN);
5134
5135 /* We could have started connection after asking user for the PIN code */
5136 if (btm_cb.pin_code_len != 0)
5137 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005138 BTM_TRACE_EVENT ("btm_sec_pin_code_request bonding sending reply");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005139 btsnd_hcic_pin_code_req_reply (p_bda, btm_cb.pin_code_len, p_cb->pin_code);
5140
5141#ifdef PORCHE_PAIRING_CONFLICT
5142 btm_cb.pin_code_len_saved = btm_cb.pin_code_len;
5143#endif
5144
5145 /* Mark that we forwarded received from the user PIN code */
5146 btm_cb.pin_code_len = 0;
5147
5148 /* We can change mode back right away, that other connection being established */
5149 /* is not forced to be secure - found a FW issue, so we can not do this
5150 btm_restore_mode(); */
5151
5152 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
5153 }
5154
5155 /* If pairing disabled OR (no PIN callback and not bonding) */
5156 /* OR we could not allocate entry in the database reject pairing request */
5157 else if (p_cb->pairing_disabled
5158 || (p_cb->api.p_pin_callback == NULL)
5159
5160 /* OR Microsoft keyboard can for some reason try to establish connection */
5161 /* the only thing we can do here is to shut it up. Normally we will be originator */
5162 /* for keyboard bonding */
5163 || (!p_dev_rec->is_originator
5164 && ((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) == BTM_COD_MAJOR_PERIPHERAL)
5165 && (p_dev_rec->dev_class[2] & BTM_COD_MINOR_KEYBOARD)) )
5166 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005167 BTM_TRACE_WARNING("btm_sec_pin_code_request(): Pairing disabled:%d; PIN callback:%x, Dev Rec:%x!",
The Android Open Source Project5738f832012-12-12 16:00:35 -08005168 p_cb->pairing_disabled, p_cb->api.p_pin_callback, p_dev_rec);
5169
5170 btsnd_hcic_pin_code_neg_reply (p_bda);
5171 }
5172 /* Notify upper layer of PIN request and start expiration timer */
5173 else
5174 {
5175 btm_cb.pin_code_len_saved = 0;
5176 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_PIN);
5177 /* Pin code request can not come at the same time as connection request */
5178 memcpy (p_cb->connecting_bda, p_bda, BD_ADDR_LEN);
5179 memcpy (p_cb->connecting_dc, p_dev_rec->dev_class, DEV_CLASS_LEN);
5180
5181 /* Check if the name is known */
5182 /* Even if name is not known we might not be able to get one */
5183 /* this is the case when we are already getting something from the */
5184 /* device, so HCI level is flow controlled */
5185 /* Also cannot send remote name request while paging, i.e. connection is not completed */
5186 if (p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN)
5187 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005188 BTM_TRACE_EVENT ("btm_sec_pin_code_request going for callback");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005189
5190 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
5191 if (p_cb->api.p_pin_callback)
5192 (*p_cb->api.p_pin_callback) (p_bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name);
5193 }
5194 else
5195 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005196 BTM_TRACE_EVENT ("btm_sec_pin_code_request going for remote name");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005197
5198 /* We received PIN code request for the device with unknown name */
5199 /* it is not user friendly just to ask for the PIN without name */
5200 /* try to get name at first */
5201 if (!btsnd_hcic_rmt_name_req (p_dev_rec->bd_addr,
5202 HCI_PAGE_SCAN_REP_MODE_R1,
5203 HCI_MANDATARY_PAGE_SCAN_MODE, 0))
5204 {
5205 p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
5206 p_dev_rec->sec_bd_name[0] = 'f';
5207 p_dev_rec->sec_bd_name[1] = '0';
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005208 BTM_TRACE_ERROR ("can not send rmt_name_req?? fake a name and call callback");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005209
5210 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
5211 if (p_cb->api.p_pin_callback)
5212 (*p_cb->api.p_pin_callback) (p_bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name);
5213 }
5214 }
5215 }
5216
5217 return;
5218}
5219
5220/*******************************************************************************
5221**
5222** Function btm_sec_update_clock_offset
5223**
5224** Description This function is called to update clock offset
5225**
5226** Returns void
5227**
5228*******************************************************************************/
5229void btm_sec_update_clock_offset (UINT16 handle, UINT16 clock_offset)
5230{
5231 tBTM_SEC_DEV_REC *p_dev_rec;
5232 tBTM_INQ_INFO *p_inq_info;
5233
5234 if ((p_dev_rec = btm_find_dev_by_handle (handle)) == NULL)
5235 return;
5236
5237 p_dev_rec->clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID;
5238
5239 if ((p_inq_info = BTM_InqDbRead(p_dev_rec->bd_addr)) == NULL)
5240 return;
5241
5242 p_inq_info->results.clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID;
5243}
5244
5245
5246/******************************************************************
5247** S T A T I C F U N C T I O N S
5248*******************************************************************/
5249
5250/*******************************************************************************
5251**
5252** Function btm_sec_execute_procedure
5253**
5254** Description This function is called to start required security
5255** procedure. There is a case when multiplexing protocol
5256** calls this function on the originating side, connection to
5257** the peer will not be established. This function in this
5258** case performs only authorization.
5259**
5260** Returns BTM_SUCCESS - permission is granted
5261** BTM_CMD_STARTED - in process
5262** BTM_NO_RESOURCES - permission declined
5263**
5264*******************************************************************************/
5265static tBTM_STATUS btm_sec_execute_procedure (tBTM_SEC_DEV_REC *p_dev_rec)
5266{
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005267 BTM_TRACE_EVENT ("btm_sec_execute_procedure: Required:0x%x Flags:0x%x State:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08005268 p_dev_rec->security_required, p_dev_rec->sec_flags, p_dev_rec->sec_state);
5269
5270 /* There is a chance that we are getting name. Wait until done. */
5271 if (p_dev_rec->sec_state != 0)
5272 return(BTM_CMD_STARTED);
5273
5274 /* If any security is required, get the name first */
5275 if (!(p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN)
5276 && (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE))
5277 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005278 BTM_TRACE_EVENT ("Security Manager: Start get name");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005279 if (!btm_sec_start_get_name (p_dev_rec))
5280 {
5281 return(BTM_NO_RESOURCES);
5282 }
5283 return(BTM_CMD_STARTED);
5284 }
5285
5286 /* If connection is not authenticated and authentication is required */
5287 /* start authentication and return PENDING to the caller */
5288 if ((!(p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))
5289 && (( p_dev_rec->is_originator && (p_dev_rec->security_required & BTM_SEC_OUT_AUTHENTICATE))
5290 || (!p_dev_rec->is_originator && (p_dev_rec->security_required & BTM_SEC_IN_AUTHENTICATE)))
5291 && (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE))
5292 {
5293#if (L2CAP_UCD_INCLUDED == TRUE)
5294 /* if incoming UCD packet, discard it */
5295 if ( !p_dev_rec->is_originator && (p_dev_rec->is_ucd == TRUE ))
5296 return(BTM_FAILED_ON_SECURITY);
5297#endif
5298
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005299 BTM_TRACE_EVENT ("Security Manager: Start authentication");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005300
5301 if (!btm_sec_start_authentication (p_dev_rec))
5302 {
5303 return(BTM_NO_RESOURCES);
5304 }
5305 return(BTM_CMD_STARTED);
5306 }
5307
5308 /* If connection is not encrypted and encryption is required */
5309 /* start encryption and return PENDING to the caller */
5310 if (!(p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)
5311 && (( p_dev_rec->is_originator && (p_dev_rec->security_required & BTM_SEC_OUT_ENCRYPT))
5312 || (!p_dev_rec->is_originator && (p_dev_rec->security_required & BTM_SEC_IN_ENCRYPT)))
5313 && (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE))
5314 {
5315#if (L2CAP_UCD_INCLUDED == TRUE)
5316 /* if incoming UCD packet, discard it */
5317 if ( !p_dev_rec->is_originator && (p_dev_rec->is_ucd == TRUE ))
5318 return(BTM_FAILED_ON_SECURITY);
5319#endif
5320
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005321 BTM_TRACE_EVENT ("Security Manager: Start encryption");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005322
5323 if (!btm_sec_start_encryption (p_dev_rec))
5324 {
5325 return(BTM_NO_RESOURCES);
5326 }
5327 return(BTM_CMD_STARTED);
5328 }
5329
5330 /* If connection is not authorized and authorization is required */
5331 /* start authorization and return PENDING to the caller */
5332 if (!(p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED)
5333 && (( p_dev_rec->is_originator && (p_dev_rec->security_required & BTM_SEC_OUT_AUTHORIZE))
5334 || (!p_dev_rec->is_originator && (p_dev_rec->security_required & BTM_SEC_IN_AUTHORIZE))))
5335 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005336 BTM_TRACE_EVENT ("service id:%d, is trusted:%d",
The Android Open Source Project5738f832012-12-12 16:00:35 -08005337 p_dev_rec->p_cur_service->service_id,
5338 (BTM_SEC_IS_SERVICE_TRUSTED(p_dev_rec->trusted_mask,
5339 p_dev_rec->p_cur_service->service_id)));
5340 if ((btm_sec_are_all_trusted(p_dev_rec->trusted_mask) == FALSE) &&
5341 (p_dev_rec->p_cur_service->service_id < BTM_SEC_MAX_SERVICES) &&
5342 (BTM_SEC_IS_SERVICE_TRUSTED(p_dev_rec->trusted_mask,
5343 p_dev_rec->p_cur_service->service_id) == FALSE))
5344 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005345 BTM_TRACE_EVENT ("Security Manager: Start authorization");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005346 return(btm_sec_start_authorization (p_dev_rec));
5347 }
5348 }
5349
5350 /* All required security procedures already established */
5351 p_dev_rec->security_required &= ~(BTM_SEC_OUT_AUTHORIZE | BTM_SEC_IN_AUTHORIZE |
5352 BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_IN_AUTHENTICATE |
5353 BTM_SEC_OUT_ENCRYPT | BTM_SEC_IN_ENCRYPT |
5354 BTM_SEC_FORCE_MASTER | BTM_SEC_ATTEMPT_MASTER |
5355 BTM_SEC_FORCE_SLAVE | BTM_SEC_ATTEMPT_SLAVE);
5356
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005357 BTM_TRACE_EVENT ("Security Manager: trusted:0x%04x%04x", p_dev_rec->trusted_mask[1], p_dev_rec->trusted_mask[0]);
5358 BTM_TRACE_EVENT ("Security Manager: access granted");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005359
5360 return(BTM_SUCCESS);
5361}
5362
5363
5364/*******************************************************************************
5365**
5366** Function btm_sec_start_get_name
5367**
5368** Description This function is called to start get name procedure
5369**
5370** Returns TRUE if started
5371**
5372*******************************************************************************/
5373static BOOLEAN btm_sec_start_get_name (tBTM_SEC_DEV_REC *p_dev_rec)
5374{
5375 UINT8 tempstate = p_dev_rec->sec_state;
5376
5377 p_dev_rec->sec_state = BTM_SEC_STATE_GETTING_NAME;
5378
5379 /* Device should be connected, no need to provide correct page params */
5380 /* 0 and NULL are as timeout and callback params because they are not used in security get name case */
5381 if ((btm_initiate_rem_name (p_dev_rec->bd_addr, NULL, BTM_RMT_NAME_SEC,
5382 0, NULL)) != BTM_CMD_STARTED)
5383 {
5384 p_dev_rec->sec_state = tempstate;
5385 return(FALSE);
5386 }
5387
5388 return(TRUE);
5389}
5390
5391/*******************************************************************************
5392**
5393** Function btm_sec_start_authentication
5394**
5395** Description This function is called to start authentication
5396**
5397** Returns TRUE if started
5398**
5399*******************************************************************************/
5400static BOOLEAN btm_sec_start_authentication (tBTM_SEC_DEV_REC *p_dev_rec)
5401{
5402 p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
5403
5404 return(btsnd_hcic_auth_request (p_dev_rec->hci_handle));
5405}
5406
5407/*******************************************************************************
5408**
5409** Function btm_sec_start_encryption
5410**
5411** Description This function is called to start encryption
5412**
5413** Returns TRUE if started
5414**
5415*******************************************************************************/
5416static BOOLEAN btm_sec_start_encryption (tBTM_SEC_DEV_REC *p_dev_rec)
5417{
5418 if (!btsnd_hcic_set_conn_encrypt (p_dev_rec->hci_handle, TRUE))
5419 return(FALSE);
5420
5421 p_dev_rec->sec_state = BTM_SEC_STATE_ENCRYPTING;
5422 return(TRUE);
5423}
5424
5425
5426/*******************************************************************************
5427**
5428** Function btm_sec_start_authorization
5429**
5430** Description This function is called to start authorization
5431**
5432** Returns TRUE if started
5433**
5434*******************************************************************************/
5435static UINT8 btm_sec_start_authorization (tBTM_SEC_DEV_REC *p_dev_rec)
5436{
5437 UINT8 result;
5438 UINT8 *p_service_name = NULL;
5439 UINT8 service_id;
5440
5441 if ((p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN)
5442 || (p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE))
5443 {
5444 if (!btm_cb.api.p_authorize_callback)
5445 return(BTM_MODE_UNSUPPORTED);
5446
5447 if (p_dev_rec->p_cur_service)
5448 {
5449#if BTM_SEC_SERVICE_NAME_LEN > 0
5450 if (p_dev_rec->is_originator)
5451 p_service_name = p_dev_rec->p_cur_service->orig_service_name;
5452 else
5453 p_service_name = p_dev_rec->p_cur_service->term_service_name;
5454#endif
5455 service_id = p_dev_rec->p_cur_service->service_id;
5456 }
5457 else
5458 service_id = 0;
5459
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08005460 /* Send authorization request if not already sent during this service connection */
5461 if (p_dev_rec->last_author_service_id == BTM_SEC_NO_LAST_SERVICE_ID
5462 || p_dev_rec->last_author_service_id != service_id)
5463 {
5464 p_dev_rec->sec_state = BTM_SEC_STATE_AUTHORIZING;
5465 result = (*btm_cb.api.p_authorize_callback) (p_dev_rec->bd_addr,
The Android Open Source Project5738f832012-12-12 16:00:35 -08005466 p_dev_rec->dev_class,
5467 p_dev_rec->sec_bd_name,
5468 p_service_name,
5469 service_id,
5470 p_dev_rec->is_originator);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08005471 }
5472
5473 else /* Already authorized once for this L2CAP bringup */
5474 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005475 BTM_TRACE_DEBUG ("btm_sec_start_authorization: (Ignoring extra Authorization prompt for service %d)", service_id);
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08005476 return (BTM_SUCCESS);
5477 }
5478
The Android Open Source Project5738f832012-12-12 16:00:35 -08005479 if (result == BTM_SUCCESS)
5480 {
5481 p_dev_rec->sec_flags |= BTM_SEC_AUTHORIZED;
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08005482
5483 /* Save the currently authorized service in case we are asked again by another multiplexer layer */
5484 if (!p_dev_rec->is_originator)
5485 p_dev_rec->last_author_service_id = service_id;
5486
The Android Open Source Project5738f832012-12-12 16:00:35 -08005487 p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
5488 }
5489 return(result);
5490 }
5491 btm_sec_start_get_name (p_dev_rec);
5492 return(BTM_CMD_STARTED);
5493}
5494
5495/*******************************************************************************
5496**
5497** Function btm_sec_are_all_trusted
5498**
5499** Description This function is called check if all services are trusted
5500**
5501** Returns TRUE if all are trusted, otherwise FALSE
5502**
5503*******************************************************************************/
5504BOOLEAN btm_sec_are_all_trusted(UINT32 p_mask[])
5505{
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08005506 UINT32 trusted_inx;
The Android Open Source Project5738f832012-12-12 16:00:35 -08005507 for (trusted_inx = 0; trusted_inx < BTM_SEC_SERVICE_ARRAY_SIZE; trusted_inx++)
5508 {
5509 if (p_mask[trusted_inx] != BTM_SEC_TRUST_ALL)
5510 return(FALSE);
5511 }
5512
5513 return(TRUE);
5514}
5515
5516/*******************************************************************************
5517**
5518** Function btm_sec_find_first_serv
5519**
5520** Description Look for the first record in the service database
5521** with specified PSM
5522**
5523** Returns Pointer to the record or NULL
5524**
5525*******************************************************************************/
5526static tBTM_SEC_SERV_REC *btm_sec_find_first_serv (CONNECTION_TYPE conn_type, UINT16 psm)
5527{
5528 tBTM_SEC_SERV_REC *p_serv_rec = &btm_cb.sec_serv_rec[0];
5529 int i;
5530 BOOLEAN is_originator;
5531
5532#if (L2CAP_UCD_INCLUDED == TRUE)
5533
5534 if ( conn_type & CONNECTION_TYPE_ORIG_MASK )
5535 is_originator = TRUE;
5536 else
5537 is_originator = FALSE;
5538#else
5539 is_originator = conn_type;
5540#endif
5541
5542 if (is_originator && btm_cb.p_out_serv && btm_cb.p_out_serv->psm == psm)
5543 {
5544 /* If this is outgoing connection and the PSM matches p_out_serv,
5545 * use it as the current service */
5546 return btm_cb.p_out_serv;
5547 }
5548
5549 /* otherwise, just find the first record with the specified PSM */
5550 for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_serv_rec++)
5551 {
5552 if ( (p_serv_rec->security_flags & BTM_SEC_IN_USE) && (p_serv_rec->psm == psm) )
5553 return(p_serv_rec);
5554 }
5555 return(NULL);
5556}
5557
5558
5559/*******************************************************************************
5560**
5561** Function btm_sec_find_next_serv
5562**
5563** Description Look for the next record in the service database
5564** with specified PSM
5565**
5566** Returns Pointer to the record or NULL
5567**
5568*******************************************************************************/
5569static tBTM_SEC_SERV_REC *btm_sec_find_next_serv (tBTM_SEC_SERV_REC *p_cur)
5570{
5571 tBTM_SEC_SERV_REC *p_serv_rec = &btm_cb.sec_serv_rec[0];
5572 int i;
5573
5574 for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_serv_rec++)
5575 {
5576 if ((p_serv_rec->security_flags & BTM_SEC_IN_USE)
5577 && (p_serv_rec->psm == p_cur->psm) )
5578 {
5579 if (p_cur != p_serv_rec)
5580 {
5581 return(p_serv_rec);
5582 }
5583 }
5584 }
5585 return(NULL);
5586}
5587
5588
5589/*******************************************************************************
5590**
5591** Function btm_sec_find_mx_serv
5592**
5593** Description Look for the record in the service database with specified
5594** PSM and multiplexor channel information
5595**
5596** Returns Pointer to the record or NULL
5597**
5598*******************************************************************************/
5599static tBTM_SEC_SERV_REC *btm_sec_find_mx_serv (UINT8 is_originator, UINT16 psm,
5600 UINT32 mx_proto_id, UINT32 mx_chan_id)
5601{
5602 tBTM_SEC_SERV_REC *p_out_serv = btm_cb.p_out_serv;
5603 tBTM_SEC_SERV_REC *p_serv_rec = &btm_cb.sec_serv_rec[0];
5604 int i;
5605
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005606 BTM_TRACE_DEBUG ("btm_sec_find_mx_serv");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005607 if (is_originator && p_out_serv && p_out_serv->psm == psm
5608 && p_out_serv->mx_proto_id == mx_proto_id
5609 && p_out_serv->orig_mx_chan_id == mx_chan_id)
5610 {
5611 /* If this is outgoing connection and the parameters match p_out_serv,
5612 * use it as the current service */
5613 return btm_cb.p_out_serv;
5614 }
5615
5616 /* otherwise, the old way */
5617 for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_serv_rec++)
5618 {
5619 if ((p_serv_rec->security_flags & BTM_SEC_IN_USE)
5620 && (p_serv_rec->psm == psm)
5621 && (p_serv_rec->mx_proto_id == mx_proto_id)
5622 && (( is_originator && (p_serv_rec->orig_mx_chan_id == mx_chan_id))
5623 || (!is_originator && (p_serv_rec->term_mx_chan_id == mx_chan_id))))
5624 {
5625 return(p_serv_rec);
5626 }
5627 }
5628 return(NULL);
5629}
5630
5631
5632/*******************************************************************************
5633**
5634** Function btm_sec_collision_timeout
5635**
5636** Description Encryption could not start because of the collision
5637** try to do it again
5638**
5639** Returns Pointer to the TLE struct
5640**
5641*******************************************************************************/
5642static void btm_sec_collision_timeout (TIMER_LIST_ENT *p_tle)
5643{
5644 tBTM_STATUS status;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -08005645 UNUSED(p_tle);
The Android Open Source Project5738f832012-12-12 16:00:35 -08005646
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005647 BTM_TRACE_EVENT ("btm_sec_collision_timeout()");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005648 btm_cb.sec_collision_tle.param = 0;
5649
5650 status = btm_sec_execute_procedure (btm_cb.p_collided_dev_rec);
5651
5652 /* If result is pending reply from the user or from the device is pending */
5653 if (status != BTM_CMD_STARTED)
5654 {
5655 /* There is no next procedure or start of procedure failed, notify the waiting layer */
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07005656 btm_sec_dev_rec_cback_event (btm_cb.p_collided_dev_rec, status, FALSE);
The Android Open Source Project5738f832012-12-12 16:00:35 -08005657 }
5658}
5659
5660/*******************************************************************************
5661**
5662** Function btm_sec_link_key_request
5663**
5664** Description This function is called when controller requests link key
5665**
5666** Returns Pointer to the record or NULL
5667**
5668*******************************************************************************/
5669static void btm_send_link_key_notif (tBTM_SEC_DEV_REC *p_dev_rec)
5670{
5671 if (btm_cb.api.p_link_key_callback)
5672 (*btm_cb.api.p_link_key_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
5673 p_dev_rec->sec_bd_name, p_dev_rec->link_key,
5674 p_dev_rec->link_key_type);
5675}
5676
5677/*******************************************************************************
5678**
5679** Function BTM_ReadTrustedMask
5680**
5681** Description Get trusted mask for the peer device
5682**
5683** Parameters: bd_addr - Address of the device
5684**
5685** Returns NULL, if the device record is not found.
5686** otherwise, the trusted mask
5687**
5688*******************************************************************************/
5689UINT32 * BTM_ReadTrustedMask (BD_ADDR bd_addr)
5690{
5691 tBTM_SEC_DEV_REC *p_dev_rec;
5692
5693 if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
5694 {
5695 return(p_dev_rec->trusted_mask);
5696 }
5697 else
5698 {
5699 return NULL;
5700 }
5701}
5702
5703/*******************************************************************************
5704**
5705** Function btm_restore_mode
5706**
5707** Description This function returns the security mode to previous setting
5708** if it was changed during bonding.
5709**
5710**
5711** Parameters: void
5712**
5713*******************************************************************************/
5714static void btm_restore_mode(void)
5715{
5716 if (btm_cb.security_mode_changed)
5717 {
5718 btm_cb.security_mode_changed = FALSE;
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005719 BTM_TRACE_DEBUG("btm_restore_mode: Authen Enable -> %d", (btm_cb.security_mode == BTM_SEC_MODE_LINK));
The Android Open Source Project5738f832012-12-12 16:00:35 -08005720 btsnd_hcic_write_auth_enable ((UINT8)(btm_cb.security_mode == BTM_SEC_MODE_LINK));
5721 }
5722
5723 if (btm_cb.pin_type_changed)
5724 {
5725 btm_cb.pin_type_changed = FALSE;
5726 btsnd_hcic_write_pin_type (btm_cb.cfg.pin_type);
5727 }
5728}
5729
5730
5731/*******************************************************************************
5732**
5733** Function btm_sec_find_dev_by_sec_state
5734**
5735** Description Look for the record in the device database for the device
5736** which is being authenticated or encrypted
5737**
5738** Returns Pointer to the record or NULL
5739**
5740*******************************************************************************/
5741tBTM_SEC_DEV_REC *btm_sec_find_dev_by_sec_state (UINT8 state)
5742{
5743 tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
5744 int i;
5745
5746 for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
5747 {
5748 if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
5749 && (p_dev_rec->sec_state == state))
5750 return(p_dev_rec);
5751 }
5752 return(NULL);
5753}
5754
5755/*******************************************************************************
5756**
5757** Function BTM_snd_conn_encrypt
5758**
5759** Description This function is called to start/stop encryption
5760** Used by JSR-82
5761**
5762** Returns TRUE if request started
5763**
5764*******************************************************************************/
5765BOOLEAN BTM_snd_conn_encrypt (UINT16 handle, BOOLEAN enable)
5766{
5767 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
5768
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005769 BTM_TRACE_EVENT ("BTM_snd_conn_encrypt Security Manager: encrypt_change p_dev_rec : 0x%x, enable = %s", p_dev_rec, (enable == TRUE) ? "TRUE" : "FALSE");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005770
5771 if (!p_dev_rec)
5772 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005773 BTM_TRACE_EVENT ("BTM_snd_conn_encrypt Error no p_dev_rec : 0x%x\n", p_dev_rec);
The Android Open Source Project5738f832012-12-12 16:00:35 -08005774 return(FALSE);
5775 }
5776
5777 if ( p_dev_rec->sec_state == BTM_SEC_STATE_IDLE)
5778 {
5779 if (!btsnd_hcic_set_conn_encrypt (handle, enable))
5780 return(FALSE);
5781
5782 p_dev_rec->sec_state = BTM_SEC_STATE_ENCRYPTING;
5783
5784 return(TRUE);
5785 }
5786 else
5787 return(FALSE);
5788}
5789
5790/*******************************************************************************
5791**
5792** Function btm_sec_change_pairing_state
5793**
5794** Description This function is called to change pairing state
5795**
5796*******************************************************************************/
5797static void btm_sec_change_pairing_state (tBTM_PAIRING_STATE new_state)
5798{
5799 tBTM_PAIRING_STATE old_state = btm_cb.pairing_state;
5800
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005801 BTM_TRACE_EVENT ("btm_sec_change_pairing_state Old: %s", btm_pair_state_descr(btm_cb.pairing_state));
5802 BTM_TRACE_EVENT ("btm_sec_change_pairing_state New: %s pairing_flags:0x%x",btm_pair_state_descr(new_state), btm_cb.pairing_flags);
The Android Open Source Project5738f832012-12-12 16:00:35 -08005803
5804 btm_cb.pairing_state = new_state;
5805
5806 if (new_state == BTM_PAIR_STATE_IDLE)
5807 {
5808 btu_stop_timer (&btm_cb.pairing_tle);
5809
5810 btm_cb.pairing_flags = 0;
5811 btm_cb.pin_code_len = 0;
5812
5813 /* Make sure the the lcb shows we are not bonding */
5814 l2cu_update_lcb_4_bonding (btm_cb.pairing_bda, FALSE);
5815
5816 btm_restore_mode();
5817 btm_sec_check_pending_reqs();
5818 btm_inq_clear_ssp();
5819
5820 memset (btm_cb.pairing_bda, 0xFF, BD_ADDR_LEN);
5821 }
5822 else
5823 {
5824 /* If transitionng out of idle, mark the lcb as bonding */
5825 if (old_state == BTM_PAIR_STATE_IDLE)
5826 l2cu_update_lcb_4_bonding (btm_cb.pairing_bda, TRUE);
5827
5828 btm_cb.pairing_tle.param = (TIMER_PARAM_TYPE)btm_sec_pairing_timeout;
5829
5830 btu_start_timer (&btm_cb.pairing_tle, BTU_TTYPE_USER_FUNC, BTM_SEC_TIMEOUT_VALUE);
5831 }
5832}
5833
5834
5835/*******************************************************************************
5836**
5837** Function btm_pair_state_descr
5838**
5839** Description Return state description for tracing
5840**
5841*******************************************************************************/
5842#if (BT_USE_TRACES == TRUE)
5843static char *btm_pair_state_descr (tBTM_PAIRING_STATE state)
5844{
5845#if (BT_TRACE_VERBOSE == TRUE)
5846 switch (state)
5847 {
5848 case BTM_PAIR_STATE_IDLE: return("IDLE");
5849 case BTM_PAIR_STATE_GET_REM_NAME: return("GET_REM_NAME");
5850 case BTM_PAIR_STATE_WAIT_PIN_REQ: return("WAIT_PIN_REQ");
5851 case BTM_PAIR_STATE_WAIT_LOCAL_PIN: return("WAIT_LOCAL_PIN");
5852 case BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM: return("WAIT_NUM_CONFIRM");
5853 case BTM_PAIR_STATE_KEY_ENTRY: return("KEY_ENTRY");
5854 case BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP: return("WAIT_LOCAL_OOB_RSP");
5855 case BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS: return("WAIT_LOCAL_IOCAPS");
5856 case BTM_PAIR_STATE_INCOMING_SSP: return("INCOMING_SSP");
5857 case BTM_PAIR_STATE_WAIT_AUTH_COMPLETE: return("WAIT_AUTH_COMPLETE");
5858 case BTM_PAIR_STATE_WAIT_DISCONNECT: return("WAIT_DISCONNECT");
5859 }
5860
5861 return("???");
5862#else
5863 sprintf(btm_cb.state_temp_buffer,"%hu",state);
5864
5865 return(btm_cb.state_temp_buffer);
5866#endif
5867}
5868#endif
5869
5870
5871/*******************************************************************************
5872**
5873** Function btm_sec_dev_rec_cback_event
5874**
5875** Description This function calls the callback function with the given
5876** result and clear the callback function.
5877**
5878** Parameters: void
5879**
5880*******************************************************************************/
Andre Eisenbach32429182014-07-25 15:46:21 -07005881void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res, BOOLEAN is_le_transport)
The Android Open Source Project5738f832012-12-12 16:00:35 -08005882{
5883 tBTM_SEC_CALLBACK *p_callback = p_dev_rec->p_callback;
Andre Eisenbach32429182014-07-25 15:46:21 -07005884 tBT_TRANSPORT transport = is_le_transport ? BT_TRANSPORT_LE : BT_TRANSPORT_BR_EDR;
The Android Open Source Project5738f832012-12-12 16:00:35 -08005885
5886 if (p_dev_rec->p_callback)
5887 {
5888 p_dev_rec->p_callback = NULL;
5889
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07005890 (*p_callback) (p_dev_rec->bd_addr, transport, p_dev_rec->p_ref_data, res);
The Android Open Source Project5738f832012-12-12 16:00:35 -08005891
5892 }
5893 btm_sec_check_pending_reqs();
5894}
5895
5896/*******************************************************************************
5897**
5898** Function btm_sec_queue_mx_request
5899**
5900** Description Return state description for tracing
5901**
5902*******************************************************************************/
5903static BOOLEAN btm_sec_queue_mx_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_orig,
5904 UINT32 mx_proto_id, UINT32 mx_chan_id,
5905 tBTM_SEC_CALLBACK *p_callback, void *p_ref_data)
5906{
5907 tBTM_SEC_QUEUE_ENTRY *p_e;
5908
5909 p_e = (tBTM_SEC_QUEUE_ENTRY *)GKI_getbuf (sizeof(tBTM_SEC_QUEUE_ENTRY));
5910
5911 if (p_e)
5912 {
5913 p_e->psm = psm;
5914 p_e->is_orig = is_orig;
5915 p_e->p_callback = p_callback;
5916 p_e->p_ref_data = p_ref_data;
5917 p_e->mx_proto_id = mx_proto_id;
5918 p_e->mx_chan_id = mx_chan_id;
5919
5920 memcpy (p_e->bd_addr, bd_addr, BD_ADDR_LEN);
5921
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005922 BTM_TRACE_EVENT ("btm_sec_queue_mx_request() PSM: 0x%04x Is_Orig: %u mx_proto_id: %u mx_chan_id: %u",
The Android Open Source Project5738f832012-12-12 16:00:35 -08005923 psm, is_orig, mx_proto_id, mx_chan_id);
5924
5925 GKI_enqueue (&btm_cb.sec_pending_q, p_e);
5926
5927 return(TRUE);
5928 }
5929
5930 return(FALSE);
5931}
5932
5933static BOOLEAN btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC *p_dev_rec)
5934{
5935 UINT8 major = (UINT8)(p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK);
5936 UINT8 minor = (UINT8)(p_dev_rec->dev_class[2] & BTM_COD_MINOR_CLASS_MASK);
5937 BOOLEAN rv = FALSE;
5938
5939 if ((major == BTM_COD_MAJOR_AUDIO)
5940 && ((minor == BTM_COD_MINOR_CONFM_HANDSFREE) || (minor == BTM_COD_MINOR_CAR_AUDIO)) )
5941 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005942 BTM_TRACE_EVENT ("btm_sec_check_prefetch_pin: Skipping pre-fetch PIN for carkit COD Major: 0x%02x Minor: 0x%02x", major, minor);
The Android Open Source Project5738f832012-12-12 16:00:35 -08005943
5944 if (btm_cb.security_mode_changed == FALSE)
5945 {
5946 btm_cb.security_mode_changed = TRUE;
5947#ifdef APPL_AUTH_WRITE_EXCEPTION
5948 if(!(APPL_AUTH_WRITE_EXCEPTION)(p_dev_rec->bd_addr))
5949#endif
5950 btsnd_hcic_write_auth_enable (TRUE);
5951 }
5952 }
5953 else
5954 {
5955 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_PIN);
5956
5957 /* If we got a PIN, use that, else try to get one */
5958 if (btm_cb.pin_code_len)
5959 {
5960 BTM_PINCodeReply (p_dev_rec->bd_addr, BTM_SUCCESS, btm_cb.pin_code_len, btm_cb.pin_code, p_dev_rec->trusted_mask);
5961 }
5962 else
5963 {
5964 /* pin was not supplied - pre-fetch pin code now */
5965 if (btm_cb.api.p_pin_callback && ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0))
5966 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005967 BTM_TRACE_DEBUG("btm_sec_check_prefetch_pin: PIN code callback called");
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07005968 if (btm_bda_to_acl(p_dev_rec->bd_addr, BT_TRANSPORT_BR_EDR) == NULL)
The Android Open Source Project5738f832012-12-12 16:00:35 -08005969 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
5970 (btm_cb.api.p_pin_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, p_dev_rec->sec_bd_name);
5971 }
5972 }
5973
5974 rv = TRUE;
5975 }
5976
5977 return rv;
5978}
5979
5980#if (BLE_INCLUDED == TRUE)
5981/*******************************************************************************
5982**
5983** Function btm_sec_clear_ble_keys
5984**
5985** Description This function is called to clear out the BLE keys.
5986** Typically when devices are removed in BTM_SecDeleteDevice,
5987** or when a new BT Link key is generated.
5988**
5989** Returns void
5990**
5991*******************************************************************************/
5992void btm_sec_clear_ble_keys (tBTM_SEC_DEV_REC *p_dev_rec)
5993{
5994
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07005995 BTM_TRACE_DEBUG ("btm_sec_clear_ble_keys: Clearing BLE Keys");
The Android Open Source Project5738f832012-12-12 16:00:35 -08005996#if (SMP_INCLUDED== TRUE)
5997 p_dev_rec->ble.key_type = 0;
5998 memset (&p_dev_rec->ble.keys, 0, sizeof(tBTM_SEC_BLE_KEYS));
5999#endif
6000 gatt_delete_dev_from_srv_chg_clt_list(p_dev_rec->bd_addr);
6001}
6002
6003
6004/*******************************************************************************
6005**
6006** Function btm_sec_is_a_bonded_dev
6007**
6008** Description Is the specified device is a bonded device
6009**
6010** Returns TRUE - dev is bonded
6011**
6012*******************************************************************************/
6013BOOLEAN btm_sec_is_a_bonded_dev (BD_ADDR bda)
6014{
6015
6016 tBTM_SEC_DEV_REC *p_dev_rec= btm_find_dev (bda);
6017 BOOLEAN is_bonded= FALSE;
6018
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07006019 if (p_dev_rec &&
The Android Open Source Project5738f832012-12-12 16:00:35 -08006020#if (SMP_INCLUDED== TRUE)
Ganesh Ganapathi Batta7fa4fba2014-04-16 16:50:09 -07006021 ((p_dev_rec->ble.key_type && (p_dev_rec->sec_flags & BTM_SEC_LE_LINK_KEY_KNOWN))||
6022#endif
6023 (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)))
The Android Open Source Project5738f832012-12-12 16:00:35 -08006024 {
6025 is_bonded = TRUE;
6026 }
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07006027 BTM_TRACE_DEBUG ("btm_sec_is_a_bonded_dev is_bonded=%d", is_bonded);
The Android Open Source Project5738f832012-12-12 16:00:35 -08006028 return(is_bonded);
6029}
6030
6031/*******************************************************************************
6032**
Ganesh Ganapathi Battaead3cde2013-02-05 15:22:31 -08006033** Function btm_sec_is_le_capable_dev
6034**
6035** Description Is the specified device is dual mode or LE only device
6036**
6037** Returns TRUE - dev is a dual mode
6038**
6039*******************************************************************************/
6040BOOLEAN btm_sec_is_le_capable_dev (BD_ADDR bda)
6041{
6042 tBTM_SEC_DEV_REC *p_dev_rec= btm_find_dev (bda);
6043 BOOLEAN le_capable = FALSE;
6044
6045#if (BLE_INCLUDED== TRUE)
6046 if (p_dev_rec && ((p_dev_rec->device_type == BT_DEVICE_TYPE_DUMO) ||
6047 (p_dev_rec->device_type == BT_DEVICE_TYPE_BLE) ) )
6048 {
6049 le_capable = TRUE;
6050 }
6051#endif
6052 return le_capable;
6053}
6054
6055/*******************************************************************************
6056**
The Android Open Source Project5738f832012-12-12 16:00:35 -08006057** Function btm_sec_find_bonded_dev
6058**
6059** Description Find a bonded device starting from the specified index
6060**
6061** Returns TRUE - found a bonded device
6062**
6063*******************************************************************************/
Mike J. Chene68ffb02014-01-31 15:06:49 -08006064BOOLEAN btm_sec_find_bonded_dev (UINT8 start_idx, UINT8 *p_found_idx, tBTM_SEC_DEV_REC **p_rec)
The Android Open Source Project5738f832012-12-12 16:00:35 -08006065{
6066 BOOLEAN found= FALSE;
6067
6068#if (SMP_INCLUDED== TRUE)
6069 tBTM_SEC_DEV_REC *p_dev_rec;
6070 int i;
6071 if (start_idx >= BTM_SEC_MAX_DEVICE_RECORDS)
6072 {
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07006073 BTM_TRACE_DEBUG ("LE bonded device not found");
The Android Open Source Project5738f832012-12-12 16:00:35 -08006074 return found;
6075 }
6076
6077 p_dev_rec = &btm_cb.sec_dev_rec[start_idx];
6078 for (i = start_idx; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
6079 {
6080 if (p_dev_rec->ble.key_type || (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN))
6081 {
6082 *p_found_idx = i;
Mike J. Chene68ffb02014-01-31 15:06:49 -08006083 *p_rec = p_dev_rec;
The Android Open Source Project5738f832012-12-12 16:00:35 -08006084 break;
6085 }
6086 }
Sharvil Nanavati5344d6d2014-05-04 00:46:57 -07006087 BTM_TRACE_DEBUG ("btm_sec_find_bonded_dev=%d", found);
The Android Open Source Project5738f832012-12-12 16:00:35 -08006088#endif
6089 return(found);
6090}
6091#endif /* BLE_INCLUDED */
6092