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