OSDN Git Service

Merge "Fix potential OOB write in btm_read_remote_ext_features_complete" into oc...
authorAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Wed, 4 Dec 2019 08:13:37 +0000 (08:13 +0000)
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Wed, 4 Dec 2019 08:13:37 +0000 (08:13 +0000)
Change-Id: I0767ba267fc51a926930288752a1a079414d5a76

1  2 
stack/btm/btm_acl.cc
stack/btm/btm_int.h
stack/btu/btu_hcif.cc

diff --combined stack/btm/btm_acl.cc
  #include "btm_int.h"
  #include "btu.h"
  #include "device/include/controller.h"
 +#include "device/include/interop.h"
  #include "hcidefs.h"
  #include "hcimsgs.h"
+ #include "log/log.h"
  #include "l2c_int.h"
  #include "osi/include/osi.h"
  
@@@ -232,7 -232,6 +233,7 @@@ void btm_acl_created(BD_ADDR bda, DEV_C
               BD_ADDR_LEN);
  
  #endif
 +      p->switch_role_failed_attempts = 0;
        p->switch_role_state = BTM_ACL_SWKEY_STATE_IDLE;
  
        btm_pm_sm_alloc(xx);
@@@ -571,11 -570,6 +572,11 @@@ tBTM_STATUS BTM_SwitchRole(BD_ADDR remo
    /* Finished if already in desired role */
    if (p->link_role == new_role) return (BTM_SUCCESS);
  
 +  if (interop_match_addr(INTEROP_DISABLE_ROLE_SWITCH,
 +                         (const bt_bdaddr_t*)&remote_bd_addr)) {
 +    return BTM_DEV_BLACKLISTED;
 +  }
 +
  #if (BTM_SCO_INCLUDED == TRUE)
    /* Check if there is any SCO Active on this BD Address */
    is_sco_active = btm_is_sco_active_by_bdaddr(remote_bd_addr);
      return (BTM_BUSY);
    }
  
 +  if (interop_match_addr(INTEROP_DYNAMIC_ROLE_SWITCH,
 +                         (const bt_bdaddr_t*)&remote_bd_addr)) {
 +    BTM_TRACE_DEBUG("%s, Device blacklisted under INTEROP_DYNAMIC_ROLE_SWITCH.",
 +                    __func__);
 +    return BTM_DEV_BLACKLISTED;
 +  }
 +
    status = BTM_ReadPowerMode(p->remote_addr, &pwr_mode);
    if (status != BTM_SUCCESS) return (status);
  
