Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 991e8722 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

Move all HCI LE Create Connection management into single file

Currently handling of LE Create Connection, LE Create Connection
Cancel, LE Connection Complete and other HCI commands related to LE
connection establishment is in two separate files.
Move all this code into single file.

Bug: 112827989
Test: compilation
Change-Id: Ibc2f6ca2324f4df8a23c2722762d0e5297782b33
parent 69fd7652
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ cc_library_static {
        "btm/btm_ble_adv_filter.cc",
        "btm/btm_ble_batchscan.cc",
        "btm/btm_ble_bgconn.cc",
        "btm/btm_ble_connection_establishment.cc",
        "btm/btm_ble_cont_energy.cc",
        "btm/btm_ble_gap.cc",
        "btm/btm_ble_multi_adv.cc",
+0 −138
Original line number Diff line number Diff line
@@ -43,12 +43,9 @@
#include "osi/include/log.h"
#include "osi/include/osi.h"
#include "stack/crypto_toolbox/crypto_toolbox.h"
#include "stack/gatt/connection_manager.h"

extern void gatt_notify_phy_updated(uint8_t status, uint16_t handle,
                                    uint8_t tx_phy, uint8_t rx_phy);
extern void btm_ble_advertiser_notify_terminated_legacy(
    uint8_t status, uint16_t connection_handle);

/******************************************************************************/
/* External Function to be called by other modules                            */
@@ -1887,141 +1884,6 @@ void btm_ble_connected(const RawAddress& bda, uint16_t handle, uint8_t enc_mode,
  return;
}

/*****************************************************************************
 *  Function        btm_ble_conn_complete
 *
 *  Description     LE connection complete.
 *
 *****************************************************************************/
void btm_ble_conn_complete(uint8_t* p, UNUSED_ATTR uint16_t evt_len,
                           bool enhanced) {
#if (BLE_PRIVACY_SPT == TRUE)
  uint8_t peer_addr_type;
#endif
  RawAddress local_rpa, peer_rpa;
  uint8_t role, status, bda_type;
  uint16_t handle;
  RawAddress bda;
  uint16_t conn_interval, conn_latency, conn_timeout;
  bool match = false;

  STREAM_TO_UINT8(status, p);
  STREAM_TO_UINT16(handle, p);
  STREAM_TO_UINT8(role, p);
  STREAM_TO_UINT8(bda_type, p);
  STREAM_TO_BDADDR(bda, p);

  if (status == 0) {
    if (enhanced) {
      STREAM_TO_BDADDR(local_rpa, p);
      STREAM_TO_BDADDR(peer_rpa, p);
    }

    STREAM_TO_UINT16(conn_interval, p);
    STREAM_TO_UINT16(conn_latency, p);
    STREAM_TO_UINT16(conn_timeout, p);
    handle = HCID_GET_HANDLE(handle);

#if (BLE_PRIVACY_SPT == TRUE)
    peer_addr_type = bda_type;
    bool addr_is_rpa =
        (peer_addr_type == BLE_ADDR_RANDOM && BTM_BLE_IS_RESOLVE_BDA(bda));

    /* We must translate whatever address we received into the "pseudo" address.
     * i.e. if we bonded with device that was using RPA for first connection,
     * "pseudo" address is equal to this RPA. If it later decides to use Public
     * address, or Random Static Address, we convert it into the "pseudo"
     * address here. */
    if (!addr_is_rpa || peer_addr_type & BLE_ADDR_TYPE_ID_BIT) {
      match = btm_identity_addr_to_random_pseudo(&bda, &bda_type, true);
    }

    /* possiblly receive connection complete with resolvable random while
       the device has been paired */
    if (!match && addr_is_rpa) {
      tBTM_SEC_DEV_REC* match_rec = btm_ble_resolve_random_addr(bda);
      if (match_rec) {
        LOG_INFO(LOG_TAG, "%s matched and resolved random address", __func__);
        match = true;
        match_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA;
        match_rec->ble.cur_rand_addr = bda;
        if (!btm_ble_init_pseudo_addr(match_rec, bda)) {
          /* assign the original address to be the current report address */
          bda = match_rec->ble.pseudo_addr;
        } else {
          bda = match_rec->bd_addr;
        }
      } else {
        LOG_INFO(LOG_TAG, "%s unable to match and resolve random address",
                 __func__);
      }
    }
#endif

    if (role == HCI_ROLE_MASTER) {
      btm_ble_set_conn_st(BLE_CONN_IDLE);
    }

    connection_manager::on_connection_complete(bda);
    btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type,
                      match);

    l2cble_conn_comp(handle, role, bda, bda_type, conn_interval, conn_latency,
                     conn_timeout);

#if (BLE_PRIVACY_SPT == TRUE)
    if (enhanced) {
      btm_ble_refresh_local_resolvable_private_addr(bda, local_rpa);

      if (peer_addr_type & BLE_ADDR_TYPE_ID_BIT)
        btm_ble_refresh_peer_resolvable_private_addr(bda, peer_rpa,
                                                     BLE_ADDR_RANDOM);
    }
#endif
  } else {
    role = HCI_ROLE_UNKNOWN;
    if (status != HCI_ERR_ADVERTISING_TIMEOUT) {
      btm_ble_set_conn_st(BLE_CONN_IDLE);
#if (BLE_PRIVACY_SPT == TRUE)
      btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, true);
#endif
    } else {
#if (BLE_PRIVACY_SPT == TRUE)
      btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
      btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, true);
#endif
    }
  }

  btm_ble_update_mode_operation(role, &bda, status);

  if (role == HCI_ROLE_SLAVE)
    btm_ble_advertiser_notify_terminated_legacy(status, handle);
}

