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

Commit 42582a54 authored by Hansong Zhang's avatar Hansong Zhang
Browse files

L2cap classic shim: Use new helper

Fixes to the new shim, including thread sync, shim redirection in ACL
shim, security level settings.

Tag: #gd-refactor
Bug: 141555841
Test: cert/run --host
Test: Pair and connect with a headset
Change-Id: Ia66a968b545eed843552d1ee9953adf1f9f57c9d
parent b3ad9c1a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ void DynamicChannelAllocator::FreeChannel(Cid cid) {
  used_cid_.erase(cid);
  auto channel = FindChannelByCid(cid);
  if (channel == nullptr) {
    LOG_INFO("Channel is not in use: psm %d, device %s", cid, link_->GetDevice().ToString().c_str());
    LOG_INFO("Channel is not in use: cid %d, device %s", cid, link_->GetDevice().ToString().c_str());
    return;
  }
  used_remote_cid_.erase(channel->GetRemoteCid());
+201 −118
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include "stack/btm/btm_sec.h"
#include "stack/include/acl_hci_link_interface.h"
#include "stack/include/btm_api.h"
#include "stack/include/btu.h"

using bluetooth::hci::AddressWithType;
using namespace bluetooth::l2cap;
@@ -40,20 +41,19 @@ static bluetooth::shim::legacy::L2cap shim_l2cap;

// Classic Dynamic Channel Shim Helper

uint16_t classic_cid_token_counter_ = 1;
uint16_t classic_cid_token_counter_ = 0x41;

struct ClassicDynamicChannelInfo {
  uint16_t psm;
  RawAddress remote;
};
std::unordered_map<uint16_t, ClassicDynamicChannelInfo>
    classic_cid_token_to_channel_map_;

uint16_t add_classic_cid_token_entry(uint16_t psm, RawAddress remote) {
uint16_t add_classic_cid_token_entry(uint16_t psm) {
  uint16_t new_token = classic_cid_token_counter_;
  classic_cid_token_to_channel_map_[new_token] = {psm, remote};
  classic_cid_token_to_channel_map_[new_token] = {psm};
  classic_cid_token_counter_++;
  if (classic_cid_token_counter_ == 0) classic_cid_token_counter_++;
  if (classic_cid_token_counter_ == 0) classic_cid_token_counter_ = 0x41;
  return new_token;
}

@@ -61,33 +61,26 @@ void remove_classic_cid_token_entry(uint16_t cid_token) {
  classic_cid_token_to_channel_map_.erase(cid_token);
}

uint16_t find_classic_cid_token_by_psm_address(uint16_t psm,
                                               RawAddress remote) {
  for (const auto& entry : classic_cid_token_to_channel_map_) {
    if (entry.second.psm == psm && entry.second.remote == remote) {
      return entry.first;
    }
  }
  LOG(ERROR) << __func__ << "Can't find channel";
  return 0;
}

struct ClassicDynamicChannelHelper {
  ClassicDynamicChannelHelper(uint16_t psm, tL2CAP_APPL_INFO appl_info)
      : psm_(psm), appl_info_(appl_info) {}
  ClassicDynamicChannelHelper(uint16_t psm, tL2CAP_APPL_INFO appl_info,
                              classic::DynamicChannelConfigurationOption config,
                              classic::SecurityPolicy policy)
      : psm_(psm), appl_info_(appl_info), config_(config), policy_(policy) {}

  uint16_t psm_;
  tL2CAP_APPL_INFO appl_info_;
  classic::DynamicChannelConfigurationOption config_;
  classic::SecurityPolicy policy_;

  void Register() {
    bluetooth::shim::GetL2capClassicModule()
        ->GetDynamicChannelManager()
        ->RegisterService(
            psm_, {}, {},
            psm_, config_, policy_,
            bluetooth::shim::GetGdShimHandler()->BindOnceOn(
                this, &ClassicDynamicChannelHelper::on_registration_complete),
            bluetooth::shim::GetGdShimHandler()->BindOn(
                this, &ClassicDynamicChannelHelper::on_channel_open));
                this, &ClassicDynamicChannelHelper::on_channel_open, 0));
  }

  void on_registration_complete(
@@ -102,31 +95,30 @@ struct ClassicDynamicChannelHelper {

  std::unique_ptr<classic::DynamicChannelService> channel_service_ = nullptr;

  void Connect(bluetooth::hci::AddressWithType device) {
  void Connect(uint16_t cid_token, bluetooth::hci::AddressWithType device) {
    if (channel_service_ == nullptr) {
      return;
    }
    initiated_by_us_[device] = true;
    initiated_by_us_[cid_token] = true;
    bluetooth::shim::GetL2capClassicModule()
        ->GetDynamicChannelManager()
        ->ConnectChannel(
            device.GetAddress(), {}, psm_,
            device.GetAddress(), config_, psm_,
            bluetooth::shim::GetGdShimHandler()->BindOn(
                this, &ClassicDynamicChannelHelper::on_channel_open),
                this, &ClassicDynamicChannelHelper::on_channel_open, cid_token),
            bluetooth::shim::GetGdShimHandler()->BindOnceOn(
                this,
                &ClassicDynamicChannelHelper::on_outgoing_connection_fail));
  }

  void Disconnect(bluetooth::hci::AddressWithType device) {
  void Disconnect(uint16_t cid_token) {
    if (channel_service_ == nullptr) {
      return;
    }
    if (channels_.count(device) == 0) {
    if (channels_.count(cid_token) == 0) {
      return;
    }
    channels_[device]->Close();
    disconnected_by_us_[device] = true;
    channels_[cid_token]->Close();
  }

  void Unregister() {
@@ -144,16 +136,16 @@ struct ClassicDynamicChannelHelper {
    }
  }

  void on_channel_close(bluetooth::hci::AddressWithType device,
  void on_channel_close(uint16_t cid_token,
                        bluetooth::hci::ErrorCode error_code) {
    channel_enqueue_buffer_[device] = nullptr;
    channels_[device]->GetQueueUpEnd()->UnregisterDequeue();
    channels_.erase(device);
    auto address = bluetooth::ToRawAddress(device.GetAddress());
    auto cid_token = find_classic_cid_token_by_psm_address(psm_, address);
    (appl_info_.pL2CA_DisconnectInd_Cb)(cid_token, false);
    channel_enqueue_buffer_[cid_token] = nullptr;
    channels_[cid_token]->GetQueueUpEnd()->UnregisterDequeue();
    channels_.erase(cid_token);
    do_in_main_thread(FROM_HERE, base::Bind(appl_info_.pL2CA_DisconnectInd_Cb,
                                            cid_token, false));

    remove_classic_cid_token_entry(cid_token);
    initiated_by_us_.erase(device);
    initiated_by_us_.erase(cid_token);

    if (channel_service_ == nullptr && channels_.empty()) {
      // Try again
@@ -161,36 +153,56 @@ struct ClassicDynamicChannelHelper {
    }
  }

  void on_channel_open(std::unique_ptr<classic::DynamicChannel> channel) {
  void on_channel_open(uint16_t cid_token,
                       std::unique_ptr<classic::DynamicChannel> channel) {
    auto device = channel->GetDevice();
    auto address = bluetooth::ToRawAddress(device.GetAddress());
    bool initiator_local = (cid_token != 0);
    if (cid_token == 0) {
      cid_token = add_classic_cid_token_entry(psm_);
    }

    channel->RegisterOnCloseCallback(
        bluetooth::shim::GetGdShimHandler()->BindOnceOn(
            this, &ClassicDynamicChannelHelper::on_channel_close, device));
    channel_enqueue_buffer_[device] = std::make_unique<
        bluetooth::os::EnqueueBuffer<bluetooth::packet::BasePacketBuilder>>(
        channel->GetQueueUpEnd());
            this, &ClassicDynamicChannelHelper::on_channel_close, cid_token));

    channel->GetQueueUpEnd()->RegisterDequeue(
        bluetooth::shim::GetGdShimHandler(),
        bluetooth::common::Bind(&ClassicDynamicChannelHelper::on_incoming_data,
                                bluetooth::common::Unretained(this), device));
    channels_[device] = std::move(channel);
                                bluetooth::common::Unretained(this),
                                cid_token));

    auto address = bluetooth::ToRawAddress(device.GetAddress());
    if (initiated_by_us_[device]) {
      auto cid_token = find_classic_cid_token_by_psm_address(psm_, address);
      appl_info_.pL2CA_ConnectCfm_Cb(cid_token, 0);
    channel_enqueue_buffer_[cid_token] = std::make_unique<
        bluetooth::os::EnqueueBuffer<bluetooth::packet::BasePacketBuilder>>(
        channel->GetQueueUpEnd());

    channels_[cid_token] = std::move(channel);

    if (initiator_local) {
      do_in_main_thread(
          FROM_HERE, base::Bind(appl_info_.pL2CA_ConnectCfm_Cb, cid_token, 0));

      tL2CAP_CFG_INFO cfg_info{};
      do_in_main_thread(FROM_HERE, base::Bind(appl_info_.pL2CA_ConfigCfm_Cb,
                                              cid_token, L2CAP_INITIATOR_LOCAL,
                                              base::Unretained(&cfg_info)));
    } else {
      if (appl_info_.pL2CA_ConnectInd_Cb == nullptr) {
        Disconnect(device);
        Disconnect(cid_token);
        return;
      }
      auto cid_token = add_classic_cid_token_entry(psm_, address);
      appl_info_.pL2CA_ConnectInd_Cb(address, cid_token, psm_, 0);
      do_in_main_thread(FROM_HERE, base::Bind(appl_info_.pL2CA_ConnectInd_Cb,
                                              address, cid_token, psm_, 0));

      tL2CAP_CFG_INFO cfg_info{};
      do_in_main_thread(FROM_HERE, base::Bind(appl_info_.pL2CA_ConfigCfm_Cb,
                                              cid_token, L2CAP_INITIATOR_LOCAL,
                                              base::Unretained(&cfg_info)));
    }
  }

  void on_incoming_data(bluetooth::hci::AddressWithType remote) {
    auto channel = channels_.find(remote);
  void on_incoming_data(uint16_t cid_token) {
    auto channel = channels_.find(cid_token);
    if (channel == channels_.end()) {
      LOG_ERROR("Channel is not open");
      return;
@@ -201,9 +213,9 @@ struct ClassicDynamicChannelHelper {
        static_cast<BT_HDR*>(osi_calloc(packet_vector.size() + sizeof(BT_HDR)));
    std::copy(packet_vector.begin(), packet_vector.end(), buffer->data);
    buffer->len = packet_vector.size();
    auto address = bluetooth::ToRawAddress(remote.GetAddress());
    auto cid_token = find_classic_cid_token_by_psm_address(psm_, address);
    appl_info_.pL2CA_DataInd_Cb(cid_token, buffer);
    do_in_main_thread(FROM_HERE,
                      base::Bind(appl_info_.pL2CA_DataInd_Cb, cid_token,
                                 base::Unretained(buffer)));
  }

  void on_outgoing_connection_fail(
@@ -211,9 +223,9 @@ struct ClassicDynamicChannelHelper {
    LOG(ERROR) << "Outgoing connection failed";
  }

  bool send(AddressWithType remote,
  bool send(uint16_t cid,
            std::unique_ptr<bluetooth::packet::BasePacketBuilder> packet) {
    auto buffer = channel_enqueue_buffer_.find(remote);
    auto buffer = channel_enqueue_buffer_.find(cid);
    if (buffer == channel_enqueue_buffer_.end() || buffer->second == nullptr) {
      LOG(ERROR) << "Channel is not open";
      return false;
@@ -223,15 +235,21 @@ struct ClassicDynamicChannelHelper {
    return true;
  }

  std::unordered_map<AddressWithType, std::unique_ptr<classic::DynamicChannel>>
  uint16_t GetRemoteCid(uint16_t cid) {
    auto channel = channels_.find(cid);
    if (channel == channels_.end()) {
      LOG_ERROR("Channel is not open");
      return 0;
    }
    return channel->second->HACK_GetRemoteCid();
  }

  std::unordered_map<uint16_t, std::unique_ptr<classic::DynamicChannel>>
      channels_;
  std::unordered_map<AddressWithType,
                     std::unique_ptr<bluetooth::os::EnqueueBuffer<
  std::unordered_map<uint16_t, std::unique_ptr<bluetooth::os::EnqueueBuffer<
                                   bluetooth::packet::BasePacketBuilder>>>
      channel_enqueue_buffer_;
  std::unordered_map<AddressWithType, uint16_t> cid_map_;
  std::unordered_map<AddressWithType, bool> initiated_by_us_;
  std::unordered_map<AddressWithType, bool> disconnected_by_us_;
  std::unordered_map<uint16_t, bool> initiated_by_us_;
};

std::unordered_map<uint16_t, std::unique_ptr<ClassicDynamicChannelHelper>>
@@ -330,10 +348,10 @@ class SecurityListenerShim
  void OnLinkDisconnected(bluetooth::hci::Address remote) override {
    auto bda = bluetooth::ToRawAddress(remote);
    uint16_t handle = address_to_handle_[bda];
    btm_sec_disconnected(handle, HCI_ERR_PEER_USER);
    BTA_dm_acl_down(bda, BT_TRANSPORT_BR_EDR);
    address_to_handle_.erase(bda);
    address_to_interface_.erase(bda);
    btm_sec_disconnected(handle, HCI_ERR_PEER_USER);
    BTA_dm_acl_down(bda, BT_TRANSPORT_BR_EDR);
  }

  void OnEncryptionChange(bluetooth::hci::Address remote,
@@ -389,6 +407,19 @@ class SecurityListenerShim
           bluetooth::hci::Role::CENTRAL;
  }

  void Disconnect(RawAddress remote) {
    if (address_to_interface_.count(remote) == 0) {
      return;
    }
    return address_to_interface_[remote]->Disconnect();
  }

  uint16_t GetNumAclLinks() { return address_to_handle_.size(); }

  bool IsLinkUp(RawAddress remote) {
    return address_to_interface_.count(remote) != 0;
  }

  std::unordered_map<RawAddress, uint16_t> address_to_handle_;
  std::unordered_map<
      RawAddress,
@@ -476,60 +507,74 @@ void bluetooth::shim::L2CA_UseLegacySecurityModule() {

  bluetooth::shim::GetL2capLeModule()->InjectSecurityEnforcementInterface(
      &le_security_enforcement_shim_);
  ACL_ConfigureLePrivacy(true);

  // TODO(b/161543441): read the privacy policy from device-specific
  // configuration, and IRK from config file.
  hci::LeAddressManager::AddressPolicy address_policy =
      hci::LeAddressManager::AddressPolicy::USE_RESOLVABLE_ADDRESS;
  hci::AddressWithType empty_address_with_type(
      hci::Address{}, hci::AddressType::RANDOM_DEVICE_ADDRESS);
  crypto_toolbox::Octet16 rotation_irk = {0x44, 0xfb, 0x4b, 0x8d, 0x6c, 0x58,
                                          0x21, 0x0c, 0xf9, 0x3d, 0xda, 0xf1,
                                          0x64, 0xa3, 0xbb, 0x7f};
  /* 7 minutes minimum, 15 minutes maximum for random address refreshing */
  auto minimum_rotation_time = std::chrono::minutes(7);
  auto maximum_rotation_time = std::chrono::minutes(15);

  GetAclManager()->SetPrivacyPolicyForInitiatorAddress(
      address_policy, empty_address_with_type, rotation_irk,
      minimum_rotation_time, maximum_rotation_time);
}

/**
 * Classic Service Registration APIs
 */
uint16_t bluetooth::shim::L2CA_Register(uint16_t client_psm,
                                        const tL2CAP_APPL_INFO& callbacks,
                                        bool enable_snoop,
                                        tL2CAP_ERTM_INFO* p_ertm_info,
                                        uint16_t my_mtu,
                                        uint16_t required_remote_mtu) {
  if (L2C_INVALID_PSM(client_psm)) {
    LOG_ERROR("%s Invalid classic psm:%hd", __func__, client_psm);
uint16_t bluetooth::shim::L2CA_Register(
    uint16_t client_psm, const tL2CAP_APPL_INFO& callbacks, bool enable_snoop,
    tL2CAP_ERTM_INFO* p_ertm_info, uint16_t my_mtu,
    uint16_t required_remote_mtu, uint16_t sec_level) {
  if (classic_dynamic_channel_helper_map_.count(client_psm) != 0) {
    LOG(ERROR) << __func__ << "Already registered psm: " << client_psm;
    return 0;
  }

  if ((callbacks.pL2CA_ConfigCfm_Cb == nullptr) ||
      (callbacks.pL2CA_ConfigInd_Cb == nullptr) ||
      (callbacks.pL2CA_DataInd_Cb == nullptr) ||
      (callbacks.pL2CA_DisconnectInd_Cb == nullptr)) {
    LOG_ERROR("%s Invalid classic callbacks psm:%hd", __func__, client_psm);
    return 0;
  }
  classic::DynamicChannelConfigurationOption config;
  config.minimal_remote_mtu = std::max<uint16_t>(required_remote_mtu, 48);
  config.incoming_mtu = my_mtu;
  config.channel_mode =
      (p_ertm_info != nullptr &&
               p_ertm_info->preferred_mode == L2CAP_FCR_ERTM_MODE
           ? classic::DynamicChannelConfigurationOption::
                 RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION
           : classic::DynamicChannelConfigurationOption::
                 RetransmissionAndFlowControlMode::L2CAP_BASIC);

  /**
   * Check if this is a registration for an outgoing-only connection.
   */
  const bool is_outgoing_connection_only =
      callbacks.pL2CA_ConnectInd_Cb == nullptr;
  const uint16_t psm = shim_l2cap.ConvertClientToRealPsm(
      client_psm, is_outgoing_connection_only);

  if (shim_l2cap.Classic().IsPsmRegistered(psm)) {
    LOG_ERROR("%s Already registered classic client_psm:%hd psm:%hd", __func__,
              client_psm, psm);
    return 0;
  classic::SecurityPolicy policy =
      (client_psm == 1
           ? classic::SecurityPolicy::
                 _SDP_ONLY_NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK
           : classic::SecurityPolicy::ENCRYPTED_TRANSPORT);
  if (sec_level & (BTM_SEC_IN_AUTHENTICATE | BTM_SEC_OUT_AUTHENTICATE)) {
    policy = classic::SecurityPolicy::BEST;
  }
  LOG_INFO("%s classic client_psm:%hd psm:%hd", __func__, client_psm, psm);
  // Minimum acceptable MTU is 48 bytes
  required_remote_mtu = std::max<uint16_t>(required_remote_mtu, 48);
  return shim_l2cap.RegisterService(psm, callbacks, enable_snoop, p_ertm_info,
                                    my_mtu, required_remote_mtu);

  classic_dynamic_channel_helper_map_[client_psm] =
      std::make_unique<ClassicDynamicChannelHelper>(client_psm, callbacks,
                                                    config, policy);

  classic_dynamic_channel_helper_map_[client_psm]->Register();
  return client_psm;
}

void bluetooth::shim::L2CA_Deregister(uint16_t client_psm) {
  if (L2C_INVALID_PSM(client_psm)) {
    LOG_ERROR("%s Invalid classic client_psm:%hd", __func__, client_psm);
void bluetooth::shim::L2CA_Deregister(uint16_t psm) {
  if (classic_dynamic_channel_helper_map_.count(psm) == 0) {
    LOG(ERROR) << __func__ << "Not registered psm: " << psm;
    return;
  }
  uint16_t psm = shim_l2cap.ConvertClientToRealPsm(client_psm);

  shim_l2cap.UnregisterService(psm);
  shim_l2cap.RemoveClientPsm(psm);
  classic_dynamic_channel_helper_map_[psm]->Unregister();
  if (classic_dynamic_channel_helper_map_[psm]->channels_.empty()) {
    classic_dynamic_channel_helper_map_.erase(psm);
  }
}

uint16_t bluetooth::shim::L2CA_AllocateLePSM(void) {
@@ -549,11 +594,41 @@ void bluetooth::shim::L2CA_FreeLePSM(uint16_t psm) {
 */
uint16_t bluetooth::shim::L2CA_ConnectReq(uint16_t psm,
                                          const RawAddress& raw_address) {
  return shim_l2cap.CreateConnection(psm, raw_address);
  if (classic_dynamic_channel_helper_map_.count(psm) == 0) {
    LOG(ERROR) << __func__ << "Not registered psm: " << psm;
    return 0;
  }
  uint16_t cid_token = add_classic_cid_token_entry(psm);
  classic_dynamic_channel_helper_map_[psm]->Connect(
      cid_token, ToAddressWithType(raw_address, BLE_ADDR_PUBLIC));
  return cid_token;
}

bool bluetooth::shim::L2CA_DisconnectReq(uint16_t cid) {
  return shim_l2cap.DisconnectRequest(cid);
  auto psm = classic_cid_token_to_channel_map_[cid].psm;
  if (classic_dynamic_channel_helper_map_.count(psm) == 0) {
    LOG(ERROR) << __func__ << "Not registered psm: " << psm;
    return false;
  }
  classic_dynamic_channel_helper_map_[psm]->Disconnect(cid);
  return true;
}

uint8_t bluetooth::shim::L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) {
  if (classic_cid_token_to_channel_map_.count(cid) == 0) {
    LOG(ERROR) << __func__ << "Invalid cid: " << cid;
    return 0;
  }
  auto psm = classic_cid_token_to_channel_map_[cid].psm;
  if (classic_dynamic_channel_helper_map_.count(psm) == 0) {
    LOG(ERROR) << __func__ << "Not registered psm: " << psm;
    return 0;
  }
  auto len = p_data->len;
  auto* data = p_data->data + p_data->offset;
  return classic_dynamic_channel_helper_map_[psm]->send(
             cid, MakeUniquePacket(data, len)) *
         len;
}

bool bluetooth::shim::L2CA_ReconfigCreditBasedConnsReq(
@@ -579,11 +654,6 @@ bool bluetooth::shim::L2CA_ConnectCreditBasedRsp(
  return false;
}

uint8_t bluetooth::shim::L2CA_DataWrite(uint16_t cid, BT_HDR* p_data) {
  bool write_success = shim_l2cap.Write(cid, p_data);
  return write_success ? L2CAP_DW_SUCCESS : L2CAP_DW_FAILED;
}

/**
 * Link APIs
 */
@@ -798,7 +868,13 @@ bool bluetooth::shim::L2CA_RemoveFixedChnl(uint16_t cid,
 * Channel hygiene APIs
 */
bool bluetooth::shim::L2CA_GetRemoteCid(uint16_t lcid, uint16_t* rcid) {
  return shim_l2cap.GetRemoteCid(lcid, rcid);
  auto psm = classic_cid_token_to_channel_map_[lcid].psm;
  if (classic_dynamic_channel_helper_map_.count(psm) == 0) {
    LOG(ERROR) << __func__ << "Not registered psm: " << psm;
    return false;
  }
  *rcid = classic_dynamic_channel_helper_map_[psm]->GetRemoteCid(lcid);
  return *rcid != 0;
}

bool bluetooth::shim::L2CA_SetTxPriority(uint16_t cid,
@@ -828,8 +904,7 @@ uint16_t bluetooth::shim::L2CA_FlushChannel(uint16_t lcid,

bool bluetooth::shim::L2CA_IsLinkEstablished(const RawAddress& bd_addr,
                                             tBT_TRANSPORT transport) {
  LOG_INFO("UNIMPLEMENTED %s", __func__);
  return true;
  return security_listener_shim_.IsLinkUp(bd_addr);
}

void bluetooth::shim::L2CA_ConnectForSecurity(const RawAddress& bd_addr) {
@@ -842,6 +917,14 @@ void bluetooth::shim::L2CA_SetBondingState(const RawAddress& bd_addr,
  security_listener_shim_.UpdateLinkHoldForSecurity(bd_addr, is_bonding);
}

void bluetooth::shim::L2CA_DisconnectLink(const RawAddress& remote) {
  security_listener_shim_.Disconnect(remote);
}

uint16_t bluetooth::shim::L2CA_GetNumLinks() {
  return security_listener_shim_.GetNumAclLinks();
}

// LE COC Shim Helper

uint16_t le_cid_token_counter_ = 1;
+6 −1
Original line number Diff line number Diff line
@@ -41,7 +41,8 @@ namespace shim {
 ******************************************************************************/
uint16_t L2CA_Register(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
                       bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
                       uint16_t my_mtu, uint16_t required_remote_mtu);
                       uint16_t my_mtu, uint16_t required_remote_mtu,
                       uint16_t sec_level);

/*******************************************************************************
 *
@@ -508,5 +509,9 @@ void L2CA_SwitchRoleToCentral(const RawAddress& addr);
bool L2CA_ReadRemoteVersion(const RawAddress& addr, uint8_t* lmp_version,
                            uint16_t* manufacturer, uint16_t* lmp_sub_version);

void L2CA_DisconnectLink(const RawAddress& remote);

uint16_t L2CA_GetNumLinks();

}  // namespace shim
}  // namespace bluetooth
+18 −0
Original line number Diff line number Diff line
@@ -1126,11 +1126,19 @@ tBTM_STATUS BTM_SetLinkSuperTout(const RawAddress& remote_bda,

bool BTM_IsAclConnectionUp(const RawAddress& remote_bda,
                           tBT_TRANSPORT transport) {
  if (bluetooth::shim::is_gd_l2cap_enabled()) {
    return bluetooth::shim::L2CA_IsLinkEstablished(remote_bda, transport);
  }

  return internal_.btm_bda_to_acl(remote_bda, transport) != nullptr;
}

bool BTM_IsAclConnectionUpAndHandleValid(const RawAddress& remote_bda,
                                         tBT_TRANSPORT transport) {
  if (bluetooth::shim::is_gd_l2cap_enabled()) {
    return bluetooth::shim::L2CA_IsLinkEstablished(remote_bda, transport);
  }

  tACL_CONN* p_acl = internal_.btm_bda_to_acl(remote_bda, transport);
  if (p_acl == nullptr) {
    LOG_WARN("Unable to find active acl");
@@ -1154,6 +1162,9 @@ bool BTM_IsAclConnectionUpFromHandle(uint16_t hci_handle) {
 *
 ******************************************************************************/
uint16_t BTM_GetNumAclLinks(void) {
  if (bluetooth::shim::is_gd_l2cap_enabled()) {
    return bluetooth::shim::L2CA_GetNumLinks();
  }
  uint16_t num_acl = 0;

  for (uint16_t i = 0; i < MAX_L2CAP_LINKS; ++i) {
@@ -2081,6 +2092,13 @@ void btm_read_link_quality_complete(uint8_t* p) {
 *
 ******************************************************************************/
tBTM_STATUS btm_remove_acl(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
  if (bluetooth::shim::is_gd_l2cap_enabled()) {
    if (transport == BT_TRANSPORT_LE) {
      LOG(ERROR) << __func__ << ": Unsupported";
    }
    bluetooth::shim::L2CA_DisconnectLink(bd_addr);
    return BTM_SUCCESS;
  }
  uint16_t hci_handle = BTM_GetHCIConnHandle(bd_addr, transport);
  tBTM_STATUS status = BTM_SUCCESS;
  tACL_CONN* p_acl = internal_.btm_bda_to_acl(bd_addr, transport);
+2 −1
Original line number Diff line number Diff line
@@ -339,7 +339,8 @@ uint16_t L2CA_Register2(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
 ******************************************************************************/
extern uint16_t L2CA_Register(uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info,
                              bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
                              uint16_t my_mtu, uint16_t required_remote_mtu);
                              uint16_t my_mtu, uint16_t required_remote_mtu,
                              uint16_t sec_level);

/*******************************************************************************
 *
Loading