Home | History | Annotate | Download | only in btm
      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
     45 BOOLEAN (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 *********************************************************************************/
     52 static tBTM_SEC_SERV_REC *btm_sec_find_first_serv (BOOLEAN is_originator, UINT16 psm);
     53 static tBTM_SEC_SERV_REC *btm_sec_find_next_serv (tBTM_SEC_SERV_REC *p_cur);
     54 static 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 
     58 static tBTM_STATUS btm_sec_execute_procedure (tBTM_SEC_DEV_REC *p_dev_rec);
     59 static BOOLEAN  btm_sec_start_get_name (tBTM_SEC_DEV_REC *p_dev_rec);
     60 static BOOLEAN  btm_sec_start_authentication (tBTM_SEC_DEV_REC *p_dev_rec);
     61 static BOOLEAN  btm_sec_start_encryption (tBTM_SEC_DEV_REC *p_dev_rec);
     62 static void     btm_sec_collision_timeout (TIMER_LIST_ENT *p_tle);
     63 static void     btm_restore_mode(void);
     64 static void     btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle);
     65 static tBTM_STATUS btm_sec_dd_create_conn (tBTM_SEC_DEV_REC *p_dev_rec);
     66 static void     btm_sec_change_pairing_state (tBTM_PAIRING_STATE new_state);
     67 
     68 #if (BT_USE_TRACES == TRUE)
     69 static char     *btm_pair_state_descr (tBTM_PAIRING_STATE state);
     70 #endif
     71 
     72 static void     btm_sec_check_pending_reqs(void);
     73 static 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);
     76 static void     btm_sec_bond_cancel_complete (void);
     77 static void     btm_send_link_key_notif (tBTM_SEC_DEV_REC *p_dev_rec);
     78 static BOOLEAN  btm_sec_check_prefetch_pin (tBTM_SEC_DEV_REC  *p_dev_rec);
     79 
     80 static UINT8    btm_sec_start_authorization (tBTM_SEC_DEV_REC *p_dev_rec);
     81 BOOLEAN         btm_sec_are_all_trusted(UINT32 p_mask[]);
     82 
     83 static tBTM_STATUS btm_sec_send_hci_disconnect (tBTM_SEC_DEV_REC *p_dev_rec, UINT8 reason, UINT16 conn_handle);
     84 UINT8           btm_sec_start_role_switch (tBTM_SEC_DEV_REC *p_dev_rec);
     85 tBTM_SEC_DEV_REC *btm_sec_find_dev_by_sec_state (UINT8 state);
     86 
     87 static 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 
     91 static BOOLEAN btm_dev_authenticated(tBTM_SEC_DEV_REC *p_dev_rec);
     92 static BOOLEAN btm_dev_encrypted(tBTM_SEC_DEV_REC *p_dev_rec);
     93 static BOOLEAN btm_dev_authorized(tBTM_SEC_DEV_REC *p_dev_rec);
     94 static 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 */
     97 static 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 *******************************************************************************/
    119 static 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 *******************************************************************************/
    137 static 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 *******************************************************************************/
    155 static 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 *******************************************************************************/
    173 static 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 *******************************************************************************/
    193 BOOLEAN  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 *******************************************************************************/
    245 BOOLEAN 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 *******************************************************************************/
    262 BOOLEAN  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 *******************************************************************************/
    289 BOOLEAN  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 *******************************************************************************/
    318 void 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 *******************************************************************************/
    332 UINT8 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 *******************************************************************************/
    346 BOOLEAN 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 *******************************************************************************/
    368 BOOLEAN 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 *******************************************************************************/
    395 void 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 *******************************************************************************/
    466 void 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 *******************************************************************************/
    497 void 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 *******************************************************************************/
    527 BOOLEAN 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 *******************************************************************************/
    572 BOOLEAN 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 *******************************************************************************/
    611 static 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 *******************************************************************************/
    832 UINT8 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 *******************************************************************************/
    872 UINT8 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 *******************************************************************************/
    905 void 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 *******************************************************************************/
    938 UINT8 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 *******************************************************************************/
    978 void 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 *******************************************************************************/
   1099 void 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 *******************************************************************************/
   1161 tBTM_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 *******************************************************************************/
   1343 tBTM_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 *******************************************************************************/
   1376 tBTM_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 *******************************************************************************/
   1396 tBTM_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 *******************************************************************************/
   1483 tBTM_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 *******************************************************************************/
   1499 void 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 *******************************************************************************/
   1517 tBTM_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 *******************************************************************************/
   1558 tBTM_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 *******************************************************************************/
   1645 static 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 *******************************************************************************/
   1692 void 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)
   1740 void 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)
   1808 void 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 *******************************************************************************/
   1832 void 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 *******************************************************************************/
   1861 tBTM_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 *******************************************************************************/
   1883 void 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 *******************************************************************************/
   1925 UINT16 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 *******************************************************************************/
   2018 UINT8 * 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 *******************************************************************************/
   2087 void 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 *******************************************************************************/
   2125 static 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 *******************************************************************************/
   2172 static 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 
   2227 tBTM_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 *******************************************************************************/
   2553 tBTM_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 *******************************************************************************/
   2677 void 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 *******************************************************************************/
   2769 static 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 *******************************************************************************/
   2806 void 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 *******************************************************************************/
   2842 void 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 *******************************************************************************/
   2888 void 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 *******************************************************************************/
   2913 void 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 *******************************************************************************/
   2929 void 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 *******************************************************************************/
   2984 void 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 *******************************************************************************/
   3012 static 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 *******************************************************************************/
   3062 void 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 *******************************************************************************/
   3324 void 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 *******************************************************************************/
   3358 void 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]
   3397 Event uninit_use_in_call: Using uninitialized element of array "evt_data.bd_addr" in call to function "memcmp"
   3398 False-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]
   3424 Event uninit_use_in_call: Using uninitialized element of array "evt_data.bd_addr" in call to function "memcmp"
   3425 False-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]
   3450 Event uninit_use_in_call: Using uninitialized element of array "evt_data.bd_addr" in call to function "memcmp"
   3451 False-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 *******************************************************************************/
   3507 void 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]
   3540 Event uninit_use_in_call: Using uninitialized element of array "evt_data.bd_addr" in call to function "memcmp"
   3541 FALSE-POSITIVE error from Coverity test-tool. evt_data.bd_addr is set at the beginning with:     STREAM_TO_BDADDR (evt_data.bd_addr, p);
   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 *******************************************************************************/
   3573 void 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 *******************************************************************************/
   3712 void  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 *******************************************************************************/
   3739 void 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 *******************************************************************************/
   3820 void 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 *******************************************************************************/
   3866 void 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 *******************************************************************************/
   3896 static 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 *******************************************************************************/
   3937 void 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 *******************************************************************************/
   4116 void 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 *******************************************************************************/
   4145 void 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 *******************************************************************************/
   4244 BOOLEAN 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 *******************************************************************************/
   4276 static 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 *******************************************************************************/
   4307 void 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 *******************************************************************************/
   4610 void 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 *******************************************************************************/
   4651 tBTM_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 *******************************************************************************/
   4685 void 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 *******************************************************************************/
   4787 void 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 *******************************************************************************/
   4874 void 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 *******************************************************************************/
   4928 static 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 *******************************************************************************/
   5055 void 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 *******************************************************************************/
   5232 void 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 *******************************************************************************/
   5268 static 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 *******************************************************************************/
   5376 static 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 *******************************************************************************/
   5403 static 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 *******************************************************************************/
   5419 static 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 *******************************************************************************/
   5438 static 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 *******************************************************************************/
   5507 BOOLEAN 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 *******************************************************************************/
   5529 static 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 *******************************************************************************/
   5572 static 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 *******************************************************************************/
   5602 static 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 *******************************************************************************/
   5645 static 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 *******************************************************************************/
   5672 static 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 *******************************************************************************/
   5692 UINT32 * 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 *******************************************************************************/
   5717 static 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 *******************************************************************************/
   5744 tBTM_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 *******************************************************************************/
   5768 BOOLEAN 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 *******************************************************************************/
   5800 static 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)
   5846 static 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 *******************************************************************************/
   5884 void 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 *******************************************************************************/
   5906 static 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 
   5936 static 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 *******************************************************************************/
   5995 void 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 *******************************************************************************/
   6016 BOOLEAN 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 *******************************************************************************/
   6043 BOOLEAN 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 *******************************************************************************/
   6067 BOOLEAN 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