/*****************************************************************************
 * Function btm_ble_create_ll_conn_complete
 *
 * Description LE connection complete.
 *
 *****************************************************************************/
void btm_ble_create_ll_conn_complete(uint8_t status) {
  if (status == HCI_SUCCESS) return;

  btm_ble_set_conn_st(BLE_CONN_IDLE);
  btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, NULL, status);

  LOG(WARNING) << "LE Create Connection attempt failed, status="
               << loghex(status);

  if (status == HCI_ERR_COMMAND_DISALLOWED) {
    /* There is already either direct connect, or whitelist connection
     * pending, but we don't know which one, or to which state should we
     * transition now. This can be triggered only in case of rare race
     * condition. Crash to recover. */
    LOG(FATAL) << "LE Create Connection - command disallowed";
  }
}
/*****************************************************************************
 *  Function        btm_proc_smp_cback
 *
+11 −86
Original line number Diff line number Diff line
@@ -32,6 +32,14 @@
#include "hcimsgs.h"
#include "l2c_int.h"

extern void btm_send_hci_create_connection(
    uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
    uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
    uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
    uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
    uint8_t phy);
extern void btm_ble_create_conn_cancel();

// Unfortunately (for now?) we have to maintain a copy of the device whitelist
// on the host to determine if a device is pending to be connected or not. This
// controls whether the host should keep trying to scan for whitelisted
@@ -142,7 +150,7 @@ void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy) {
 *
 ******************************************************************************/