@@@ -1076,7 -1063,7 +1077,7 @@@ void btm_read_remote_features_complete(
   * Returns          void
   *
   ******************************************************************************/
- void btm_read_remote_ext_features_complete(uint8_t* p) {
+ void btm_read_remote_ext_features_complete(uint8_t* p, uint8_t evt_len) {
    tACL_CONN* p_acl_cb;
    uint8_t page_num, max_page;
    uint16_t handle;
  
    BTM_TRACE_DEBUG("btm_read_remote_ext_features_complete");
  
+   if (evt_len < HCI_EXT_FEATURES_SUCCESS_EVT_LEN) {
+     android_errorWriteLog(0x534e4554, "141552859");
+     BTM_TRACE_ERROR(
+         "btm_read_remote_ext_features_complete evt length too short. length=%d",
+         evt_len);
+     return;
+   }
    ++p;
    STREAM_TO_UINT16(handle, p);
    STREAM_TO_UINT8(page_num, p);
      return;
    }
  
+   if (page_num > HCI_EXT_FEATURES_PAGE_MAX) {
+     android_errorWriteLog(0x534e4554, "141552859");
+     BTM_TRACE_ERROR("btm_read_remote_ext_features_complete num_page=%d invalid",
+                     page_num);
+     return;
+   }
+   if (page_num > max_page) {
+     BTM_TRACE_WARNING(
+         "btm_read_remote_ext_features_complete num_page=%d, max_page=%d "
+         "invalid", page_num, max_page);
+   }
    p_acl_cb = &btm_cb.acl_db[acl_idx];
  
    /* Copy the received features page */
@@@ -1378,58 -1386,6 +1400,58 @@@ void btm_process_clk_off_comp_evt(uint1
  }
  
  /*******************************************************************************
 +*
 +* Function         btm_blacklist_role_change_device
 +*
 +* Description      This function is used to blacklist the device if the role
 +*                  switch fails for maximum number of times. It also removes
 +*                  the device from the black list if the role switch succeeds.
 +*
 +* Input Parms      bd_addr - remote BD addr
 +*                  hci_status - role switch status
 +*
 +* Returns          void
 +*
 +*******************************************************************************/
 +void btm_blacklist_role_change_device(BD_ADDR bd_addr, uint8_t hci_status) {
 +  tACL_CONN* p = btm_bda_to_acl(bd_addr, BT_TRANSPORT_BR_EDR);
 +  tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
 +
 +  if (!p || !p_dev_rec) {
 +    return;
 +  }
 +  if (hci_status == HCI_SUCCESS) {
 +    p->switch_role_failed_attempts = 0;
 +    return;
 +  }
 +
 +  /* check for carkits */
 +  const uint32_t cod_audio_device =
 +      (BTM_COD_SERVICE_AUDIO | BTM_COD_MAJOR_AUDIO) << 8;
 +  const uint32_t cod =
 +      ((p_dev_rec->dev_class[0] << 16) | (p_dev_rec->dev_class[1] << 8) |
 +       p_dev_rec->dev_class[2]) &
 +      0xffffff;
 +  if ((hci_status != HCI_SUCCESS) &&
 +      ((p->switch_role_state == BTM_ACL_SWKEY_STATE_SWITCHING) ||
 +       (p->switch_role_state == BTM_ACL_SWKEY_STATE_IN_PROGRESS)) &&
 +      ((cod & cod_audio_device) == cod_audio_device) &&
 +      (!interop_match_addr(INTEROP_DYNAMIC_ROLE_SWITCH,
 +                           (const bt_bdaddr_t*)&bd_addr))) {
 +    p->switch_role_failed_attempts++;
 +    if (p->switch_role_failed_attempts == BTM_MAX_SW_ROLE_FAILED_ATTEMPTS) {
 +      BTM_TRACE_WARNING(
 +          "%s: Device %02x:%02x:%02x:%02x:%02x:%02x blacklisted for role "
 +          "switching - multiple role switch failed attempts: %u",
 +          __func__, bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4],
 +          bd_addr[5], p->switch_role_failed_attempts);
 +      interop_database_add(INTEROP_DYNAMIC_ROLE_SWITCH,
 +                           (const bt_bdaddr_t*)&bd_addr, 3);
 +    }
 +  }
 +}
 +
 +/*******************************************************************************
   *
   * Function         btm_acl_role_changed
   *
diff --combined stack/btm/btm_int.h
@@@ -105,14 -105,12 +105,14 @@@ extern void btm_process_clk_off_comp_ev
                                           uint16_t clock_offset);
  extern void btm_acl_role_changed(uint8_t hci_status, BD_ADDR bd_addr,
                                   uint8_t new_role);
 +extern void btm_blacklist_role_change_device(BD_ADDR bd_addr,
 +                                             uint8_t hci_status);
  extern void btm_acl_encrypt_change(uint16_t handle, uint8_t status,
                                     uint8_t encr_enable);
  extern uint16_t btm_get_acl_disc_reason_code(void);
  extern tBTM_STATUS btm_remove_acl(BD_ADDR bd_addr, tBT_TRANSPORT transport);
  extern void btm_read_remote_features_complete(uint8_t* p);
- extern void btm_read_remote_ext_features_complete(uint8_t* p);
+ extern void btm_read_remote_ext_features_complete(uint8_t* p, uint8_t evt_len);
  extern void btm_read_remote_ext_features_failed(uint8_t status,
                                                  uint16_t handle);
  extern void btm_read_remote_version_complete(uint8_t* p);
diff --combined stack/btu/btu_hcif.cc
@@@ -31,7 -31,7 +31,7 @@@
  #include <base/callback.h>
  #include <base/location.h>
  #include <base/logging.h>
 -#include <log/log.h>
 +#include <base/threading/thread.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
@@@ -51,6 -51,9 +51,6 @@@
  
  using tracked_objects::Location;
  
 -// TODO(zachoverflow): remove this horrible hack
 -extern fixed_queue_t* btu_hci_msg_queue;
 -
  extern void btm_process_cancel_complete(uint8_t status, uint8_t mode);
  extern void btm_ble_test_command_complete(uint8_t* p);
  
@@@ -69,7 -72,8 +69,8 @@@ static void btu_hcif_authentication_com
  static void btu_hcif_rmt_name_request_comp_evt(uint8_t* p, uint16_t evt_len);
  static void btu_hcif_encryption_change_evt(uint8_t* p);
  static void btu_hcif_read_rmt_features_comp_evt(uint8_t* p);
- static void btu_hcif_read_rmt_ext_features_comp_evt(uint8_t* p);
+ static void btu_hcif_read_rmt_ext_features_comp_evt(uint8_t* p,
+                                                     uint8_t evt_len);
  static void btu_hcif_read_rmt_version_comp_evt(uint8_t* p);
  static void btu_hcif_qos_setup_comp_evt(uint8_t* p);
  static void btu_hcif_command_complete_evt(BT_HDR* response, void* context);
@@@ -126,18 -130,6 +127,18 @@@ static void btu_ble_rc_param_req_evt(ui
  static void btu_ble_proc_enhanced_conn_cmpl(uint8_t* p, uint16_t evt_len);
  #endif
  
 +static void do_in_hci_thread(const tracked_objects::Location& from_here,
 +                             const base::Closure& task) {
 +  base::MessageLoop* hci_message_loop = get_message_loop();
 +  if (!hci_message_loop || !hci_message_loop->task_runner().get()) {
 +    LOG_ERROR(LOG_TAG, "%s: HCI message loop not running, accessed from %s",
 +              __func__, from_here.ToString().c_str());
 +    return;
 +  }
 +
 +  hci_message_loop->task_runner()->PostTask(from_here, task);
 +}
 +
  /*******************************************************************************
   *
   * Function         btu_hcif_process_event
@@@ -193,7 -185,7 +194,7 @@@ void btu_hcif_process_event(UNUSED_ATT
        btu_hcif_read_rmt_features_comp_evt(p);
        break;
      case HCI_READ_RMT_EXT_FEATURES_COMP_EVT:
-       btu_hcif_read_rmt_ext_features_comp_evt(p);
+       btu_hcif_read_rmt_ext_features_comp_evt(p, hci_evt_len);
        break;
      case HCI_READ_RMT_VERSION_COMP_EVT:
        btu_hcif_read_rmt_version_comp_evt(p);
@@@ -413,48 -405,58 +414,48 @@@ void cmd_with_cb_data_cleanup(cmd_with_
    cb_wrapper->posted_from.~Location();
  }
  
 -static void btu_hcif_command_complete_evt_with_cb_on_task(BT_HDR* event) {
 -  command_complete_hack_t* hack = (command_complete_hack_t*)&event->data[0];
 -
 +static void btu_hcif_command_complete_evt_with_cb_on_task(BT_HDR* event,
 +                                                          void* context) {
    command_opcode_t opcode;
    uint8_t* stream =
 -      hack->response->data + hack->response->offset +
 +      event->data + event->offset +
        3;  // 2 to skip the event headers, 1 to skip the command credits
    STREAM_TO_UINT16(opcode, stream);
  
 -  cmd_with_cb_data* cb_wrapper = (cmd_with_cb_data*)hack->context;
 +  cmd_with_cb_data* cb_wrapper = (cmd_with_cb_data*)context;
    HCI_TRACE_DEBUG("command complete for: %s",
                    cb_wrapper->posted_from.ToString().c_str());
 -  cb_wrapper->cb.Run(stream, hack->response->len - 5);
 +  cb_wrapper->cb.Run(stream, event->len - 5);
    cmd_with_cb_data_cleanup(cb_wrapper);
    osi_free(cb_wrapper);
  
 -  osi_free(hack->response);
    osi_free(event);
  }
  
  static void btu_hcif_command_complete_evt_with_cb(BT_HDR* response,
                                                    void* context) {
 -  BT_HDR* event = static_cast<BT_HDR*>(
 -      osi_calloc(sizeof(BT_HDR) + sizeof(command_complete_hack_t)));
 -  command_complete_hack_t* hack = (command_complete_hack_t*)&event->data[0];
 -
 -  hack->callback = btu_hcif_command_complete_evt_with_cb_on_task;
 -  hack->response = response;
 -  hack->context = context;
 -  event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK;
 -
 -  fixed_queue_enqueue(btu_hci_msg_queue, event);
 +  do_in_hci_thread(FROM_HERE,
 +                   base::Bind(btu_hcif_command_complete_evt_with_cb_on_task,
 +                              response, context));
  }
  
 -static void btu_hcif_command_status_evt_with_cb_on_task(BT_HDR* event) {
 -  command_status_hack_t* hack = (command_status_hack_t*)&event->data[0];
 -
 +static void btu_hcif_command_status_evt_with_cb_on_task(uint8_t status,
 +                                                        BT_HDR* event,
 +                                                        void* context) {
    command_opcode_t opcode;
 -  uint8_t* stream = hack->command->data + hack->command->offset;
 +  uint8_t* stream = event->data + event->offset;
    STREAM_TO_UINT16(opcode, stream);
  
 -  CHECK(hack->status != 0);
 +  CHECK(status != 0);
  
    // report command status error
 -  cmd_with_cb_data* cb_wrapper = (cmd_with_cb_data*)hack->context;
 +  cmd_with_cb_data* cb_wrapper = (cmd_with_cb_data*)context;
    HCI_TRACE_DEBUG("command status for: %s",
                    cb_wrapper->posted_from.ToString().c_str());
 -  cb_wrapper->cb.Run(&hack->status, sizeof(uint16_t));
 +  cb_wrapper->cb.Run(&status, sizeof(uint16_t));
    cmd_with_cb_data_cleanup(cb_wrapper);
    osi_free(cb_wrapper);
  
 -  osi_free(hack->command);
    osi_free(event);
  }
  
@@@ -466,9 -468,18 +467,9 @@@ static void btu_hcif_command_status_evt
      return;
    }
  
 -  BT_HDR* event = static_cast<BT_HDR*>(
 -      osi_calloc(sizeof(BT_HDR) + sizeof(command_status_hack_t)));
 -  command_status_hack_t* hack = (command_status_hack_t*)&event->data[0];
 -
 -  hack->callback = btu_hcif_command_status_evt_with_cb_on_task;
 -  hack->status = status;
 -  hack->command = command;
 -  hack->context = context;
 -
 -  event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK;
 -
 -  fixed_queue_enqueue(btu_hci_msg_queue, event);
 +  do_in_hci_thread(
 +      FROM_HERE, base::Bind(btu_hcif_command_status_evt_with_cb_on_task, status,
 +                            command, context));
  }
  
  /* This function is called to send commands to the Host Controller. |cb| is
@@@ -705,6 -716,40 +706,6 @@@ static void btu_hcif_rmt_name_request_c
    btm_sec_rmt_name_request_complete(bd_addr, p, status);
  }
  
 -constexpr uint8_t MIN_KEY_SIZE = 7;
 -
 -static void read_encryption_key_size_complete_after_encryption_change(
 -    uint8_t status, uint16_t handle, uint8_t key_size) {
 -  if (status == HCI_ERR_INSUFFCIENT_SECURITY) {
 -    /* If remote device stop the encryption before we call "Read Encryption Key
 -     * Size", we might receive Insufficient Security, which means that link is
 -     * no longer encrypted. */
 -    HCI_TRACE_WARNING("%s encryption stopped on link: 0x%02x", __func__,
 -                      handle);
 -    return;
 -  }
 -
 -  if (status != HCI_SUCCESS) {
 -    HCI_TRACE_WARNING("%s: disconnecting, status: 0x%02x", __func__, status);
 -    btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER);
 -    return;
 -  }
 -
 -  if (key_size < MIN_KEY_SIZE) {
 -    android_errorWriteLog(0x534e4554, "124301137");
 -    HCI_TRACE_ERROR(
 -        "%s encryption key too short, disconnecting. handle: 0x%02x, key_size: "
 -        "%d",
 -        __func__, handle, key_size);
 -
 -    btsnd_hcic_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY);
 -    return;
 -  }
 -
 -  // good key size - succeed
 -  btm_acl_encrypt_change(handle, status, 1 /* enable */);
 -  btm_sec_encrypt_change(handle, status, 1 /* enable */);
 -}
  /*******************************************************************************
   *
   * Function         btu_hcif_encryption_change_evt
@@@ -723,8 -768,15 +724,8 @@@ static void btu_hcif_encryption_change_
    STREAM_TO_UINT16(handle, p);
    STREAM_TO_UINT8(encr_enable, p);
  
 -  if (status != HCI_SUCCESS || encr_enable == 0 ||
 -      BTM_IsBleConnection(handle)) {
 -    btm_acl_encrypt_change(handle, status, encr_enable);
 -    btm_sec_encrypt_change(handle, status, encr_enable);
 -  } else {
 -    btsnd_hcic_read_encryption_key_size(
 -        handle,
 -        base::Bind(&read_encryption_key_size_complete_after_encryption_change));
 -  }
 +  btm_acl_encrypt_change(handle, status, encr_enable);
 +  btm_sec_encrypt_change(handle, status, encr_enable);
  }
  
  /*******************************************************************************
@@@ -749,7 -801,8 +750,8 @@@ static void btu_hcif_read_rmt_features_
   * Returns          void
   *
   ******************************************************************************/
