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

Commit c683ac0a authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by android-build-merger
Browse files

Move all HCI LE Create Connection management into single file

am: 991e8722

Change-Id: I96f122540d82b5f564023f3f2ff3d7b1a64b7a47
parents e2978f1f 991e8722
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);