void btm_ble_bgconn_cancel_if_disconnected(const RawAddress& bd_addr) {
  if (btm_cb.ble_ctr_cb.conn_state != BLE_BG_CONN) return;
  if (btm_ble_get_conn_st() != BLE_BG_CONN) return;

  auto map_it = background_connections.find(bd_addr);
  if (map_it != background_connections.end()) {
@@ -298,59 +306,6 @@ void btm_ble_white_list_init(uint8_t white_list_size) {
  BTM_TRACE_DEBUG("%s white_list_size = %d", __func__, white_list_size);
}

void btm_ble_create_conn_cancel_complete(uint8_t* p) {
  uint8_t status;
  STREAM_TO_UINT8(status, p);

  if (status == HCI_ERR_COMMAND_DISALLOWED) {
    /* This is a sign that logic around keeping connection state is broken */
    LOG(ERROR)
        << "Attempt to cancel LE connection, when no connection is pending.";
    if (btm_ble_get_conn_st() == BLE_CONN_CANCEL) {
      btm_ble_set_conn_st(BLE_CONN_IDLE);
      btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, nullptr, status);
    }
  }
}

void btm_send_hci_create_connection(
    uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
    uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
    uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
    uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
    uint8_t initiating_phys) {
  if (controller_get_interface()->supports_ble_extended_advertising()) {
    EXT_CONN_PHY_CFG phy_cfg[3];  // maximum three phys

    int phy_cnt =
        std::bitset<std::numeric_limits<uint8_t>::digits>(initiating_phys)
            .count();

    LOG_ASSERT(phy_cnt < 3) << "More than three phys provided";
    // TODO(jpawlowski): tune parameters for different transports
    for (int i = 0; i < phy_cnt; i++) {
      phy_cfg[i].scan_int = scan_int;
      phy_cfg[i].scan_win = scan_win;
      phy_cfg[i].conn_int_min = conn_int_min;
      phy_cfg[i].conn_int_max = conn_int_max;
      phy_cfg[i].conn_latency = conn_latency;
      phy_cfg[i].sup_timeout = conn_timeout;
      phy_cfg[i].min_ce_len = min_ce_len;
      phy_cfg[i].max_ce_len = max_ce_len;
    }

    addr_type_peer &= ~BLE_ADDR_TYPE_ID_BIT;
    btsnd_hcic_ble_ext_create_conn(init_filter_policy, addr_type_own,
                                   addr_type_peer, bda_peer, initiating_phys,
                                   phy_cfg);
  } else {
    btsnd_hcic_ble_create_ll_conn(scan_int, scan_win, init_filter_policy,
                                  addr_type_peer, bda_peer, addr_type_own,
                                  conn_int_min, conn_int_max, conn_latency,
                                  conn_timeout, min_ce_len, max_ce_len);
  }
}

bool BTM_SetLeConnectionModeToFast() {
  VLOG(2) << __func__;
  tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
@@ -433,7 +388,6 @@ bool btm_ble_start_auto_conn() {
      0,                              /* uint16_t min_len       */
      0,                              /* uint16_t max_len       */
      phy);
  btm_ble_set_conn_st(BLE_BG_CONN);
  return true;
}

@@ -448,8 +402,8 @@ bool btm_ble_stop_auto_conn() {
    return false;
  }

  btsnd_hcic_ble_create_conn_cancel();
  btm_ble_set_conn_st(BLE_CONN_CANCEL);
  btm_ble_create_conn_cancel();

  p_cb->wl_state &= ~BTM_BLE_WL_INIT;
  return true;
}
@@ -484,35 +438,6 @@ bool btm_ble_suspend_bg_conn(void) {
 *
 ******************************************************************************/
bool btm_ble_resume_bg_conn(void) { return btm_ble_start_auto_conn(); }
/*******************************************************************************
 *
 * Function         btm_ble_get_conn_st
 *
 * Description      This function get BLE connection state
 *
 * Returns          connection state
 *
 ******************************************************************************/
tBTM_BLE_CONN_ST btm_ble_get_conn_st(void) {
  return btm_cb.ble_ctr_cb.conn_state;
}
/*******************************************************************************
 *
 * Function         btm_ble_set_conn_st
 *
 * Description      This function set BLE connection state
 *
 * Returns          None.
 *
 ******************************************************************************/
void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st) {
  btm_cb.ble_ctr_cb.conn_state = new_st;

  if (new_st == BLE_BG_CONN || new_st == BLE_DIR_CONN)
    btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT);
  else
    btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT);
}

/** Adds the device into white list. Returns false if white list is full and
 * device can't be added, true otherwise. */
+227 −0
Original line number Diff line number Diff line
/******************************************************************************
 *
 *  Copyright 2019 The Android Open Source Project
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

#include "bt_types.h"
#include "btm_int.h"
#include "device/include/controller.h"
#include "l2c_int.h"
#include "stack/gatt/connection_manager.h"
#include "stack/include/hcimsgs.h"

extern void btm_ble_advertiser_notify_terminated_legacy(
    uint8_t status, uint16_t connection_handle);

/** This function get BLE connection state */
tBTM_BLE_CONN_ST btm_ble_get_conn_st(void) {
  return btm_cb.ble_ctr_cb.conn_state;
}

/** This function set BLE connection state */
void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st) {
  btm_cb.ble_ctr_cb.conn_state = new_st;

  if (new_st == BLE_BG_CONN || new_st == BLE_DIR_CONN)
    btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT);
  else
    btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT);
}