- static void btu_hcif_read_rmt_ext_features_comp_evt(uint8_t* p) {
+ static void btu_hcif_read_rmt_ext_features_comp_evt(uint8_t* p,
+                                                     uint8_t evt_len) {
    uint8_t* p_cur = p;
    uint8_t status;
    uint16_t handle;
    STREAM_TO_UINT8(status, p_cur);
  
    if (status == HCI_SUCCESS)
-     btm_read_remote_ext_features_complete(p);
+     btm_read_remote_ext_features_complete(p, evt_len);
    else {
      STREAM_TO_UINT16(handle, p_cur);
      btm_read_remote_ext_features_failed(status, handle);
@@@ -993,26 -1046,37 +995,26 @@@ static void btu_hcif_hdl_command_comple
   * Returns          void
   *
   ******************************************************************************/
 -static void btu_hcif_command_complete_evt_on_task(BT_HDR* event) {
 -  command_complete_hack_t* hack = (command_complete_hack_t*)&event->data[0];
 -
 +static void btu_hcif_command_complete_evt_on_task(BT_HDR* event,
 +                                                  void* context) {
    command_opcode_t opcode;
    uint8_t* stream =
 -      hack->response->data + hack->response->offset +
 +      event->data + event->offset +
        3;  // 2 to skip the event headers, 1 to skip the command credits
    STREAM_TO_UINT16(opcode, stream);
  
    btu_hcif_hdl_command_complete(
        opcode, stream,
 -      hack->response->len -
 +      event->len -
            5,  // 3 for the command complete headers, 2 for the event headers
 -      hack->context);
 +      context);
  
 -  osi_free(hack->response);
    osi_free(event);
  }
  
  static void btu_hcif_command_complete_evt(BT_HDR* response, void* context) {
 -  BT_HDR* event = static_cast<BT_HDR*>(
 -      osi_calloc(sizeof(BT_HDR) + sizeof(command_complete_hack_t)));
 -  command_complete_hack_t* hack = (command_complete_hack_t*)&event->data[0];
 -
 -  hack->callback = btu_hcif_command_complete_evt_on_task;
 -  hack->response = response;
 -  hack->context = context;
 -
 -  event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK;
 -
 -  fixed_queue_enqueue(btu_hci_msg_queue, event);
 +  do_in_hci_thread(FROM_HERE, base::Bind(btu_hcif_command_complete_evt_on_task,
 +                                         response, context));
  }
  
  /*******************************************************************************
@@@ -1173,20 -1237,33 +1175,20 @@@ static void btu_hcif_hdl_command_status
   * Returns          void
   *
   ******************************************************************************/
 -static void btu_hcif_command_status_evt_on_task(BT_HDR* event) {
 -  command_status_hack_t* hack = (command_status_hack_t*)&event->data[0];
 -
 +static void btu_hcif_command_status_evt_on_task(uint8_t status, BT_HDR* event,
 +                                                void* context) {
    command_opcode_t opcode;
 -  uint8_t* stream = hack->command->data + hack->command->offset;
 +  uint8_t* stream = event->data + event->offset;
    STREAM_TO_UINT16(opcode, stream);
  
 -  btu_hcif_hdl_command_status(opcode, hack->status, stream, hack->context);
 -
 -  osi_free(hack->command);
 +  btu_hcif_hdl_command_status(opcode, status, stream, context);
    osi_free(event);
  }
  
  static void btu_hcif_command_status_evt(uint8_t status, BT_HDR* command,
                                          void* context) {
 -  BT_HDR* event = static_cast<BT_HDR*>(
 -      osi_calloc(sizeof(BT_HDR) + sizeof(command_status_hack_t)));
 -  command_status_hack_t* hack = (command_status_hack_t*)&event->data[0];
 -
 -  hack->callback = btu_hcif_command_status_evt_on_task;
 -  hack->status = status;
 -  hack->command = command;
 -  hack->context = context;
 -
 -  event->event = BTU_POST_TO_TASK_NO_GOOD_HORRIBLE_HACK;
 -
 -  fixed_queue_enqueue(btu_hci_msg_queue, event);
 +  do_in_hci_thread(FROM_HERE, base::Bind(btu_hcif_command_status_evt_on_task,
 +                                         status, command, context));
  }
  
  /*******************************************************************************
@@@ -1237,7 -1314,6 +1239,7 @@@ static void btu_hcif_role_change_evt(ui
    STREAM_TO_BDADDR(bda, p);
    STREAM_TO_UINT8(role, p);
  
 +  btm_blacklist_role_change_device(bda, status);
    l2c_link_role_changed(bda, role, status);
    btm_acl_role_changed(status, bda, role);
  }
@@@ -1612,21 -1688,56 +1614,21 @@@ static void btu_hcif_enhanced_flush_com
   * End of Simple Pairing Events
   **********************************************/
  
 -static void read_encryption_key_size_complete_after_key_refresh(
 -    uint8_t status, uint16_t handle, uint8_t key_size) {
 -  if (status == HCI_ERR_INSUFFCIENT_SECURITY) {
 -    /* If remote device stop the encryption before we call "Read Encryption Key
 -     * Size", we might receive Insufficient Security, which means that link is
 -     * no longer encrypted. */
 -    HCI_TRACE_WARNING("%s encryption stopped on link: 0x%02x", __func__,
 -                      handle);
 -    return;
 -  }
 -
 -  if (status != HCI_SUCCESS) {
 -    HCI_TRACE_WARNING("%s: disconnecting, status: 0x%02x", __func__, status);
 -    btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER);
 -    return;
 -  }
 -
 -  if (key_size < MIN_KEY_SIZE) {
 -    android_errorWriteLog(0x534e4554, "124301137");
 -    HCI_TRACE_ERROR(
 -        "%s encryption key too short, disconnecting. handle: 0x%02x, key_size: "
 -        "%d",
 -        __func__, handle, key_size);
 -
 -    btsnd_hcic_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY);
 -    return;
 -  }
 -
 -  btm_sec_encrypt_change(handle, status, 1 /* enc_enable */);
 -}
 -
 +/**********************************************
 + * BLE Events
 + **********************************************/
  static void btu_hcif_encryption_key_refresh_cmpl_evt(uint8_t* p) {
    uint8_t status;
 +  uint8_t enc_enable = 0;
    uint16_t handle;
  
    STREAM_TO_UINT8(status, p);
    STREAM_TO_UINT16(handle, p);
  
 -  if (status != HCI_SUCCESS || BTM_IsBleConnection(handle)) {
 -    btm_sec_encrypt_change(handle, status, (status == HCI_SUCCESS) ? 1 : 0);
 -  } else {
 -    btsnd_hcic_read_encryption_key_size(
 -        handle,
 -        base::Bind(&read_encryption_key_size_complete_after_key_refresh));
 -  }
 -}
 +  if (status == HCI_SUCCESS) enc_enable = 1;
  
 -/**********************************************
 - * BLE Events
 - **********************************************/
 +  btm_sec_encrypt_change(handle, status, enc_enable);
 +}
  
  static void btu_ble_ll_conn_complete_evt(uint8_t* p, uint16_t evt_len) {
    btm_ble_conn_complete(p, evt_len, false);