• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 1999-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains functions for the Bluetooth 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"
31 
32 #if (BT_USE_TRACES == TRUE && BT_TRACE_VERBOSE == FALSE)
33 /* needed for sprintf() */
34 #include <stdio.h>
35 #endif
36 
37 #if BLE_INCLUDED == TRUE
38     #include "gatt_int.h"
39 #endif
40 
41 #define BTM_SEC_MAX_COLLISION_DELAY     (GKI_SECS_TO_TICKS(5))
42 
43 #ifdef APPL_AUTH_WRITE_EXCEPTION
44 BOOLEAN (APPL_AUTH_WRITE_EXCEPTION)(BD_ADDR bd_addr);
45 #endif
46 
47 /********************************************************************************/
48 /*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
49 /********************************************************************************/
50 static tBTM_SEC_SERV_REC *btm_sec_find_first_serv (BOOLEAN is_originator, UINT16 psm);
51 static tBTM_SEC_SERV_REC *btm_sec_find_next_serv (tBTM_SEC_SERV_REC *p_cur);
52 static tBTM_SEC_SERV_REC *btm_sec_find_mx_serv (UINT8 is_originator, UINT16 psm,
53                                                 UINT32 mx_proto_id,
54                                                 UINT32 mx_chan_id);
55 
56 static tBTM_STATUS btm_sec_execute_procedure (tBTM_SEC_DEV_REC *p_dev_rec);
57 static BOOLEAN  btm_sec_start_get_name (tBTM_SEC_DEV_REC *p_dev_rec);
58 static BOOLEAN  btm_sec_start_authentication (tBTM_SEC_DEV_REC *p_dev_rec);
59 static BOOLEAN  btm_sec_start_encryption (tBTM_SEC_DEV_REC *p_dev_rec);
60 static void     btm_sec_collision_timeout (TIMER_LIST_ENT *p_tle);
61 static void     btm_restore_mode(void);
62 static void     btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle);
63 static tBTM_STATUS btm_sec_dd_create_conn (tBTM_SEC_DEV_REC *p_dev_rec);
64 static void     btm_sec_change_pairing_state (tBTM_PAIRING_STATE new_state);
65 
66 #if (BT_USE_TRACES == TRUE)
67 static char     *btm_pair_state_descr (tBTM_PAIRING_STATE state);
68 #endif
69 
70 static void     btm_sec_check_pending_reqs(void);
71 static BOOLEAN  btm_sec_queue_mx_request (BD_ADDR bd_addr,  UINT16 psm,  BOOLEAN is_orig,
72                                           UINT32 mx_proto_id, UINT32 mx_chan_id,
73                                           tBTM_SEC_CALLBACK *p_callback, void *p_ref_data);
74 static void     btm_sec_bond_cancel_complete (void);
75 static void     btm_send_link_key_notif (tBTM_SEC_DEV_REC *p_dev_rec);
76 static BOOLEAN  btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC  *p_dev_rec);
77 
78 static UINT8    btm_sec_start_authorization (tBTM_SEC_DEV_REC *p_dev_rec);
79 BOOLEAN         btm_sec_are_all_trusted(UINT32 p_mask[]);
80 
81 static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason);
82 tBTM_SEC_DEV_REC *btm_sec_find_dev_by_sec_state (UINT8 state);
83 
84 static BOOLEAN  btm_sec_set_security_level ( CONNECTION_TYPE conn_type, char *p_name, UINT8 service_id,
85                                             UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id,
86                                             UINT32 mx_chan_id);
87 
88 /* TRUE - authenticated link key is possible */
89 static const BOOLEAN btm_sec_io_map [BTM_IO_CAP_MAX][BTM_IO_CAP_MAX] =
90 {
91     /*   OUT,    IO,     IN,     NONE */
92 /* OUT  */ {FALSE,  FALSE,  TRUE,   FALSE},
93 /* IO   */ {FALSE,  TRUE,   TRUE,   FALSE},
94 /* IN   */ {TRUE,   TRUE,   TRUE,   FALSE},
95 /* NONE */ {FALSE,  FALSE,  FALSE,  FALSE}
96 };
97 /*  BTM_IO_CAP_OUT      0   DisplayOnly */
98 /*  BTM_IO_CAP_IO       1   DisplayYesNo */
99 /*  BTM_IO_CAP_IN       2   KeyboardOnly */
100 /*  BTM_IO_CAP_NONE     3   NoInputNoOutput */
101 
102 /*******************************************************************************
103 **
104 ** Function         BTM_SecRegister
105 **
106 ** Description      Application manager calls this function to register for
107 **                  security services.  There can be one and only one application
108 **                  saving link keys.  BTM allows only first registration.
109 **
110 ** Returns          TRUE if registered OK, else FALSE
111 **
112 *******************************************************************************/
BTM_SecRegister(tBTM_APPL_INFO * p_cb_info)113 BOOLEAN  BTM_SecRegister (tBTM_APPL_INFO *p_cb_info)
114 {
115 #if BLE_INCLUDED == TRUE
116     BT_OCTET16      temp_value = {0};
117 #endif
118 
119     BTM_TRACE_EVENT0 ("BTM_Sec: application registered");
120 
121 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
122     BTM_TRACE_ERROR1 ("BTM_SecRegister:p_cb_info->p_le_callback == 0x%x ", p_cb_info->p_le_callback);
123 
124     if (p_cb_info->p_le_callback)
125     {
126 #if SMP_INCLUDED == TRUE
127         BTM_TRACE_EVENT0 ("BTM_Sec: SMP_Register( btm_proc_smp_cback )");
128         SMP_Register(btm_proc_smp_cback);
129 #endif
130         /* if no IR is loaded, need to regenerate all the keys */
131         if (memcmp(btm_cb.devcb.id_keys.ir, &temp_value, sizeof(BT_OCTET16)) == 0)
132         {
133             btm_ble_reset_id();
134         }
135     }
136     else
137     {
138         BTM_TRACE_ERROR0 ("BTM_SecRegister:p_cb_info->p_le_callback == NULL ");
139     }
140 #endif
141 
142 
143 
144     btm_cb.api = *p_cb_info;
145 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
146      BTM_TRACE_ERROR1 ("BTM_SecRegister: btm_cb.api.p_le_callback = 0x%x ", btm_cb.api.p_le_callback);
147 #endif
148     BTM_TRACE_EVENT0 ("BTM_Sec: application registered");
149     return(TRUE);
150 }
151 
152 
153 /*******************************************************************************
154 **
155 ** Function         BTM_SecRegisterLinkKeyNotificationCallback
156 **
157 ** Description      Application manager calls this function to register for
158 **                  link key notification.  When there is nobody registered
159 **                  we should avoid changing link key
160 **
161 ** Returns          TRUE if registered OK, else FALSE
162 **
163 *******************************************************************************/
BTM_SecRegisterLinkKeyNotificationCallback(tBTM_LINK_KEY_CALLBACK * p_callback)164 BOOLEAN BTM_SecRegisterLinkKeyNotificationCallback (tBTM_LINK_KEY_CALLBACK *p_callback)
165 {
166     btm_cb.api.p_link_key_callback = p_callback;
167     return(TRUE);
168 }
169 
170 
171 /*******************************************************************************
172 **
173 ** Function         BTM_SecAddRmtNameNotifyCallback
174 **
175 ** Description      Any profile can register to be notified when name of the
176 **                  remote device is resolved.
177 **
178 ** Returns          TRUE if registered OK, else FALSE
179 **
180 *******************************************************************************/
BTM_SecAddRmtNameNotifyCallback(tBTM_RMT_NAME_CALLBACK * p_callback)181 BOOLEAN  BTM_SecAddRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback)
182 {
183     int i;
184 
185     for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++)
186     {
187         if (btm_cb.p_rmt_name_callback[i] == NULL)
188         {
189             btm_cb.p_rmt_name_callback[i] = p_callback;
190             return(TRUE);
191         }
192     }
193 
194     return(FALSE);
195 }
196 
197 
198 /*******************************************************************************
199 **
200 ** Function         BTM_SecDeleteRmtNameNotifyCallback
201 **
202 ** Description      Any profile can deregister notification when a new Link Key
203 **                  is generated per connection.
204 **
205 ** Returns          TRUE if OK, else FALSE
206 **
207 *******************************************************************************/
BTM_SecDeleteRmtNameNotifyCallback(tBTM_RMT_NAME_CALLBACK * p_callback)208 BOOLEAN  BTM_SecDeleteRmtNameNotifyCallback (tBTM_RMT_NAME_CALLBACK *p_callback)
209 {
210     int i;
211 
212     for (i = 0; i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++)
213     {
214         if (btm_cb.p_rmt_name_callback[i] == p_callback)
215         {
216             btm_cb.p_rmt_name_callback[i] = NULL;
217             return(TRUE);
218         }
219     }
220 
221     return(FALSE);
222 }
223 
224 
225 /*******************************************************************************
226 **
227 ** Function         BTM_SecSetConnectFilterCallback
228 **
229 ** Description      Host can register to be asked whenever a HCI connection
230 **                  request is received.  In the registered function host
231 **                  suppose to check connectibility filters.  Yes/No result
232 **                  should be returned syncronously
233 **
234 ** Returns          void
235 **
236 *******************************************************************************/
BTM_SecSetConnectFilterCallback(tBTM_FILTER_CB * p_callback)237 void BTM_SecSetConnectFilterCallback (tBTM_FILTER_CB *p_callback)
238 {
239     btm_cb.p_conn_filter_cb = p_callback;
240 }
241 
242 /*******************************************************************************
243 **
244 ** Function         BTM_GetSecurityMode
245 **
246 ** Description      Get security mode for the device
247 **
248 ** Returns          void
249 **
250 *******************************************************************************/
BTM_GetSecurityMode(void)251 UINT8 BTM_GetSecurityMode (void)
252 {
253     return(btm_cb.security_mode);
254 }
255 
256 /*******************************************************************************
257 **
258 ** Function         BTM_GetSecurityFlags
259 **
260 ** Description      Get security flags for the device
261 **
262 ** Returns          BOOLEAN TRUE or FALSE is device found
263 **
264 *******************************************************************************/
BTM_GetSecurityFlags(BD_ADDR bd_addr,UINT8 * p_sec_flags)265 BOOLEAN BTM_GetSecurityFlags (BD_ADDR bd_addr, UINT8 * p_sec_flags)
266 {
267     tBTM_SEC_DEV_REC *p_dev_rec;
268 
269     if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
270     {
271         *p_sec_flags = p_dev_rec->sec_flags;
272         return(TRUE);
273     }
274     BTM_TRACE_ERROR0 ("BTM_GetSecurityFlags false");
275     return(FALSE);
276 }
277 
278 /*******************************************************************************
279 **
280 ** Function         BTM_SetSecurityMode
281 **
282 ** Description      Set security mode for the device
283 **
284 ** Returns          void
285 **
286 *******************************************************************************/
BTM_SetSecurityMode(UINT8 security_mode)287 void BTM_SetSecurityMode (UINT8 security_mode)
288 {
289     UINT8   old_mode = btm_cb.security_mode;
290 
291     UINT8   sp_mode = HCI_SPD_MODE_ENABLED;
292     UINT8   sp_debug_mode = HCI_SPD_MODE_DISABLED;
293 
294     switch (security_mode)
295     {
296 #if (BTM_PRE_LISBON_INCLUDED == TRUE)
297         case BTM_SEC_MODE_NONE:
298         case BTM_SEC_MODE_SERVICE:
299         case BTM_SEC_MODE_LINK:
300             break;
301 #endif
302 
303         case BTM_SEC_MODE_SP_DEBUG:
304             sp_debug_mode = HCI_SPD_MODE_ENABLED;
305             break;
306         case BTM_SEC_MODE_SP:
307             /* the default is enabled */
308             break;
309         default:
310             BTM_TRACE_ERROR1 ("BTM_SetSecurityMode: unknown mode:%d", security_mode);
311             return;
312     }
313     btm_cb.security_mode = security_mode;
314 
315     if (HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_features))
316     {
317         /* Lisbon devices and only use BTM_SEC_MODE_SP */
318         btm_cb.security_mode = BTM_SEC_MODE_SP;
319         BTM_TRACE_DEBUG2("BTM_SetSecurityMode: SP:%d, debug:%d", sp_mode, sp_debug_mode);
320         btsnd_hcic_write_simple_pairing_mode(sp_mode);
321         btsnd_hcic_write_simp_pair_debug_mode(sp_debug_mode);
322         return;
323     }
324 
325     /* must be a pre-Lisbon device */
326 #if (BTM_PRE_LISBON_INCLUDED == TRUE)
327     /* If previously security mode was Link Level and now lesser notify */
328     /* controller not to perform authentication, encryption on startup  */
329     if ((old_mode == BTM_SEC_MODE_LINK)
330         && (       security_mode != BTM_SEC_MODE_LINK))
331     {
332         BTM_TRACE_DEBUG0("BTM_SetSecurityMode: Authen Enable -> FALSE");
333         btsnd_hcic_write_auth_enable (FALSE);
334         btsnd_hcic_write_encr_mode (HCI_ENCRYPT_MODE_DISABLED);
335     }
336 
337     /* If previously security is increased to Link Level notify */
338     /* controller to perform authentication, encryption on startup  */
339     if ((old_mode != BTM_SEC_MODE_LINK)
340         && (       security_mode == BTM_SEC_MODE_LINK))
341     {
342         BTM_TRACE_DEBUG0("BTM_SetSecurityMode: Authen Enable -> TRUE");
343         btsnd_hcic_write_auth_enable (TRUE);
344         btsnd_hcic_write_encr_mode (HCI_ENCRYPT_MODE_POINT_TO_POINT);
345     }
346 #endif  /* BTM_PRE_LISBON_INCLUDED == TRUE */
347 }
348 
349 /*******************************************************************************
350 **
351 ** Function         BTM_SetPinType
352 **
353 ** Description      Set PIN type for the device.
354 **
355 ** Returns          void
356 **
357 *******************************************************************************/
BTM_SetPinType(UINT8 pin_type,PIN_CODE pin_code,UINT8 pin_code_len)358 void BTM_SetPinType (UINT8 pin_type, PIN_CODE pin_code, UINT8 pin_code_len)
359 {
360     BTM_TRACE_API3 ("BTM_SetPinType: pin type %d [variable-0, fixed-1], code %s, length %d",
361                     pin_type, (char *) pin_code, pin_code_len);
362 
363     /* If device is not up security mode will be set as a part of startup */
364     if ( (btm_cb.cfg.pin_type != pin_type)
365          && (btm_cb.devcb.state > BTM_DEV_STATE_WAIT_AFTER_RESET) )
366     {
367         btsnd_hcic_write_pin_type (pin_type);
368     }
369 
370     btm_cb.cfg.pin_type     = pin_type;
371     btm_cb.cfg.pin_code_len = pin_code_len;
372     memcpy (btm_cb.cfg.pin_code, pin_code, pin_code_len);
373 }
374 
375 /*******************************************************************************
376 **
377 ** Function         BTM_SetPairableMode
378 **
379 ** Description      Enable or disable pairing
380 **
381 ** Parameters       allow_pairing - (TRUE or FALSE) whether or not the device
382 **                      allows pairing.
383 **                  connect_only_paired - (TRUE or FALSE) whether or not to
384 **                      only allow paired devices to connect.
385 **
386 ** Returns          void
387 **
388 *******************************************************************************/
BTM_SetPairableMode(BOOLEAN allow_pairing,BOOLEAN connect_only_paired)389 void BTM_SetPairableMode (BOOLEAN allow_pairing, BOOLEAN connect_only_paired)
390 {
391     BTM_TRACE_API2 ("BTM_SetPairableMode()  allow_pairing: %u   connect_only_paired: %u", allow_pairing, connect_only_paired);
392 
393     btm_cb.pairing_disabled    = !allow_pairing;
394     btm_cb.connect_only_paired = connect_only_paired;
395 }
396 
397 
398 #define BTM_NO_AVAIL_SEC_SERVICES   ((UINT16) 0xffff)
399 
400 /*******************************************************************************
401 **
402 ** Function         BTM_SetUCDSecurityLevel
403 **
404 ** Description      Register UCD service security level with Security Manager
405 **
406 ** Parameters:      is_originator - TRUE if originating the connection, FALSE if not
407 **                  p_name      - Name of the service relevant only if
408 **                                authorization will show this name to user. ignored
409 **                                if BTM_SEC_SERVICE_NAME_LEN is 0.
410 **                  service_id  - service ID for the service passed to authorization callback
411 **                  sec_level   - bit mask of the security features
412 **                  psm         - L2CAP PSM
413 **                  mx_proto_id - protocol ID of multiplexing proto below
414 **                  mx_chan_id  - channel ID of multiplexing proto below
415 **
416 ** Returns          TRUE if registered OK, else FALSE
417 **
418 *******************************************************************************/
BTM_SetUCDSecurityLevel(BOOLEAN is_originator,char * p_name,UINT8 service_id,UINT16 sec_level,UINT16 psm,UINT32 mx_proto_id,UINT32 mx_chan_id)419 BOOLEAN BTM_SetUCDSecurityLevel (BOOLEAN is_originator, char *p_name, UINT8 service_id,
420                                  UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id,
421                                  UINT32 mx_chan_id)
422 {
423 #if (L2CAP_UCD_INCLUDED == TRUE)
424     CONNECTION_TYPE conn_type;
425 
426     if (is_originator)
427         conn_type = CONNLESS_ORIG;
428     else
429         conn_type = CONNLESS_TERM;
430 
431     return(btm_sec_set_security_level (conn_type, p_name, service_id,
432                                        sec_level, psm, mx_proto_id, mx_chan_id));
433 #else
434     return FALSE;
435 #endif
436 }
437 
438 /*******************************************************************************
439 **
440 ** Function         BTM_SetSecurityLevel
441 **
442 ** Description      Register service security level with Security Manager
443 **
444 ** Parameters:      is_originator - TRUE if originating the connection, FALSE if not
445 **                  p_name      - Name of the service relevant only if
446 **                                authorization will show this name to user. ignored
447 **                                if BTM_SEC_SERVICE_NAME_LEN is 0.
448 **                  service_id  - service ID for the service passed to authorization callback
449 **                  sec_level   - bit mask of the security features
450 **                  psm         - L2CAP PSM
451 **                  mx_proto_id - protocol ID of multiplexing proto below
452 **                  mx_chan_id  - channel ID of multiplexing proto below
453 **
454 ** Returns          TRUE if registered OK, else FALSE
455 **
456 *******************************************************************************/
BTM_SetSecurityLevel(BOOLEAN is_originator,char * p_name,UINT8 service_id,UINT16 sec_level,UINT16 psm,UINT32 mx_proto_id,UINT32 mx_chan_id)457 BOOLEAN BTM_SetSecurityLevel (BOOLEAN is_originator, char *p_name, UINT8 service_id,
458                               UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id,
459                               UINT32 mx_chan_id)
460 {
461 #if (L2CAP_UCD_INCLUDED == TRUE)
462     CONNECTION_TYPE conn_type;
463 
464     if (is_originator)
465         conn_type = CONN_ORIENT_ORIG;
466     else
467         conn_type = CONN_ORIENT_TERM;
468 
469     return(btm_sec_set_security_level (conn_type, p_name, service_id,
470                                        sec_level, psm, mx_proto_id, mx_chan_id));
471 #else
472     return(btm_sec_set_security_level (is_originator, p_name, service_id,
473                                        sec_level, psm, mx_proto_id, mx_chan_id));
474 #endif
475 }
476 
477 /*******************************************************************************
478 **
479 ** Function         btm_sec_set_security_level
480 **
481 ** Description      Register service security level with Security Manager
482 **
483 ** Parameters:      conn_type   - TRUE if originating the connection, FALSE if not
484 **                  p_name      - Name of the service relevant only if
485 **                                authorization will show this name to user. ignored
486 **                                if BTM_SEC_SERVICE_NAME_LEN is 0.
487 **                  service_id  - service ID for the service passed to authorization callback
488 **                  sec_level   - bit mask of the security features
489 **                  psm         - L2CAP PSM
490 **                  mx_proto_id - protocol ID of multiplexing proto below
491 **                  mx_chan_id  - channel ID of multiplexing proto below
492 **
493 ** Returns          TRUE if registered OK, else FALSE
494 **
495 *******************************************************************************/
btm_sec_set_security_level(CONNECTION_TYPE conn_type,char * p_name,UINT8 service_id,UINT16 sec_level,UINT16 psm,UINT32 mx_proto_id,UINT32 mx_chan_id)496 static BOOLEAN btm_sec_set_security_level (CONNECTION_TYPE conn_type, char *p_name, UINT8 service_id,
497                                            UINT16 sec_level, UINT16 psm, UINT32 mx_proto_id,
498                                            UINT32 mx_chan_id)
499 {
500     tBTM_SEC_SERV_REC   *p_srec;
501     UINT16               index;
502     UINT16               first_unused_record = BTM_NO_AVAIL_SEC_SERVICES;
503     BOOLEAN              record_allocated = FALSE;
504     BOOLEAN              is_originator;
505 #if (L2CAP_UCD_INCLUDED == TRUE)
506     BOOLEAN              is_ucd;
507 
508     if (conn_type & CONNECTION_TYPE_ORIG_MASK)
509         is_originator = TRUE;
510     else
511         is_originator = FALSE;
512 
513     if (conn_type & CONNECTION_TYPE_CONNLESS_MASK )
514     {
515         is_ucd = TRUE;
516     }
517     else
518     {
519         is_ucd = FALSE;
520     }
521 #else
522     is_originator = conn_type;
523 #endif
524 
525     /* See if the record can be reused (same service name, psm, mx_proto_id,
526        service_id, and mx_chan_id), or obtain the next unused record */
527 
528     p_srec = &btm_cb.sec_serv_rec[0];
529 
530 
531     for (index = 0; index < BTM_SEC_MAX_SERVICE_RECORDS; index++, p_srec++)
532     {
533         /* Check if there is already a record for this service */
534         if (p_srec->security_flags & BTM_SEC_IN_USE)
535         {
536 #if BTM_SEC_SERVICE_NAME_LEN > 0
537             if (p_srec->psm == psm                  &&
538                 p_srec->mx_proto_id == mx_proto_id  &&
539                 service_id == p_srec->service_id    &&
540                 (!strncmp (p_name, (char *) p_srec->orig_service_name,
541                            BTM_SEC_SERVICE_NAME_LEN) ||
542                  !strncmp (p_name, (char *) p_srec->term_service_name,
543                            BTM_SEC_SERVICE_NAME_LEN)))
544 #else
545             if (p_srec->psm == psm                  &&
546                 p_srec->mx_proto_id == mx_proto_id  &&
547                 service_id == p_srec->service_id)
548 #endif
549             {
550                 record_allocated = TRUE;
551                 break;
552             }
553         }
554         /* Mark the first available service record */
555         else if (!record_allocated)
556         {
557             memset (p_srec, 0, sizeof(tBTM_SEC_SERV_REC));
558             record_allocated = TRUE;
559             first_unused_record = index;
560         }
561     }
562 
563     if (!record_allocated)
564     {
565         BTM_TRACE_WARNING1("BTM_SEC_REG: Out of Service Records (%d)",  BTM_SEC_MAX_SERVICE_RECORDS);
566         return(record_allocated);
567     }
568 
569     /* Process the request if service record is valid */
570     /* If a duplicate service wasn't found, use the first available */
571     if (index >= BTM_SEC_MAX_SERVICE_RECORDS)
572     {
573         index = first_unused_record;
574         p_srec = &btm_cb.sec_serv_rec[index];
575     }
576 
577     p_srec->psm         = psm;
578     p_srec->service_id  = service_id;
579     p_srec->mx_proto_id = mx_proto_id;
580 
581     if (is_originator)
582     {
583         p_srec->orig_mx_chan_id = mx_chan_id;
584 #if BTM_SEC_SERVICE_NAME_LEN > 0
585         BCM_STRNCPY_S ((char *)p_srec->orig_service_name, sizeof(p_srec->orig_service_name), p_name, BTM_SEC_SERVICE_NAME_LEN);
586 #endif
587         /* clear out the old setting, just in case it exists */
588 #if (L2CAP_UCD_INCLUDED == TRUE)
589         if ( is_ucd )
590         {
591             p_srec->ucd_security_flags &=
592             ~(BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_ENCRYPT    | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_MITM |
593               BTM_SEC_FORCE_MASTER | BTM_SEC_ATTEMPT_MASTER | BTM_SEC_FORCE_SLAVE | BTM_SEC_ATTEMPT_SLAVE);
594         }
595         else
596 #endif
597         {
598             p_srec->security_flags &=
599             ~(BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_ENCRYPT    | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_MITM |
600               BTM_SEC_FORCE_MASTER | BTM_SEC_ATTEMPT_MASTER | BTM_SEC_FORCE_SLAVE | BTM_SEC_ATTEMPT_SLAVE);
601         }
602 
603         /* Parameter validation.  Originator should not set requirements for incoming connections */
604         sec_level &= ~(BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_ENCRYPT | BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_MITM);
605 
606         if (btm_cb.security_mode == BTM_SEC_MODE_SP)
607         {
608             if (sec_level & BTM_SEC_OUT_AUTHENTICATE)
609                 sec_level |= BTM_SEC_OUT_MITM;
610         }
611 
612         /* Make sure the authenticate bit is set, when encrypt bit is set */
613         if (sec_level & BTM_SEC_OUT_ENCRYPT)
614             sec_level |= BTM_SEC_OUT_AUTHENTICATE;
615 
616         /* outgoing connections usually set the security level right before
617          * the connection is initiated.
618          * set it to be the outgoing service */
619 #if (L2CAP_UCD_INCLUDED == TRUE)
620         if ( is_ucd == FALSE )
621 #endif
622         {
623             btm_cb.p_out_serv = p_srec;
624         }
625     }
626     else
627     {
628         p_srec->term_mx_chan_id = mx_chan_id;
629 #if BTM_SEC_SERVICE_NAME_LEN > 0
630         BCM_STRNCPY_S ((char *)p_srec->term_service_name, sizeof(p_srec->term_service_name), p_name, BTM_SEC_SERVICE_NAME_LEN);
631 #endif
632         /* clear out the old setting, just in case it exists */
633 #if (L2CAP_UCD_INCLUDED == TRUE)
634         if ( is_ucd )
635         {
636             p_srec->ucd_security_flags &=
637             ~(BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_ENCRYPT     | BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_MITM |
638               BTM_SEC_FORCE_MASTER | BTM_SEC_ATTEMPT_MASTER | BTM_SEC_FORCE_SLAVE | BTM_SEC_ATTEMPT_SLAVE);
639         }
640         else
641 #endif
642         {
643             p_srec->security_flags &=
644             ~(BTM_SEC_IN_AUTHORIZE | BTM_SEC_IN_ENCRYPT     | BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_MITM |
645               BTM_SEC_FORCE_MASTER | BTM_SEC_ATTEMPT_MASTER | BTM_SEC_FORCE_SLAVE | BTM_SEC_ATTEMPT_SLAVE);
646         }
647 
648         /* Parameter validation.  Acceptor should not set requirements for outgoing connections */
649         sec_level &= ~(BTM_SEC_OUT_AUTHORIZE | BTM_SEC_OUT_ENCRYPT | BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_MITM);
650 
651         if (btm_cb.security_mode == BTM_SEC_MODE_SP)
652         {
653             if (sec_level & BTM_SEC_IN_AUTHENTICATE)
654                 sec_level |= BTM_SEC_IN_MITM;
655         }
656 
657         /* Make sure the authenticate bit is set, when encrypt bit is set */
658         if (sec_level & BTM_SEC_IN_ENCRYPT)
659             sec_level |= BTM_SEC_IN_AUTHENTICATE;
660     }
661 
662 #if (L2CAP_UCD_INCLUDED == TRUE)
663     if ( is_ucd )
664     {
665         p_srec->security_flags     |= (UINT16)(BTM_SEC_IN_USE);
666         p_srec->ucd_security_flags |= (UINT16)(sec_level | BTM_SEC_IN_USE);
667     }
668     else
669     {
670         p_srec->security_flags |= (UINT16)(sec_level | BTM_SEC_IN_USE);
671     }
672 
673     BTM_TRACE_API6("BTM_SEC_REG[%d]: id %d, conn_type 0x%x, psm 0x%04x, proto_id %d, chan_id %d",
674                    index, service_id, conn_type, psm, mx_proto_id, mx_chan_id);
675 
676     BTM_TRACE_API2("               : security_flags: 0x%04x, ucd_security_flags: 0x%04x",
677                    p_srec->security_flags, p_srec->ucd_security_flags);
678 
679 #if BTM_SEC_SERVICE_NAME_LEN > 0
680     BTM_TRACE_API2("               : service name [%s] (up to %d chars saved)",
681                    p_name, BTM_SEC_SERVICE_NAME_LEN);
682 #endif
683 #else
684     p_srec->security_flags |= (UINT16)(sec_level | BTM_SEC_IN_USE);
685 
686     BTM_TRACE_API6("BTM_SEC_REG[%d]: id %d, is_orig %d, psm 0x%04x, proto_id %d, chan_id %d",
687                    index, service_id, is_originator, psm, mx_proto_id, mx_chan_id);
688 
689 #if BTM_SEC_SERVICE_NAME_LEN > 0
690     BTM_TRACE_API3("               : sec: 0x%x, service name [%s] (up to %d chars saved)",
691                    p_srec->security_flags, p_name, BTM_SEC_SERVICE_NAME_LEN);
692 #endif
693 #endif
694 
695 
696     return(record_allocated);
697 }
698 
699 /*******************************************************************************
700 **
701 ** Function         BTM_SecClrService
702 **
703 ** Description      Removes specified service record(s) from the security database.
704 **                  All service records with the specified name are removed.
705 **                  Typically used only by devices with limited RAM so that it can
706 **                  reuse an old security service record.
707 **
708 **                  Note: Unpredictable results may occur if a service is cleared
709 **                      that is still in use by an application/profile.
710 **
711 ** Parameters       Service ID - Id of the service to remove. ('0' removes all service
712 **                          records (except SDP).
713 **
714 ** Returns          Number of records that were freed.
715 **
716 *******************************************************************************/
BTM_SecClrService(UINT8 service_id)717 UINT8 BTM_SecClrService (UINT8 service_id)
718 {
719     tBTM_SEC_SERV_REC   *p_srec = &btm_cb.sec_serv_rec[0];
720     UINT8   num_freed = 0;
721     int     i;
722 
723     for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_srec++)
724     {
725         /* Delete services with specified name (if in use and not SDP) */
726         if ((p_srec->security_flags & BTM_SEC_IN_USE) && (p_srec->psm != BT_PSM_SDP) &&
727             (!service_id || (service_id == p_srec->service_id)))
728         {
729             BTM_TRACE_API2("BTM_SEC_CLR[%d]: id %d", i, service_id);
730             p_srec->security_flags = 0;
731 #if (L2CAP_UCD_INCLUDED == TRUE)
732             p_srec->ucd_security_flags = 0;
733 #endif
734             num_freed++;
735         }
736     }
737 
738     return(num_freed);
739 }
740 
741 /*******************************************************************************
742 **
743 ** Function         btm_sec_clr_service_by_psm
744 **
745 ** Description      Removes specified service record from the security database.
746 **                  All service records with the specified psm are removed.
747 **                  Typically used by L2CAP to free up the service record used
748 **                  by dynamic PSM clients when the channel is closed.
749 **                  The given psm must be a virtual psm.
750 **
751 ** Parameters       Service ID - Id of the service to remove. ('0' removes all service
752 **                          records (except SDP).
753 **
754 ** Returns          Number of records that were freed.
755 **
756 *******************************************************************************/
btm_sec_clr_service_by_psm(UINT16 psm)757 UINT8 btm_sec_clr_service_by_psm (UINT16 psm)
758 {
759     tBTM_SEC_SERV_REC   *p_srec = &btm_cb.sec_serv_rec[0];
760     UINT8   num_freed = 0;
761     int     i;
762 
763     for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_srec++)
764     {
765         /* Delete services with specified name (if in use and not SDP) */
766         if ((p_srec->security_flags & BTM_SEC_IN_USE) && (p_srec->psm == psm) )
767         {
768             BTM_TRACE_API2("BTM_SEC_CLR[%d]: id %d ", i, p_srec->service_id);
769             p_srec->security_flags = 0;
770             num_freed++;
771         }
772     }
773     BTM_TRACE_API2("btm_sec_clr_service_by_psm psm:0x%x num_freed:%d", psm, num_freed);
774 
775     return(num_freed);
776 }
777 
778 /*******************************************************************************
779 **
780 ** Function         BTM_SecClrUCDService
781 **
782 ** Description
783 **
784 ** Parameters       Service ID - Id of the service to remove.
785 **                               ('0' removes all service records )
786 **
787 ** Returns          Number of records that were cleared.
788 **
789 *******************************************************************************/
BTM_SecClrUCDService(UINT8 service_id)790 UINT8 BTM_SecClrUCDService (UINT8 service_id)
791 {
792 #if (L2CAP_UCD_INCLUDED == TRUE)
793     tBTM_SEC_SERV_REC   *p_srec = &btm_cb.sec_serv_rec[0];
794     UINT8   num_cleared = 0;
795     int     i;
796 
797     for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_srec++)
798     {
799         /* Delete services with specified name (if in use and not SDP) */
800         if ((p_srec->security_flags & BTM_SEC_IN_USE) &&
801             (!service_id || (service_id == (UINT32)p_srec->service_id)))
802         {
803             BTM_TRACE_API2("BTM_UCD_SEC_CLR[%d]: id %d", i, service_id);
804             p_srec->ucd_security_flags = 0;
805             num_cleared++;
806         }
807     }
808 
809     return(num_cleared);
810 #else
811     return(0);
812 #endif
813 }
814 
815 /*******************************************************************************
816 **
817 ** Function         BTM_PINCodeReply
818 **
819 ** Description      This function is called after Security Manager submitted
820 **                  PIN code request to the UI.
821 **
822 ** Parameters:      bd_addr      - Address of the device for which PIN was requested
823 **                  res          - result of the operation BTM_SUCCESS if success
824 **                  pin_len      - length in bytes of the PIN Code
825 **                  p_pin        - pointer to array with the PIN Code
826 **                  trusted_mask - bitwise OR of trusted services (array of UINT32)
827 **
828 *******************************************************************************/
BTM_PINCodeReply(BD_ADDR bd_addr,UINT8 res,UINT8 pin_len,UINT8 * p_pin,UINT32 trusted_mask[])829 void BTM_PINCodeReply (BD_ADDR bd_addr, UINT8 res, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
830 {
831     tBTM_SEC_DEV_REC *p_dev_rec;
832 
833     BTM_TRACE_API4 ("BTM_PINCodeReply(): PairState: %s   PairFlags: 0x%02x  PinLen:%d  Result:%d",
834                     btm_pair_state_descr(btm_cb.pairing_state), btm_cb.pairing_flags, pin_len, res);
835 
836     /* If timeout already expired or has been canceled, ignore the reply */
837     if (btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_LOCAL_PIN)
838     {
839         BTM_TRACE_WARNING1 ("BTM_PINCodeReply() - Wrong State: %d", btm_cb.pairing_state);
840         return;
841     }
842 
843     if (memcmp (bd_addr, btm_cb.pairing_bda, BD_ADDR_LEN) != 0)
844     {
845         BTM_TRACE_ERROR0 ("BTM_PINCodeReply() - Wrong BD Addr");
846         return;
847     }
848 
849     if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
850     {
851         BTM_TRACE_ERROR0 ("BTM_PINCodeReply() - no dev CB");
852         return;
853     }
854 
855     if ( (pin_len > PIN_CODE_LEN) || (pin_len == 0) || (p_pin == NULL) )
856         res = BTM_ILLEGAL_VALUE;
857 
858     if (res != BTM_SUCCESS)
859     {
860         /* if peer started dd OR we started dd and pre-fetch pin was not used send negative reply */
861         if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PEER_STARTED_DD) ||
862             ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) &&
863             (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE)) )
864         {
865             /* use BTM_PAIR_STATE_WAIT_AUTH_COMPLETE to report authentication failed event */
866             btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
867             btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
868 
869             btsnd_hcic_pin_code_neg_reply (bd_addr);
870         }
871         else
872         {
873             p_dev_rec->security_required = BTM_SEC_NONE;
874             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
875         }
876         return;
877     }
878     if (trusted_mask)
879         BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
880     p_dev_rec->sec_flags   |= BTM_SEC_LINK_KEY_AUTHED;
881 
882     if ( (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
883          &&  (p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE)
884          &&  (btm_cb.security_mode_changed == FALSE) )
885     {
886         /* This is start of the dedicated bonding if local device is 2.0 */
887         btm_cb.pin_code_len = pin_len;
888         memcpy (btm_cb.pin_code, p_pin, pin_len);
889 
890         btm_cb.security_mode_changed = TRUE;
891 #ifdef APPL_AUTH_WRITE_EXCEPTION
892         if(!(APPL_AUTH_WRITE_EXCEPTION)(p_dev_rec->bd_addr))
893 #endif
894         btsnd_hcic_write_auth_enable (TRUE);
895 
896         btm_cb.acl_disc_reason = 0xff ;
897 
898         /* if we rejected incoming connection request, we have to wait HCI_Connection_Complete event */
899         /*  before originating  */
900         if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT)
901         {
902             BTM_TRACE_WARNING0 ("BTM_PINCodeReply(): waiting HCI_Connection_Complete after rejected incoming connection");
903             /* we change state little bit early so btm_sec_connected() will originate connection */
904             /*   when existing ACL link is down completely */
905             btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
906         }
907         /* if we already accepted incoming connection from pairing device */
908         else if (p_dev_rec->sm4 & BTM_SM4_CONN_PEND)
909         {
910             BTM_TRACE_WARNING0 ("BTM_PINCodeReply(): link is connecting so wait pin code request from peer");
911             btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
912         }
913         else if (btm_sec_dd_create_conn(p_dev_rec) != BTM_CMD_STARTED)
914         {
915             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
916             p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_AUTHED;
917 
918             (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,  p_dev_rec->dev_class,
919                                                     p_dev_rec->sec_bd_name, HCI_ERR_AUTH_FAILURE);
920         }
921         return;
922     }
923 
924     btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
925     btm_cb.acl_disc_reason = HCI_SUCCESS;
926 
927 #ifdef PORCHE_PAIRING_CONFLICT
928     BTM_TRACE_EVENT2("BTM_PINCodeReply(): Saving pin_len: %d btm_cb.pin_code_len: %d", pin_len, btm_cb.pin_code_len);
929     /* if this was not pre-fetched, save the PIN */
930     if (btm_cb.pin_code_len == 0)
931         memcpy (btm_cb.pin_code, p_pin, pin_len);
932     btm_cb.pin_code_len_saved = pin_len;
933 #endif
934     btsnd_hcic_pin_code_req_reply (bd_addr, pin_len, p_pin);
935 }
936 
937 
938 /*******************************************************************************
939 **
940 ** Function         BTM_DeviceAuthorized
941 **
942 ** Description      This function is called after Security Manager submitted
943 **                  authorization request to the UI.
944 **
945 ** Parameters:      bd_addr     - Address of the device for which PIN was requested
946 **                  res         - result of the operation BTM_SUCCESS if success
947 **
948 *******************************************************************************/
BTM_DeviceAuthorized(BD_ADDR bd_addr,UINT8 res,UINT32 trusted_mask[])949 void BTM_DeviceAuthorized (BD_ADDR bd_addr, UINT8 res, UINT32 trusted_mask[])
950 {
951     tBTM_SEC_DEV_REC *p_dev_rec;
952 
953     if ((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
954     {
955         BTM_TRACE_WARNING6 ("Security Manager: Attempting Authorization of Unknown Device Address [%02x%02x%02x%02x%02x%02x]",
956                             bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
957         return;
958     }
959 
960     BTM_TRACE_EVENT4 ("Security Manager: authorized status:%d State:%d Trusted:%08x %08x",
961                       res, (p_dev_rec) ? p_dev_rec->sec_state : 0, trusted_mask[0], trusted_mask[1]);
962 
963     if (res == BTM_SUCCESS)
964     {
965         p_dev_rec->sec_flags   |= BTM_SEC_AUTHORIZED;
966         if (trusted_mask)
967             BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
968     }
969 
970     if (p_dev_rec->sec_state != BTM_SEC_STATE_AUTHORIZING)
971         return;
972 
973     p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
974 
975     if (res != BTM_SUCCESS)
976     {
977         btm_sec_dev_rec_cback_event (p_dev_rec, res);
978         return;
979     }
980 
981     if ((res = (UINT8)btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
982     {
983         btm_sec_dev_rec_cback_event (p_dev_rec, res);
984     }
985 }
986 
987 
988 
989 /*******************************************************************************
990 **
991 ** Function         BTM_SecBond
992 **
993 ** Description      This function is called to perform bonding with peer device.
994 **                  If the connection is already up, but not secure, pairing
995 **                  is attempted.  If already paired BTM_SUCCESS is returned.
996 **
997 ** Parameters:      bd_addr      - Address of the device to bond
998 **                  pin_len      - length in bytes of the PIN Code
999 **                  p_pin        - pointer to array with the PIN Code
1000 **                  trusted_mask - bitwise OR of trusted services (array of UINT32)
1001 **
1002 **  Note: After 2.1 parameters are not used and preserved here not to change API
1003 *******************************************************************************/
BTM_SecBond(BD_ADDR bd_addr,UINT8 pin_len,UINT8 * p_pin,UINT32 trusted_mask[])1004 tBTM_STATUS BTM_SecBond (BD_ADDR bd_addr, UINT8 pin_len, UINT8 *p_pin, UINT32 trusted_mask[])
1005 {
1006     tBTM_SEC_DEV_REC *p_dev_rec;
1007     tBTM_STATUS      status;
1008 #if SMP_INCLUDED == TRUE
1009     tACL_CONN   *p=NULL;
1010     BOOLEAN     is_le_slave_role=FALSE;
1011 #endif
1012     BTM_TRACE_API6 ("BTM_SecBond BDA: %02x:%02x:%02x:%02x:%02x:%02x",
1013                     bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
1014 
1015     /* Other security process is in progress */
1016     if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
1017     {
1018         BTM_TRACE_ERROR1 ("BTM_SecBond: already busy in state: %s", btm_pair_state_descr(btm_cb.pairing_state));
1019         return(BTM_WRONG_MODE);
1020     }
1021 
1022 
1023     p_dev_rec = btm_find_or_alloc_dev (bd_addr);
1024     BTM_TRACE_DEBUG1 ("before update sec_flags=0x%x", p_dev_rec->sec_flags);
1025 
1026 
1027 #if SMP_INCLUDED == TRUE
1028     p = btm_bda_to_acl(bd_addr);
1029     if (p && p->is_le_link )
1030     {
1031         if (p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING)
1032         {
1033             BTM_TRACE_ERROR1 ("BTM_SecBond: LE already busy in state: %x", p_dev_rec->sec_state );
1034             return(BTM_WRONG_MODE);
1035         }
1036 
1037         if (p->link_role == BTM_ROLE_SLAVE)
1038         {
1039             is_le_slave_role = TRUE;
1040             BTM_TRACE_DEBUG0 ("LE Link Slave" );
1041         }
1042         else
1043         {
1044             BTM_TRACE_DEBUG0 ("LE Link Maste" );
1045         }
1046     }
1047     else
1048     {
1049         BTM_TRACE_DEBUG0 ("No LE Link" );
1050     }
1051 
1052     if (!is_le_slave_role)
1053     {
1054         /* Finished if connection is active and already paired */
1055         if ( (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
1056              &&  (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED) )
1057         {
1058             BTM_TRACE_WARNING0("BTM_SecBond -> Already Paired");
1059             return(BTM_SUCCESS);
1060         }
1061     }
1062 #else
1063     /* Finished if connection is active and already paired */
1064     if ( (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
1065          &&  (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED) )
1066     {
1067         BTM_TRACE_WARNING0("BTM_SecBond -> Already Paired");
1068         return(BTM_SUCCESS);
1069     }
1070 #endif
1071 
1072     /* Tell controller to get rid of the link key if it has one stored */
1073     if ((BTM_DeleteStoredLinkKey (bd_addr, NULL)) != BTM_SUCCESS)
1074         return(BTM_NO_RESOURCES);
1075 
1076     /* Save the PIN code if we got a valid one */
1077     if (p_pin && (pin_len <= PIN_CODE_LEN) && (pin_len != 0))
1078     {
1079         btm_cb.pin_code_len = pin_len;
1080         memcpy (btm_cb.pin_code, p_pin, PIN_CODE_LEN);
1081     }
1082 
1083     memcpy (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN);
1084 
1085     btm_cb.pairing_flags = BTM_PAIR_FLAGS_WE_STARTED_DD;
1086 
1087     p_dev_rec->security_required = BTM_SEC_OUT_AUTHENTICATE;
1088     p_dev_rec->is_originator     = TRUE;
1089     if (trusted_mask)
1090         BTM_SEC_COPY_TRUSTED_DEVICE(trusted_mask, p_dev_rec->trusted_mask);
1091 
1092 
1093 
1094 #if SMP_INCLUDED == TRUE
1095 
1096     if (!is_le_slave_role)
1097     {
1098         p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED
1099                                   | BTM_SEC_ROLE_SWITCHED  | BTM_SEC_LINK_KEY_AUTHED);
1100 
1101     }
1102 
1103     /* LE device, do SMP pairing */
1104     if (p_dev_rec->device_type == BT_DEVICE_TYPE_BLE)
1105     {
1106         if (SMP_Pair(p_dev_rec->bd_addr) == SMP_STARTED)
1107         {
1108             p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
1109             return BTM_CMD_STARTED;
1110         }
1111         else
1112             return(BTM_NO_RESOURCES);
1113     }
1114 #else
1115     p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED
1116                               | BTM_SEC_ROLE_SWITCHED  | BTM_SEC_LINK_KEY_AUTHED);
1117 #endif
1118 
1119     BTM_TRACE_DEBUG1 ("after update sec_flags=0x%x", p_dev_rec->sec_flags);
1120     if (!HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_features))
1121     {
1122         /* The special case when we authenticate keyboard.  Set pin type to fixed */
1123         /* It would be probably better to do it from the application, but it is */
1124         /* complicated */
1125         if (((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) == BTM_COD_MAJOR_PERIPHERAL)
1126             && (p_dev_rec->dev_class[2] & BTM_COD_MINOR_KEYBOARD)
1127             && (btm_cb.cfg.pin_type != HCI_PIN_TYPE_FIXED))
1128         {
1129             btm_cb.pin_type_changed = TRUE;
1130             btsnd_hcic_write_pin_type (HCI_PIN_TYPE_FIXED);
1131         }
1132     }
1133 
1134     BTM_TRACE_EVENT1("BTM_SecBond: Local device supports SSP=%d", HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_features));
1135 
1136     BTM_TRACE_EVENT4("  remote_features=%02x-%02x-%02x-%02x",
1137                      p_dev_rec->features[0], p_dev_rec->features[1], p_dev_rec->features[2], p_dev_rec->features[3]);
1138     BTM_TRACE_EVENT4("                  %02x-%02x-%02x-%02x",
1139                      p_dev_rec->features[4], p_dev_rec->features[5], p_dev_rec->features[6], p_dev_rec->features[7]);
1140 
1141     BTM_TRACE_EVENT2 ("BTM_SecBond: Remote sm4: 0x%x  HCI Handle: 0x%04x", p_dev_rec->sm4, p_dev_rec->hci_handle);
1142 
1143 #if BTM_SEC_FORCE_RNR_FOR_DBOND == TRUE
1144     p_dev_rec->sec_flags &= ~BTM_SEC_NAME_KNOWN;
1145 #endif
1146 
1147     /* If connection already exists... */
1148     if (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
1149     {
1150         if (!btm_sec_start_authentication (p_dev_rec))
1151             return(BTM_NO_RESOURCES);
1152 
1153         btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
1154 
1155         /* Mark lcb as bonding */
1156         l2cu_update_lcb_4_bonding (bd_addr, TRUE);
1157         return(BTM_CMD_STARTED);
1158     }
1159 
1160     BTM_TRACE_DEBUG2 ("sec mode: %d sm4:x%x", btm_cb.security_mode, p_dev_rec->sm4);
1161     if (!HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_features)
1162         || (p_dev_rec->sm4 == BTM_SM4_KNOWN))
1163     {
1164         if ( btm_sec_check_prefetch_pin (p_dev_rec) )
1165 	        return(BTM_CMD_STARTED);
1166     }
1167     if (BTM_SEC_MODE_SP == btm_cb.security_mode && BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4))
1168     {
1169         /* local is 2.1 and peer is unknown */
1170         if ((p_dev_rec->sm4 & BTM_SM4_CONN_PEND) == 0)
1171         {
1172             /* we are not accepting connection request from peer
1173              * -> RNR (to learn if peer is 2.1)
1174              * RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */
1175             btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);
1176             BTM_ReadRemoteDeviceName(bd_addr, NULL);
1177         }
1178         else
1179         {
1180             /* We are accepting connection request from peer */
1181             btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
1182         }
1183         BTM_TRACE_DEBUG3 ("State:%s sm4: 0x%x sec_state:%d", btm_pair_state_descr (btm_cb.pairing_state), p_dev_rec->sm4, p_dev_rec->sec_state);
1184         return BTM_CMD_STARTED;
1185     }
1186 
1187     /* both local and peer are 2.1  */
1188     status = btm_sec_dd_create_conn(p_dev_rec);
1189 
1190     if (status != BTM_CMD_STARTED)
1191     {
1192         btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
1193     }
1194 
1195     return status;
1196 }
1197 
1198 
1199 /*******************************************************************************
1200 **
1201 ** Function         BTM_SecBondCancel
1202 **
1203 ** Description      This function is called to cancel ongoing bonding process
1204 **                  with peer device.
1205 **
1206 ** Parameters:      bd_addr      - Address of the peer device
1207 **
1208 *******************************************************************************/
BTM_SecBondCancel(BD_ADDR bd_addr)1209 tBTM_STATUS BTM_SecBondCancel (BD_ADDR bd_addr)
1210 {
1211     tBTM_SEC_DEV_REC *p_dev_rec;
1212 #if SMP_INCLUDED == TRUE
1213     tACL_CONN   *p=NULL;
1214 #endif
1215 
1216     BTM_TRACE_API2 ("BTM_SecBondCancel()  State: %s flags:0x%x",
1217                     btm_pair_state_descr (btm_cb.pairing_state), btm_cb.pairing_flags);
1218 
1219     if (((p_dev_rec = btm_find_dev (bd_addr)) == NULL)
1220         ||  (memcmp (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN) != 0) )
1221         return BTM_UNKNOWN_ADDR;
1222 
1223 #if SMP_INCLUDED == TRUE
1224     p = btm_bda_to_acl(bd_addr);
1225     if (p && p->is_le_link &&
1226         (p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING))
1227     {
1228         BTM_TRACE_DEBUG0 ("Cancel LE pairing");
1229         if (SMP_PairCancel(bd_addr))
1230         {
1231             return BTM_CMD_STARTED;
1232         }
1233         else
1234         {
1235             return BTM_WRONG_MODE;
1236         }
1237     }
1238 
1239 #endif
1240     BTM_TRACE_DEBUG2 ("hci_handle:0x%x sec_state:%d", p_dev_rec->hci_handle, p_dev_rec->sec_state );
1241     if (BTM_PAIR_STATE_WAIT_LOCAL_PIN == btm_cb.pairing_state &&
1242         BTM_PAIR_FLAGS_WE_STARTED_DD & btm_cb.pairing_flags)
1243     {
1244         /* pre-fetching pin for dedicated bonding */
1245         btm_sec_bond_cancel_complete();
1246         return BTM_SUCCESS;
1247     }
1248 
1249     /* If this BDA is in a bonding procedure */
1250     if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
1251          &&  (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD))
1252     {
1253         /* If the HCI link is up */
1254         if (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
1255         {
1256             /* If some other thread disconnecting, we do not send second command */
1257             if (p_dev_rec->sec_state == BTM_SEC_STATE_DISCONNECTING)
1258                 return(BTM_CMD_STARTED);
1259 
1260             /* If the HCI link was set up by Bonding process */
1261             if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE)
1262                 return btm_sec_send_hci_disconnect(p_dev_rec, HCI_ERR_PEER_USER);
1263             else
1264                 l2cu_update_lcb_4_bonding(bd_addr, FALSE);
1265 
1266             return BTM_NOT_AUTHORIZED;
1267         }
1268         else /*HCI link is not up */
1269         {
1270             /* If the HCI link creation was started by Bonding process */
1271             if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE)
1272             {
1273                 if (btsnd_hcic_create_conn_cancel(bd_addr))
1274                     return BTM_CMD_STARTED;
1275 
1276                 return BTM_NO_RESOURCES;
1277             }
1278 
1279             return BTM_NOT_AUTHORIZED;
1280         }
1281     }
1282 
1283     return BTM_WRONG_MODE;
1284 }
1285 
1286 /*******************************************************************************
1287 **
1288 ** Function         BTM_SecUseMasterLinkKey
1289 **
1290 ** Description      This function is called to tell master of the piconet to
1291 **                  switch to master link key
1292 **
1293 ** Parameters:      use_master_key - If true Master Link Key shoul be used
1294 **
1295 *******************************************************************************/
BTM_SecUseMasterLinkKey(BOOLEAN use_master_key)1296 tBTM_STATUS BTM_SecUseMasterLinkKey (BOOLEAN use_master_key)
1297 {
1298     return(btsnd_hcic_master_link_key (use_master_key) ?  BTM_SUCCESS :
1299            BTM_NO_RESOURCES);
1300 }
1301 
1302 /*******************************************************************************
1303 **
1304 ** Function         BTM_SetMasterKeyCompCback
1305 **
1306 ** Description      This function is called to register for the master key complete
1307 **                  status event.
1308 **
1309 ** Parameters:      mkey_cback - callback registered with the security manager
1310 **
1311 *******************************************************************************/
BTM_SetMasterKeyCompCback(tBTM_MKEY_CALLBACK * mkey_cback)1312 void BTM_SetMasterKeyCompCback( tBTM_MKEY_CALLBACK *mkey_cback )
1313 {
1314     btm_cb.mkey_cback = mkey_cback;
1315 }
1316 
1317 /*******************************************************************************
1318 **
1319 ** Function         BTM_SecGetDeviceLinkKey
1320 **
1321 ** Description      This function is called to obtain link key for the device
1322 **                  it returns BTM_SUCCESS if link key is available, or
1323 **                  BTM_UNKNOWN_ADDR if Security Manager does not know about
1324 **                  the device or device record does not contain link key info
1325 **
1326 ** Parameters:      bd_addr      - Address of the device
1327 **                  link_key     - Link Key is copied into this array
1328 **
1329 *******************************************************************************/
BTM_SecGetDeviceLinkKey(BD_ADDR bd_addr,LINK_KEY link_key)1330 tBTM_STATUS BTM_SecGetDeviceLinkKey (BD_ADDR bd_addr, LINK_KEY link_key)
1331 {
1332     tBTM_SEC_DEV_REC *p_dev_rec;
1333 
1334     if (((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
1335         && (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN))
1336     {
1337         memcpy (link_key, p_dev_rec->link_key, LINK_KEY_LEN);
1338         return(BTM_SUCCESS);
1339     }
1340     return(BTM_UNKNOWN_ADDR);
1341 }
1342 
1343 
1344 /*******************************************************************************
1345 **
1346 ** Function         BTM_SetEncryption
1347 **
1348 ** Description      This function is called to ensure that connection is
1349 **                  encrypted.  Should be called only on an open connection.
1350 **                  Typically only needed for connections that first want to
1351 **                  bring up unencrypted links, then later encrypt them.
1352 **
1353 ** Parameters:      bd_addr       - Address of the peer device
1354 **                  p_callback    - Pointer to callback function called if
1355 **                                  this function returns PENDING after required
1356 **                                  procedures are completed.  Can be set to NULL
1357 **                                  if status is not desired.
1358 **                  p_ref_data    - pointer to any data the caller wishes to receive
1359 **                                  in the callback function upon completion.
1360 *                                   can be set to NULL if not used.
1361 **
1362 ** Returns          BTM_SUCCESS   - already encrypted
1363 **                  BTM_PENDING   - command will be returned in the callback
1364 **                  BTM_WRONG_MODE- connection not up.
1365 **                  BTM_BUSY      - security procedures are currently active
1366 **                  BTM_MODE_UNSUPPORTED - if security manager not linked in.
1367 **
1368 *******************************************************************************/
BTM_SetEncryption(BD_ADDR bd_addr,tBTM_SEC_CBACK * p_callback,void * p_ref_data)1369 tBTM_STATUS BTM_SetEncryption (BD_ADDR bd_addr, tBTM_SEC_CBACK *p_callback,
1370                                void *p_ref_data)
1371 {
1372     tBTM_SEC_DEV_REC  *p_dev_rec;
1373     tBTM_STATUS       rc;
1374 
1375 #if BLE_INCLUDED == TRUE
1376     tACL_CONN         *p;
1377     p = btm_bda_to_acl(bd_addr);
1378 #endif
1379 
1380     p_dev_rec = btm_find_dev (bd_addr);
1381     if (!p_dev_rec || (p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE))
1382     {
1383         /* Connection should be up and runnning */
1384         BTM_TRACE_WARNING0 ("Security Manager: BTM_SetEncryption not connected");
1385 
1386         if (p_callback)
1387             (*p_callback) (bd_addr, p_ref_data, BTM_WRONG_MODE);
1388 
1389         return(BTM_WRONG_MODE);
1390     }
1391 
1392 
1393     if (
1394 #if BLE_INCLUDED == TRUE
1395        !p->is_le_link &&
1396 #endif
1397        (p_dev_rec->sec_flags & (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED))
1398        == (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED))
1399     {
1400         BTM_TRACE_EVENT0 ("Security Manager: BTM_SetEncryption already encrypted");
1401 
1402         if (p_callback)
1403             (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS);
1404 
1405         return(BTM_SUCCESS);
1406     }
1407 
1408     if (p_dev_rec->p_callback)
1409     {
1410         /* Connection should be up and runnning */
1411         BTM_TRACE_WARNING0 ("Security Manager: BTM_SetEncryption busy");
1412 
1413         if (p_callback)
1414             (*p_callback) (bd_addr, p_ref_data, BTM_BUSY);
1415 
1416         return(BTM_BUSY);
1417     }
1418 
1419     p_dev_rec->p_callback        = p_callback;
1420     p_dev_rec->p_ref_data        = p_ref_data;
1421     p_dev_rec->security_required |= (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT);
1422     p_dev_rec->is_originator     = FALSE;
1423 
1424     BTM_TRACE_API4 ("Security Manager: BTM_SetEncryption Handle:%d State:%d Flags:0x%x Required:0x%x",
1425                     p_dev_rec->hci_handle, p_dev_rec->sec_state, p_dev_rec->sec_flags,
1426                     p_dev_rec->security_required);
1427 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
1428     if (p->is_le_link)
1429     {
1430         rc = btm_ble_set_encryption(bd_addr, p_ref_data, p->link_role);
1431     }
1432     else
1433 #endif
1434 
1435         rc = btm_sec_execute_procedure (p_dev_rec);
1436 
1437     if ( rc != BTM_CMD_STARTED)
1438     {
1439         if (p_callback)
1440         {
1441             p_dev_rec->p_callback = NULL;
1442             (*p_callback) (bd_addr, p_dev_rec->p_ref_data, rc);
1443         }
1444     }
1445     return(rc);
1446 }
1447 
1448 /*******************************************************************************
1449  * disconnect the ACL link, if it's not done yet.
1450 *******************************************************************************/
btm_sec_send_hci_disconnect(tBTM_SEC_DEV_REC * p_dev_rec,UINT8 reason)1451 static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason)
1452 {
1453     UINT8 old_state = p_dev_rec->sec_state;
1454 
1455     BTM_TRACE_EVENT2 ("btm_sec_send_hci_disconnect:  handle:0x%x, reason=0x%x",
1456                       p_dev_rec->hci_handle, reason);
1457 
1458     /* if some other thread disconnecting, we do not send second command */
1459     if (BTM_SEC_STATE_DISCONNECTING != old_state)
1460     {
1461         p_dev_rec->sec_state = BTM_SEC_STATE_DISCONNECTING;
1462 
1463 #if BTM_DISC_DURING_RS == TRUE
1464         /* If a Role Switch is in progress, delay the HCI Disconnect to avoid controller problem (4329B1) */
1465         if (p_dev_rec->rs_disc_pending == BTM_SEC_RS_PENDING)
1466         {
1467                  BTM_TRACE_ERROR0("RS in progress - Set DISC Pending flag in btm_sec_send_hci_disconnect to delay disconnect");
1468                  p_dev_rec->rs_disc_pending = BTM_SEC_DISC_PENDING;
1469                  return BTM_SUCCESS;
1470         }
1471 #endif
1472         /* Tear down the HCI link */
1473         if (!btsnd_hcic_disconnect (p_dev_rec->hci_handle, reason))
1474         {
1475             /* could not send disconnect. restore old state */
1476             p_dev_rec->sec_state = old_state;
1477             return(BTM_NO_RESOURCES);
1478         }
1479     }
1480     return(BTM_CMD_STARTED);
1481 }
1482 
1483 /*******************************************************************************
1484 **
1485 ** Function         BTM_ConfirmReqReply
1486 **
1487 ** Description      This function is called to confirm the numeric value for
1488 **                  Simple Pairing in response to BTM_SP_CFM_REQ_EVT
1489 **
1490 ** Parameters:      res           - result of the operation BTM_SUCCESS if success
1491 **                  bd_addr       - Address of the peer device
1492 **
1493 *******************************************************************************/
BTM_ConfirmReqReply(tBTM_STATUS res,BD_ADDR bd_addr)1494 void BTM_ConfirmReqReply(tBTM_STATUS res, BD_ADDR bd_addr)
1495 {
1496     tBTM_SEC_DEV_REC *p_dev_rec;
1497 
1498     BTM_TRACE_EVENT2 ("BTM_ConfirmReqReply() State: %s  Res: %u",
1499                       btm_pair_state_descr(btm_cb.pairing_state), res);
1500 
1501     /* If timeout already expired or has been canceled, ignore the reply */
1502     if ( (btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM)
1503          ||  (memcmp (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN) != 0) )
1504         return;
1505 
1506     btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
1507 
1508     if ( (res == BTM_SUCCESS) || (res == BTM_SUCCESS_NO_SECURITY) )
1509     {
1510         btm_cb.acl_disc_reason = HCI_SUCCESS;
1511 
1512         if (res == BTM_SUCCESS)
1513         {
1514             if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
1515                 p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_AUTHED;
1516         }
1517 
1518         btsnd_hcic_user_conf_reply (bd_addr, TRUE);
1519     }
1520     else
1521     {
1522         /* Report authentication failed event from state BTM_PAIR_STATE_WAIT_AUTH_COMPLETE */
1523         btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
1524         btsnd_hcic_user_conf_reply (bd_addr, FALSE);
1525     }
1526 }
1527 
1528 /*******************************************************************************
1529 **
1530 ** Function         BTM_PasskeyReqReply
1531 **
1532 ** Description      This function is called to provide the passkey for
1533 **                  Simple Pairing in response to BTM_SP_KEY_REQ_EVT
1534 **
1535 ** Parameters:      res     - result of the operation BTM_SUCCESS if success
1536 **                  bd_addr - Address of the peer device
1537 **                  passkey - numeric value in the range of
1538 **                  BTM_MIN_PASSKEY_VAL(0) - BTM_MAX_PASSKEY_VAL(999999(0xF423F)).
1539 **
1540 *******************************************************************************/
1541 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
BTM_PasskeyReqReply(tBTM_STATUS res,BD_ADDR bd_addr,UINT32 passkey)1542 void BTM_PasskeyReqReply(tBTM_STATUS res, BD_ADDR bd_addr, UINT32 passkey)
1543 {
1544     tBTM_SEC_DEV_REC *p_dev_rec;
1545 
1546     BTM_TRACE_API2 ("BTM_PasskeyReqReply: State: %s  res:%d",
1547                     btm_pair_state_descr(btm_cb.pairing_state), res);
1548 
1549     if ( (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE)
1550          ||  (memcmp (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN) != 0) )
1551     {
1552         return;
1553     }
1554 
1555     /* If timeout already expired or has been canceled, ignore the reply */
1556     if ( (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_AUTH_COMPLETE) && (res != BTM_SUCCESS) )
1557     {
1558         if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
1559         {
1560             btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
1561 
1562             if (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE)
1563                 btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE);
1564             else
1565                 BTM_SecBondCancel(bd_addr);
1566 
1567             p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_AUTHED | BTM_SEC_LINK_KEY_KNOWN);
1568 
1569             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
1570             return;
1571         }
1572     }
1573     else if (btm_cb.pairing_state != BTM_PAIR_STATE_KEY_ENTRY)
1574         return;
1575 
1576     if (passkey > BTM_MAX_PASSKEY_VAL)
1577         res = BTM_ILLEGAL_VALUE;
1578 
1579     btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
1580 
1581     if (res != BTM_SUCCESS)
1582     {
1583         /* use BTM_PAIR_STATE_WAIT_AUTH_COMPLETE to report authentication failed event */
1584         btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
1585         btsnd_hcic_user_passkey_neg_reply (bd_addr);
1586     }
1587     else
1588     {
1589         btm_cb.acl_disc_reason = HCI_SUCCESS;
1590         btsnd_hcic_user_passkey_reply (bd_addr, passkey);
1591     }
1592 }
1593 #endif
1594 
1595 /*******************************************************************************
1596 **
1597 ** Function         BTM_SendKeypressNotif
1598 **
1599 ** Description      This function is used during the passkey entry model
1600 **                  by a device with KeyboardOnly IO capabilities
1601 **                  (very likely to be a HID Device).
1602 **                  It is called by a HID Device to inform the remote device when
1603 **                  a key has been entered or erased.
1604 **
1605 ** Parameters:      bd_addr - Address of the peer device
1606 **                  type - notification type
1607 **
1608 *******************************************************************************/
1609 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
BTM_SendKeypressNotif(BD_ADDR bd_addr,tBTM_SP_KEY_TYPE type)1610 void BTM_SendKeypressNotif(BD_ADDR bd_addr, tBTM_SP_KEY_TYPE type)
1611 {
1612     /* This API only make sense between PASSKEY_REQ and SP complete */
1613     if (btm_cb.pairing_state == BTM_PAIR_STATE_KEY_ENTRY)
1614         btsnd_hcic_send_keypress_notif (bd_addr, type);
1615 }
1616 #endif
1617 
1618 #if BTM_OOB_INCLUDED == TRUE
1619 /*******************************************************************************
1620 **
1621 ** Function         BTM_IoCapRsp
1622 **
1623 ** Description      This function is called in response to BTM_SP_IO_REQ_EVT
1624 **                  When the event data io_req.oob_data is set to BTM_OOB_UNKNOWN
1625 **                  by the tBTM_SP_CALLBACK implementation, this function is
1626 **                  called to provide the actual response
1627 **
1628 ** Parameters:      bd_addr - Address of the peer device
1629 **                  io_cap  - The IO capability of local device.
1630 **                  oob     - BTM_OOB_NONE or BTM_OOB_PRESENT.
1631 **                  auth_req- MITM protection required or not.
1632 **
1633 *******************************************************************************/
BTM_IoCapRsp(BD_ADDR bd_addr,tBTM_IO_CAP io_cap,tBTM_OOB_DATA oob,tBTM_AUTH_REQ auth_req)1634 void BTM_IoCapRsp(BD_ADDR bd_addr, tBTM_IO_CAP io_cap, tBTM_OOB_DATA oob, tBTM_AUTH_REQ auth_req)
1635 {
1636     BTM_TRACE_EVENT3 ("BTM_IoCapRsp: state: %s  oob: %d io_cap: %d",
1637                       btm_pair_state_descr(btm_cb.pairing_state), oob, io_cap);
1638 
1639     if ( (btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS)
1640          ||  (memcmp (btm_cb.pairing_bda, bd_addr, BD_ADDR_LEN) != 0) )
1641         return;
1642 
1643     if (oob < BTM_OOB_UNKNOWN && io_cap < BTM_IO_CAP_MAX)
1644     {
1645         btm_cb.devcb.loc_auth_req   = auth_req;
1646         btm_cb.devcb.loc_io_caps    = io_cap;
1647 
1648         if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
1649             auth_req = (BTM_AUTH_DD_BOND | (auth_req&BTM_AUTH_YN_BIT));
1650 
1651         btsnd_hcic_io_cap_req_reply (bd_addr, io_cap, oob, auth_req);
1652     }
1653 }
1654 
1655 /*******************************************************************************
1656 **
1657 ** Function         BTM_ReadLocalOobData
1658 **
1659 ** Description      This function is called to read the local OOB data from
1660 **                  LM
1661 **
1662 *******************************************************************************/
BTM_ReadLocalOobData(void)1663 tBTM_STATUS BTM_ReadLocalOobData(void)
1664 {
1665     tBTM_STATUS status = BTM_SUCCESS;
1666 
1667     if (btsnd_hcic_read_local_oob_data() == FALSE)
1668         status = BTM_NO_RESOURCES;
1669 
1670     return status;
1671 }
1672 
1673 /*******************************************************************************
1674 **
1675 ** Function         BTM_RemoteOobDataReply
1676 **
1677 ** Description      This function is called to provide the remote OOB data for
1678 **                  Simple Pairing in response to BTM_SP_RMT_OOB_EVT
1679 **
1680 ** Parameters:      bd_addr     - Address of the peer device
1681 **                  c           - simple pairing Hash C.
1682 **                  r           - simple pairing Randomizer  C.
1683 **
1684 *******************************************************************************/
BTM_RemoteOobDataReply(tBTM_STATUS res,BD_ADDR bd_addr,BT_OCTET16 c,BT_OCTET16 r)1685 void BTM_RemoteOobDataReply(tBTM_STATUS res, BD_ADDR bd_addr, BT_OCTET16 c, BT_OCTET16 r)
1686 {
1687     BTM_TRACE_EVENT2 ("BTM_RemoteOobDataReply():  State: %s  res:%d",
1688                       btm_pair_state_descr(btm_cb.pairing_state), res);
1689 
1690     /* If timeout already expired or has been canceled, ignore the reply */
1691     if (btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP)
1692         return;
1693 
1694     btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
1695 
1696     if (res != BTM_SUCCESS)
1697     {
1698         /* use BTM_PAIR_STATE_WAIT_AUTH_COMPLETE to report authentication failed event */
1699         btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
1700         btsnd_hcic_rem_oob_neg_reply (bd_addr);
1701     }
1702     else
1703     {
1704         btm_cb.acl_disc_reason = HCI_SUCCESS;
1705         btsnd_hcic_rem_oob_reply (bd_addr, c, r);
1706     }
1707 }
1708 
1709 /*******************************************************************************
1710 **
1711 ** Function         BTM_BuildOobData
1712 **
1713 ** Description      This function is called to build the OOB data payload to
1714 **                  be sent over OOB (non-Bluetooth) link
1715 **
1716 ** Parameters:      p_data  - the location for OOB data
1717 **                  max_len - p_data size.
1718 **                  c       - simple pairing Hash C.
1719 **                  r       - simple pairing Randomizer  C.
1720 **                  name_len- 0, local device name would not be included.
1721 **                            otherwise, the local device name is included for
1722 **                            up to this specified length
1723 **
1724 ** Returns          Number of bytes in p_data.
1725 **
1726 *******************************************************************************/
BTM_BuildOobData(UINT8 * p_data,UINT16 max_len,BT_OCTET16 c,BT_OCTET16 r,UINT8 name_len)1727 UINT16 BTM_BuildOobData(UINT8 *p_data, UINT16 max_len, BT_OCTET16 c,
1728                         BT_OCTET16 r, UINT8 name_len)
1729 {
1730     UINT8   *p = p_data;
1731     UINT16  len = 0;
1732     UINT16  delta;
1733 #if BTM_MAX_LOC_BD_NAME_LEN > 0
1734     UINT16  name_size;
1735     UINT8   name_type = BTM_EIR_SHORTENED_LOCAL_NAME_TYPE;
1736 #endif
1737 
1738     if (p_data && max_len >= BTM_OOB_MANDATORY_SIZE)
1739     {
1740         /* add mandatory part */
1741         UINT16_TO_STREAM(p, len);
1742         BDADDR_TO_STREAM(p, btm_cb.devcb.local_addr);
1743 
1744         len = BTM_OOB_MANDATORY_SIZE;
1745         max_len -= len;
1746 
1747         /* now optional part */
1748 
1749         /* add Hash C */
1750         delta = BTM_OOB_HASH_C_SIZE + 2;
1751         if (max_len >= delta)
1752         {
1753             *p++ = BTM_OOB_HASH_C_SIZE + 1;
1754             *p++ = BTM_EIR_OOB_SSP_HASH_C_TYPE;
1755             ARRAY_TO_STREAM(p, c, BTM_OOB_HASH_C_SIZE);
1756             len     += delta;
1757             max_len -= delta;
1758         }
1759 
1760         /* add Rand R */
1761         delta = BTM_OOB_RAND_R_SIZE + 2;
1762         if (max_len >= delta)
1763         {
1764             *p++ = BTM_OOB_RAND_R_SIZE + 1;
1765             *p++ = BTM_EIR_OOB_SSP_RAND_R_TYPE;
1766             ARRAY_TO_STREAM(p, r, BTM_OOB_RAND_R_SIZE);
1767             len     += delta;
1768             max_len -= delta;
1769         }
1770 
1771         /* add class of device */
1772         delta = BTM_OOB_COD_SIZE + 2;
1773         if (max_len >= delta)
1774         {
1775             *p++ = BTM_OOB_COD_SIZE + 1;
1776             *p++ = BTM_EIR_OOB_COD_TYPE;
1777             DEVCLASS_TO_STREAM(p, btm_cb.devcb.dev_class);
1778             len     += delta;
1779             max_len -= delta;
1780         }
1781 #if BTM_MAX_LOC_BD_NAME_LEN > 0
1782         name_size = name_len;
1783         if (name_size > strlen(btm_cb.cfg.bd_name))
1784         {
1785             name_type = BTM_EIR_COMPLETE_LOCAL_NAME_TYPE;
1786             name_size = (UINT16)strlen(btm_cb.cfg.bd_name);
1787         }
1788         delta = name_size + 2;
1789         if (max_len >= delta)
1790         {
1791             *p++ = name_size + 1;
1792             *p++ = name_type;
1793             ARRAY_TO_STREAM (p, btm_cb.cfg.bd_name, name_size);
1794             len     += delta;
1795             max_len -= delta;
1796         }
1797 #endif
1798         /* update len */
1799         p = p_data;
1800         UINT16_TO_STREAM(p, len);
1801     }
1802     return len;
1803 }
1804 
1805 /*******************************************************************************
1806 **
1807 ** Function         BTM_ReadOobData
1808 **
1809 ** Description      This function is called to parse the OOB data payload
1810 **                  received over OOB (non-Bluetooth) link
1811 **
1812 ** Parameters:      p_data  - the location for OOB data
1813 **                  eir_tag - The associated EIR tag to read the data.
1814 **                  *p_len(output) - the length of the data with the given tag.
1815 **
1816 ** Returns          the beginning of the data with the given tag.
1817 **                  NULL, if the tag is not found.
1818 **
1819 *******************************************************************************/
BTM_ReadOobData(UINT8 * p_data,UINT8 eir_tag,UINT8 * p_len)1820 UINT8 * BTM_ReadOobData(UINT8 *p_data, UINT8 eir_tag, UINT8 *p_len)
1821 {
1822     UINT8   *p = p_data;
1823     UINT16  max_len;
1824     UINT8   len, type;
1825     UINT8   *p_ret = NULL;
1826     UINT8   ret_len = 0;
1827 
1828     if (p_data)
1829     {
1830         STREAM_TO_UINT16(max_len, p);
1831         if (max_len >= BTM_OOB_MANDATORY_SIZE)
1832         {
1833             if (BTM_EIR_OOB_BD_ADDR_TYPE == eir_tag)
1834             {
1835                 p_ret = p; /* the location for bd_addr */
1836                 ret_len = BTM_OOB_BD_ADDR_SIZE;
1837             }
1838             else
1839             {
1840                 p += BD_ADDR_LEN;
1841                 max_len -= BTM_OOB_MANDATORY_SIZE;
1842                 /* now the optional data in EIR format */
1843                 while (max_len > 0)
1844                 {
1845                     len     = *p++; /* tag data len + 1 */
1846                     type    = *p++;
1847                     if (eir_tag == type)
1848                     {
1849                         p_ret = p;
1850                         ret_len = len - 1;
1851                         break;
1852                     }
1853                     /* the data size of this tag is len + 1 (tag data len + 2) */
1854                     if (max_len > len)
1855                     {
1856                         max_len -= len;
1857                         max_len--;
1858                         len--;
1859                         p += len;
1860                     }
1861                     else
1862                         max_len = 0;
1863                 }
1864             }
1865         }
1866     }
1867 
1868     if (p_len)
1869         *p_len = ret_len;
1870 
1871     return p_ret;
1872 }
1873 #endif
1874 
1875 /*******************************************************************************
1876 **
1877 ** Function         BTM_SetOutService
1878 **
1879 ** Description      This function is called to set the service for
1880 **                  outgoing connections.
1881 **
1882 **                  If the profile/application calls BTM_SetSecurityLevel
1883 **                  before initiating a connection, this function does not
1884 **                  need to be called.
1885 **
1886 ** Returns          void
1887 **
1888 *******************************************************************************/
BTM_SetOutService(BD_ADDR bd_addr,UINT8 service_id,UINT32 mx_chan_id)1889 void BTM_SetOutService(BD_ADDR bd_addr, UINT8 service_id, UINT32 mx_chan_id)
1890 {
1891     tBTM_SEC_DEV_REC *p_dev_rec;
1892     tBTM_SEC_SERV_REC *p_serv_rec = &btm_cb.sec_serv_rec[0];
1893     int i;
1894 
1895     btm_cb.p_out_serv = p_serv_rec;
1896     p_dev_rec = btm_find_dev (bd_addr);
1897 
1898     for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_serv_rec++)
1899     {
1900         if ((p_serv_rec->security_flags & BTM_SEC_IN_USE)
1901             && (p_serv_rec->service_id == service_id)
1902             && (p_serv_rec->orig_mx_chan_id == mx_chan_id))
1903         {
1904             BTM_TRACE_API4("BTM_SetOutService p_out_serv id %d, psm 0x%04x, proto_id %d, chan_id %d",
1905                            p_serv_rec->service_id, p_serv_rec->psm, p_serv_rec->mx_proto_id, p_serv_rec->orig_mx_chan_id);
1906             btm_cb.p_out_serv = p_serv_rec;
1907             if (p_dev_rec)
1908                 p_dev_rec->p_cur_service = p_serv_rec;
1909             break;
1910         }
1911     }
1912 }
1913 
1914 /************************************************************************
1915 **              I N T E R N A L     F U N C T I O N S
1916 *************************************************************************/
1917 /*******************************************************************************
1918 **
1919 ** Function         btm_sec_check_upgrade
1920 **
1921 ** Description      This function is called to check if the existing link key
1922 **                  needs to be upgraded.
1923 **
1924 ** Returns          void
1925 **
1926 *******************************************************************************/
btm_sec_check_upgrade(tBTM_SEC_DEV_REC * p_dev_rec,BOOLEAN is_originator)1927 static void btm_sec_check_upgrade(tBTM_SEC_DEV_REC  *p_dev_rec, BOOLEAN is_originator)
1928 {
1929     tBTM_SP_UPGRADE     evt_data;
1930     UINT16              mtm_check = is_originator ? BTM_SEC_OUT_MITM : BTM_SEC_IN_MITM;
1931 
1932     if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)
1933     {
1934 
1935         BTM_TRACE_DEBUG5 ("btm_sec_check_upgrade id:%d, link_key_typet:%d, rmt_io_caps:%d, chk flags:x%x, flags:x%x",
1936                           p_dev_rec->p_cur_service->service_id, p_dev_rec->link_key_type, p_dev_rec->rmt_io_caps,
1937                           mtm_check, p_dev_rec->p_cur_service->security_flags);
1938         /* Already have a link key to the connected peer. Is the link key secure enough?
1939         ** Is a link key upgrade even possible?
1940         */
1941         if ((p_dev_rec->security_required & mtm_check)                          /* needs MITM */
1942             && (p_dev_rec->link_key_type == BTM_LKEY_TYPE_UNAUTH_COMB) /* has unauthenticated link key */
1943             && (p_dev_rec->rmt_io_caps < BTM_IO_CAP_MAX)                           /* a valid peer IO cap */
1944             && (btm_sec_io_map[p_dev_rec->rmt_io_caps][btm_cb.devcb.loc_io_caps])) /* authenticated link key is possible */
1945         {
1946             BTM_TRACE_DEBUG1 ("need upgrade!! sec_flags:0x%x", p_dev_rec->sec_flags);
1947             /* upgrade is possible: check if the application wants the upgrade.
1948              * If the application is configured to use a global MITM flag,
1949              * it probably would not want to upgrade the link key based on the security level database */
1950             memcpy (evt_data.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
1951             evt_data.upgrade = TRUE;
1952             if (btm_cb.api.p_sp_callback)
1953                 (*btm_cb.api.p_sp_callback) (BTM_SP_UPGRADE_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
1954 
1955             BTM_TRACE_DEBUG1 ("evt_data.upgrade:0x%x", evt_data.upgrade);
1956             if (evt_data.upgrade)
1957             {
1958                 /* if the application confirms the upgrade, set the upgrade bit */
1959                 p_dev_rec->sm4 |= BTM_SM4_UPGRADE;
1960 
1961                 /* Clear the link key known to go through authentication/pairing again */
1962                 p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED);
1963                 p_dev_rec->sec_flags &= ~BTM_SEC_AUTHENTICATED;
1964                 BTM_TRACE_DEBUG1 ("sec_flags:0x%x", p_dev_rec->sec_flags);
1965             }
1966         }
1967     }
1968 }
1969 
1970 /*******************************************************************************
1971 **
1972 ** Function         btm_sec_l2cap_access_req
1973 **
1974 ** Description      This function is called by the L2CAP to grant permission to
1975 **                  establish L2CAP connection to or from the peer device.
1976 **
1977 ** Parameters:      bd_addr       - Address of the peer device
1978 **                  psm           - L2CAP PSM
1979 **                  is_originator - TRUE if protocol above L2CAP originates
1980 **                                  connection
1981 **                  p_callback    - Pointer to callback function called if
1982 **                                  this function returns PENDING after required
1983 **                                  procedures are complete. MUST NOT BE NULL.
1984 **
1985 ** Returns          tBTM_STATUS
1986 **
1987 *******************************************************************************/
1988 #define BTM_SEC_OUT_FLAGS   (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT | BTM_SEC_OUT_AUTHORIZE)
1989 #define BTM_SEC_IN_FLAGS    (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT | BTM_SEC_IN_AUTHORIZE)
1990 
btm_sec_l2cap_access_req(BD_ADDR bd_addr,UINT16 psm,UINT16 handle,CONNECTION_TYPE conn_type,tBTM_SEC_CALLBACK * p_callback,void * p_ref_data)1991 tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle,
1992                                       CONNECTION_TYPE conn_type,
1993                                       tBTM_SEC_CALLBACK *p_callback,
1994                                       void *p_ref_data)
1995 {
1996     tBTM_SEC_DEV_REC  *p_dev_rec;
1997     tBTM_SEC_SERV_REC *p_serv_rec;
1998     UINT16         security_required;
1999     UINT16         old_security_required;
2000     BOOLEAN       old_is_originator;
2001     tBTM_STATUS   rc = BTM_SUCCESS;
2002     BOOLEAN       chk_acp_auth_done = FALSE;
2003     BOOLEAN is_originator;
2004 
2005 #if (L2CAP_UCD_INCLUDED == TRUE)
2006     if (conn_type & CONNECTION_TYPE_ORIG_MASK)
2007         is_originator = TRUE;
2008     else
2009         is_originator = FALSE;
2010 
2011     BTM_TRACE_DEBUG2 ("btm_sec_l2cap_access_req conn_type:0x%x, 0x%x", conn_type, p_ref_data);
2012 #else
2013     is_originator = conn_type;
2014 
2015     BTM_TRACE_DEBUG2 ("btm_sec_l2cap_access_req is_originator:%d, 0x%x", is_originator, p_ref_data);
2016 #endif
2017 
2018     /* Find or get oldest record */
2019     p_dev_rec = btm_find_or_alloc_dev (bd_addr);
2020 
2021     p_dev_rec->hci_handle = handle;
2022 
2023     /* Find the service record for the PSM */
2024     p_serv_rec = btm_sec_find_first_serv (conn_type, psm);
2025 
2026     /* If there is no application registered with this PSM do not allow connection */
2027     if (!p_serv_rec)
2028     {
2029         BTM_TRACE_WARNING1 ("btm_sec_l2cap_access_req()  PSM:%d no application registerd", psm);
2030 
2031         (*p_callback) (bd_addr, p_ref_data, BTM_MODE_UNSUPPORTED);
2032 
2033         return(BTM_MODE_UNSUPPORTED);
2034     }
2035 
2036     /* SDP connection we will always let through */
2037     if (BT_PSM_SDP == psm)
2038     {
2039         (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS_NO_SECURITY);
2040 
2041         return(BTM_SUCCESS);
2042     }
2043 #if (L2CAP_UCD_INCLUDED == TRUE)
2044     if ( conn_type & CONNECTION_TYPE_CONNLESS_MASK )
2045     {
2046         security_required = p_serv_rec->ucd_security_flags;
2047 
2048         rc = BTM_CMD_STARTED;
2049         if (is_originator)
2050         {
2051             if (((security_required & BTM_SEC_OUT_FLAGS) == 0) ||
2052                 ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
2053                 ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) ||
2054                 ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_FLAGS) && (p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED))) )
2055             {
2056                 rc = BTM_SUCCESS;
2057             }
2058         }
2059         else
2060         {
2061             if (((security_required & BTM_SEC_IN_FLAGS) == 0) ||
2062                 ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
2063                 ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) ||
2064                 ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_FLAGS) && (p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED))) )
2065             {
2066                 rc = BTM_SUCCESS;
2067             }
2068         }
2069 
2070         if (rc == BTM_SUCCESS)
2071         {
2072             if (p_callback)
2073                 (*p_callback) (bd_addr, (void *)p_ref_data, BTM_SUCCESS);
2074 
2075             return(BTM_SUCCESS);
2076         }
2077     }
2078     else
2079 #endif
2080     {
2081         security_required = p_serv_rec->security_flags;
2082     }
2083 
2084     /* there are some devices (moto KRZR) which connects to several services at the same time */
2085     /* we will process one after another */
2086     if ( (p_dev_rec->p_callback) || (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) )
2087     {
2088         BTM_TRACE_EVENT2 ("btm_sec_l2cap_access_req() - busy - PSM:%d delayed  state: %s",
2089                           psm, btm_pair_state_descr(btm_cb.pairing_state));
2090         rc = BTM_CMD_STARTED;
2091         if ((BTM_SEC_MODE_SP != btm_cb.security_mode)
2092             || ((BTM_SEC_MODE_SP == btm_cb.security_mode) && (BTM_SM4_KNOWN == p_dev_rec->sm4))
2093            )
2094         {
2095             BTM_TRACE_EVENT2 ("security_flags:x%x, sec_flags:x%x", security_required, p_dev_rec->sec_flags);
2096             /* legacy mode - local is legacy or local is lisbon/peer is legacy */
2097             if (is_originator)
2098             {
2099                 if (((security_required & BTM_SEC_OUT_FLAGS) == 0) ||
2100                     ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
2101                     ((((security_required & BTM_SEC_OUT_FLAGS) == (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) ||
2102                     ((((security_required & BTM_SEC_OUT_FLAGS) == BTM_SEC_OUT_FLAGS) && (p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED))) )
2103                 {
2104                     rc = BTM_SUCCESS;
2105                 }
2106             }
2107             else
2108             {
2109                 if (((security_required & BTM_SEC_IN_FLAGS) == 0) ||
2110                     ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_AUTHENTICATE) && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))) ||
2111                     ((((security_required & BTM_SEC_IN_FLAGS) == (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT)) && (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED))) ||
2112                     ((((security_required & BTM_SEC_IN_FLAGS) == BTM_SEC_IN_FLAGS) && (p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED))) )
2113                 {
2114                     rc = BTM_SUCCESS;
2115                 }
2116             }
2117 
2118             if (rc == BTM_SUCCESS)
2119             {
2120                 if (p_callback)
2121                     (*p_callback) (bd_addr, (void *)p_ref_data, BTM_SUCCESS);
2122 
2123                 return(BTM_SUCCESS);
2124             }
2125         }
2126 
2127         btm_cb.sec_req_pending = TRUE;
2128         return(BTM_CMD_STARTED);
2129     }
2130 
2131     /* Save pointer to service record */
2132     p_dev_rec->p_cur_service = p_serv_rec;
2133 
2134 
2135     /* mess /w security_required in btm_sec_l2cap_access_req for Lisbon */
2136     if (btm_cb.security_mode == BTM_SEC_MODE_SP)
2137     {
2138         if (is_originator)
2139         {
2140             if (BTM_SEC_IS_SM4(p_dev_rec->sm4))
2141             {
2142                 /* SM4 to SM4 -> always authenticate & encrypt */
2143                 security_required |= (BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_OUT_ENCRYPT);
2144             }
2145             else
2146             {
2147                 if ( !(BTM_SM4_KNOWN & p_dev_rec->sm4))
2148                 {
2149                     BTM_TRACE_DEBUG1 ("remote features unknown!!sec_flags:0x%x", p_dev_rec->sec_flags);
2150                     /* the remote features are not known yet */
2151                     p_dev_rec->sm4          |= BTM_SM4_REQ_PEND;
2152 
2153                     return(BTM_CMD_STARTED);
2154                 }
2155             }
2156         }
2157         else
2158         {
2159             /* responder */
2160             if (BTM_SEC_IS_SM4(p_dev_rec->sm4))
2161             {
2162                 /* SM4 to SM4: the acceptor needs to make sure the authentication is already done */
2163                 chk_acp_auth_done = TRUE;
2164                 /* SM4 to SM4 -> always authenticate & encrypt */
2165                 security_required |= (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_IN_ENCRYPT);
2166             }
2167             else
2168             {
2169                 if ( !(BTM_SM4_KNOWN & p_dev_rec->sm4))
2170                 {
2171                     BTM_TRACE_DEBUG1 ("(rsp) remote features unknown!!sec_flags:0x%x", p_dev_rec->sec_flags);
2172                     /* the remote features are not known yet */
2173                     p_dev_rec->sm4          |= BTM_SM4_REQ_PEND;
2174 
2175                     return(BTM_CMD_STARTED);
2176                 }
2177             }
2178         }
2179     }
2180 
2181     BTM_TRACE_DEBUG4 ("btm_sec_l2cap_access_req()  sm4:0x%x, sec_flags:0x%x, security_required:0x%x chk:%d",
2182                       p_dev_rec->sm4, p_dev_rec->sec_flags, security_required, chk_acp_auth_done);
2183 
2184     old_security_required        = p_dev_rec->security_required;
2185     old_is_originator            = p_dev_rec->is_originator;
2186     p_dev_rec->security_required = security_required;
2187     p_dev_rec->p_ref_data        = p_ref_data;
2188     p_dev_rec->is_originator     = is_originator;
2189 
2190 #if (L2CAP_UCD_INCLUDED == TRUE)
2191     if ( conn_type & CONNECTION_TYPE_CONNLESS_MASK )
2192         p_dev_rec->is_ucd = TRUE;
2193     else
2194         p_dev_rec->is_ucd = FALSE;
2195 #endif
2196 
2197     /* If there are multiple service records used through the same PSM */
2198     /* leave security decision for the multiplexor on the top */
2199 #if (L2CAP_UCD_INCLUDED == TRUE)
2200     if (((btm_sec_find_next_serv (p_serv_rec)) != NULL)
2201         &&(!( conn_type & CONNECTION_TYPE_CONNLESS_MASK ))) /* if not UCD */
2202 #else
2203     if ((btm_sec_find_next_serv (p_serv_rec)) != NULL)
2204 #endif
2205     {
2206         BTM_TRACE_DEBUG2 ("no next_serv sm4:0x%x, chk:%d", p_dev_rec->sm4, chk_acp_auth_done);
2207         if (!BTM_SEC_IS_SM4(p_dev_rec->sm4))
2208         {
2209             BTM_TRACE_EVENT1 ("Security Manager: l2cap_access_req PSM:%d postponed for multiplexer", psm);
2210             /* pre-Lisbon: restore the old settings */
2211             p_dev_rec->security_required = old_security_required;
2212             p_dev_rec->is_originator     = old_is_originator;
2213 
2214             (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS);
2215 
2216             return(BTM_SUCCESS);
2217         }
2218     }
2219 
2220     /* if the originator is using dynamic PSM in legacy mode, do not start any security process now.
2221      * The layer above L2CAP needs to carry out the security requirement after L2CAP connect response is received*/
2222     if (is_originator && (btm_cb.security_mode != BTM_SEC_MODE_SP || !BTM_SEC_IS_SM4(p_dev_rec->sm4)) && (psm >= 0x1001))
2223     {
2224         BTM_TRACE_EVENT1 ("dynamic PSM:0x%x in legacy mode - postponed for upper layer", psm);
2225         /* restore the old settings */
2226         p_dev_rec->security_required = old_security_required;
2227         p_dev_rec->is_originator     = old_is_originator;
2228 
2229         (*p_callback) (bd_addr, p_ref_data, BTM_SUCCESS);
2230 
2231         return(BTM_SUCCESS);
2232     }
2233 
2234     if (chk_acp_auth_done)
2235     {
2236         BTM_TRACE_DEBUG2 ("(SM4 to SM4) btm_sec_l2cap_access_req rspd. authenticated: x%x, enc: x%x",
2237                           (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED), (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED));
2238         /* SM4, but we do not know for sure which level of security we need.
2239          * as long as we have a link key, it's OK */
2240         if ((0 == (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))
2241             ||(0 == (p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)))
2242         {
2243             rc = BTM_DELAY_CHECK;
2244             /*
2245             2046 may report HCI_Encryption_Change and L2C Connection Request out of sequence
2246             because of data path issues. Delay this disconnect a little bit
2247             */
2248             BTM_TRACE_ERROR0 ("peer should have initiated security process by now (SM4 to SM4)");
2249             p_dev_rec->p_callback        = p_callback;
2250             p_dev_rec->sec_state         = BTM_SEC_STATE_DELAY_FOR_ENC;
2251             (*p_callback) (bd_addr, p_ref_data, rc);
2252 
2253             return(BTM_SUCCESS);
2254         }
2255     }
2256 
2257     p_dev_rec->p_callback        = p_callback;
2258 
2259     /* Although authentication and encryption are per connection */
2260     /* authorization is per access request.  For example when serial connection */
2261     /* is up and authorized and client requests to read file (access to other */
2262     /* scn, we need to request user's permission again. */
2263     p_dev_rec->sec_flags &= ~BTM_SEC_AUTHORIZED;
2264 
2265     if (BTM_SEC_IS_SM4(p_dev_rec->sm4))
2266     {
2267         /* If we already have a link key to the connected peer, is the link key secure enough ? */
2268         btm_sec_check_upgrade(p_dev_rec, is_originator);
2269     }
2270 
2271     BTM_TRACE_EVENT6 ("Security Manager: l2cap_access_req PSM:%d Handle:%d State:%d Flags:0x%x Required:0x%x Service ID:%d",
2272                       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);
2273 
2274     if ((rc = btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
2275     {
2276         p_dev_rec->p_callback = NULL;
2277         (*p_callback) (bd_addr, p_dev_rec->p_ref_data, (UINT8)rc);
2278     }
2279 
2280     return(rc);
2281 }
2282 
2283 /*******************************************************************************
2284 **
2285 ** Function         btm_sec_mx_access_request
2286 **
2287 ** Description      This function is called by all Multiplexing Protocols during
2288 **                  establishing connection to or from peer device to grant
2289 **                  permission to establish application connection.
2290 **
2291 ** Parameters:      bd_addr       - Address of the peer device
2292 **                  psm           - L2CAP PSM
2293 **                  is_originator - TRUE if protocol above L2CAP originates
2294 **                                  connection
2295 **                  mx_proto_id   - protocol ID of the multiplexer
2296 **                  mx_chan_id    - multiplexer channel to reach application
2297 **                  p_callback    - Pointer to callback function called if
2298 **                                  this function returns PENDING after required
2299 **                                  procedures are completed
2300 **                  p_ref_data    - Pointer to any reference data needed by the
2301 **                                  the callback function.
2302 **
2303 ** Returns          BTM_CMD_STARTED
2304 **
2305 *******************************************************************************/
btm_sec_mx_access_request(BD_ADDR bd_addr,UINT16 psm,BOOLEAN is_originator,UINT32 mx_proto_id,UINT32 mx_chan_id,tBTM_SEC_CALLBACK * p_callback,void * p_ref_data)2306 tBTM_STATUS btm_sec_mx_access_request (BD_ADDR bd_addr, UINT16 psm, BOOLEAN is_originator,
2307                                        UINT32 mx_proto_id, UINT32 mx_chan_id,
2308                                        tBTM_SEC_CALLBACK *p_callback, void *p_ref_data)
2309 
2310 {
2311     tBTM_SEC_DEV_REC  *p_dev_rec;
2312     tBTM_SEC_SERV_REC *p_serv_rec;
2313     tBTM_STATUS        rc;
2314 
2315     BTM_TRACE_DEBUG1 ("btm_sec_mx_access_request is_originator:%d", is_originator);
2316     /* Find or get oldest record */
2317     p_dev_rec = btm_find_or_alloc_dev (bd_addr);
2318 
2319     /* Find the service record for the PSM */
2320     p_serv_rec = btm_sec_find_mx_serv (is_originator, psm, mx_proto_id, mx_chan_id);
2321 
2322     /* If there is no application registered with this PSM do not allow connection */
2323     if (!p_serv_rec)
2324     {
2325         if (p_callback)
2326             (*p_callback) (bd_addr, p_ref_data, BTM_MODE_UNSUPPORTED);
2327 
2328         BTM_TRACE_ERROR3 ("Security Manager: MX service not found PSM:%d Proto:%d SCN:%d",
2329                           psm, mx_proto_id, mx_chan_id);
2330         return BTM_NO_RESOURCES;
2331     }
2332 
2333     /* there are some devices (moto phone) which connects to several services at the same time */
2334     /* we will process one after another */
2335     if ( (p_dev_rec->p_callback) || (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) )
2336     {
2337         BTM_TRACE_EVENT4 ("btm_sec_mx_access_request service PSM:%d Proto:%d SCN:%d delayed  state: %s",
2338                           psm, mx_proto_id, mx_chan_id, btm_pair_state_descr(btm_cb.pairing_state));
2339 
2340         btm_sec_queue_mx_request (bd_addr, psm,  is_originator, mx_proto_id, mx_chan_id, p_callback, p_ref_data);
2341         return BTM_CMD_STARTED;
2342     }
2343 
2344     p_dev_rec->p_cur_service     = p_serv_rec;
2345     p_dev_rec->security_required = p_serv_rec->security_flags;
2346 
2347     if (BTM_SEC_MODE_SP == btm_cb.security_mode)
2348     {
2349         if (BTM_SEC_IS_SM4(p_dev_rec->sm4))
2350         {
2351             /* If we already have a link key, check if that link key is good enough */
2352             btm_sec_check_upgrade(p_dev_rec, is_originator);
2353         }
2354     }
2355 
2356     p_dev_rec->is_originator     = is_originator;
2357     p_dev_rec->p_callback        = p_callback;
2358     p_dev_rec->p_ref_data        = p_ref_data;
2359 
2360     /* Although authentication and encryption are per connection */
2361     /* authorization is per access request.  For example when serial connection */
2362     /* is up and authorized and client requests to read file (access to other */
2363     /* scn, we need to request user's permission again. */
2364     p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED);
2365 
2366     BTM_TRACE_EVENT6 ("Security Manager: mx_access_req proto_id:%d chan_id:%d State:%d Flags:0x%x Required:0x%x Service ID:%d",
2367                       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);
2368 
2369     if ((rc = btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
2370     {
2371         if (p_callback)
2372         {
2373             p_dev_rec->p_callback = NULL;
2374 
2375             (*p_callback) (bd_addr, p_ref_data, (UINT8)rc);
2376         }
2377     }
2378 
2379     return rc;
2380 }
2381 
2382 /*******************************************************************************
2383 **
2384 ** Function         btm_sec_conn_req
2385 **
2386 ** Description      This function is when the peer device is requesting
2387 **                  connection
2388 **
2389 ** Returns          void
2390 **
2391 *******************************************************************************/
btm_sec_conn_req(UINT8 * bda,UINT8 * dc)2392 void btm_sec_conn_req (UINT8 *bda, UINT8 *dc)
2393 {
2394     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev (bda);
2395 
2396     /* Some device may request a connection before we are done with the HCI_Reset sequence */
2397     if (btm_cb.devcb.state != BTM_DEV_STATE_READY)
2398     {
2399         BTM_TRACE_EVENT0 ("Security Manager: connect request when device not ready");
2400         btsnd_hcic_reject_conn (bda, HCI_ERR_HOST_REJECT_DEVICE);
2401         return;
2402     }
2403 
2404     /* Security guys wants us not to allow connection from not paired devices */
2405 
2406     /* Check if connection is allowed for only paired devices */
2407     if (btm_cb.connect_only_paired)
2408     {
2409         if (!p_dev_rec || !(p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED))
2410         {
2411             BTM_TRACE_EVENT0 ("Security Manager: connect request from non-paired device");
2412             btsnd_hcic_reject_conn (bda, HCI_ERR_HOST_REJECT_DEVICE);
2413             return;
2414         }
2415     }
2416 
2417 #if BTM_ALLOW_CONN_IF_NONDISCOVER == FALSE
2418     /* If non-discoverable, only allow known devices to connect */
2419     if (btm_cb.btm_inq_vars.discoverable_mode == BTM_NON_DISCOVERABLE)
2420     {
2421         if (!p_dev_rec)
2422         {
2423             BTM_TRACE_EVENT0 ("Security Manager: connect request from not paired device");
2424             btsnd_hcic_reject_conn (bda, HCI_ERR_HOST_REJECT_DEVICE);
2425             return;
2426         }
2427     }
2428 #endif
2429 
2430     /* Host can be registered to verify comming BDA or DC */
2431     if (btm_cb.p_conn_filter_cb)
2432     {
2433         if (!(* btm_cb.p_conn_filter_cb) (bda, dc))
2434         {
2435             BTM_TRACE_EVENT0 ("Security Manager: connect request did not pass filter");
2436 
2437             /* incomming call did not pass connection filters.  Reject */
2438             btsnd_hcic_reject_conn (bda, HCI_ERR_HOST_REJECT_DEVICE);
2439             return;
2440         }
2441     }
2442 
2443     if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
2444         &&(btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
2445         &&(!memcmp (btm_cb.pairing_bda, bda, BD_ADDR_LEN)))
2446     {
2447         BTM_TRACE_EVENT0 ("Security Manager: reject connect request from bonding device");
2448 
2449         /* incoming connection from bonding device is rejected */
2450         btm_cb.pairing_flags |= BTM_PAIR_FLAGS_REJECTED_CONNECT;
2451         btsnd_hcic_reject_conn (bda, HCI_ERR_HOST_REJECT_DEVICE);
2452         return;
2453     }
2454 
2455     /* Host is not interested or approved connection.  Save BDA and DC and */
2456     /* pass request to L2CAP */
2457     memcpy (btm_cb.connecting_bda, bda, BD_ADDR_LEN);
2458     memcpy (btm_cb.connecting_dc,  dc,  DEV_CLASS_LEN);
2459 
2460     if (l2c_link_hci_conn_req (bda))
2461     {
2462         if (!p_dev_rec)
2463         {
2464             /* accept the connection -> allocate a device record */
2465             p_dev_rec = btm_sec_alloc_dev (bda);
2466         }
2467         if (p_dev_rec)
2468         {
2469             p_dev_rec->sm4 |= BTM_SM4_CONN_PEND;
2470         }
2471     }
2472 }
2473 
2474 /*******************************************************************************
2475 **
2476 ** Function         btm_sec_bond_cancel_complete
2477 **
2478 ** Description      This function is called to report bond cancel complete
2479 **                  event.
2480 **
2481 ** Returns          void
2482 **
2483 *******************************************************************************/
btm_sec_bond_cancel_complete(void)2484 static void btm_sec_bond_cancel_complete (void)
2485 {
2486     tBTM_SEC_DEV_REC *p_dev_rec;
2487 
2488     if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE) ||
2489         (BTM_PAIR_STATE_WAIT_LOCAL_PIN == btm_cb.pairing_state &&
2490          BTM_PAIR_FLAGS_WE_STARTED_DD & btm_cb.pairing_flags))
2491     {
2492         /* for dedicated bonding in legacy mode, authentication happens at "link level"
2493          * btm_sec_connected is called with failed status.
2494          * In theory, the code that handles is_pairing_device/TRUE should clean out security related code.
2495          * However, this function may clean out the security related flags and btm_sec_connected would not know
2496          * this function also needs to do proper clean up.
2497          */
2498         if ((p_dev_rec = btm_find_dev (btm_cb.pairing_bda)) != NULL)
2499             p_dev_rec->security_required = BTM_SEC_NONE;
2500         btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
2501 
2502         /* Notify application that the cancel succeeded */
2503         if (btm_cb.api.p_bond_cancel_cmpl_callback)
2504             btm_cb.api.p_bond_cancel_cmpl_callback(BTM_SUCCESS);
2505     }
2506 }
2507 
2508 /*******************************************************************************
2509 **
2510 ** Function         btm_create_conn_cancel_complete
2511 **
2512 ** Description      This function is called when the command complete message
2513 **                  is received from the HCI for the create connection cancel
2514 **                  command.
2515 **
2516 ** Returns          void
2517 **
2518 *******************************************************************************/
btm_create_conn_cancel_complete(UINT8 * p)2519 void btm_create_conn_cancel_complete (UINT8 *p)
2520 {
2521     UINT8       status;
2522 
2523     STREAM_TO_UINT8 (status, p);
2524     BTM_TRACE_EVENT2 ("btm_create_conn_cancel_complete(): in State: %s  status:%d",
2525                       btm_pair_state_descr(btm_cb.pairing_state), status);
2526 
2527     /* if the create conn cancel cmd was issued by the bond cancel,
2528     ** the application needs to be notified that bond cancel succeeded
2529     */
2530     switch (status)
2531     {
2532         case HCI_SUCCESS:
2533             btm_sec_bond_cancel_complete();
2534             break;
2535         case HCI_ERR_CONNECTION_EXISTS:
2536         case HCI_ERR_NO_CONNECTION:
2537         default:
2538             /* Notify application of the error */
2539             if (btm_cb.api.p_bond_cancel_cmpl_callback)
2540                 btm_cb.api.p_bond_cancel_cmpl_callback(BTM_ERR_PROCESSING);
2541             break;
2542     }
2543 }
2544 
2545 /*******************************************************************************
2546 **
2547 ** Function         btm_sec_check_pending_reqs
2548 **
2549 ** Description      This function is called at the end of the security procedure
2550 **                  to let L2CAP and RFCOMM know to re-submit any pending requests
2551 **
2552 ** Returns          void
2553 **
2554 *******************************************************************************/
btm_sec_check_pending_reqs(void)2555 void btm_sec_check_pending_reqs (void)
2556 {
2557     tBTM_SEC_QUEUE_ENTRY    *p_e;
2558     BUFFER_Q                bq;
2559 
2560     if (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE)
2561     {
2562         /* First, resubmit L2CAP requests */
2563         if (btm_cb.sec_req_pending)
2564         {
2565             btm_cb.sec_req_pending = FALSE;
2566             l2cu_resubmit_pending_sec_req (NULL);
2567         }
2568 
2569         /* Now, re-submit anything in the mux queue */
2570         bq = btm_cb.sec_pending_q;
2571 
2572         GKI_init_q (&btm_cb.sec_pending_q);
2573 
2574         while ((p_e = (tBTM_SEC_QUEUE_ENTRY *)GKI_dequeue (&bq)) != NULL)
2575         {
2576             /* Check that the ACL is still up before starting security procedures */
2577             if (btm_bda_to_acl(p_e->bd_addr) != NULL)
2578             {
2579                 BTM_TRACE_EVENT4 ("btm_sec_check_pending_reqs() submitting  PSM: 0x%04x  Is_Orig: %u  mx_proto_id: %u  mx_chan_id: %u",
2580                                   p_e->psm, p_e->is_orig, p_e->mx_proto_id, p_e->mx_chan_id);
2581 
2582                 btm_sec_mx_access_request (p_e->bd_addr, p_e->psm, p_e->is_orig,
2583                                            p_e->mx_proto_id, p_e->mx_chan_id,
2584                                            p_e->p_callback, p_e->p_ref_data);
2585             }
2586 
2587             GKI_freebuf (p_e);
2588         }
2589     }
2590 }
2591 
2592 /*******************************************************************************
2593 **
2594 ** Function         btm_sec_init
2595 **
2596 ** Description      This function is on the SEC startup
2597 **
2598 ** Returns          void
2599 **
2600 *******************************************************************************/
btm_sec_init(UINT8 sec_mode)2601 void btm_sec_init (UINT8 sec_mode)
2602 {
2603 #if 0  /* cleared in btm_init; put back in if calling from anywhere else! */
2604     int i;
2605 
2606     memset (btm_cb.sec_serv_rec, 0, sizeof (btm_cb.sec_serv_rec));
2607     memset (btm_cb.sec_dev_rec, 0, sizeof (btm_cb.sec_dev_rec));
2608     memset (&btm_cb.pairing_tle, 0, sizeof(TIMER_LIST_ENT));
2609 
2610 #endif
2611     btm_cb.security_mode = sec_mode;
2612     memset (btm_cb.pairing_bda, 0xff, BD_ADDR_LEN);
2613     btm_cb.max_collision_delay = BTM_SEC_MAX_COLLISION_DELAY;
2614 }
2615 
2616 /*******************************************************************************
2617 **
2618 ** Function         btm_sec_device_down
2619 **
2620 ** Description      This function should be called when device is disabled or
2621 **                  turned off
2622 **
2623 ** Returns          void
2624 **
2625 *******************************************************************************/
btm_sec_device_down(void)2626 void btm_sec_device_down (void)
2627 {
2628     BTM_TRACE_EVENT1 ("btm_sec_device_down()  State: %s", btm_pair_state_descr(btm_cb.pairing_state));
2629 
2630     btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
2631 }
2632 
2633 /*******************************************************************************
2634 **
2635 ** Function         btm_sec_dev_reset
2636 **
2637 ** Description      This function should be called after device reset
2638 **
2639 ** Returns          void
2640 **
2641 *******************************************************************************/
btm_sec_dev_reset(void)2642 void btm_sec_dev_reset (void)
2643 {
2644 #if (BTM_PRE_LISBON_INCLUDED == TRUE)
2645     if (btm_cb.security_mode == BTM_SEC_MODE_LINK)
2646     {
2647         btsnd_hcic_write_auth_enable (TRUE);
2648         btsnd_hcic_write_encr_mode (HCI_ENCRYPT_MODE_POINT_TO_POINT);
2649     }
2650 #endif
2651 #if (BTM_PRE_LISBON_INCLUDED == TRUE)
2652     else
2653 #endif
2654         /* this function is only called from btm_read_local_features_complete()
2655          * right now. */
2656         if (HCI_SIMPLE_PAIRING_SUPPORTED(btm_cb.devcb.local_features))
2657     {
2658         btsnd_hcic_write_simple_pairing_mode(HCI_SP_MODE_ENABLED);
2659 #if BLE_INCLUDED == TRUE
2660         btsnd_hcic_set_event_mask(LOCAL_BR_EDR_CONTROLLER_ID,
2661                                   (UINT8 *)HCI_DUMO_EVENT_MASK_EXT);
2662 #else
2663         btsnd_hcic_set_event_mask(LOCAL_BR_EDR_CONTROLLER_ID,
2664                                   (UINT8 *)HCI_LISBON_EVENT_MASK_EXT);
2665 #endif
2666         /* set the default IO capabilities */
2667         btm_cb.devcb.loc_io_caps = BTM_LOCAL_IO_CAPS;
2668         /* add mx service to use no security */
2669 #if (RFCOMM_INCLUDED == TRUE)
2670         BTM_SetSecurityLevel(FALSE, "RFC_MUX", BTM_SEC_SERVICE_RFC_MUX,
2671                              BTM_SEC_NONE, BT_PSM_RFCOMM, BTM_SEC_PROTO_RFCOMM, 0);
2672 #endif
2673     }
2674     else
2675     {
2676         btm_cb.security_mode = BTM_SEC_MODE_SERVICE;
2677     }
2678 
2679     BTM_TRACE_DEBUG1 ("btm_sec_dev_reset sec mode: %d", btm_cb.security_mode);
2680 }
2681 
2682 /*******************************************************************************
2683 **
2684 ** Function         btm_sec_abort_access_req
2685 **
2686 ** Description      This function is called by the L2CAP or RFCOMM to abort
2687 **                  the pending operation.
2688 **
2689 ** Parameters:      bd_addr       - Address of the peer device
2690 **
2691 ** Returns          void
2692 **
2693 *******************************************************************************/
btm_sec_abort_access_req(BD_ADDR bd_addr)2694 void btm_sec_abort_access_req (BD_ADDR bd_addr)
2695 {
2696     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev (bd_addr);
2697 
2698     if (!p_dev_rec)
2699         return;
2700 
2701     if (btm_cb.api.p_abort_callback)
2702         (*btm_cb.api.p_abort_callback)(bd_addr, p_dev_rec->dev_class, p_dev_rec->sec_bd_name);
2703 
2704     if ((p_dev_rec->sec_state != BTM_SEC_STATE_AUTHORIZING)
2705         && (p_dev_rec->sec_state != BTM_SEC_STATE_AUTHENTICATING))
2706         return;
2707 
2708     p_dev_rec->sec_state  = BTM_SEC_STATE_IDLE;
2709     p_dev_rec->p_callback = NULL;
2710 }
2711 
2712 /*******************************************************************************
2713 **
2714 ** Function         btm_sec_dd_create_conn
2715 **
2716 ** Description      This function is called to create the ACL connection for
2717 **                  the dedicated boding process
2718 **
2719 ** Returns          void
2720 **
2721 *******************************************************************************/
btm_sec_dd_create_conn(tBTM_SEC_DEV_REC * p_dev_rec)2722 static tBTM_STATUS btm_sec_dd_create_conn (tBTM_SEC_DEV_REC *p_dev_rec)
2723 {
2724     tL2C_LCB         *p_lcb;
2725 
2726     /* Make sure an L2cap link control block is available */
2727     if ((p_lcb = l2cu_allocate_lcb (p_dev_rec->bd_addr, TRUE)) == NULL)
2728     {
2729         BTM_TRACE_WARNING6 ("Security Manager: failed allocate LCB [%02x%02x%02x%02x%02x%02x]",
2730                             p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
2731                             p_dev_rec->bd_addr[3], p_dev_rec->bd_addr[4], p_dev_rec->bd_addr[5]);
2732 
2733         return(BTM_NO_RESOURCES);
2734     }
2735 
2736     /* set up the control block to indicated dedicated bonding */
2737     btm_cb.pairing_flags |= BTM_PAIR_FLAGS_DISC_WHEN_DONE;
2738 
2739     if (l2cu_create_conn(p_lcb) == FALSE)
2740     {
2741         BTM_TRACE_WARNING6 ("Security Manager: failed create  [%02x%02x%02x%02x%02x%02x]",
2742                             p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
2743                             p_dev_rec->bd_addr[3], p_dev_rec->bd_addr[4], p_dev_rec->bd_addr[5]);
2744 
2745         l2cu_release_lcb(p_lcb);
2746         return(BTM_NO_RESOURCES);
2747     }
2748 
2749 #if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2750     btm_acl_update_busy_level (BTM_BLI_PAGE_EVT);
2751 #endif
2752 
2753     BTM_TRACE_DEBUG6 ("Security Manager: btm_sec_dd_create_conn [%02x%02x%02x%02x%02x%02x]",
2754                       p_dev_rec->bd_addr[0], p_dev_rec->bd_addr[1], p_dev_rec->bd_addr[2],
2755                       p_dev_rec->bd_addr[3], p_dev_rec->bd_addr[4], p_dev_rec->bd_addr[5]);
2756 
2757     btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_PIN_REQ);
2758 
2759     return(BTM_CMD_STARTED);
2760 }
2761 
2762 /*******************************************************************************
2763 **
2764 ** Function         btm_sec_rmt_name_request_complete
2765 **
2766 ** Description      This function is called when remote name was obtained from
2767 **                  the peer device
2768 **
2769 ** Returns          void
2770 **
2771 *******************************************************************************/
btm_sec_rmt_name_request_complete(UINT8 * p_bd_addr,UINT8 * p_bd_name,UINT8 status)2772 void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT8 status)
2773 {
2774     tBTM_SEC_DEV_REC *p_dev_rec;
2775     int              i;
2776     DEV_CLASS        dev_class;
2777     UINT8            old_sec_state;
2778 
2779     BTM_TRACE_EVENT0 ("btm_sec_rmt_name_request_complete");
2780     if (((p_bd_addr == NULL) && !BTM_ACL_IS_CONNECTED(btm_cb.connecting_bda))
2781         || ((p_bd_addr != NULL) && !BTM_ACL_IS_CONNECTED(p_bd_addr)))
2782     {
2783         btm_acl_resubmit_page();
2784     }
2785 
2786     /* If remote name request failed, p_bd_addr is null and we need to search */
2787     /* based on state assuming that we are doing 1 at a time */
2788     if (p_bd_addr)
2789         p_dev_rec = btm_find_dev (p_bd_addr);
2790     else
2791     {
2792         p_dev_rec = &btm_cb.sec_dev_rec[0];
2793 
2794         for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
2795         {
2796             if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
2797                 && (p_dev_rec->sec_state == BTM_SEC_STATE_GETTING_NAME))
2798             {
2799                 p_bd_addr = p_dev_rec->bd_addr;
2800                 break;
2801             }
2802         }
2803 
2804         if (i == BTM_SEC_MAX_DEVICE_RECORDS)
2805             p_dev_rec = NULL;
2806     }
2807 
2808 
2809     /* Commenting out trace due to obf/compilation problems.
2810     */
2811 #if (BT_USE_TRACES == TRUE)
2812     if (!p_bd_name)
2813         p_bd_name = (UINT8 *)"";
2814 
2815     if (p_dev_rec)
2816     {
2817         BTM_TRACE_EVENT5 ("Security Manager: rmt_name_complete PairState: %s  RemName: %s  status: %d State:%d  p_dev_rec: 0x%08x ",
2818                           btm_pair_state_descr (btm_cb.pairing_state), p_bd_name,
2819                           status, p_dev_rec->sec_state, p_dev_rec);
2820     }
2821     else
2822     {
2823         BTM_TRACE_EVENT3 ("Security Manager: rmt_name_complete PairState: %s  RemName: %s  status: %d",
2824                           btm_pair_state_descr (btm_cb.pairing_state), p_bd_name,
2825                           status);
2826     }
2827 #endif
2828 
2829     if (p_dev_rec)
2830     {
2831         old_sec_state = p_dev_rec->sec_state;
2832         if (status == HCI_SUCCESS)
2833         {
2834             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);
2835             p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
2836             BTM_TRACE_EVENT1 ("setting BTM_SEC_NAME_KNOWN sec_flags:0x%x", p_dev_rec->sec_flags);
2837         }
2838         else
2839         {
2840             /* Notify all clients waiting for name to be resolved even if it failed so clients can continue */
2841             p_dev_rec->sec_bd_name[0] = 0;
2842         }
2843 
2844         if (p_dev_rec->sec_state == BTM_SEC_STATE_GETTING_NAME)
2845             p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
2846 
2847         /* Notify all clients waiting for name to be resolved */
2848         for (i = 0;i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++)
2849         {
2850             if (btm_cb.p_rmt_name_callback[i])
2851                 (*btm_cb.p_rmt_name_callback[i])(p_bd_addr, p_dev_rec->dev_class,
2852                                                  p_dev_rec->sec_bd_name);
2853         }
2854     }
2855     else
2856     {
2857         dev_class[0] = 0;
2858         dev_class[1] = 0;
2859         dev_class[2] = 0;
2860 
2861         /* Notify all clients waiting for name to be resolved even if not found so clients can continue */
2862         for (i = 0;i < BTM_SEC_MAX_RMT_NAME_CALLBACKS; i++)
2863         {
2864             if (btm_cb.p_rmt_name_callback[i])
2865                 (*btm_cb.p_rmt_name_callback[i])(p_bd_addr, dev_class, (UINT8 *)"");
2866         }
2867 
2868         return;
2869     }
2870 
2871     /* If we were delaying asking UI for a PIN because name was not resolved, ask now */
2872     if ( (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_LOCAL_PIN) && p_bd_addr
2873          &&  (memcmp (btm_cb.pairing_bda, p_bd_addr, BD_ADDR_LEN) == 0) )
2874     {
2875         BTM_TRACE_EVENT2 ("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);
2876 
2877         if (((btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) == 0) &&
2878             ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0) &&
2879             btm_cb.api.p_pin_callback)
2880         {
2881             BTM_TRACE_EVENT0 ("btm_sec_rmt_name_request_complete() calling pin_callback");
2882             btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
2883             (*btm_cb.api.p_pin_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, p_bd_name);
2884         }
2885 
2886         /* Set the same state again to force the timer to be restarted */
2887         btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_PIN);
2888         return;
2889     }
2890 
2891     /* Check if we were delaying bonding because name was not resolved */
2892     if ( btm_cb.pairing_state == BTM_PAIR_STATE_GET_REM_NAME)
2893     {
2894         if (p_bd_addr && memcmp (btm_cb.pairing_bda, p_bd_addr, BD_ADDR_LEN) == 0)
2895         {
2896             BTM_TRACE_EVENT2 ("btm_sec_rmt_name_request_complete() continue bonding sm4: 0x%04x, status:0x%x", p_dev_rec->sm4, status);
2897             if (status != HCI_SUCCESS)
2898             {
2899                 btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
2900 
2901                 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,  p_dev_rec->dev_class,
2902                                                         p_dev_rec->sec_bd_name, status);
2903                 return;
2904             }
2905 
2906             /* if peer is very old legacy devices, HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT is not reported */
2907             if (BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4))
2908             {
2909                 /* set the KNOWN flag only if BTM_PAIR_FLAGS_REJECTED_CONNECT is not set.
2910                  * If it is set, there may be a race condition */
2911 				BTM_TRACE_EVENT1 ("btm_sec_rmt_name_request_complete  IS_SM4_UNKNOWN Flags:0x%04x", btm_cb.pairing_flags);
2912                 if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT) == 0)
2913                 {
2914                     p_dev_rec->sm4 |= BTM_SM4_KNOWN;
2915                 }
2916             }
2917 
2918             /* BT 2.1 or carkit, bring up the connection to force the peer to request PIN.
2919             ** Else prefetch (btm_sec_check_prefetch_pin will do the prefetching if needed)
2920             */
2921             if ((p_dev_rec->sm4 != BTM_SM4_KNOWN) || !btm_sec_check_prefetch_pin(p_dev_rec))
2922             {
2923                 /* if we rejected incoming connection request, we have to wait HCI_Connection_Complete event */
2924                 /*  before originating  */
2925                 if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT)
2926                 {
2927                     BTM_TRACE_WARNING0 ("btm_sec_rmt_name_request_complete: waiting HCI_Connection_Complete after rejecting connection");
2928                 }
2929                 /* Both we and the peer are 2.1 - continue to create connection */
2930                 else if (btm_sec_dd_create_conn(p_dev_rec) != BTM_CMD_STARTED)
2931                 {
2932                     BTM_TRACE_WARNING0 ("btm_sec_rmt_name_request_complete: failed to start connection");
2933 
2934                     btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
2935 
2936                     (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,  p_dev_rec->dev_class,
2937                                                             p_dev_rec->sec_bd_name, HCI_ERR_MEMORY_FULL);
2938                 }
2939             }
2940             return;
2941         }
2942         else
2943         {
2944             BTM_TRACE_WARNING0 ("btm_sec_rmt_name_request_complete: wrong BDA, retry with pairing BDA");
2945 
2946             BTM_ReadRemoteDeviceName (btm_cb.pairing_bda, NULL);
2947             return;
2948         }
2949     }
2950 
2951     /* check if we were delaying link_key_callback because name was not resolved */
2952     if (p_dev_rec->link_key_not_sent)
2953     {
2954         /* If HCI connection complete has not arrived, wait for it */
2955         if (p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE)
2956             return;
2957 
2958         p_dev_rec->link_key_not_sent = FALSE;
2959         btm_send_link_key_notif(p_dev_rec);
2960 
2961         /* If its not us who perform authentication, we should tell stackserver */
2962         /* that some authentication has been completed                          */
2963         /* This is required when different entities receive link notification and auth complete */
2964         if (!(p_dev_rec->security_required & BTM_SEC_OUT_AUTHENTICATE))
2965         {
2966             if (btm_cb.api.p_auth_complete_callback)
2967                 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
2968                                                         p_dev_rec->dev_class,
2969                                                         p_dev_rec->sec_bd_name, HCI_SUCCESS);
2970 
2971         }
2972     }
2973 
2974     /* If this is a bonding procedure can disconnect the link now */
2975     if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
2976         && (p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))
2977     {
2978         BTM_TRACE_WARNING0 ("btm_sec_rmt_name_request_complete (none/ce)");
2979         p_dev_rec->security_required &= ~(BTM_SEC_OUT_AUTHENTICATE);
2980         l2cu_start_post_bond_timer(p_dev_rec->hci_handle);
2981         return;
2982     }
2983 
2984     if (old_sec_state != BTM_SEC_STATE_GETTING_NAME)
2985         return;
2986 
2987     /* If get name failed, notify the waiting layer */
2988     if (status != HCI_SUCCESS)
2989     {
2990         btm_sec_dev_rec_cback_event  (p_dev_rec, BTM_ERR_PROCESSING);
2991         return;
2992     }
2993 
2994     if (p_dev_rec->sm4 & BTM_SM4_REQ_PEND)
2995     {
2996         BTM_TRACE_EVENT0 ("waiting for remote features!!");
2997         return;
2998     }
2999 
3000     /* Remote Name succeeded, execute the next security procedure, if any */
3001     status = (UINT8)btm_sec_execute_procedure (p_dev_rec);
3002 
3003     /* If result is pending reply from the user or from the device is pending */
3004     if (status == BTM_CMD_STARTED)
3005         return;
3006 
3007     /* There is no next procedure or start of procedure failed, notify the waiting layer */
3008     btm_sec_dev_rec_cback_event  (p_dev_rec, status);
3009 }
3010 
3011 /*******************************************************************************
3012 **
3013 ** Function         btm_sec_rmt_host_support_feat_evt
3014 **
3015 ** Description      This function is called when the
3016 **                  HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT is received
3017 **
3018 ** Returns          void
3019 **
3020 *******************************************************************************/
btm_sec_rmt_host_support_feat_evt(UINT8 * p)3021 void btm_sec_rmt_host_support_feat_evt (UINT8 *p)
3022 {
3023     tBTM_SEC_DEV_REC *p_dev_rec;
3024     BD_ADDR         bd_addr;        /* peer address */
3025     BD_FEATURES     features;
3026 
3027     STREAM_TO_BDADDR (bd_addr, p);
3028     p_dev_rec = btm_find_or_alloc_dev (bd_addr);
3029 
3030     BTM_TRACE_EVENT2 ("btm_sec_rmt_host_support_feat_evt  sm4: 0x%x  p[0]: 0x%x", p_dev_rec->sm4, p[0]);
3031 
3032     if (BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4))
3033     {
3034         p_dev_rec->sm4 = BTM_SM4_KNOWN;
3035         STREAM_TO_ARRAY(features, p, BD_FEATURES_LEN);
3036         if (HCI_SSP_HOST_SUPPORTED(features))
3037         {
3038             p_dev_rec->sm4 = BTM_SM4_TRUE;
3039         }
3040         BTM_TRACE_EVENT2 ("btm_sec_rmt_host_support_feat_evt sm4: 0x%x features[0]: 0x%x", p_dev_rec->sm4, features[0]);
3041     }
3042 }
3043 
3044 /*******************************************************************************
3045 **
3046 ** Function         btm_io_capabilities_req
3047 **
3048 ** Description      This function is called when LM request for the IO
3049 **                  capability of the local device and
3050 **                  if the OOB data is present for the device in the event
3051 **
3052 ** Returns          void
3053 **
3054 *******************************************************************************/
btm_io_capabilities_req(UINT8 * p)3055 void btm_io_capabilities_req (UINT8 *p)
3056 {
3057     tBTM_SP_IO_REQ  evt_data;
3058     UINT8           err_code = 0;
3059     tBTM_SEC_DEV_REC *p_dev_rec;
3060     BOOLEAN         is_orig = TRUE;
3061     UINT8           callback_rc = BTM_SUCCESS;
3062 
3063     STREAM_TO_BDADDR (evt_data.bd_addr, p);
3064 
3065     /* setup the default response according to compile options */
3066     /* assume that the local IO capability does not change
3067      * loc_io_caps is initialized with the default value */
3068     evt_data.io_cap = btm_cb.devcb.loc_io_caps;
3069     evt_data.oob_data = BTM_OOB_NONE;
3070     evt_data.auth_req = BTM_DEFAULT_AUTH_REQ;
3071 
3072     BTM_TRACE_EVENT1 ("btm_io_capabilities_req() State: %s", btm_pair_state_descr(btm_cb.pairing_state));
3073 
3074     p_dev_rec = btm_find_or_alloc_dev (evt_data.bd_addr);
3075     p_dev_rec->sm4 |= BTM_SM4_TRUE;
3076 
3077     BTM_TRACE_EVENT3 ("btm_io_capabilities_req() State: %s  Flags: 0x%04x  p_cur_service: 0x%08x",
3078                       btm_pair_state_descr(btm_cb.pairing_state), btm_cb.pairing_flags, p_dev_rec->p_cur_service);
3079 
3080     if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
3081     {
3082         if (btm_cb.pairing_state == BTM_PAIR_STATE_INCOMING_SSP)
3083         {
3084             /* received IO capability response already-> not the originator of SSP */
3085             is_orig = FALSE;
3086 
3087             if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_PEER_STARTED_DD)
3088                 evt_data.auth_req = BTM_DEFAULT_DD_AUTH_REQ;
3089         }
3090         /* security is already in progress */
3091         else if (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_PIN_REQ)
3092         {
3093 /* coverity[uninit_use_in_call]
3094 Event uninit_use_in_call: Using uninitialized element of array "evt_data.bd_addr" in call to function "memcmp"
3095 False-positive: evt_data.bd_addr is set at the beginning with:     STREAM_TO_BDADDR (evt_data.bd_addr, p);
3096 */
3097             if (memcmp (evt_data.bd_addr, btm_cb.pairing_bda, BD_ADDR_LEN))
3098             {
3099                 /* and it's not the device in bonding -> reject it */
3100                 err_code = HCI_ERR_HOST_BUSY_PAIRING;
3101             }
3102             else
3103             {
3104                 /* local device initiated dedicated bonding */
3105                 evt_data.auth_req = BTM_DEFAULT_DD_AUTH_REQ;
3106             }
3107         }
3108         else
3109         {
3110             err_code = HCI_ERR_HOST_BUSY_PAIRING;
3111         }
3112     }
3113 
3114     /* paring is not allowed */
3115     if (btm_cb.pairing_disabled)
3116         err_code = HCI_ERR_PAIRING_NOT_ALLOWED;
3117 
3118     if (err_code != 0)
3119     {
3120 /* coverity[uninit_use_in_call]
3121 Event uninit_use_in_call: Using uninitialized element of array "evt_data.bd_addr" in call to function "memcmp"
3122 False-positive: evt_data.bd_addr is set at the beginning with:     STREAM_TO_BDADDR (evt_data.bd_addr, p);
3123 */
3124         btsnd_hcic_io_cap_req_neg_reply(evt_data.bd_addr, err_code);
3125         return;
3126     }
3127 
3128     evt_data.is_orig = is_orig;
3129 
3130     if (is_orig)
3131     {
3132         /* local device initiated the pairing non-bonding -> use p_cur_service */
3133         if (!(btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) &&
3134             p_dev_rec->p_cur_service &&
3135             (p_dev_rec->p_cur_service->security_flags & BTM_SEC_OUT_AUTHENTICATE))
3136         {
3137             evt_data.auth_req = (p_dev_rec->p_cur_service->security_flags & BTM_SEC_OUT_MITM) ? BTM_AUTH_SP_YES : BTM_AUTH_SP_NO;
3138         }
3139     }
3140 
3141     /* Notify L2CAP to increase timeout */
3142     l2c_pin_code_request (evt_data.bd_addr);
3143 
3144     memcpy (btm_cb.pairing_bda, evt_data.bd_addr, BD_ADDR_LEN);
3145 
3146 /* coverity[uninit_use_in_call]
3147 Event uninit_use_in_call: Using uninitialized element of array "evt_data.bd_addr" in call to function "memcmp"
3148 False-positive: False-positive: evt_data.bd_addr is set at the beginning with:     STREAM_TO_BDADDR (evt_data.bd_addr, p);
3149 */
3150     if (!memcmp (evt_data.bd_addr, btm_cb.connecting_bda, BD_ADDR_LEN))
3151         memcpy (p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN);
3152 
3153     btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS);
3154 
3155     callback_rc = BTM_SUCCESS;
3156     if (p_dev_rec->sm4 & BTM_SM4_UPGRADE)
3157     {
3158         p_dev_rec->sm4 &= ~BTM_SM4_UPGRADE;
3159 
3160         /* link key upgrade: always use SPGB_YES - assuming we want to save the link key */
3161         evt_data.auth_req = BTM_AUTH_SPGB_YES;
3162     }
3163     else if (btm_cb.api.p_sp_callback)
3164     {
3165         /* the callback function implementation may change the IO capability... */
3166         callback_rc = (*btm_cb.api.p_sp_callback) (BTM_SP_IO_REQ_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
3167     }
3168 
3169 #if BTM_OOB_INCLUDED == TRUE
3170     if ((callback_rc == BTM_SUCCESS) || (BTM_OOB_UNKNOWN != evt_data.oob_data))
3171 #else
3172     if (callback_rc == BTM_SUCCESS)
3173 #endif
3174     {
3175         if ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD))
3176         {
3177             evt_data.auth_req = (BTM_AUTH_DD_BOND | (evt_data.auth_req & BTM_AUTH_YN_BIT));
3178         }
3179 
3180         /* if the user does not indicate "reply later" by setting the oob_data to unknown
3181          * send the response right now. Save the current IO capability in the control block */
3182         btm_cb.devcb.loc_auth_req   = evt_data.auth_req;
3183         btm_cb.devcb.loc_io_caps    = evt_data.io_cap;
3184 
3185         BTM_TRACE_EVENT4 ("btm_io_capabilities_req: State: %s  IO_CAP:%d oob_data:%d auth_req:%d",
3186                           btm_pair_state_descr(btm_cb.pairing_state), evt_data.io_cap,
3187                           evt_data.oob_data, evt_data.auth_req);
3188 
3189         btsnd_hcic_io_cap_req_reply(evt_data.bd_addr, evt_data.io_cap,
3190                                     evt_data.oob_data, evt_data.auth_req);
3191     }
3192 }
3193 
3194 /*******************************************************************************
3195 **
3196 ** Function         btm_io_capabilities_rsp
3197 **
3198 ** Description      This function is called when the IO capability of the
3199 **                  specified device is received
3200 **
3201 ** Returns          void
3202 **
3203 *******************************************************************************/
btm_io_capabilities_rsp(UINT8 * p)3204 void btm_io_capabilities_rsp (UINT8 *p)
3205 {
3206     tBTM_SEC_DEV_REC *p_dev_rec;
3207     tBTM_SP_IO_RSP evt_data;
3208 
3209     STREAM_TO_BDADDR (evt_data.bd_addr, p);
3210     STREAM_TO_UINT8 (evt_data.io_cap, p);
3211     STREAM_TO_UINT8 (evt_data.oob_data, p);
3212     STREAM_TO_UINT8 (evt_data.auth_req, p);
3213 
3214     /* Allocate a new device record or reuse the oldest one */
3215     p_dev_rec = btm_find_or_alloc_dev (evt_data.bd_addr);
3216 
3217     /* If no security is in progress, this indicates incoming security */
3218     if (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE)
3219     {
3220         memcpy (btm_cb.pairing_bda, evt_data.bd_addr, BD_ADDR_LEN);
3221 
3222         btm_sec_change_pairing_state (BTM_PAIR_STATE_INCOMING_SSP);
3223 
3224         /* Make sure we reset the trusted mask to help against attacks */
3225         BTM_SEC_CLR_TRUSTED_DEVICE(p_dev_rec->trusted_mask);
3226 
3227         /* work around for FW bug */
3228         btm_inq_stop_on_ssp();
3229     }
3230 
3231     /* Notify L2CAP to increase timeout */
3232     l2c_pin_code_request (evt_data.bd_addr);
3233 
3234     /* We must have a device record here.
3235      * Use the connecting device's CoD for the connection */
3236 /* coverity[uninit_use_in_call]
3237 Event uninit_use_in_call: Using uninitialized element of array "evt_data.bd_addr" in call to function "memcmp"
3238 FALSE-POSITIVE error from Coverity test-tool. evt_data.bd_addr is set at the beginning with:     STREAM_TO_BDADDR (evt_data.bd_addr, p);
3239 */
3240     if (!memcmp (evt_data.bd_addr, btm_cb.connecting_bda, BD_ADDR_LEN))
3241         memcpy (p_dev_rec->dev_class, btm_cb.connecting_dc, DEV_CLASS_LEN);
3242 
3243     /* peer sets dedicated bonding bit and we did not initiate dedicated bonding */
3244     if (btm_cb.pairing_state == BTM_PAIR_STATE_INCOMING_SSP /* peer initiated bonding */
3245         && (evt_data.auth_req & BTM_AUTH_DD_BOND) )            /* and dedicated bonding bit is set */
3246     {
3247         btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PEER_STARTED_DD;
3248     }
3249 
3250     /* save the IO capability in the device record */
3251     p_dev_rec->rmt_io_caps  = evt_data.io_cap;
3252     p_dev_rec->rmt_auth_req = evt_data.auth_req;
3253 
3254     if (btm_cb.api.p_sp_callback)
3255         (*btm_cb.api.p_sp_callback) (BTM_SP_IO_RSP_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
3256 }
3257 
3258 /*******************************************************************************
3259 **
3260 ** Function         btm_proc_sp_req_evt
3261 **
3262 ** Description      This function is called to process/report
3263 **                  HCI_USER_CONFIRMATION_REQUEST_EVT
3264 **                  or HCI_USER_PASSKEY_REQUEST_EVT
3265 **                  or HCI_USER_PASSKEY_NOTIFY_EVT
3266 **
3267 ** Returns          void
3268 **
3269 *******************************************************************************/
btm_proc_sp_req_evt(tBTM_SP_EVT event,UINT8 * p)3270 void btm_proc_sp_req_evt (tBTM_SP_EVT event, UINT8 *p)
3271 {
3272     tBTM_STATUS status = BTM_ERR_PROCESSING;
3273     tBTM_SP_EVT_DATA evt_data;
3274     UINT8               *p_bda = evt_data.cfm_req.bd_addr;
3275     tBTM_SEC_DEV_REC *p_dev_rec;
3276 
3277     /* All events start with bd_addr */
3278     STREAM_TO_BDADDR (p_bda, p);
3279 
3280     BTM_TRACE_EVENT4 ("btm_proc_sp_req_evt() BDA: %08x%04x event: 0x%x, State: %s",
3281                       (p_bda[0]<<24) + (p_bda[1]<<16) + (p_bda[2]<<8) + p_bda[3], (p_bda[4] << 8) + p_bda[5],
3282                       event, btm_pair_state_descr(btm_cb.pairing_state));
3283 
3284     if ( ((p_dev_rec = btm_find_dev (p_bda)) != NULL)
3285          &&  (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
3286          &&  (memcmp (btm_cb.pairing_bda, p_bda, BD_ADDR_LEN) == 0) )
3287     {
3288         memcpy (evt_data.cfm_req.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
3289         memcpy (evt_data.cfm_req.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN);
3290 
3291         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);
3292 
3293         switch (event)
3294         {
3295             case BTM_SP_CFM_REQ_EVT:
3296                 /* Numeric confirmation. Need user to conf the passkey */
3297                 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM);
3298 
3299                 /* The device record must be allocated in the "IO cap exchange" step */
3300                 STREAM_TO_UINT32 (evt_data.cfm_req.num_val, p);
3301 
3302                 evt_data.cfm_req.just_works = TRUE;
3303 
3304                 /* process user confirm req in association with the auth_req param */
3305 #if (BTM_LOCAL_IO_CAPS == BTM_IO_CAP_IO)
3306                 if ( (p_dev_rec->rmt_io_caps == BTM_IO_CAP_IO)
3307                      &&  (btm_cb.devcb.loc_io_caps == BTM_IO_CAP_IO)
3308                      &&  ((p_dev_rec->rmt_auth_req & BTM_AUTH_SP_YES) || (btm_cb.devcb.loc_auth_req & BTM_AUTH_SP_YES)) )
3309                 {
3310                     /* Both devices are DisplayYesNo and one or both devices want to authenticate
3311                        -> use authenticated link key */
3312                     evt_data.cfm_req.just_works = FALSE;
3313                 }
3314 #endif
3315                 BTM_TRACE_DEBUG5 ("btm_proc_sp_req_evt()  just_works:%d, io loc:%d, rmt:%d, auth loc:%d, rmt:%d",
3316                                   evt_data.cfm_req.just_works, btm_cb.devcb.loc_io_caps, p_dev_rec->rmt_io_caps,
3317                                   btm_cb.devcb.loc_auth_req, p_dev_rec->rmt_auth_req);
3318 
3319                 evt_data.cfm_req.loc_auth_req   = btm_cb.devcb.loc_auth_req;
3320                 evt_data.cfm_req.rmt_auth_req   = p_dev_rec->rmt_auth_req;
3321                 evt_data.cfm_req.loc_io_caps    = btm_cb.devcb.loc_io_caps;
3322                 evt_data.cfm_req.rmt_io_caps    = p_dev_rec->rmt_io_caps;
3323                 break;
3324 
3325             case BTM_SP_KEY_NOTIF_EVT:
3326                 /* Passkey notification (other side is a keyboard) */
3327                 STREAM_TO_UINT32 (evt_data.key_notif.passkey, p);
3328 
3329                 BTM_TRACE_DEBUG1 ("BTM_SP_KEY_NOTIF_EVT:  passkey: %u", evt_data.key_notif.passkey);
3330 
3331                 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
3332                 break;
3333 
3334 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
3335             case BTM_SP_KEY_REQ_EVT:
3336                 /* HCI_USER_PASSKEY_REQUEST_EVT */
3337                 btm_sec_change_pairing_state (BTM_PAIR_STATE_KEY_ENTRY);
3338                 break;
3339 #endif
3340         }
3341 
3342         if (btm_cb.api.p_sp_callback)
3343         {
3344             status = (*btm_cb.api.p_sp_callback) (event, (tBTM_SP_EVT_DATA *)&evt_data);
3345             if (status != BTM_NOT_AUTHORIZED)
3346             {
3347                 return;
3348             }
3349             /* else BTM_NOT_AUTHORIZED means when the app wants to reject the req right now */
3350         }
3351         else if ( (event == BTM_SP_CFM_REQ_EVT) && (evt_data.cfm_req.just_works == TRUE) )
3352         {
3353             /* automatically reply with just works if no sp_cback */
3354             status = BTM_SUCCESS;
3355         }
3356 
3357         if (event == BTM_SP_CFM_REQ_EVT)
3358         {
3359             BTM_TRACE_DEBUG1 ("calling BTM_ConfirmReqReply with status: %d", status);
3360             BTM_ConfirmReqReply (status, p_bda);
3361         }
3362 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
3363         else if (event == BTM_SP_KEY_REQ_EVT)
3364         {
3365             BTM_PasskeyReqReply(status, p_bda, 0);
3366         }
3367 #endif
3368         return;
3369     }
3370 
3371     /* Something bad. we can only fail this connection */
3372     btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
3373 
3374     if (BTM_SP_CFM_REQ_EVT == event)
3375     {
3376         btsnd_hcic_user_conf_reply (p_bda, FALSE);
3377     }
3378     else if (BTM_SP_KEY_NOTIF_EVT == event)
3379     {
3380         /* do nothing -> it very unlikely to happen.
3381         This event is most likely to be received by a HID host when it first connects to a HID device.
3382         Usually the Host initiated the connection in this case.
3383         On Mobile platforms, if there's a security process happening,
3384         the host probably can not initiate another connection.
3385         BTW (PC) is another story.  */
3386         if (NULL != (p_dev_rec = btm_find_dev (p_bda)) )
3387         {
3388             btm_sec_disconnect (p_dev_rec->hci_handle, HCI_ERR_AUTH_FAILURE);
3389         }
3390     }
3391 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
3392     else
3393     {
3394         btsnd_hcic_user_passkey_neg_reply(p_bda);
3395     }
3396 #endif
3397 }
3398 
3399 /*******************************************************************************
3400 **
3401 ** Function         btm_keypress_notif_evt
3402 **
3403 ** Description      This function is called when a key press notification is
3404 **                  received
3405 **
3406 ** Returns          void
3407 **
3408 *******************************************************************************/
btm_keypress_notif_evt(UINT8 * p)3409 void  btm_keypress_notif_evt (UINT8 *p)
3410 {
3411     tBTM_SP_KEYPRESS    evt_data;
3412     UINT8 *p_bda;
3413 
3414     /* parse & report BTM_SP_KEYPRESS_EVT */
3415     if (btm_cb.api.p_sp_callback)
3416     {
3417         p_bda = evt_data.bd_addr;
3418 
3419         STREAM_TO_BDADDR (p_bda, p);
3420         evt_data.notif_type = *p;
3421 
3422         (*btm_cb.api.p_sp_callback) (BTM_SP_KEYPRESS_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
3423     }
3424 }
3425 
3426 /*******************************************************************************
3427 **
3428 ** Function         btm_simple_pair_complete
3429 **
3430 ** Description      This function is called when simple pairing process is
3431 **                  complete
3432 **
3433 ** Returns          void
3434 **
3435 *******************************************************************************/
btm_simple_pair_complete(UINT8 * p)3436 void btm_simple_pair_complete (UINT8 *p)
3437 {
3438     tBTM_SP_COMPLT  evt_data;
3439     tBTM_SEC_DEV_REC *p_dev_rec;
3440     UINT8           status;
3441     BOOLEAN         disc = FALSE;
3442 
3443     status = *p++;
3444     STREAM_TO_BDADDR (evt_data.bd_addr, p);
3445 
3446     if ((p_dev_rec = btm_find_dev (evt_data.bd_addr)) == NULL)
3447     {
3448         BTM_TRACE_ERROR2 ("btm_simple_pair_complete() with unknown BDA: %08x%04x",
3449                           (evt_data.bd_addr[0]<<24) + (evt_data.bd_addr[1]<<16) + (evt_data.bd_addr[2]<<8) + evt_data.bd_addr[3],
3450                           (evt_data.bd_addr[4] << 8) + evt_data.bd_addr[5]);
3451         return;
3452     }
3453 
3454     BTM_TRACE_EVENT3 ("btm_simple_pair_complete()  Pair State: %s  Status:%d  sec_state: %u",
3455                       btm_pair_state_descr(btm_cb.pairing_state),  status, p_dev_rec->sec_state);
3456 
3457     evt_data.status = BTM_ERR_PROCESSING;
3458     if (status == HCI_SUCCESS)
3459     {
3460         evt_data.status = BTM_SUCCESS;
3461         p_dev_rec->sec_flags |= BTM_SEC_AUTHENTICATED;
3462     }
3463     else
3464     {
3465         if (status == HCI_ERR_PAIRING_NOT_ALLOWED)
3466         {
3467             /* The test spec wants the peer device to get this failure code. */
3468             btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_DISCONNECT);
3469 
3470             /* Change the timer to 1 second */
3471             btu_start_timer (&btm_cb.pairing_tle, BTU_TTYPE_USER_FUNC, BT_1SEC_TIMEOUT);
3472         }
3473         else if (memcmp (btm_cb.pairing_bda, evt_data.bd_addr, BD_ADDR_LEN) == 0)
3474         {
3475             /* stop the timer */
3476             btu_stop_timer (&btm_cb.pairing_tle);
3477 
3478             if (p_dev_rec->sec_state != BTM_SEC_STATE_AUTHENTICATING)
3479             {
3480                 /* the initiating side: will receive auth complete event. disconnect ACL at that time */
3481                 disc = TRUE;
3482             }
3483         }
3484         else
3485             disc = TRUE;
3486     }
3487 
3488     /* Let the pairing state stay active, p_auth_complete_callback will report the failure */
3489     memcpy (evt_data.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
3490     memcpy (evt_data.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN);
3491 
3492     if (btm_cb.api.p_sp_callback)
3493         (*btm_cb.api.p_sp_callback) (BTM_SP_COMPLT_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
3494 
3495     if (disc)
3496     {
3497         /* simple pairing failed */
3498         btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE);
3499     }
3500 }
3501 
3502 #if BTM_OOB_INCLUDED == TRUE
3503 /*******************************************************************************
3504 **
3505 ** Function         btm_rem_oob_req
3506 **
3507 ** Description      This function is called to process/report
3508 **                  HCI_REMOTE_OOB_DATA_REQUEST_EVT
3509 **
3510 ** Returns          void
3511 **
3512 *******************************************************************************/
btm_rem_oob_req(UINT8 * p)3513 void btm_rem_oob_req (UINT8 *p)
3514 {
3515     UINT8 *p_bda;
3516     tBTM_SP_RMT_OOB  evt_data;
3517     tBTM_SEC_DEV_REC *p_dev_rec;
3518     BT_OCTET16      c;
3519     BT_OCTET16      r;
3520 
3521     p_bda = evt_data.bd_addr;
3522 
3523     STREAM_TO_BDADDR (p_bda, p);
3524 
3525     BTM_TRACE_EVENT6 ("btm_rem_oob_req() BDA: %02x:%02x:%02x:%02x:%02x:%02x",
3526                       p_bda[0], p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]);
3527 
3528     if ( (NULL != (p_dev_rec = btm_find_dev (p_bda))) &&
3529          btm_cb.api.p_sp_callback)
3530     {
3531         memcpy (evt_data.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
3532         memcpy (evt_data.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN);
3533         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);
3534 
3535         btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP);
3536         if ((*btm_cb.api.p_sp_callback) (BTM_SP_RMT_OOB_EVT, (tBTM_SP_EVT_DATA *)&evt_data) == BTM_NOT_AUTHORIZED)
3537         {
3538             BTM_RemoteOobDataReply(TRUE, p_bda, c, r);
3539         }
3540         return;
3541     }
3542 
3543     /* something bad. we can only fail this connection */
3544     btm_cb.acl_disc_reason = HCI_ERR_HOST_REJECT_SECURITY;
3545     btsnd_hcic_rem_oob_neg_reply (p_bda);
3546 }
3547 
3548 /*******************************************************************************
3549 **
3550 ** Function         btm_read_local_oob_complete
3551 **
3552 ** Description      This function is called when read local oob data is
3553 **                  completed by the LM
3554 **
3555 ** Returns          void
3556 **
3557 *******************************************************************************/
btm_read_local_oob_complete(UINT8 * p)3558 void btm_read_local_oob_complete (UINT8 *p)
3559 {
3560     tBTM_SP_LOC_OOB evt_data;
3561     UINT8           status = *p++;
3562 
3563     BTM_TRACE_EVENT1 ("btm_read_local_oob_complete:%d", status);
3564     if (status == HCI_SUCCESS)
3565     {
3566         evt_data.status = BTM_SUCCESS;
3567         STREAM_TO_ARRAY16(evt_data.c, p);
3568         STREAM_TO_ARRAY16(evt_data.r, p);
3569     }
3570     else
3571         evt_data.status = BTM_ERR_PROCESSING;
3572 
3573     if (btm_cb.api.p_sp_callback)
3574         (*btm_cb.api.p_sp_callback) (BTM_SP_LOC_OOB_EVT, (tBTM_SP_EVT_DATA *)&evt_data);
3575 }
3576 #endif /* BTM_OOB_INCLUDED */
3577 
3578 /*******************************************************************************
3579 **
3580 ** Function         btm_sec_auth_collision
3581 **
3582 ** Description      This function is called when authentication or encryption
3583 **                  needs to be retried at a later time.
3584 **
3585 ** Returns          void
3586 **
3587 *******************************************************************************/
btm_sec_auth_collision(UINT16 handle)3588 static void btm_sec_auth_collision (UINT16 handle)
3589 {
3590     tBTM_SEC_DEV_REC *p_dev_rec;
3591 
3592     if (!btm_cb.collision_start_time)
3593         btm_cb.collision_start_time = GKI_get_tick_count ();
3594 
3595     if ((GKI_get_tick_count () - btm_cb.collision_start_time) < btm_cb.max_collision_delay)
3596     {
3597         if (handle == BTM_SEC_INVALID_HANDLE)
3598         {
3599             if ((p_dev_rec = btm_sec_find_dev_by_sec_state (BTM_SEC_STATE_AUTHENTICATING)) == NULL)
3600                 p_dev_rec = btm_sec_find_dev_by_sec_state (BTM_SEC_STATE_ENCRYPTING);
3601         }
3602         else
3603             p_dev_rec = btm_find_dev_by_handle (handle);
3604 
3605         if (p_dev_rec != NULL)
3606         {
3607             BTM_TRACE_DEBUG1 ("btm_sec_auth_collision: state %d (retrying in a moment...)", p_dev_rec->sec_state);
3608             /* We will restart authentication after timeout */
3609             if (p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING || p_dev_rec->sec_state == BTM_SEC_STATE_ENCRYPTING)
3610                 p_dev_rec->sec_state = 0;
3611 
3612             btm_cb.p_collided_dev_rec = p_dev_rec;
3613             btm_cb.sec_collision_tle.param = (UINT32) btm_sec_collision_timeout;
3614             btu_start_timer (&btm_cb.sec_collision_tle, BTU_TTYPE_USER_FUNC, BT_1SEC_TIMEOUT);
3615         }
3616     }
3617 }
3618 
3619 /*******************************************************************************
3620 **
3621 ** Function         btm_sec_auth_complete
3622 **
3623 ** Description      This function is when authentication of the connection is
3624 **                  completed by the LM
3625 **
3626 ** Returns          void
3627 **
3628 *******************************************************************************/
btm_sec_auth_complete(UINT16 handle,UINT8 status)3629 void btm_sec_auth_complete (UINT16 handle, UINT8 status)
3630 {
3631     UINT8            old_sm4;
3632     tBTM_PAIRING_STATE  old_state   = btm_cb.pairing_state;
3633     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev_by_handle (handle);
3634     BOOLEAN             are_bonding = FALSE;
3635 
3636     /* Commenting out trace due to obf/compilation problems.
3637     */
3638 #if (BT_USE_TRACES == TRUE)
3639     if (p_dev_rec)
3640     {
3641         BTM_TRACE_EVENT6 ("Security Manager: auth_complete PairState: %s  handle:%u  status:%d  dev->sec_state: %u  Bda:%08x, RName:%s",
3642                           btm_pair_state_descr (btm_cb.pairing_state),
3643                           handle, status,
3644                           p_dev_rec->sec_state,
3645                           (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],
3646                           p_dev_rec->sec_bd_name);
3647     }
3648     else
3649     {
3650         BTM_TRACE_EVENT3 ("Security Manager: auth_complete PairState: %s  handle:%u  status:%d",
3651                           btm_pair_state_descr (btm_cb.pairing_state),
3652                           handle, status);
3653     }
3654 #endif
3655 
3656     /* For transaction collision we need to wait and repeat.  There is no need */
3657     /* for random timeout because only slave should receive the result */
3658     if ((status == HCI_ERR_LMP_ERR_TRANS_COLLISION) || (status == HCI_ERR_DIFF_TRANSACTION_COLLISION))
3659     {
3660         btm_sec_auth_collision(handle);
3661         return;
3662     }
3663     btm_cb.collision_start_time = 0;
3664 
3665     btm_restore_mode();
3666 
3667     /* Check if connection was made just to do bonding.  If we authenticate
3668        the connection that is up, this is the last event received.
3669     */
3670     if (p_dev_rec
3671         && (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
3672         && !(btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE))
3673     {
3674         p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
3675 
3676         l2cu_start_post_bond_timer (p_dev_rec->hci_handle);
3677     }
3678 
3679     if (!p_dev_rec)
3680         return;
3681 
3682     /* keep the old sm4 flag and clear the retry bit in control block */
3683     old_sm4 = p_dev_rec->sm4;
3684     p_dev_rec->sm4 &= ~BTM_SM4_RETRY;
3685 
3686     if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
3687          &&  (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
3688          &&  (memcmp (p_dev_rec->bd_addr, btm_cb.pairing_bda, BD_ADDR_LEN) == 0) )
3689         are_bonding = TRUE;
3690 
3691     btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
3692 
3693     if (p_dev_rec->sec_state != BTM_SEC_STATE_AUTHENTICATING)
3694     {
3695         if ( (btm_cb.api.p_auth_complete_callback && status != HCI_SUCCESS)
3696              &&  (old_state != BTM_PAIR_STATE_IDLE) )
3697         {
3698             (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
3699                                                     p_dev_rec->dev_class,
3700                                                     p_dev_rec->sec_bd_name, status);
3701         }
3702         return;
3703     }
3704 
3705     /* There can be a race condition, when we are starting authentication and
3706     ** the peer device is doing encryption.
3707     ** If first we receive encryption change up, then initiated authentication
3708     ** can not be performed.  According to the spec we can not do authentication
3709     ** on the encrypted link, so device is correct.
3710     */
3711     if ((status == HCI_ERR_COMMAND_DISALLOWED)
3712         && ((p_dev_rec->sec_flags & (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED)) ==
3713             (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED)))
3714     {
3715         status = HCI_SUCCESS;
3716     }
3717     /* Currently we do not notify user if it is a keyboard which connects */
3718     /* User probably Disabled the keyboard while it was asleap.  Let her try */
3719     if (btm_cb.api.p_auth_complete_callback)
3720     {
3721         /* report the suthentication status */
3722         if (old_state != BTM_PAIR_STATE_IDLE)
3723             (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
3724                                                     p_dev_rec->dev_class,
3725                                                     p_dev_rec->sec_bd_name, status);
3726     }
3727 
3728     p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
3729 
3730     /* If this is a bonding procedure can disconnect the link now */
3731     if (are_bonding)
3732     {
3733         p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
3734 
3735         if (status != HCI_SUCCESS)
3736             btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_PEER_USER);
3737         else
3738             l2cu_start_post_bond_timer (p_dev_rec->hci_handle);
3739 
3740         return;
3741     }
3742 
3743     /* If authentication failed, notify the waiting layer */
3744     if (status != HCI_SUCCESS)
3745     {
3746         if ((old_sm4 & BTM_SM4_RETRY) == 0)
3747         {
3748             /* allow retry only once */
3749             if (status == HCI_ERR_LMP_ERR_TRANS_COLLISION)
3750             {
3751                 /* not retried yet. set the retry bit */
3752                 p_dev_rec->sm4 |= BTM_SM4_RETRY;
3753                 BTM_TRACE_DEBUG2 ("Collision retry sm4:x%x sec_flags:0x%x", p_dev_rec->sm4, p_dev_rec->sec_flags);
3754             }
3755             /* this retry for missing key is for Lisbon or later only.
3756              * Legacy device do not need this. the controller will drive the retry automatically */
3757             else if (HCI_ERR_KEY_MISSING == status && BTM_SEC_IS_SM4(p_dev_rec->sm4))
3758             {
3759                 /* not retried yet. set the retry bit */
3760                 p_dev_rec->sm4 |= BTM_SM4_RETRY;
3761                 p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN;
3762                 BTM_TRACE_DEBUG2 ("Retry for missing key sm4:x%x sec_flags:0x%x", p_dev_rec->sm4, p_dev_rec->sec_flags);
3763 
3764                 /* With BRCM controller, we do not need to delete the stored link key in controller.
3765                 If the stack may sit on top of other controller, we may need this
3766                 BTM_DeleteStoredLinkKey (bd_addr, NULL); */
3767             }
3768 
3769             if (p_dev_rec->sm4 & BTM_SM4_RETRY)
3770             {
3771                 btm_sec_execute_procedure (p_dev_rec);
3772                 return;
3773             }
3774         }
3775 
3776         btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
3777 
3778         if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_DISC_WHEN_DONE)
3779         {
3780             btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE);
3781         }
3782         return;
3783     }
3784 
3785     p_dev_rec->sec_flags |= BTM_SEC_AUTHENTICATED;
3786 
3787     /* Authentication succeeded, execute the next security procedure, if any */
3788     status = btm_sec_execute_procedure (p_dev_rec);
3789 
3790     /* If there is no next procedure, or procedure failed to start, notify the caller */
3791     if (status != BTM_CMD_STARTED)
3792         btm_sec_dev_rec_cback_event (p_dev_rec, status);
3793 }
3794 
3795 /*******************************************************************************
3796 **
3797 ** Function         btm_sec_mkey_comp_event
3798 **
3799 ** Description      This function is when encryption of the connection is
3800 **                  completed by the LM
3801 **
3802 ** Returns          void
3803 **
3804 *******************************************************************************/
btm_sec_mkey_comp_event(UINT16 handle,UINT8 status,UINT8 key_flg)3805 void btm_sec_mkey_comp_event (UINT16 handle, UINT8 status, UINT8 key_flg)
3806 {
3807     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev_by_handle (handle);
3808     UINT8 bd_addr[BD_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} ;
3809 
3810     BTM_TRACE_EVENT2 ("Security Manager: mkey comp status:%d State:%d",
3811                       status, (p_dev_rec) ? p_dev_rec->sec_state : 0);
3812 
3813     /* If encryption setup failed, notify the waiting layer */
3814     /* There is no next procedure or start of procedure failed, notify the waiting layer */
3815     if (btm_cb.mkey_cback)
3816     {
3817         if (!p_dev_rec)
3818             (btm_cb.mkey_cback)(bd_addr, status, key_flg );
3819         else
3820             (btm_cb.mkey_cback)(p_dev_rec->bd_addr, status, key_flg );
3821     }
3822 }
3823 
3824 /*******************************************************************************
3825 **
3826 ** Function         btm_sec_encrypt_change
3827 **
3828 ** Description      This function is when encryption of the connection is
3829 **                  completed by the LM
3830 **
3831 ** Returns          void
3832 **
3833 *******************************************************************************/
btm_sec_encrypt_change(UINT16 handle,UINT8 status,UINT8 encr_enable)3834 void btm_sec_encrypt_change (UINT16 handle, UINT8 status, UINT8 encr_enable)
3835 {
3836     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev_by_handle (handle);
3837 
3838     BTM_TRACE_EVENT3 ("Security Manager: encrypt_change status:%d State:%d, encr_enable = %d",
3839                       status, (p_dev_rec) ? p_dev_rec->sec_state : 0, encr_enable);
3840     BTM_TRACE_DEBUG1 ("before update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags );
3841 
3842     /* For transaction collision we need to wait and repeat.  There is no need */
3843     /* for random timeout because only slave should receive the result */
3844     if ((status == HCI_ERR_LMP_ERR_TRANS_COLLISION) || (status == HCI_ERR_DIFF_TRANSACTION_COLLISION))
3845     {
3846         btm_sec_auth_collision(handle);
3847         return;
3848     }
3849     btm_cb.collision_start_time = 0;
3850 
3851     if (!p_dev_rec)
3852         return;
3853 
3854     if ((status == HCI_SUCCESS) && encr_enable)
3855         p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED);
3856 
3857     /* It is possible that we decrypted the link to perform role switch */
3858     /* mark link not to be encrypted, so that when we execute security next time it will kick in again */
3859     if ((status == HCI_SUCCESS) && !encr_enable)
3860         p_dev_rec->sec_flags &= ~BTM_SEC_ENCRYPTED;
3861 
3862     BTM_TRACE_DEBUG1 ("after update p_dev_rec->sec_flags=0x%x", p_dev_rec->sec_flags );
3863 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
3864     if (p_dev_rec->device_type  == BT_DEVICE_TYPE_BLE)
3865     {
3866         btm_ble_link_encrypted(p_dev_rec->bd_addr, encr_enable);
3867         return;
3868     }
3869     else
3870         /* BR/EDR connection, update the encryption key size to be 16 as always */
3871         p_dev_rec->enc_key_size = 16;
3872 #endif
3873 
3874     /* If this encryption was started by peer do not need to do anything */
3875     if (p_dev_rec->sec_state != BTM_SEC_STATE_ENCRYPTING)
3876     {
3877         if (BTM_SEC_STATE_DELAY_FOR_ENC == p_dev_rec->sec_state)
3878         {
3879             p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
3880             p_dev_rec->p_callback = NULL;
3881             l2cu_resubmit_pending_sec_req (p_dev_rec->bd_addr);
3882         }
3883         return;
3884     }
3885 
3886     p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
3887 
3888     /* If encryption setup failed, notify the waiting layer */
3889     if (status != HCI_SUCCESS)
3890     {
3891         btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
3892         return;
3893     }
3894 
3895     /* Encryption setup succeeded, execute the next security procedure, if any */
3896     status = (UINT8)btm_sec_execute_procedure (p_dev_rec);
3897 
3898     /* If there is no next procedure, or procedure failed to start, notify the caller */
3899     if (status != BTM_CMD_STARTED)
3900         btm_sec_dev_rec_cback_event (p_dev_rec, status);
3901 }
3902 
3903 /*******************************************************************************
3904 **
3905 ** Function         btm_sec_create_conn
3906 **
3907 ** Description      This function records current role and forwards request to
3908 **                  HCI
3909 **
3910 ** Returns          void
3911 **
3912 *******************************************************************************/
btm_sec_create_conn(BD_ADDR bda,UINT16 packet_types,UINT8 page_scan_rep_mode,UINT8 page_scan_mode,UINT16 clock_offset,UINT8 allow_switch)3913 BOOLEAN btm_sec_create_conn (BD_ADDR bda, UINT16 packet_types,
3914                              UINT8 page_scan_rep_mode, UINT8 page_scan_mode,
3915                              UINT16 clock_offset, UINT8 allow_switch)
3916 {
3917     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bda);
3918 
3919     memcpy (btm_cb.connecting_bda, p_dev_rec->bd_addr,   BD_ADDR_LEN);
3920     memcpy (btm_cb.connecting_dc,  p_dev_rec->dev_class, DEV_CLASS_LEN);
3921 
3922     btm_cb.acl_disc_reason = 0xff ;
3923 
3924     p_dev_rec->sec_state   = BTM_SEC_STATE_IDLE;
3925     p_dev_rec->role_master = TRUE;
3926 
3927     /* If any SCO link up, do not allow a switch */
3928     if (BTM_GetNumScoLinks() != 0)
3929         allow_switch = HCI_CR_CONN_NOT_ALLOW_SWITCH;
3930 
3931     return(btsnd_hcic_create_conn (bda, packet_types, page_scan_rep_mode,
3932                                    page_scan_mode, clock_offset, allow_switch));
3933 }
3934 
3935 /*******************************************************************************
3936 **
3937 ** Function         btm_sec_connect_after_reject_timeout
3938 **
3939 ** Description      Connection for bonding could not start because of the collision
3940 **                  Initiate outgoing connection
3941 **
3942 ** Returns          Pointer to the TLE struct
3943 **
3944 *******************************************************************************/
btm_sec_connect_after_reject_timeout(TIMER_LIST_ENT * p_tle)3945 static void btm_sec_connect_after_reject_timeout (TIMER_LIST_ENT *p_tle)
3946 {
3947     tBTM_SEC_DEV_REC *p_dev_rec = btm_cb.p_collided_dev_rec;
3948 
3949     BTM_TRACE_EVENT0 ("btm_sec_connect_after_reject_timeout()");
3950     btm_cb.sec_collision_tle.param = 0;
3951     btm_cb.p_collided_dev_rec = 0;
3952 
3953     if (btm_sec_dd_create_conn(p_dev_rec) != BTM_CMD_STARTED)
3954     {
3955         BTM_TRACE_WARNING0 ("Security Manager: btm_sec_connect_after_reject_timeout: failed to start connection");
3956 
3957         btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
3958 
3959         (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,  p_dev_rec->dev_class,
3960                                                 p_dev_rec->sec_bd_name, HCI_ERR_MEMORY_FULL);
3961     }
3962 }
3963 
3964 /*******************************************************************************
3965 **
3966 ** Function         btm_sec_connected
3967 **
3968 ** Description      This function is when a connection to the peer device is
3969 **                  establsihed
3970 **
3971 ** Returns          void
3972 **
3973 *******************************************************************************/
btm_sec_connected(UINT8 * bda,UINT16 handle,UINT8 status,UINT8 enc_mode)3974 void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode)
3975 {
3976     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bda);
3977     UINT8            res;
3978     BOOLEAN          is_pairing_device = FALSE;
3979     tACL_CONN        *p_acl_cb;
3980 
3981     btm_acl_resubmit_page();
3982 
3983     /* Commenting out trace due to obf/compilation problems.
3984     */
3985 #if (BT_USE_TRACES == TRUE)
3986     if (p_dev_rec)
3987     {
3988         BTM_TRACE_EVENT6 ("Security Manager: btm_sec_connected in state: %s  handle:%d status:%d enc_mode:%d  bda:%x RName:%s",
3989                           btm_pair_state_descr(btm_cb.pairing_state), handle, status, enc_mode,
3990                           (bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5],
3991                           p_dev_rec->sec_bd_name);
3992     }
3993     else
3994     {
3995         BTM_TRACE_EVENT5 ("Security Manager: btm_sec_connected in state: %s  handle:%d status:%d enc_mode:%d  bda:%x ",
3996                           btm_pair_state_descr(btm_cb.pairing_state), handle, status, enc_mode,
3997                           (bda[2]<<24)+(bda[3]<<16)+(bda[4]<<8)+bda[5]);
3998     }
3999 #endif
4000 
4001     if (!p_dev_rec)
4002     {
4003         /* There is no device record for new connection.  Allocate one */
4004         if (status == HCI_SUCCESS)
4005         {
4006             p_dev_rec = btm_sec_alloc_dev (bda);
4007         }
4008         else
4009         {
4010             /* can not find the device record and the status is error,
4011              * just ignore it */
4012             return;
4013         }
4014     }
4015     else    /* Update the timestamp for this device */
4016     {
4017         p_dev_rec->timestamp = btm_cb.dev_rec_count++;
4018         if (p_dev_rec->sm4 & BTM_SM4_CONN_PEND)
4019         {
4020             /* tell L2CAP it's a bonding connection. */
4021             if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
4022                  &&  (memcmp (btm_cb.pairing_bda, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0)
4023                  &&  (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) )
4024             {
4025                 /* if incoming connection failed while pairing, then try to connect and continue */
4026                 /* Motorola S9 disconnects without asking pin code */
4027                 if ((status != HCI_SUCCESS)&&(btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_PIN_REQ))
4028                 {
4029                     BTM_TRACE_WARNING0 ("Security Manager: btm_sec_connected: incoming connection failed without asking PIN");
4030 
4031                     p_dev_rec->sm4 &= ~BTM_SM4_CONN_PEND;
4032                     if (p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN)
4033                     {
4034                         /* Start timer with 0 to initiate connection with new LCB */
4035                         /* because L2CAP will delete current LCB with this event  */
4036                         btm_cb.p_collided_dev_rec = p_dev_rec;
4037                         btm_cb.sec_collision_tle.param = (UINT32) btm_sec_connect_after_reject_timeout;
4038                         btu_start_timer (&btm_cb.sec_collision_tle, BTU_TTYPE_USER_FUNC, 0);
4039                     }
4040                     else
4041                     {
4042                         btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);
4043                         BTM_ReadRemoteDeviceName(p_dev_rec->bd_addr, NULL);
4044                     }
4045 #if BTM_DISC_DURING_RS == TRUE
4046                     p_dev_rec->rs_disc_pending   = BTM_SEC_RS_NOT_PENDING;     /* reset flag */
4047 #endif
4048                     return;
4049                 }
4050                 else
4051                 {
4052                     l2cu_update_lcb_4_bonding(p_dev_rec->bd_addr, TRUE);
4053                 }
4054             }
4055             /* always clear the pending flag */
4056             p_dev_rec->sm4 &= ~BTM_SM4_CONN_PEND;
4057         }
4058     }
4059 
4060 #if BTM_DISC_DURING_RS == TRUE
4061     p_dev_rec->rs_disc_pending   = BTM_SEC_RS_NOT_PENDING;     /* reset flag */
4062 #endif
4063 
4064     if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
4065          && (memcmp (btm_cb.pairing_bda, bda, BD_ADDR_LEN) == 0) )
4066     {
4067         /* if we rejected incoming connection from bonding device */
4068         if ((status == HCI_ERR_HOST_REJECT_DEVICE)
4069             &&(btm_cb.pairing_flags & BTM_PAIR_FLAGS_REJECTED_CONNECT))
4070         {
4071             BTM_TRACE_WARNING2 ("Security Manager: btm_sec_connected: HCI_Conn_Comp Flags:0x%04x, sm4: 0x%x",
4072                 btm_cb.pairing_flags, p_dev_rec->sm4);
4073 
4074             btm_cb.pairing_flags &= ~BTM_PAIR_FLAGS_REJECTED_CONNECT;
4075             if (BTM_SEC_IS_SM4_UNKNOWN(p_dev_rec->sm4))
4076             {
4077                 /* Try again: RNR when no ACL causes HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT */
4078                 btm_sec_change_pairing_state (BTM_PAIR_STATE_GET_REM_NAME);
4079                 BTM_ReadRemoteDeviceName(bda, NULL);
4080                 return;
4081             }
4082 
4083             /* if we already have pin code */
4084             if (btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_LOCAL_PIN)
4085             {
4086                 /* Start timer with 0 to initiate connection with new LCB */
4087                 /* because L2CAP will delete current LCB with this event  */
4088                 btm_cb.p_collided_dev_rec = p_dev_rec;
4089                 btm_cb.sec_collision_tle.param = (UINT32) btm_sec_connect_after_reject_timeout;
4090                 btu_start_timer (&btm_cb.sec_collision_tle, BTU_TTYPE_USER_FUNC, 0);
4091             }
4092 
4093             return;
4094         }
4095         /* wait for incoming connection without resetting pairing state */
4096         else if (status == HCI_ERR_CONNECTION_EXISTS)
4097         {
4098             BTM_TRACE_WARNING0 ("Security Manager: btm_sec_connected: Wait for incoming connection");
4099             return;
4100         }
4101 
4102         is_pairing_device = TRUE;
4103     }
4104 
4105     /* If connection was made to do bonding restore link security if changed */
4106     btm_restore_mode();
4107 
4108     /* if connection fails during pin request, notify application */
4109     if (status != HCI_SUCCESS)
4110     {
4111         /* If connection failed because of during pairing, need to tell user */
4112         if (is_pairing_device)
4113         {
4114             p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
4115             p_dev_rec->sec_flags &= ~(BTM_SEC_LINK_KEY_KNOWN | BTM_SEC_LINK_KEY_AUTHED);
4116             BTM_TRACE_DEBUG1 ("security_required:%x ", p_dev_rec->security_required );
4117 
4118             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4119 
4120             /* We need to notify host that the key is not known any more */
4121             if (btm_cb.api.p_auth_complete_callback)
4122             {
4123                 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
4124                                                         p_dev_rec->dev_class,
4125                                                         p_dev_rec->sec_bd_name, status);
4126             }
4127         }
4128         else if ((status == HCI_ERR_AUTH_FAILURE)                   ||
4129                  (status == HCI_ERR_KEY_MISSING)                         ||
4130                  (status == HCI_ERR_HOST_REJECT_SECURITY)                ||
4131                  (status == HCI_ERR_PAIRING_NOT_ALLOWED)                 ||
4132                  (status == HCI_ERR_UNIT_KEY_USED)                       ||
4133                  (status == HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED) ||
4134                  (status == HCI_ERR_ENCRY_MODE_NOT_ACCEPTABLE)           ||
4135                  (status == HCI_ERR_REPEATED_ATTEMPTS))
4136         {
4137             p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
4138             p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN;
4139 
4140             /* We need to notify host that the key is not known any more */
4141             if (btm_cb.api.p_auth_complete_callback)
4142             {
4143                 (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
4144                                                         p_dev_rec->dev_class,
4145                                                         p_dev_rec->sec_bd_name, status);
4146             }
4147         }
4148 
4149         if (status == HCI_ERR_CONNECTION_TOUT || status == HCI_ERR_LMP_RESPONSE_TIMEOUT  ||
4150             status == HCI_ERR_UNSPECIFIED     || status == HCI_ERR_PAGE_TIMEOUT)
4151             btm_sec_dev_rec_cback_event (p_dev_rec, BTM_DEVICE_TIMEOUT);
4152         else
4153             btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
4154 
4155         return;
4156     }
4157 
4158     /* If initiated dedicated bonding, return the link key now, and initiate disconnect */
4159     /* If dedicated bonding, and we now have a link key, we are all done */
4160     if ( is_pairing_device
4161          && (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN) )
4162     {
4163         if (p_dev_rec->link_key_not_sent)
4164         {
4165             p_dev_rec->link_key_not_sent = FALSE;
4166             btm_send_link_key_notif(p_dev_rec);
4167         }
4168 
4169         p_dev_rec->security_required &= ~BTM_SEC_OUT_AUTHENTICATE;
4170 
4171         /* remember flag before it is initialized */
4172         if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
4173             res = TRUE;
4174         else
4175             res = FALSE;
4176 
4177         if (btm_cb.api.p_auth_complete_callback)
4178             (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
4179                                                     p_dev_rec->dev_class,
4180                                                     p_dev_rec->sec_bd_name, HCI_SUCCESS);
4181 
4182         btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4183 
4184         if ( res )
4185         {
4186             /* Let l2cap start bond timer */
4187             l2cu_update_lcb_4_bonding (p_dev_rec->bd_addr, TRUE);
4188         }
4189 
4190         return;
4191     }
4192 
4193     p_dev_rec->hci_handle = handle;
4194 
4195     /* role may not be correct here, it will be updated by l2cap, but we need to */
4196     /* notify btm_acl that link is up, so starting of rmt name request will not */
4197     /* set paging flag up */
4198     p_acl_cb = btm_bda_to_acl(bda);
4199     if (p_acl_cb)
4200     {
4201         /* whatever is in btm_establish_continue() without reporting the BTM_BL_CONN_EVT event */
4202 #if (!defined(BTM_BYPASS_EXTRA_ACL_SETUP) || BTM_BYPASS_EXTRA_ACL_SETUP == FALSE)
4203         /* For now there are a some devices that do not like sending */
4204         /* commands events and data at the same time. */
4205         /* Set the packet types to the default allowed by the device */
4206         btm_set_packet_types (p_acl_cb, btm_cb.btm_acl_pkt_types_supported);
4207 
4208         if (btm_cb.btm_def_link_policy)
4209             BTM_SetLinkPolicy (p_acl_cb->remote_addr, &btm_cb.btm_def_link_policy);
4210 #endif
4211 
4212         BTM_SetLinkSuperTout (p_acl_cb->remote_addr, btm_cb.btm_def_link_super_tout);
4213     }
4214     btm_acl_created (bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name, handle, HCI_ROLE_SLAVE, FALSE);
4215 
4216     /* Initialize security flags.  We need to do that because some            */
4217     /* authorization complete could have come after the connection is dropped */
4218     /* and that would set wrong flag that link has been authorized already    */
4219     p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED |
4220                               BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
4221 
4222     if (enc_mode != HCI_ENCRYPT_MODE_DISABLED)
4223         p_dev_rec->sec_flags |= (BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED);
4224 
4225     if (btm_cb.security_mode == BTM_SEC_MODE_LINK)
4226         p_dev_rec->sec_flags |= BTM_SEC_AUTHENTICATED;
4227 
4228     p_dev_rec->link_key_changed = FALSE;
4229 
4230     /* After connection is established we perform security if we do not know */
4231     /* the name, or if we are originator because some procedure can have */
4232     /* been scheduled while connection was down */
4233     BTM_TRACE_DEBUG1 ("is_originator:%d ", p_dev_rec->is_originator);
4234     if (!(p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN) || p_dev_rec->is_originator)
4235     {
4236         if ((res = btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
4237             btm_sec_dev_rec_cback_event (p_dev_rec, res);
4238     }
4239     return;
4240 }
4241 
4242 /*******************************************************************************
4243 **
4244 ** Function         btm_sec_role_changed
4245 **
4246 ** Description      This function is colled when controller reports role
4247 **                  changed, or failed command status for Role Change request
4248 **
4249 ** Returns          void
4250 **
4251 *******************************************************************************/
btm_sec_role_changed(void * p_ref_data)4252 void btm_sec_role_changed (void *p_ref_data)
4253 {
4254     tBTM_SEC_DEV_REC *p_dev_rec = (tBTM_SEC_DEV_REC *)p_ref_data;
4255     UINT8 res;
4256 
4257     BTM_TRACE_EVENT0 ("Security Manager: role changed");
4258 
4259     /* If this role switch was started by peer do not need to do anything */
4260     if (p_dev_rec->sec_state != BTM_SEC_STATE_SWITCHING_ROLE)
4261         return;
4262 
4263     /* If serurity required was to FORCE switch and it failed, notify the waiting layer */
4264     if (((p_dev_rec->security_required & BTM_SEC_FORCE_MASTER) && !p_dev_rec->role_master)
4265         || ((p_dev_rec->security_required & BTM_SEC_FORCE_SLAVE)  &&  p_dev_rec->role_master))
4266     {
4267         btm_sec_dev_rec_cback_event (p_dev_rec, BTM_ERR_PROCESSING);
4268         return;
4269     }
4270 
4271     p_dev_rec->sec_flags |= BTM_SEC_ROLE_SWITCHED;
4272 
4273     p_dev_rec->security_required &= ~(BTM_SEC_FORCE_MASTER | BTM_SEC_ATTEMPT_MASTER |
4274                                       BTM_SEC_FORCE_SLAVE  | BTM_SEC_ATTEMPT_SLAVE);
4275 
4276     p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
4277 
4278     if ((res = (UINT8)btm_sec_execute_procedure (p_dev_rec)) != BTM_CMD_STARTED)
4279     {
4280         btm_sec_dev_rec_cback_event (p_dev_rec, res);
4281     }
4282 }
4283 
4284 /*******************************************************************************
4285 **
4286 ** Function         btm_sec_disconnect
4287 **
4288 ** Description      This function is called to disconnect HCI link
4289 **
4290 ** Returns          btm status
4291 **
4292 *******************************************************************************/
btm_sec_disconnect(UINT16 handle,UINT8 reason)4293 tBTM_STATUS btm_sec_disconnect (UINT16 handle, UINT8 reason)
4294 {
4295     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev_by_handle (handle);
4296 
4297     /* In some weird race condition we may not have a record */
4298     if (!p_dev_rec)
4299     {
4300         btsnd_hcic_disconnect (handle, reason);
4301         return(BTM_SUCCESS);
4302     }
4303 
4304     /* If we are in the process of bonding we need to tell client that auth failed */
4305     if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
4306          &&  (memcmp (btm_cb.pairing_bda, p_dev_rec->bd_addr, BD_ADDR_LEN) == 0)
4307          &&  (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) )
4308     {
4309         /* we are currently doing bonding.  Link will be disconnected when done */
4310         btm_cb.pairing_flags |= BTM_PAIR_FLAGS_DISC_WHEN_DONE;
4311         return(BTM_BUSY);
4312     }
4313 
4314     return(btm_sec_send_hci_disconnect(p_dev_rec, reason));
4315 }
4316 
4317 /*******************************************************************************
4318 **
4319 ** Function         btm_sec_disconnected
4320 **
4321 ** Description      This function is when a connection to the peer device is
4322 **                  dropped
4323 **
4324 ** Returns          void
4325 **
4326 *******************************************************************************/
btm_sec_disconnected(UINT16 handle,UINT8 reason)4327 void btm_sec_disconnected (UINT16 handle, UINT8 reason)
4328 {
4329     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev_by_handle (handle);
4330     UINT8             old_pairing_flags = btm_cb.pairing_flags;
4331     int               result = HCI_ERR_AUTH_FAILURE;
4332 
4333     /* If page was delayed for disc complete, can do it now */
4334     btm_cb.discing = FALSE;
4335 
4336     btm_acl_resubmit_page();
4337 
4338     if (!p_dev_rec)
4339         return;
4340 
4341 #if BTM_DISC_DURING_RS == TRUE
4342     BTM_TRACE_ERROR0("btm_sec_disconnected - Clearing Pending flag");
4343     p_dev_rec->rs_disc_pending = BTM_SEC_RS_NOT_PENDING;     /* reset flag */
4344 #endif
4345 
4346     /* clear unused flags */
4347     p_dev_rec->sm4 &= BTM_SM4_TRUE;
4348 
4349     BTM_TRACE_EVENT6("btm_sec_disconnected() sec_req:x%x  State: %s   reason:%d bda:%04x%08x RName:%s",
4350                      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],
4351                      (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);
4352 
4353     BTM_TRACE_EVENT1("before Update sec_flags=0x%x", p_dev_rec->sec_flags);
4354 
4355     /* If we are in the process of bonding we need to tell client that auth failed */
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     {
4359         btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4360         p_dev_rec->sec_flags &= ~BTM_SEC_LINK_KEY_KNOWN;
4361         if (btm_cb.api.p_auth_complete_callback)
4362         {
4363             /* If the disconnection reason is REPEATED_ATTEMPTS,
4364                send this error message to complete callback function
4365                to display the error message of Repeated attempts.
4366                All others, send HCI_ERR_AUTH_FAILURE. */
4367             if (reason == HCI_ERR_REPEATED_ATTEMPTS)
4368             {
4369                 result = HCI_ERR_REPEATED_ATTEMPTS;
4370             }
4371             else if (old_pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
4372             {
4373                 result = HCI_ERR_HOST_REJECT_SECURITY;
4374             }
4375             (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,     p_dev_rec->dev_class,
4376                                                     p_dev_rec->sec_bd_name, result);
4377         }
4378     }
4379 
4380     p_dev_rec->hci_handle = BTM_SEC_INVALID_HANDLE;
4381     p_dev_rec->sec_state  = BTM_SEC_STATE_IDLE;
4382 
4383 #if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE
4384     p_dev_rec->enc_key_size = 0;
4385     btm_ble_resume_bg_conn(NULL, TRUE);
4386     /* see sec_flags processing in btm_acl_removed */
4387 #endif
4388     p_dev_rec->sec_flags &= ~(BTM_SEC_AUTHORIZED | BTM_SEC_AUTHENTICATED | BTM_SEC_ENCRYPTED | BTM_SEC_ROLE_SWITCHED);
4389 
4390     p_dev_rec->security_required = BTM_SEC_NONE;
4391     p_dev_rec->p_callback = NULL; /* when the peer device time out the authentication before we do, this call back must be reset here */
4392     BTM_TRACE_EVENT1("after Update sec_flags=0x%x", p_dev_rec->sec_flags);
4393 }
4394 
4395 /*******************************************************************************
4396 **
4397 ** Function         btm_sec_link_key_notification
4398 **
4399 ** Description      This function is called when a new connection link key is
4400 **                  generated
4401 **
4402 ** Returns          Pointer to the record or NULL
4403 **
4404 *******************************************************************************/
btm_sec_link_key_notification(UINT8 * p_bda,UINT8 * p_link_key,UINT8 key_type)4405 void btm_sec_link_key_notification (UINT8 *p_bda, UINT8 *p_link_key, UINT8 key_type)
4406 {
4407     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_bda);
4408     BOOLEAN          we_are_bonding = FALSE;
4409 
4410     BTM_TRACE_EVENT3 ("btm_sec_link_key_notification()  BDA:%04x%08x, TYPE: %d",
4411                       (p_bda[0]<<8)+p_bda[1], (p_bda[2]<<24)+(p_bda[3]<<16)+(p_bda[4]<<8)+p_bda[5],
4412                       key_type);
4413 
4414     /* If connection was made to do bonding restore link security if changed */
4415     btm_restore_mode();
4416 
4417     /* Override the key type if version is pre-1.1 */
4418     if (btm_cb.devcb.local_version.hci_version < HCI_VERSION_1_1)
4419         p_dev_rec->link_key_type = BTM_LKEY_TYPE_IGNORE;
4420     if (key_type != BTM_LKEY_TYPE_CHANGED_COMB)
4421         p_dev_rec->link_key_type = key_type;
4422 
4423     p_dev_rec->sec_flags |= BTM_SEC_LINK_KEY_KNOWN;
4424 
4425     memcpy (p_dev_rec->link_key, p_link_key, LINK_KEY_LEN);
4426 
4427     if ( (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
4428          && (memcmp (btm_cb.pairing_bda, p_bda, BD_ADDR_LEN) == 0) )
4429     {
4430         if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
4431             we_are_bonding = TRUE;
4432         else
4433             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4434     }
4435 
4436     /* If name is not known at this point delay calling callback until the name is   */
4437     /* resolved. Unless it is a HID Device and we really need to send all link keys. */
4438     if ((!(p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN)
4439         &&  ((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) != BTM_COD_MAJOR_PERIPHERAL)) )
4440     {
4441         BTM_TRACE_EVENT3 ("btm_sec_link_key_notification()  Delayed BDA: %08x%04x Type:%d",
4442                           (p_bda[0]<<24) + (p_bda[1]<<16) + (p_bda[2]<<8) + p_bda[3], (p_bda[4] << 8) + p_bda[5], key_type);
4443 
4444         p_dev_rec->link_key_not_sent = TRUE;
4445 
4446         /* If it is for bonding nothing else will follow, so we need to start name resolution */
4447         if (we_are_bonding)
4448         {
4449             if (!(btsnd_hcic_rmt_name_req (p_bda, HCI_PAGE_SCAN_REP_MODE_R1, HCI_MANDATARY_PAGE_SCAN_MODE, 0)))
4450                 btm_inq_rmt_name_failed();
4451         }
4452 
4453         BTM_TRACE_EVENT3 ("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])
4454         return;
4455     }
4456 
4457     /* If its not us who perform authentication, we should tell stackserver */
4458     /* that some authentication has been completed                          */
4459     /* This is required when different entities receive link notification and auth complete */
4460     if (!(p_dev_rec->security_required & BTM_SEC_OUT_AUTHENTICATE))
4461     {
4462         if (btm_cb.api.p_auth_complete_callback)
4463             (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
4464                                                     p_dev_rec->sec_bd_name, HCI_SUCCESS);
4465     }
4466 
4467     /* We will save link key only if the user authorized it - BTE report link key in all cases */
4468 #ifdef BRCM_NONE_BTE
4469     if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_AUTHED)
4470 #endif
4471     {
4472         if (btm_cb.api.p_link_key_callback)
4473         {
4474             (*btm_cb.api.p_link_key_callback) (p_bda, p_dev_rec->dev_class,  p_dev_rec->sec_bd_name,
4475                                                p_link_key, p_dev_rec->link_key_type);
4476         }
4477     }
4478 }
4479 
4480 /*******************************************************************************
4481 **
4482 ** Function         btm_sec_link_key_request
4483 **
4484 ** Description      This function is called when controller requests link key
4485 **
4486 ** Returns          Pointer to the record or NULL
4487 **
4488 *******************************************************************************/
btm_sec_link_key_request(UINT8 * p_bda)4489 void btm_sec_link_key_request (UINT8 *p_bda)
4490 {
4491     tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_bda);
4492 
4493     BTM_TRACE_EVENT6 ("btm_sec_link_key_request()  BDA: %02x:%02x:%02x:%02x:%02x:%02x",
4494                       p_bda[0], p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]);
4495 
4496     if (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)
4497     {
4498         btsnd_hcic_link_key_req_reply (p_bda, p_dev_rec->link_key);
4499         return;
4500     }
4501 
4502     /* Notify L2CAP to increase timeout */
4503     l2c_pin_code_request (p_bda);
4504 
4505     /* Only ask the host for a key if this guy is not already bonding */
4506     if ( (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE)
4507          || (memcmp (p_bda, btm_cb.pairing_bda, BD_ADDR_LEN) != 0) )
4508     {
4509         if (btm_cb.api.p_link_key_req_callback)
4510         {
4511             if ((*btm_cb.api.p_link_key_req_callback)(p_bda, p_dev_rec->link_key) == BTM_SUCCESS)
4512             {
4513                 btsnd_hcic_link_key_req_reply (p_bda, p_dev_rec->link_key);
4514                 return;
4515             }
4516         }
4517     }
4518 
4519     /* The link key is not in the database and it is not known to the manager */
4520     btsnd_hcic_link_key_neg_reply (p_bda);
4521 }
4522 
4523 /*******************************************************************************
4524 **
4525 ** Function         btm_sec_pairing_timeout
4526 **
4527 ** Description      This function is called when host does not provide PIN
4528 **                  within requested time
4529 **
4530 ** Returns          Pointer to the TLE struct
4531 **
4532 *******************************************************************************/
btm_sec_pairing_timeout(TIMER_LIST_ENT * p_tle)4533 static void btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle)
4534 {
4535     tBTM_CB *p_cb = &btm_cb;
4536     tBTM_SEC_DEV_REC *p_dev_rec;
4537 #if BTM_OOB_INCLUDED == TRUE
4538 #if (BTM_LOCAL_IO_CAPS == BTM_IO_CAP_NONE)
4539     tBTM_AUTH_REQ   auth_req = BTM_AUTH_AP_NO;
4540 #else
4541     tBTM_AUTH_REQ   auth_req = BTM_AUTH_AP_YES;
4542 #endif
4543 #endif
4544     UINT8   name[2];
4545 
4546     p_cb->pairing_tle.param = 0;
4547 /* Coverity: FALSE-POSITIVE error from Coverity tool. Please do NOT remove following comment. */
4548 /* coverity[UNUSED_VALUE] pointer p_dev_rec is actually used several times... This is a Coverity false-positive, i.e. a fake issue.
4549 */
4550     p_dev_rec = btm_find_dev (p_cb->pairing_bda);
4551 
4552     BTM_TRACE_EVENT2 ("btm_sec_pairing_timeout()  State: %s   Flags: %u",
4553                       btm_pair_state_descr(p_cb->pairing_state), p_cb->pairing_flags);
4554 
4555     switch (p_cb->pairing_state)
4556     {
4557         case BTM_PAIR_STATE_WAIT_PIN_REQ:
4558             btm_sec_bond_cancel_complete();
4559             break;
4560 
4561         case BTM_PAIR_STATE_WAIT_LOCAL_PIN:
4562             if ( (btm_cb.pairing_flags & BTM_PAIR_FLAGS_PRE_FETCH_PIN) == 0)
4563                 btsnd_hcic_pin_code_neg_reply (p_cb->pairing_bda);
4564             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4565             /* We need to notify the UI that no longer need the PIN */
4566             if (btm_cb.api.p_auth_complete_callback)
4567             {
4568                 if (p_dev_rec == NULL)
4569                 {
4570                     name[0] = 0;
4571                     (*btm_cb.api.p_auth_complete_callback) (p_cb->pairing_bda,
4572                                                             NULL,
4573                                                             name, HCI_ERR_CONNECTION_TOUT);
4574                 }
4575                 else
4576                     (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
4577                                                             p_dev_rec->dev_class,
4578                                                             p_dev_rec->sec_bd_name, HCI_ERR_CONNECTION_TOUT);
4579             }
4580             break;
4581 
4582         case BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM:
4583             btsnd_hcic_user_conf_reply (p_cb->pairing_bda, FALSE);
4584             /* btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); */
4585             break;
4586 
4587 #if (BTM_LOCAL_IO_CAPS != BTM_IO_CAP_NONE)
4588         case BTM_PAIR_STATE_KEY_ENTRY:
4589             btsnd_hcic_user_passkey_neg_reply(p_cb->pairing_bda);
4590             /* btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE); */
4591             break;
4592 #endif /* !BTM_IO_CAP_NONE */
4593 
4594 #if BTM_OOB_INCLUDED == TRUE
4595         case BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS:
4596             if (btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD)
4597                 auth_req |= BTM_AUTH_DD_BOND;
4598 
4599             btsnd_hcic_io_cap_req_reply (p_cb->pairing_bda, btm_cb.devcb.loc_io_caps,
4600                                          BTM_OOB_NONE, auth_req);
4601             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4602             break;
4603 
4604         case BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP:
4605             btsnd_hcic_rem_oob_neg_reply (p_cb->pairing_bda);
4606             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4607             break;
4608 #endif /* BTM_OOB_INCLUDED */
4609 
4610         case BTM_PAIR_STATE_WAIT_DISCONNECT:
4611             /* simple pairing failed. Started a 1-sec timer at simple pairing complete.
4612              * now it's time to tear down the ACL link*/
4613             if (p_dev_rec == NULL)
4614             {
4615                 BTM_TRACE_ERROR2 ("btm_sec_pairing_timeout() BTM_PAIR_STATE_WAIT_DISCONNECT unknown BDA: %08x%04x",
4616                                   (p_cb->pairing_bda[0]<<24) + (p_cb->pairing_bda[1]<<16) + (p_cb->pairing_bda[2]<<8) + p_cb->pairing_bda[3],
4617                                   (p_cb->pairing_bda[4] << 8) + p_cb->pairing_bda[5]);
4618                 break;
4619             }
4620             btm_sec_send_hci_disconnect (p_dev_rec, HCI_ERR_AUTH_FAILURE);
4621             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4622             break;
4623 
4624         case BTM_PAIR_STATE_WAIT_AUTH_COMPLETE:
4625             /* We need to notify the UI that timeout has happened while waiting for authentication*/
4626             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4627             if (btm_cb.api.p_auth_complete_callback)
4628             {
4629                 if (p_dev_rec == NULL)
4630                 {
4631                     name[0] = 0;
4632                     (*btm_cb.api.p_auth_complete_callback) (p_cb->pairing_bda,
4633                                                             NULL,
4634                                                             name, HCI_ERR_CONNECTION_TOUT);
4635                 }
4636                 else
4637                     (*btm_cb.api.p_auth_complete_callback) (p_dev_rec->bd_addr,
4638                                                             p_dev_rec->dev_class,
4639                                                             p_dev_rec->sec_bd_name, HCI_ERR_CONNECTION_TOUT);
4640             }
4641             break;
4642 
4643         default:
4644             BTM_TRACE_WARNING1 ("btm_sec_pairing_timeout() not processed state: %s", btm_pair_state_descr(btm_cb.pairing_state));
4645             btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
4646             break;
4647     }
4648 }
4649 
4650 /*******************************************************************************
4651 **
4652 ** Function         btm_sec_pin_code_request
4653 **
4654 ** Description      This function is called when controller requests PIN code
4655 **
4656 ** Returns          Pointer to the record or NULL
4657 **
4658 *******************************************************************************/
btm_sec_pin_code_request(UINT8 * p_bda)4659 void btm_sec_pin_code_request (UINT8 *p_bda)
4660 {
4661     tBTM_SEC_DEV_REC *p_dev_rec;
4662     tBTM_CB          *p_cb = &btm_cb;
4663 
4664     BTM_TRACE_EVENT3 ("btm_sec_pin_code_request()  State: %s, BDA:%04x%08x",
4665                       btm_pair_state_descr(btm_cb.pairing_state),
4666                       (p_bda[0]<<8)+p_bda[1], (p_bda[2]<<24)+(p_bda[3]<<16)+(p_bda[4]<<8)+p_bda[5] );
4667 
4668     if (btm_cb.pairing_state != BTM_PAIR_STATE_IDLE)
4669     {
4670         if ( (memcmp (p_bda, btm_cb.pairing_bda, BD_ADDR_LEN) == 0)  &&
4671              (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_AUTH_COMPLETE) )
4672         {
4673              /* fake this out - porshe carkit issue - */
4674 //            btm_cb.pairing_state = BTM_PAIR_STATE_IDLE;
4675              if(! btm_cb.pin_code_len_saved)
4676              {
4677                  btsnd_hcic_pin_code_neg_reply (p_bda);
4678                  return;
4679              }
4680              else
4681              {
4682                  btsnd_hcic_pin_code_req_reply (p_bda, btm_cb.pin_code_len_saved, p_cb->pin_code);
4683       	         return;
4684              }
4685         }
4686         else if ((btm_cb.pairing_state != BTM_PAIR_STATE_WAIT_PIN_REQ)
4687                  || memcmp (p_bda, btm_cb.pairing_bda, BD_ADDR_LEN) != 0)
4688         {
4689             BTM_TRACE_WARNING1 ("btm_sec_pin_code_request() rejected - state: %s",
4690                                 btm_pair_state_descr(btm_cb.pairing_state));
4691 
4692 #ifdef PORCHE_PAIRING_CONFLICT
4693             /* reply pin code again due to counter in_rand when local initiates pairing */
4694             BTM_TRACE_EVENT0 ("btm_sec_pin_code_request from remote dev. for local initiated pairing");
4695             if(! btm_cb.pin_code_len_saved)
4696             {
4697                 btsnd_hcic_pin_code_neg_reply (p_bda);
4698             }
4699             else
4700             {
4701                 btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
4702                 btsnd_hcic_pin_code_req_reply (p_bda, btm_cb.pin_code_len_saved, p_cb->pin_code);
4703             }
4704 #else
4705             btsnd_hcic_pin_code_neg_reply (p_bda);
4706 #endif
4707             return;
4708         }
4709     }
4710 
4711     p_dev_rec = btm_find_or_alloc_dev (p_bda);
4712     /* received PIN code request. must be non-sm4 */
4713     p_dev_rec->sm4 = BTM_SM4_KNOWN;
4714 
4715     if (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE)
4716     {
4717         memcpy (btm_cb.pairing_bda, p_bda, BD_ADDR_LEN);
4718 
4719         btm_cb.pairing_flags = BTM_PAIR_FLAGS_PEER_STARTED_DD;
4720         /* Make sure we reset the trusted mask to help against attacks */
4721         BTM_SEC_CLR_TRUSTED_DEVICE(p_dev_rec->trusted_mask);
4722     }
4723 
4724     if (!p_cb->pairing_disabled && (p_cb->cfg.pin_type == HCI_PIN_TYPE_FIXED))
4725     {
4726         BTM_TRACE_EVENT0 ("btm_sec_pin_code_request fixed pin replying");
4727         btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
4728         btsnd_hcic_pin_code_req_reply (p_bda, p_cb->cfg.pin_code_len, p_cb->cfg.pin_code);
4729         return;
4730     }
4731 
4732     /* Use the connecting device's CoD for the connection */
4733     if ( (!memcmp (p_bda, p_cb->connecting_bda, BD_ADDR_LEN))
4734          &&  (p_cb->connecting_dc[0] || p_cb->connecting_dc[1] || p_cb->connecting_dc[2]) )
4735         memcpy (p_dev_rec->dev_class, p_cb->connecting_dc, DEV_CLASS_LEN);
4736 
4737     /* We could have started connection after asking user for the PIN code */
4738     if (btm_cb.pin_code_len != 0)
4739     {
4740         BTM_TRACE_EVENT0 ("btm_sec_pin_code_request bonding sending reply");
4741         btsnd_hcic_pin_code_req_reply (p_bda, btm_cb.pin_code_len, p_cb->pin_code);
4742 
4743 #ifdef PORCHE_PAIRING_CONFLICT
4744         btm_cb.pin_code_len_saved = btm_cb.pin_code_len;
4745 #endif
4746 
4747         /* Mark that we forwarded received from the user PIN code */
4748         btm_cb.pin_code_len = 0;
4749 
4750         /* We can change mode back right away, that other connection being established */
4751         /* is not forced to be secure - found a FW issue, so we can not do this
4752         btm_restore_mode(); */
4753 
4754         btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_AUTH_COMPLETE);
4755     }
4756 
4757     /* If pairing disabled OR (no PIN callback and not bonding) */
4758     /* OR we could not allocate entry in the database reject pairing request */
4759     else if (p_cb->pairing_disabled
4760              || (p_cb->api.p_pin_callback == NULL)
4761 
4762              /* OR Microsoft keyboard can for some reason try to establish connection */
4763              /*  the only thing we can do here is to shut it up.  Normally we will be originator */
4764              /*  for keyboard bonding */
4765              || (!p_dev_rec->is_originator
4766                  && ((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) == BTM_COD_MAJOR_PERIPHERAL)
4767                  &&  (p_dev_rec->dev_class[2] & BTM_COD_MINOR_KEYBOARD)) )
4768     {
4769         BTM_TRACE_WARNING3("btm_sec_pin_code_request(): Pairing disabled:%d; PIN callback:%x, Dev Rec:%x!",
4770                            p_cb->pairing_disabled, p_cb->api.p_pin_callback, p_dev_rec);
4771 
4772         btsnd_hcic_pin_code_neg_reply (p_bda);
4773     }
4774     /* Notify upper layer of PIN request and start expiration timer */
4775     else
4776     {
4777         btm_cb.pin_code_len_saved = 0;
4778         btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_PIN);
4779         /* Pin code request can not come at the same time as connection request */
4780         memcpy (p_cb->connecting_bda, p_bda, BD_ADDR_LEN);
4781         memcpy (p_cb->connecting_dc,  p_dev_rec->dev_class, DEV_CLASS_LEN);
4782 
4783         /* Check if the name is known */
4784         /* Even if name is not known we might not be able to get one */
4785         /* this is the case when we are already getting something from the */
4786         /* device, so HCI level is flow controlled */
4787         /* Also cannot send remote name request while paging, i.e. connection is not completed */
4788         if (p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN)
4789         {
4790             BTM_TRACE_EVENT0 ("btm_sec_pin_code_request going for callback");
4791 
4792             btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
4793             if (p_cb->api.p_pin_callback)
4794                 (*p_cb->api.p_pin_callback) (p_bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name);
4795         }
4796         else
4797         {
4798             BTM_TRACE_EVENT0 ("btm_sec_pin_code_request going for remote name");
4799 
4800             /* We received PIN code request for the device with unknown name */
4801             /* it is not user friendly just to ask for the PIN without name */
4802             /* try to get name at first */
4803             if (!btsnd_hcic_rmt_name_req (p_dev_rec->bd_addr,
4804                                           HCI_PAGE_SCAN_REP_MODE_R1,
4805                                           HCI_MANDATARY_PAGE_SCAN_MODE, 0))
4806             {
4807                 p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
4808                 p_dev_rec->sec_bd_name[0] = 'f';
4809                 p_dev_rec->sec_bd_name[1] = '0';
4810                 BTM_TRACE_ERROR0 ("can not send rmt_name_req?? fake a name and call callback");
4811 
4812                 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
4813                 if (p_cb->api.p_pin_callback)
4814                     (*p_cb->api.p_pin_callback) (p_bda, p_dev_rec->dev_class, p_dev_rec->sec_bd_name);
4815             }
4816         }
4817     }
4818 
4819     return;
4820 }
4821 
4822 /*******************************************************************************
4823 **
4824 ** Function         btm_sec_update_clock_offset
4825 **
4826 ** Description      This function is called to update clock offset
4827 **
4828 ** Returns          void
4829 **
4830 *******************************************************************************/
btm_sec_update_clock_offset(UINT16 handle,UINT16 clock_offset)4831 void btm_sec_update_clock_offset (UINT16 handle, UINT16 clock_offset)
4832 {
4833     tBTM_SEC_DEV_REC  *p_dev_rec;
4834     tBTM_INQ_INFO     *p_inq_info;
4835 
4836     if ((p_dev_rec = btm_find_dev_by_handle (handle)) == NULL)
4837         return;
4838 
4839     p_dev_rec->clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID;
4840 
4841     if ((p_inq_info = BTM_InqDbRead(p_dev_rec->bd_addr)) == NULL)
4842         return;
4843 
4844     p_inq_info->results.clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID;
4845 }
4846 
4847 
4848 /******************************************************************
4849 ** S T A T I C     F U N C T I O N S
4850 *******************************************************************/
4851 
4852 /*******************************************************************************
4853 **
4854 ** Function         btm_sec_execute_procedure
4855 **
4856 ** Description      This function is called to start required security
4857 **                  procedure.  There is a case when multiplexing protocol
4858 **                  calls this function on the originating side, connection to
4859 **                  the peer will not be established.  This function in this
4860 **                  case performs only authorization.
4861 **
4862 ** Returns          BTM_SUCCESS     - permission is granted
4863 **                  BTM_CMD_STARTED - in process
4864 **                  BTM_NO_RESOURCES  - permission declined
4865 **
4866 *******************************************************************************/
btm_sec_execute_procedure(tBTM_SEC_DEV_REC * p_dev_rec)4867 static tBTM_STATUS btm_sec_execute_procedure (tBTM_SEC_DEV_REC *p_dev_rec)
4868 {
4869     BTM_TRACE_EVENT3 ("btm_sec_execute_procedure: Required:0x%x Flags:0x%x State:%d",
4870                       p_dev_rec->security_required, p_dev_rec->sec_flags, p_dev_rec->sec_state);
4871 
4872     /* There is a chance that we are getting name.  Wait until done. */
4873     if (p_dev_rec->sec_state != 0)
4874         return(BTM_CMD_STARTED);
4875 
4876     /* If any security is required, get the name first */
4877     if (!(p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN)
4878         && (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE))
4879     {
4880         BTM_TRACE_EVENT0 ("Security Manager: Start get name");
4881         if (!btm_sec_start_get_name (p_dev_rec))
4882         {
4883             return(BTM_NO_RESOURCES);
4884         }
4885         return(BTM_CMD_STARTED);
4886     }
4887 
4888     /* If connection is not authenticated and authentication is required */
4889     /* start authentication and return PENDING to the caller */
4890     if ((!(p_dev_rec->sec_flags & BTM_SEC_AUTHENTICATED))
4891         && (( p_dev_rec->is_originator && (p_dev_rec->security_required & BTM_SEC_OUT_AUTHENTICATE))
4892             || (!p_dev_rec->is_originator && (p_dev_rec->security_required & BTM_SEC_IN_AUTHENTICATE)))
4893         && (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE))
4894     {
4895 #if (L2CAP_UCD_INCLUDED == TRUE)
4896         /* if incoming UCD packet, discard it */
4897         if ( !p_dev_rec->is_originator && (p_dev_rec->is_ucd == TRUE ))
4898             return(BTM_FAILED_ON_SECURITY);
4899 #endif
4900 
4901         BTM_TRACE_EVENT0 ("Security Manager: Start authentication");
4902 
4903         if (!btm_sec_start_authentication (p_dev_rec))
4904         {
4905             return(BTM_NO_RESOURCES);
4906         }
4907         return(BTM_CMD_STARTED);
4908     }
4909 
4910     /* If connection is not encrypted and encryption is required */
4911     /* start encryption and return PENDING to the caller */
4912     if (!(p_dev_rec->sec_flags & BTM_SEC_ENCRYPTED)
4913         && (( p_dev_rec->is_originator && (p_dev_rec->security_required & BTM_SEC_OUT_ENCRYPT))
4914             || (!p_dev_rec->is_originator && (p_dev_rec->security_required & BTM_SEC_IN_ENCRYPT)))
4915         && (p_dev_rec->hci_handle != BTM_SEC_INVALID_HANDLE))
4916     {
4917 #if (L2CAP_UCD_INCLUDED == TRUE)
4918         /* if incoming UCD packet, discard it */
4919         if ( !p_dev_rec->is_originator && (p_dev_rec->is_ucd == TRUE ))
4920             return(BTM_FAILED_ON_SECURITY);
4921 #endif
4922 
4923         BTM_TRACE_EVENT0 ("Security Manager: Start encryption");
4924 
4925         if (!btm_sec_start_encryption (p_dev_rec))
4926         {
4927             return(BTM_NO_RESOURCES);
4928         }
4929         return(BTM_CMD_STARTED);
4930     }
4931 
4932     /* If connection is not authorized and authorization is required */
4933     /* start authorization and return PENDING to the caller */
4934     if (!(p_dev_rec->sec_flags & BTM_SEC_AUTHORIZED)
4935         && (( p_dev_rec->is_originator && (p_dev_rec->security_required & BTM_SEC_OUT_AUTHORIZE))
4936             || (!p_dev_rec->is_originator && (p_dev_rec->security_required & BTM_SEC_IN_AUTHORIZE))))
4937     {
4938         BTM_TRACE_EVENT2 ("service id:%d, is trusted:%d",
4939                           p_dev_rec->p_cur_service->service_id,
4940                           (BTM_SEC_IS_SERVICE_TRUSTED(p_dev_rec->trusted_mask,
4941                                                       p_dev_rec->p_cur_service->service_id)));
4942         if ((btm_sec_are_all_trusted(p_dev_rec->trusted_mask) == FALSE) &&
4943             (p_dev_rec->p_cur_service->service_id < BTM_SEC_MAX_SERVICES) &&
4944             (BTM_SEC_IS_SERVICE_TRUSTED(p_dev_rec->trusted_mask,
4945                                         p_dev_rec->p_cur_service->service_id) == FALSE))
4946         {
4947             BTM_TRACE_EVENT0 ("Security Manager: Start authorization");
4948             return(btm_sec_start_authorization (p_dev_rec));
4949         }
4950     }
4951 
4952     /* All required  security procedures already established */
4953     p_dev_rec->security_required &= ~(BTM_SEC_OUT_AUTHORIZE | BTM_SEC_IN_AUTHORIZE |
4954                                       BTM_SEC_OUT_AUTHENTICATE | BTM_SEC_IN_AUTHENTICATE |
4955                                       BTM_SEC_OUT_ENCRYPT | BTM_SEC_IN_ENCRYPT |
4956                                       BTM_SEC_FORCE_MASTER | BTM_SEC_ATTEMPT_MASTER |
4957                                       BTM_SEC_FORCE_SLAVE | BTM_SEC_ATTEMPT_SLAVE);
4958 
4959     BTM_TRACE_EVENT2 ("Security Manager: trusted:0x%04x%04x", p_dev_rec->trusted_mask[1], p_dev_rec->trusted_mask[0]);
4960     BTM_TRACE_EVENT0 ("Security Manager: access granted");
4961 
4962     return(BTM_SUCCESS);
4963 }
4964 
4965 
4966 /*******************************************************************************
4967 **
4968 ** Function         btm_sec_start_get_name
4969 **
4970 ** Description      This function is called to start get name procedure
4971 **
4972 ** Returns          TRUE if started
4973 **
4974 *******************************************************************************/
btm_sec_start_get_name(tBTM_SEC_DEV_REC * p_dev_rec)4975 static BOOLEAN btm_sec_start_get_name (tBTM_SEC_DEV_REC *p_dev_rec)
4976 {
4977     UINT8 tempstate = p_dev_rec->sec_state;
4978 
4979     p_dev_rec->sec_state = BTM_SEC_STATE_GETTING_NAME;
4980 
4981     /* Device should be connected, no need to provide correct page params */
4982     /* 0 and NULL are as timeout and callback params because they are not used in security get name case */
4983     if ((btm_initiate_rem_name (p_dev_rec->bd_addr, NULL, BTM_RMT_NAME_SEC,
4984                                 0, NULL)) != BTM_CMD_STARTED)
4985     {
4986         p_dev_rec->sec_state = tempstate;
4987         return(FALSE);
4988     }
4989 
4990     return(TRUE);
4991 }
4992 
4993 /*******************************************************************************
4994 **
4995 ** Function         btm_sec_start_authentication
4996 **
4997 ** Description      This function is called to start authentication
4998 **
4999 ** Returns          TRUE if started
5000 **
5001 *******************************************************************************/
btm_sec_start_authentication(tBTM_SEC_DEV_REC * p_dev_rec)5002 static BOOLEAN btm_sec_start_authentication (tBTM_SEC_DEV_REC *p_dev_rec)
5003 {
5004     p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
5005 
5006     return(btsnd_hcic_auth_request (p_dev_rec->hci_handle));
5007 }
5008 
5009 /*******************************************************************************
5010 **
5011 ** Function         btm_sec_start_encryption
5012 **
5013 ** Description      This function is called to start encryption
5014 **
5015 ** Returns          TRUE if started
5016 **
5017 *******************************************************************************/
btm_sec_start_encryption(tBTM_SEC_DEV_REC * p_dev_rec)5018 static BOOLEAN btm_sec_start_encryption (tBTM_SEC_DEV_REC *p_dev_rec)
5019 {
5020     if (!btsnd_hcic_set_conn_encrypt (p_dev_rec->hci_handle, TRUE))
5021         return(FALSE);
5022 
5023     p_dev_rec->sec_state = BTM_SEC_STATE_ENCRYPTING;
5024     return(TRUE);
5025 }
5026 
5027 
5028 /*******************************************************************************
5029 **
5030 ** Function         btm_sec_start_authorization
5031 **
5032 ** Description      This function is called to start authorization
5033 **
5034 ** Returns          TRUE if started
5035 **
5036 *******************************************************************************/
btm_sec_start_authorization(tBTM_SEC_DEV_REC * p_dev_rec)5037 static UINT8 btm_sec_start_authorization (tBTM_SEC_DEV_REC *p_dev_rec)
5038 {
5039     UINT8    result;
5040     UINT8   *p_service_name = NULL;
5041     UINT8    service_id;
5042 
5043     if ((p_dev_rec->sec_flags & BTM_SEC_NAME_KNOWN)
5044         || (p_dev_rec->hci_handle == BTM_SEC_INVALID_HANDLE))
5045     {
5046         if (!btm_cb.api.p_authorize_callback)
5047             return(BTM_MODE_UNSUPPORTED);
5048 
5049         if (p_dev_rec->p_cur_service)
5050         {
5051 #if BTM_SEC_SERVICE_NAME_LEN > 0
5052             if (p_dev_rec->is_originator)
5053                 p_service_name = p_dev_rec->p_cur_service->orig_service_name;
5054             else
5055                 p_service_name = p_dev_rec->p_cur_service->term_service_name;
5056 #endif
5057             service_id = p_dev_rec->p_cur_service->service_id;
5058         }
5059         else
5060             service_id = 0;
5061 
5062         p_dev_rec->sec_state = BTM_SEC_STATE_AUTHORIZING;
5063         result = (*btm_cb.api.p_authorize_callback) (p_dev_rec->bd_addr,
5064                                                      p_dev_rec->dev_class,
5065                                                      p_dev_rec->sec_bd_name,
5066                                                      p_service_name,
5067                                                      service_id,
5068                                                      p_dev_rec->is_originator);
5069         if (result == BTM_SUCCESS)
5070         {
5071             p_dev_rec->sec_flags |= BTM_SEC_AUTHORIZED;
5072             p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
5073         }
5074         return(result);
5075     }
5076     btm_sec_start_get_name (p_dev_rec);
5077     return(BTM_CMD_STARTED);
5078 }
5079 
5080 /*******************************************************************************
5081 **
5082 ** Function         btm_sec_are_all_trusted
5083 **
5084 ** Description      This function is called check if all services are trusted
5085 **
5086 ** Returns          TRUE if all are trusted, otherwise FALSE
5087 **
5088 *******************************************************************************/
btm_sec_are_all_trusted(UINT32 p_mask[])5089 BOOLEAN btm_sec_are_all_trusted(UINT32 p_mask[])
5090 {
5091     int trusted_inx;
5092     for (trusted_inx = 0; trusted_inx < BTM_SEC_SERVICE_ARRAY_SIZE; trusted_inx++)
5093     {
5094         if (p_mask[trusted_inx] != BTM_SEC_TRUST_ALL)
5095             return(FALSE);
5096     }
5097 
5098     return(TRUE);
5099 }
5100 
5101 /*******************************************************************************
5102 **
5103 ** Function         btm_sec_find_first_serv
5104 **
5105 ** Description      Look for the first record in the service database
5106 **                  with specified PSM
5107 **
5108 ** Returns          Pointer to the record or NULL
5109 **
5110 *******************************************************************************/
btm_sec_find_first_serv(CONNECTION_TYPE conn_type,UINT16 psm)5111 static tBTM_SEC_SERV_REC *btm_sec_find_first_serv (CONNECTION_TYPE conn_type, UINT16 psm)
5112 {
5113     tBTM_SEC_SERV_REC *p_serv_rec = &btm_cb.sec_serv_rec[0];
5114     int i;
5115     BOOLEAN is_originator;
5116 
5117 #if (L2CAP_UCD_INCLUDED == TRUE)
5118 
5119     if ( conn_type & CONNECTION_TYPE_ORIG_MASK )
5120         is_originator = TRUE;
5121     else
5122         is_originator = FALSE;
5123 #else
5124     is_originator = conn_type;
5125 #endif
5126 
5127     if (is_originator && btm_cb.p_out_serv && btm_cb.p_out_serv->psm == psm)
5128     {
5129         /* If this is outgoing connection and the PSM matches p_out_serv,
5130          * use it as the current service */
5131         return btm_cb.p_out_serv;
5132     }
5133 
5134     /* otherwise, just find the first record with the specified PSM */
5135     for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_serv_rec++)
5136     {
5137         if ( (p_serv_rec->security_flags & BTM_SEC_IN_USE) && (p_serv_rec->psm == psm) )
5138             return(p_serv_rec);
5139     }
5140     return(NULL);
5141 }
5142 
5143 
5144 /*******************************************************************************
5145 **
5146 ** Function         btm_sec_find_next_serv
5147 **
5148 ** Description      Look for the next record in the service database
5149 **                  with specified PSM
5150 **
5151 ** Returns          Pointer to the record or NULL
5152 **
5153 *******************************************************************************/
btm_sec_find_next_serv(tBTM_SEC_SERV_REC * p_cur)5154 static tBTM_SEC_SERV_REC *btm_sec_find_next_serv (tBTM_SEC_SERV_REC *p_cur)
5155 {
5156     tBTM_SEC_SERV_REC *p_serv_rec   = &btm_cb.sec_serv_rec[0];
5157     int               i;
5158 
5159     for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_serv_rec++)
5160     {
5161         if ((p_serv_rec->security_flags & BTM_SEC_IN_USE)
5162             && (p_serv_rec->psm == p_cur->psm) )
5163         {
5164             if (p_cur != p_serv_rec)
5165             {
5166                 return(p_serv_rec);
5167             }
5168         }
5169     }
5170     return(NULL);
5171 }
5172 
5173 
5174 /*******************************************************************************
5175 **
5176 ** Function         btm_sec_find_mx_serv
5177 **
5178 ** Description      Look for the record in the service database with specified
5179 **                  PSM and multiplexor channel information
5180 **
5181 ** Returns          Pointer to the record or NULL
5182 **
5183 *******************************************************************************/
btm_sec_find_mx_serv(UINT8 is_originator,UINT16 psm,UINT32 mx_proto_id,UINT32 mx_chan_id)5184 static tBTM_SEC_SERV_REC *btm_sec_find_mx_serv (UINT8 is_originator, UINT16 psm,
5185                                                 UINT32 mx_proto_id, UINT32 mx_chan_id)
5186 {
5187     tBTM_SEC_SERV_REC *p_out_serv = btm_cb.p_out_serv;
5188     tBTM_SEC_SERV_REC *p_serv_rec = &btm_cb.sec_serv_rec[0];
5189     int i;
5190 
5191     BTM_TRACE_DEBUG0 ("btm_sec_find_mx_serv");
5192     if (is_originator && p_out_serv && p_out_serv->psm == psm
5193         && p_out_serv->mx_proto_id == mx_proto_id
5194         && p_out_serv->orig_mx_chan_id == mx_chan_id)
5195     {
5196         /* If this is outgoing connection and the parameters match p_out_serv,
5197          * use it as the current service */
5198         return btm_cb.p_out_serv;
5199     }
5200 
5201     /* otherwise, the old way */
5202     for (i = 0; i < BTM_SEC_MAX_SERVICE_RECORDS; i++, p_serv_rec++)
5203     {
5204         if ((p_serv_rec->security_flags & BTM_SEC_IN_USE)
5205             && (p_serv_rec->psm == psm)
5206             && (p_serv_rec->mx_proto_id == mx_proto_id)
5207             && (( is_originator && (p_serv_rec->orig_mx_chan_id  == mx_chan_id))
5208                 || (!is_originator && (p_serv_rec->term_mx_chan_id  == mx_chan_id))))
5209         {
5210             return(p_serv_rec);
5211         }
5212     }
5213     return(NULL);
5214 }
5215 
5216 
5217 /*******************************************************************************
5218 **
5219 ** Function         btm_sec_collision_timeout
5220 **
5221 ** Description      Encryption could not start because of the collision
5222 **                  try to do it again
5223 **
5224 ** Returns          Pointer to the TLE struct
5225 **
5226 *******************************************************************************/
btm_sec_collision_timeout(TIMER_LIST_ENT * p_tle)5227 static void btm_sec_collision_timeout (TIMER_LIST_ENT *p_tle)
5228 {
5229     tBTM_STATUS status;
5230 
5231     BTM_TRACE_EVENT0 ("btm_sec_collision_timeout()");
5232     btm_cb.sec_collision_tle.param = 0;
5233 
5234     status = btm_sec_execute_procedure (btm_cb.p_collided_dev_rec);
5235 
5236     /* If result is pending reply from the user or from the device is pending */
5237     if (status != BTM_CMD_STARTED)
5238     {
5239         /* There is no next procedure or start of procedure failed, notify the waiting layer */
5240         btm_sec_dev_rec_cback_event (btm_cb.p_collided_dev_rec, status);
5241     }
5242 }
5243 
5244 /*******************************************************************************
5245 **
5246 ** Function         btm_sec_link_key_request
5247 **
5248 ** Description      This function is called when controller requests link key
5249 **
5250 ** Returns          Pointer to the record or NULL
5251 **
5252 *******************************************************************************/
btm_send_link_key_notif(tBTM_SEC_DEV_REC * p_dev_rec)5253 static void btm_send_link_key_notif (tBTM_SEC_DEV_REC *p_dev_rec)
5254 {
5255     if (btm_cb.api.p_link_key_callback)
5256         (*btm_cb.api.p_link_key_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class,
5257                                            p_dev_rec->sec_bd_name, p_dev_rec->link_key,
5258                                            p_dev_rec->link_key_type);
5259 }
5260 
5261 /*******************************************************************************
5262 **
5263 ** Function         BTM_ReadTrustedMask
5264 **
5265 ** Description      Get trusted mask for the peer device
5266 **
5267 ** Parameters:      bd_addr   - Address of the device
5268 **
5269 ** Returns          NULL, if the device record is not found.
5270 **                  otherwise, the trusted mask
5271 **
5272 *******************************************************************************/
BTM_ReadTrustedMask(BD_ADDR bd_addr)5273 UINT32 * BTM_ReadTrustedMask (BD_ADDR bd_addr)
5274 {
5275     tBTM_SEC_DEV_REC *p_dev_rec;
5276 
5277     if ((p_dev_rec = btm_find_dev (bd_addr)) != NULL)
5278     {
5279         return(p_dev_rec->trusted_mask);
5280     }
5281     else
5282     {
5283         return NULL;
5284     }
5285 }
5286 
5287 /*******************************************************************************
5288 **
5289 ** Function         btm_restore_mode
5290 **
5291 ** Description      This function returns the security mode to previous setting
5292 **                  if it was changed during bonding.
5293 **
5294 **
5295 ** Parameters:      void
5296 **
5297 *******************************************************************************/
btm_restore_mode(void)5298 static void btm_restore_mode(void)
5299 {
5300     if (btm_cb.security_mode_changed)
5301     {
5302         btm_cb.security_mode_changed = FALSE;
5303         BTM_TRACE_DEBUG1("btm_restore_mode: Authen Enable -> %d", (btm_cb.security_mode == BTM_SEC_MODE_LINK));
5304         btsnd_hcic_write_auth_enable ((UINT8)(btm_cb.security_mode == BTM_SEC_MODE_LINK));
5305     }
5306 
5307     if (btm_cb.pin_type_changed)
5308     {
5309         btm_cb.pin_type_changed = FALSE;
5310         btsnd_hcic_write_pin_type (btm_cb.cfg.pin_type);
5311     }
5312 }
5313 
5314 
5315 /*******************************************************************************
5316 **
5317 ** Function         btm_sec_find_dev_by_sec_state
5318 **
5319 ** Description      Look for the record in the device database for the device
5320 **                  which is being authenticated or encrypted
5321 **
5322 ** Returns          Pointer to the record or NULL
5323 **
5324 *******************************************************************************/
btm_sec_find_dev_by_sec_state(UINT8 state)5325 tBTM_SEC_DEV_REC *btm_sec_find_dev_by_sec_state (UINT8 state)
5326 {
5327     tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
5328     int i;
5329 
5330     for (i = 0; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
5331     {
5332         if ((p_dev_rec->sec_flags & BTM_SEC_IN_USE)
5333             && (p_dev_rec->sec_state == state))
5334             return(p_dev_rec);
5335     }
5336     return(NULL);
5337 }
5338 
5339 /*******************************************************************************
5340 **
5341 ** Function         BTM_snd_conn_encrypt
5342 **
5343 ** Description      This function is called to start/stop encryption
5344 **                  Used by JSR-82
5345 **
5346 ** Returns          TRUE if request started
5347 **
5348 *******************************************************************************/
BTM_snd_conn_encrypt(UINT16 handle,BOOLEAN enable)5349 BOOLEAN BTM_snd_conn_encrypt (UINT16  handle, BOOLEAN enable)
5350 {
5351     tBTM_SEC_DEV_REC  *p_dev_rec = btm_find_dev_by_handle (handle);
5352 
5353     BTM_TRACE_EVENT2 ("BTM_snd_conn_encrypt Security Manager: encrypt_change p_dev_rec : 0x%x, enable = %s", p_dev_rec, (enable == TRUE) ? "TRUE" : "FALSE");
5354 
5355     if (!p_dev_rec)
5356     {
5357         BTM_TRACE_EVENT1 ("BTM_snd_conn_encrypt Error no  p_dev_rec : 0x%x\n", p_dev_rec);
5358         return(FALSE);
5359     }
5360 
5361     if ( p_dev_rec->sec_state == BTM_SEC_STATE_IDLE)
5362     {
5363         if (!btsnd_hcic_set_conn_encrypt (handle, enable))
5364             return(FALSE);
5365 
5366         p_dev_rec->sec_state = BTM_SEC_STATE_ENCRYPTING;
5367 
5368         return(TRUE);
5369     }
5370     else
5371         return(FALSE);
5372 }
5373 
5374 /*******************************************************************************
5375 **
5376 ** Function         btm_sec_change_pairing_state
5377 **
5378 ** Description      This function is called to change pairing state
5379 **
5380 *******************************************************************************/
btm_sec_change_pairing_state(tBTM_PAIRING_STATE new_state)5381 static void btm_sec_change_pairing_state (tBTM_PAIRING_STATE new_state)
5382 {
5383     tBTM_PAIRING_STATE  old_state = btm_cb.pairing_state;
5384 
5385     BTM_TRACE_EVENT1 ("btm_sec_change_pairing_state  Old: %s",  btm_pair_state_descr(btm_cb.pairing_state));
5386     BTM_TRACE_EVENT2 ("btm_sec_change_pairing_state  New: %s pairing_flags:0x%x",btm_pair_state_descr(new_state), btm_cb.pairing_flags);
5387 
5388     btm_cb.pairing_state = new_state;
5389 
5390     if (new_state == BTM_PAIR_STATE_IDLE)
5391     {
5392         btu_stop_timer (&btm_cb.pairing_tle);
5393 
5394         btm_cb.pairing_flags = 0;
5395         btm_cb.pin_code_len  = 0;
5396 
5397         /* Make sure the the lcb shows we are not bonding */
5398         l2cu_update_lcb_4_bonding (btm_cb.pairing_bda, FALSE);
5399 
5400         btm_restore_mode();
5401         btm_sec_check_pending_reqs();
5402         btm_inq_clear_ssp();
5403 
5404         memset (btm_cb.pairing_bda, 0xFF, BD_ADDR_LEN);
5405     }
5406     else
5407     {
5408         /* If transitionng out of idle, mark the lcb as bonding */
5409         if (old_state == BTM_PAIR_STATE_IDLE)
5410             l2cu_update_lcb_4_bonding (btm_cb.pairing_bda, TRUE);
5411 
5412         btm_cb.pairing_tle.param = (TIMER_PARAM_TYPE)btm_sec_pairing_timeout;
5413 
5414         btu_start_timer (&btm_cb.pairing_tle, BTU_TTYPE_USER_FUNC, BTM_SEC_TIMEOUT_VALUE);
5415     }
5416 }
5417 
5418 
5419 /*******************************************************************************
5420 **
5421 ** Function         btm_pair_state_descr
5422 **
5423 ** Description      Return state description for tracing
5424 **
5425 *******************************************************************************/
5426 #if (BT_USE_TRACES == TRUE)
btm_pair_state_descr(tBTM_PAIRING_STATE state)5427 static char *btm_pair_state_descr (tBTM_PAIRING_STATE state)
5428 {
5429 #if (BT_TRACE_VERBOSE == TRUE)
5430     switch (state)
5431     {
5432         case BTM_PAIR_STATE_IDLE:                   return("IDLE");
5433         case BTM_PAIR_STATE_GET_REM_NAME:           return("GET_REM_NAME");
5434         case BTM_PAIR_STATE_WAIT_PIN_REQ:           return("WAIT_PIN_REQ");
5435         case BTM_PAIR_STATE_WAIT_LOCAL_PIN:         return("WAIT_LOCAL_PIN");
5436         case BTM_PAIR_STATE_WAIT_NUMERIC_CONFIRM:   return("WAIT_NUM_CONFIRM");
5437         case BTM_PAIR_STATE_KEY_ENTRY:              return("KEY_ENTRY");
5438         case BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP:     return("WAIT_LOCAL_OOB_RSP");
5439         case BTM_PAIR_STATE_WAIT_LOCAL_IOCAPS:      return("WAIT_LOCAL_IOCAPS");
5440         case BTM_PAIR_STATE_INCOMING_SSP:           return("INCOMING_SSP");
5441         case BTM_PAIR_STATE_WAIT_AUTH_COMPLETE:     return("WAIT_AUTH_COMPLETE");
5442         case BTM_PAIR_STATE_WAIT_DISCONNECT:        return("WAIT_DISCONNECT");
5443     }
5444 
5445     return("???");
5446 #else
5447     sprintf(btm_cb.state_temp_buffer,"%hu",state);
5448 
5449     return(btm_cb.state_temp_buffer);
5450 #endif
5451 }
5452 #endif
5453 
5454 
5455 /*******************************************************************************
5456 **
5457 ** Function         btm_sec_dev_rec_cback_event
5458 **
5459 ** Description      This function calls the callback function with the given
5460 **                  result and clear the callback function.
5461 **
5462 ** Parameters:      void
5463 **
5464 *******************************************************************************/
btm_sec_dev_rec_cback_event(tBTM_SEC_DEV_REC * p_dev_rec,UINT8 res)5465 void btm_sec_dev_rec_cback_event (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 res)
5466 {
5467     tBTM_SEC_CALLBACK   *p_callback = p_dev_rec->p_callback;
5468 
5469     if (p_dev_rec->p_callback)
5470     {
5471         p_dev_rec->p_callback = NULL;
5472 
5473         (*p_callback) (p_dev_rec->bd_addr, p_dev_rec->p_ref_data, res);
5474 
5475     }
5476     btm_sec_check_pending_reqs();
5477 }
5478 
5479 /*******************************************************************************
5480 **
5481 ** Function         btm_sec_queue_mx_request
5482 **
5483 ** Description      Return state description for tracing
5484 **
5485 *******************************************************************************/
btm_sec_queue_mx_request(BD_ADDR bd_addr,UINT16 psm,BOOLEAN is_orig,UINT32 mx_proto_id,UINT32 mx_chan_id,tBTM_SEC_CALLBACK * p_callback,void * p_ref_data)5486 static BOOLEAN btm_sec_queue_mx_request (BD_ADDR bd_addr,  UINT16 psm,  BOOLEAN is_orig,
5487                                          UINT32 mx_proto_id, UINT32 mx_chan_id,
5488                                          tBTM_SEC_CALLBACK *p_callback, void *p_ref_data)
5489 {
5490     tBTM_SEC_QUEUE_ENTRY    *p_e;
5491 
5492     p_e = (tBTM_SEC_QUEUE_ENTRY *)GKI_getbuf (sizeof(tBTM_SEC_QUEUE_ENTRY));
5493 
5494     if (p_e)
5495     {
5496         p_e->psm            = psm;
5497         p_e->is_orig        = is_orig;
5498         p_e->p_callback     = p_callback;
5499         p_e->p_ref_data     = p_ref_data;
5500         p_e->mx_proto_id    = mx_proto_id;
5501         p_e->mx_chan_id     = mx_chan_id;
5502 
5503         memcpy (p_e->bd_addr, bd_addr, BD_ADDR_LEN);
5504 
5505         BTM_TRACE_EVENT4 ("btm_sec_queue_mx_request() PSM: 0x%04x  Is_Orig: %u  mx_proto_id: %u  mx_chan_id: %u",
5506                           psm, is_orig, mx_proto_id, mx_chan_id);
5507 
5508         GKI_enqueue (&btm_cb.sec_pending_q, p_e);
5509 
5510         return(TRUE);
5511     }
5512 
5513     return(FALSE);
5514 }
5515 
btm_sec_check_prefetch_pin(tBTM_SEC_DEV_REC * p_dev_rec)5516 static BOOLEAN btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC  *p_dev_rec)
5517 {
5518     UINT8 major = (UINT8)(p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK);
5519     UINT8 minor = (UINT8)(p_dev_rec->dev_class[2] & BTM_COD_MINOR_CLASS_MASK);
5520     BOOLEAN rv = FALSE;
5521 
5522     if ((major == BTM_COD_MAJOR_AUDIO)
5523         &&  ((minor == BTM_COD_MINOR_CONFM_HANDSFREE) || (minor == BTM_COD_MINOR_CAR_AUDIO)) )
5524     {
5525         BTM_TRACE_EVENT2 ("btm_sec_check_prefetch_pin: Skipping pre-fetch PIN for carkit COD Major: 0x%02x Minor: 0x%02x", major, minor);
5526 
5527         if (btm_cb.security_mode_changed == FALSE)
5528         {
5529             btm_cb.security_mode_changed = TRUE;
5530 #ifdef APPL_AUTH_WRITE_EXCEPTION
5531             if(!(APPL_AUTH_WRITE_EXCEPTION)(p_dev_rec->bd_addr))
5532 #endif
5533                 btsnd_hcic_write_auth_enable (TRUE);
5534         }
5535     }
5536     else
5537     {
5538         btm_sec_change_pairing_state (BTM_PAIR_STATE_WAIT_LOCAL_PIN);
5539 
5540         /* If we got a PIN, use that, else try to get one */
5541         if (btm_cb.pin_code_len)
5542         {
5543             BTM_PINCodeReply (p_dev_rec->bd_addr, BTM_SUCCESS, btm_cb.pin_code_len, btm_cb.pin_code, p_dev_rec->trusted_mask);
5544         }
5545         else
5546         {
5547             /* pin was not supplied - pre-fetch pin code now */
5548             if (btm_cb.api.p_pin_callback && ((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0))
5549             {
5550                 BTM_TRACE_DEBUG0("btm_sec_check_prefetch_pin: PIN code callback called");
5551                 if (btm_bda_to_acl(p_dev_rec->bd_addr) == NULL)
5552                 btm_cb.pairing_flags |= BTM_PAIR_FLAGS_PIN_REQD;
5553                 (btm_cb.api.p_pin_callback) (p_dev_rec->bd_addr, p_dev_rec->dev_class, p_dev_rec->sec_bd_name);
5554             }
5555         }
5556 
5557         rv = TRUE;
5558     }
5559 
5560     return rv;
5561 }
5562 
5563 #if (BLE_INCLUDED == TRUE)
5564 /*******************************************************************************
5565 **
5566 ** Function         btm_sec_clear_ble_keys
5567 **
5568 ** Description      This function is called to clear out the BLE keys.
5569 **                  Typically when devices are removed in BTM_SecDeleteDevice,
5570 **                  or when a new BT Link key is generated.
5571 **
5572 ** Returns          void
5573 **
5574 *******************************************************************************/
btm_sec_clear_ble_keys(tBTM_SEC_DEV_REC * p_dev_rec)5575 void btm_sec_clear_ble_keys (tBTM_SEC_DEV_REC  *p_dev_rec)
5576 {
5577 
5578     BTM_TRACE_DEBUG0 ("btm_sec_clear_ble_keys: Clearing BLE Keys");
5579 #if (SMP_INCLUDED== TRUE)
5580     p_dev_rec->ble.key_type = 0;
5581     memset (&p_dev_rec->ble.keys, 0, sizeof(tBTM_SEC_BLE_KEYS));
5582 #endif
5583     gatt_delete_dev_from_srv_chg_clt_list(p_dev_rec->bd_addr);
5584 }
5585 
5586 
5587 /*******************************************************************************
5588 **
5589 ** Function         btm_sec_is_a_bonded_dev
5590 **
5591 ** Description       Is the specified device is a bonded device
5592 **
5593 ** Returns          TRUE - dev is bonded
5594 **
5595 *******************************************************************************/
btm_sec_is_a_bonded_dev(BD_ADDR bda)5596 BOOLEAN btm_sec_is_a_bonded_dev (BD_ADDR bda)
5597 {
5598 
5599     tBTM_SEC_DEV_REC *p_dev_rec= btm_find_dev (bda);
5600     BOOLEAN is_bonded= FALSE;
5601 
5602 #if (SMP_INCLUDED== TRUE)
5603     if (p_dev_rec && (p_dev_rec->ble.key_type || (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)))
5604     {
5605         is_bonded = TRUE;
5606     }
5607 #endif
5608     BTM_TRACE_DEBUG1 ("btm_sec_is_a_bonded_dev is_bonded=%d", is_bonded);
5609     return(is_bonded);
5610 }
5611 
5612 /*******************************************************************************
5613 **
5614 ** Function         btm_sec_find_bonded_dev
5615 **
5616 ** Description      Find a bonded device starting from the specified index
5617 **
5618 ** Returns          TRUE - found a bonded device
5619 **
5620 *******************************************************************************/
btm_sec_find_bonded_dev(UINT8 start_idx,UINT8 * p_found_idx,tBTM_SEC_DEV_REC * p_rec)5621 BOOLEAN btm_sec_find_bonded_dev (UINT8 start_idx, UINT8 *p_found_idx, tBTM_SEC_DEV_REC *p_rec)
5622 {
5623     BOOLEAN found= FALSE;
5624 
5625 #if (SMP_INCLUDED== TRUE)
5626     tBTM_SEC_DEV_REC *p_dev_rec;
5627     int i;
5628     if (start_idx >= BTM_SEC_MAX_DEVICE_RECORDS)
5629     {
5630         BTM_TRACE_DEBUG0 ("LE bonded device not found");
5631         return found;
5632     }
5633 
5634     p_dev_rec = &btm_cb.sec_dev_rec[start_idx];
5635     for (i = start_idx; i < BTM_SEC_MAX_DEVICE_RECORDS; i++, p_dev_rec++)
5636     {
5637         if (p_dev_rec->ble.key_type || (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN))
5638         {
5639             *p_found_idx = i;
5640             p_rec = p_dev_rec;
5641             break;
5642         }
5643     }
5644     BTM_TRACE_DEBUG1 ("btm_sec_find_bonded_dev=%d", found);
5645 #endif
5646     return(found);
5647 }
5648 #endif /* BLE_INCLUDED */
5649 
5650