void btm_send_hci_create_connection(
    uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
    uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
    uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
    uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
    uint8_t initiating_phys) {
  if (controller_get_interface()->supports_ble_extended_advertising()) {
    EXT_CONN_PHY_CFG phy_cfg[3];  // maximum three phys

    int phy_cnt =
        std::bitset<std::numeric_limits<uint8_t>::digits>(initiating_phys)
            .count();

    LOG_ASSERT(phy_cnt < 3) << "More than three phys provided";
    // TODO(jpawlowski): tune parameters for different transports
    for (int i = 0; i < phy_cnt; i++) {
      phy_cfg[i].scan_int = scan_int;
      phy_cfg[i].scan_win = scan_win;
      phy_cfg[i].conn_int_min = conn_int_min;
      phy_cfg[i].conn_int_max = conn_int_max;
      phy_cfg[i].conn_latency = conn_latency;
      phy_cfg[i].sup_timeout = conn_timeout;
      phy_cfg[i].min_ce_len = min_ce_len;
      phy_cfg[i].max_ce_len = max_ce_len;
    }

    addr_type_peer &= ~BLE_ADDR_TYPE_ID_BIT;
    btsnd_hcic_ble_ext_create_conn(init_filter_policy, addr_type_own,
                                   addr_type_peer, bda_peer, initiating_phys,
                                   phy_cfg);
  } else {
    btsnd_hcic_ble_create_ll_conn(scan_int, scan_win, init_filter_policy,
                                  addr_type_peer, bda_peer, addr_type_own,
                                  conn_int_min, conn_int_max, conn_latency,
                                  conn_timeout, min_ce_len, max_ce_len);
  }

  btm_ble_set_conn_st(BLE_BG_CONN);
}

/** LE connection complete. */
void btm_ble_create_ll_conn_complete(uint8_t status) {
  if (status == HCI_SUCCESS) return;

  btm_ble_set_conn_st(BLE_CONN_IDLE);
  btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, NULL, status);

  LOG(WARNING) << "LE Create Connection attempt failed, status="
               << loghex(status);

  if (status == HCI_ERR_COMMAND_DISALLOWED) {
    /* There is already either direct connect, or whitelist connection
     * pending, but we don't know which one, or to which state should we
     * transition now. This can be triggered only in case of rare race
     * condition. Crash to recover. */
    LOG(FATAL) << "LE Create Connection - command disallowed";
  }
}

/** LE connection complete. */
void btm_ble_conn_complete(uint8_t* p, UNUSED_ATTR uint16_t evt_len,
                           bool enhanced) {
#if (BLE_PRIVACY_SPT == TRUE)
  uint8_t peer_addr_type;
#endif
  RawAddress local_rpa, peer_rpa;
  uint8_t role, status, bda_type;
  uint16_t handle;
  RawAddress bda;
  uint16_t conn_interval, conn_latency, conn_timeout;
  bool match = false;

  STREAM_TO_UINT8(status, p);
  STREAM_TO_UINT16(handle, p);
  STREAM_TO_UINT8(role, p);
  STREAM_TO_UINT8(bda_type, p);
  STREAM_TO_BDADDR(bda, p);

  if (status == 0) {
    if (enhanced) {
      STREAM_TO_BDADDR(local_rpa, p);
      STREAM_TO_BDADDR(peer_rpa, p);
    }

    STREAM_TO_UINT16(conn_interval, p);
    STREAM_TO_UINT16(conn_latency, p);
    STREAM_TO_UINT16(conn_timeout, p);
    handle = HCID_GET_HANDLE(handle);

#if (BLE_PRIVACY_SPT == TRUE)
    peer_addr_type = bda_type;
    bool addr_is_rpa =
        (peer_addr_type == BLE_ADDR_RANDOM && BTM_BLE_IS_RESOLVE_BDA(bda));

    /* We must translate whatever address we received into the "pseudo" address.
     * i.e. if we bonded with device that was using RPA for first connection,
     * "pseudo" address is equal to this RPA. If it later decides to use Public
     * address, or Random Static Address, we convert it into the "pseudo"
     * address here. */
    if (!addr_is_rpa || peer_addr_type & BLE_ADDR_TYPE_ID_BIT) {
      match = btm_identity_addr_to_random_pseudo(&bda, &bda_type, true);
    }

    /* possiblly receive connection complete with resolvable random while
       the device has been paired */
    if (!match && addr_is_rpa) {
      tBTM_SEC_DEV_REC* match_rec = btm_ble_resolve_random_addr(bda);
      if (match_rec) {
        LOG(INFO) << __func__ << ": matched and resolved random address";
        match = true;
        match_rec->ble.active_addr_type = BTM_BLE_ADDR_RRA;
        match_rec->ble.cur_rand_addr = bda;
        if (!btm_ble_init_pseudo_addr(match_rec, bda)) {
          /* assign the original address to be the current report address */
          bda = match_rec->ble.pseudo_addr;
        } else {
          bda = match_rec->bd_addr;
        }
      } else {
        LOG(INFO) << __func__ << ": unable to match and resolve random address";
      }
    }
#endif

    if (role == HCI_ROLE_MASTER) {
      btm_ble_set_conn_st(BLE_CONN_IDLE);
    }

    connection_manager::on_connection_complete(bda);
    btm_ble_connected(bda, handle, HCI_ENCRYPT_MODE_DISABLED, role, bda_type,
                      match);

    l2cble_conn_comp(handle, role, bda, bda_type, conn_interval, conn_latency,
                     conn_timeout);

#if (BLE_PRIVACY_SPT == TRUE)
    if (enhanced) {
      btm_ble_refresh_local_resolvable_private_addr(bda, local_rpa);

      if (peer_addr_type & BLE_ADDR_TYPE_ID_BIT)
        btm_ble_refresh_peer_resolvable_private_addr(bda, peer_rpa,
                                                     BLE_ADDR_RANDOM);
    }
#endif
  } else {
    role = HCI_ROLE_UNKNOWN;
    if (status != HCI_ERR_ADVERTISING_TIMEOUT) {
      btm_ble_set_conn_st(BLE_CONN_IDLE);
#if (BLE_PRIVACY_SPT == TRUE)
      btm_ble_disable_resolving_list(BTM_BLE_RL_INIT, true);
#endif
    } else {
#if (BLE_PRIVACY_SPT == TRUE)
      btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE;
      btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, true);
#endif
    }
  }

  btm_ble_update_mode_operation(role, &bda, status);

  if (role == HCI_ROLE_SLAVE)
    btm_ble_advertiser_notify_terminated_legacy(status, handle);
}

void btm_ble_create_conn_cancel() {
  btsnd_hcic_ble_create_conn_cancel();
  btm_ble_set_conn_st(BLE_CONN_CANCEL);
}

void btm_ble_create_conn_cancel_complete(uint8_t* p) {
  uint8_t status;
  STREAM_TO_UINT8(status, p);

  if (status == HCI_ERR_COMMAND_DISALLOWED) {
    /* This is a sign that logic around keeping connection state is broken */
    LOG(ERROR)
        << "Attempt to cancel LE connection, when no connection is pending.";
    if (btm_ble_get_conn_st() == BLE_CONN_CANCEL) {
      btm_ble_set_conn_st(BLE_CONN_IDLE);
      btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, nullptr, status);
    }
  }
}
+0 −10
Original line number Diff line number Diff line
@@ -68,7 +68,6 @@ extern void btm_ble_conn_complete(uint8_t* p, uint16_t evt_len, bool enhanced);
extern void btm_read_ble_local_supported_states_complete(uint8_t* p,
                                                         uint16_t evt_len);
extern tBTM_BLE_CONN_ST btm_ble_get_conn_st(void);
extern void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st);
extern tBTM_STATUS btm_ble_start_adv(void);
extern tBTM_STATUS btm_ble_stop_adv(void);
extern void btm_le_on_advertising_set_terminated(uint8_t* p, uint16_t length);
@@ -123,17 +122,8 @@ extern void btm_ble_white_list_init(uint8_t white_list_size);
/* background connection function */
extern bool btm_ble_suspend_bg_conn(void);
extern bool btm_ble_resume_bg_conn(void);
extern void btm_send_hci_create_connection(
    uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
    uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
    uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
    uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
    uint8_t phy);
extern bool btm_ble_start_auto_conn();
extern bool btm_ble_stop_auto_conn();
extern bool btm_ble_start_select_conn(bool start);
extern bool btm_ble_renew_bg_conn_params(bool add, const RawAddress& bd_addr);
extern void btm_write_dir_conn_wl(const RawAddress& target_addr);
extern void btm_ble_update_mode_operation(uint8_t link_role,
                                          const RawAddress* bda,
                                          uint8_t status);