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

Commit 53e71b06 authored by Hansong Zhang's avatar Hansong Zhang Committed by Automerger Merge Worker
Browse files

Remove unused shim/l2cap.h and shim/l2cap.cc am: 8ea4de7f

Original change: https://android-review.googlesource.com/c/platform/system/bt/+/1510511

Change-Id: I8675e339cbddd793930252e35dc90be72bd27b62
parents dcbfe64b 8ea4de7f
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -12,7 +12,6 @@ filegroup {
        "entry.cc",
        "hci_layer.cc",
        "l2c_api.cc",
        "l2cap.cc",
        "le_advertising_manager.cc",
        "shim.cc",
        "stack.cc",
+0 −1
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@
#include "main/shim/btm.h"
#include "main/shim/entry.h"
#include "main/shim/helpers.h"
#include "main/shim/l2cap.h"
#include "main/shim/stack.h"
#include "osi/include/allocator.h"
#include "stack/btm/btm_sec.h"

system/main/shim/l2cap.cc

deleted100644 → 0
+0 −373
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.
 */
#define LOG_TAG "bt_shim_l2cap"

#include <cstdint>

#include "main/shim/dumpsys.h"
#include "main/shim/entry.h"
#include "main/shim/l2cap.h"
#include "main/shim/shim.h"
#include "osi/include/allocator.h"
#include "osi/include/log.h"
#include "stack/include/btu.h"

#include "shim/l2cap.h"

namespace {
constexpr char kModuleName[] = "shim::legacy::L2cap";
constexpr bool kDisconnectResponseRequired = false;
constexpr size_t kBtHdrSize = sizeof(BT_HDR);
constexpr uint16_t kConnectionFail = 1;
constexpr uint16_t kConnectionSuccess = 0;
constexpr uint16_t kInvalidConnectionInterfaceDescriptor = 0;
constexpr uint8_t kUnusedId = 0;
}  // namespace

bool bluetooth::shim::legacy::PsmManager::IsPsmRegistered(uint16_t psm) const {
  return psm_to_callback_map_.find(psm) != psm_to_callback_map_.end();
}

bool bluetooth::shim::legacy::PsmManager::HasClient(uint16_t psm) const {
  return IsPsmRegistered(psm) &&
         psm_to_callback_map_.find(psm) != psm_to_callback_map_.end();
}

void bluetooth::shim::legacy::PsmManager::RegisterPsm(
    uint16_t psm, const tL2CAP_APPL_INFO& callbacks) {
  CHECK(!HasClient(psm));
  psm_to_callback_map_.try_emplace(psm, tL2CAP_APPL_INFO(callbacks));
}

void bluetooth::shim::legacy::PsmManager::UnregisterPsm(uint16_t psm) {
  CHECK(IsPsmRegistered(psm));
  psm_to_callback_map_.erase(psm);
}

const tL2CAP_APPL_INFO bluetooth::shim::legacy::PsmManager::Callbacks(
    uint16_t psm) {
  CHECK(HasClient(psm));
  return psm_to_callback_map_[psm];
}

bluetooth::shim::legacy::L2cap::L2cap()
    : le_dynamic_psm_(kInitialLeDynamicPsm),
      classic_virtual_psm_(kInitialClassicVirtualPsm) {
  bluetooth::shim::RegisterDumpsysFunction(static_cast<void*>(this),
                                           [this](int fd) { Dump(fd); });
}

bluetooth::shim::legacy::L2cap::~L2cap() {
  bluetooth::shim::UnregisterDumpsysFunction(static_cast<void*>(this));
}

bluetooth::shim::legacy::PsmManager& bluetooth::shim::legacy::L2cap::Le() {
  return le_;
}

bluetooth::shim::legacy::PsmManager& bluetooth::shim::legacy::L2cap::Classic() {
  return classic_;
}

bool bluetooth::shim::legacy::L2cap::ConnectionExists(uint16_t cid) const {
  return cid_to_psm_map_.find(cid) != cid_to_psm_map_.end();
}

uint16_t bluetooth::shim::legacy::L2cap::CidToPsm(uint16_t cid) const {
  CHECK(ConnectionExists(cid));
  return cid_to_psm_map_.at(cid);
}

uint16_t bluetooth::shim::legacy::L2cap::ConvertClientToRealPsm(
    uint16_t client_psm, bool is_outgoing_only_connection) {
  if (!is_outgoing_only_connection) {
    return client_psm;
  }
  return GetNextVirtualPsm(client_psm);
}

uint16_t bluetooth::shim::legacy::L2cap::ConvertClientToRealPsm(
    uint16_t client_psm) {
  if (client_psm_to_real_psm_map_.find(client_psm) ==
      client_psm_to_real_psm_map_.end()) {
    return client_psm;
  }
  return client_psm_to_real_psm_map_.at(client_psm);
}

void bluetooth::shim::legacy::L2cap::RemoveClientPsm(uint16_t client_psm) {
  if (client_psm_to_real_psm_map_.find(client_psm) !=
      client_psm_to_real_psm_map_.end()) {
    client_psm_to_real_psm_map_.erase(client_psm);
  }
}

uint16_t bluetooth::shim::legacy::L2cap::GetNextVirtualPsm(uint16_t real_psm) {
  if (real_psm < kInitialClassicDynamicPsm) {
    return real_psm;
  }

  while (Classic().IsPsmRegistered(classic_virtual_psm_)) {
    classic_virtual_psm_ += 2;
    if (classic_virtual_psm_ >= kFinalClassicVirtualPsm) {
      classic_virtual_psm_ = kInitialClassicVirtualPsm;
    }
  }
  return classic_virtual_psm_;
}

uint16_t bluetooth::shim::legacy::L2cap::GetNextDynamicLePsm() {
  while (Le().IsPsmRegistered(le_dynamic_psm_)) {
    le_dynamic_psm_++;
    if (le_dynamic_psm_ > kFinalLeDynamicPsm) {
      le_dynamic_psm_ = kInitialLeDynamicPsm;
    }
  }
  return le_dynamic_psm_;
}

uint16_t bluetooth::shim::legacy::L2cap::RegisterService(
    uint16_t 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 (Classic().IsPsmRegistered(psm)) {
    LOG_WARN("Service is already registered psm:%hd", psm);
    return 0;
  }
  if (!enable_snoop) {
    LOG_INFO("Disable snooping on psm basis unsupported psm:%d", psm);
  }

  LOG_INFO("Registering service on psm:%hd", psm);
  RegisterServicePromise register_promise;
  auto service_registered = register_promise.get_future();
  bool use_ertm = false;
  if (p_ertm_info != nullptr &&
      p_ertm_info->preferred_mode == L2CAP_FCR_ERTM_MODE) {
    use_ertm = true;
  }
  bluetooth::shim::GetL2cap()->RegisterClassicService(
      psm, use_ertm, my_mtu, required_remote_mtu,
      std::bind(
          &bluetooth::shim::legacy::L2cap::OnRemoteInitiatedConnectionCreated,
          this, std::placeholders::_1, std::placeholders::_2,
          std::placeholders::_3, std::placeholders::_4),
      std::move(register_promise));

  uint16_t registered_psm = service_registered.get();
  if (registered_psm != psm) {
    LOG_WARN("Unable to register psm:%hd", psm);
  } else {
    LOG_INFO("Successfully registered psm:%hd", psm);
    Classic().RegisterPsm(registered_psm, callbacks);
  }
  return registered_psm;
}

void bluetooth::shim::legacy::L2cap::UnregisterService(uint16_t psm) {
  if (!Classic().IsPsmRegistered(psm)) {
    LOG_WARN("Service must be registered in order to unregister psm:%hd", psm);
    return;
  }
  for (auto& entry : cid_to_psm_map_) {
    if (entry.second == psm) {
      LOG_WARN("  Unregistering service with active channels psm:%hd cid:%hd",
               psm, entry.first);
    }
  }

  LOG_INFO("Unregistering service on psm:%hd", psm);
  UnregisterServicePromise unregister_promise;
  auto service_unregistered = unregister_promise.get_future();
  bluetooth::shim::GetL2cap()->UnregisterClassicService(
      psm, std::move(unregister_promise));
  service_unregistered.wait();
  Classic().UnregisterPsm(psm);
}

uint16_t bluetooth::shim::legacy::L2cap::CreateConnection(
    uint16_t psm, const RawAddress& raw_address) {
  if (!Classic().IsPsmRegistered(psm)) {
    LOG_WARN("Service must be registered in order to connect psm:%hd", psm);
    return kInvalidConnectionInterfaceDescriptor;
  }

  CreateConnectionPromise create_promise;
  auto created = create_promise.get_future();
  LOG_INFO("Initiating local connection to psm:%hd address:%s", psm,
           raw_address.ToString().c_str());

  bluetooth::shim::GetL2cap()->CreateClassicConnection(
      psm, raw_address.ToString(),
      std::bind(
          &bluetooth::shim::legacy::L2cap::OnLocalInitiatedConnectionCreated,
          this, std::placeholders::_1, std::placeholders::_2,
          std::placeholders::_3, std::placeholders::_4, std::placeholders::_5),
      std::move(create_promise));

  uint16_t cid = created.get();
  if (cid == kInvalidConnectionInterfaceDescriptor) {
    LOG_WARN("Failed to initiate connection interface to psm:%hd address:%s",
             psm, raw_address.ToString().c_str());
  } else {
    LOG_INFO(
        "Successfully initiated connection to psm:%hd address:%s"
        " connection_interface_descriptor:%hd",
        psm, raw_address.ToString().c_str(), cid);
    CHECK(!ConnectionExists(cid));
    cid_to_psm_map_[cid] = psm;
  }
  return cid;
}

void bluetooth::shim::legacy::L2cap::OnLocalInitiatedConnectionCreated(
    std::string string_address, uint16_t psm, uint16_t cid, uint16_t remote_cid,
    bool connected) {
  cid_to_remote_cid_map_[cid] = remote_cid;
  if (cid_closing_set_.count(cid) == 0) {
    if (connected) {
      SetDownstreamCallbacks(cid);
    } else {
      LOG_WARN("Failed intitiating connection remote:%s psm:%hd cid:%hd",
               string_address.c_str(), psm, cid);
    }
    do_in_main_thread(
        FROM_HERE,
        base::Bind(classic_.Callbacks(psm).pL2CA_ConnectCfm_Cb, cid,
                   connected ? (kConnectionSuccess) : (kConnectionFail)));
    tL2CAP_CFG_INFO cfg_info{};
    do_in_main_thread(
        FROM_HERE,
        base::Bind(classic_.Callbacks(CidToPsm(cid)).pL2CA_ConfigCfm_Cb, cid,
                   L2CAP_INITIATOR_LOCAL, base::Unretained(&cfg_info)));

  } else {
    LOG_INFO("Connection Closed before presentation to upper layer");
    if (connected) {
      SetDownstreamCallbacks(cid);
      bluetooth::shim::GetL2cap()->CloseClassicConnection(cid);
    } else {
      LOG_INFO("Connection failed after initiator closed");
    }
  }
}

void bluetooth::shim::legacy::L2cap::OnRemoteInitiatedConnectionCreated(
    std::string string_address, uint16_t psm, uint16_t cid,
    uint16_t remote_cid) {
  RawAddress raw_address;
  RawAddress::FromString(string_address, raw_address);

  LOG_INFO(
      "Sending connection indicator to upper stack from device:%s "
      "psm:%hd cid:%hd",
      string_address.c_str(), psm, cid);

  CHECK(!ConnectionExists(cid));
  cid_to_psm_map_[cid] = psm;
  cid_to_remote_cid_map_[cid] = remote_cid;
  SetDownstreamCallbacks(cid);
  do_in_main_thread(
      FROM_HERE,
      base::Bind(classic_.Callbacks(CidToPsm(cid)).pL2CA_ConnectInd_Cb,
                 raw_address, cid, psm, kUnusedId));
  tL2CAP_CFG_INFO cfg_info{};
  do_in_main_thread(
      FROM_HERE,
      base::Bind(classic_.Callbacks(CidToPsm(cid)).pL2CA_ConfigCfm_Cb, cid,
                 L2CAP_INITIATOR_REMOTE, base::Unretained(&cfg_info)));
}

bool bluetooth::shim::legacy::L2cap::Write(uint16_t cid, BT_HDR* bt_hdr) {
  CHECK(bt_hdr != nullptr);
  const uint8_t* data = bt_hdr->data + bt_hdr->offset;
  size_t len = bt_hdr->len;
  if (!ConnectionExists(cid) || len == 0) {
    return false;
  }
  LOG_INFO("Writing data cid:%hd len:%zd", cid, len);
  bluetooth::shim::GetL2cap()->Write(cid, data, len);
  return true;
}

void bluetooth::shim::legacy::L2cap::SetDownstreamCallbacks(uint16_t cid) {
  bluetooth::shim::GetL2cap()->SetReadDataReadyCallback(
      cid, [this](uint16_t cid, std::vector<const uint8_t> data) {
        LOG_INFO("OnDataReady cid:%hd len:%zd", cid, data.size());
        BT_HDR* bt_hdr =
            static_cast<BT_HDR*>(osi_calloc(data.size() + kBtHdrSize));
        std::copy(data.begin(), data.end(), bt_hdr->data);
        bt_hdr->len = data.size();
        do_in_main_thread(
            FROM_HERE,
            base::Bind(classic_.Callbacks(CidToPsm(cid)).pL2CA_DataInd_Cb, cid,
                       base::Unretained(bt_hdr)));
      });

  bluetooth::shim::GetL2cap()->SetConnectionClosedCallback(
      cid, [this](uint16_t cid, int error_code) {
        LOG_INFO("OnChannel closed callback cid:%hd", cid);
        if (!ConnectionExists(cid)) {
          LOG_WARN("%s Unexpected channel closure cid:%hd", __func__, cid);
          return;
        }
        if (cid_closing_set_.count(cid) == 1) {
          cid_closing_set_.erase(cid);
        } else {
          do_in_main_thread(
              FROM_HERE,
              base::Bind(
                  classic_.Callbacks(CidToPsm(cid)).pL2CA_DisconnectInd_Cb, cid,
                  kDisconnectResponseRequired));
        }
        cid_to_psm_map_.erase(cid);
        cid_to_remote_cid_map_.erase(cid);
      });
}

bool bluetooth::shim::legacy::L2cap::DisconnectRequest(uint16_t cid) {
  CHECK(ConnectionExists(cid));
  if (cid_closing_set_.find(cid) != cid_closing_set_.end()) {
    LOG_WARN("%s Channel already in closing state cid:%hu", __func__, cid);
    return false;
  }
  LOG_INFO("%s initiated locally cid:%hu", __func__, cid);
  cid_closing_set_.insert(cid);
  bluetooth::shim::GetL2cap()->CloseClassicConnection(cid);
  return true;
}

void bluetooth::shim::legacy::L2cap::Dump(int fd) {
  if (cid_to_psm_map_.empty()) {
    dprintf(fd, "%s No active l2cap channels\n", kModuleName);
  } else {
    for (auto& connection : cid_to_psm_map_) {
      dprintf(fd, "%s active l2cap channel cid:%hd psm:%hd\n", kModuleName,
              connection.first, connection.second);
    }
  }
}

bool bluetooth::shim::legacy::L2cap::GetRemoteCid(uint16_t cid,
                                                  uint16_t* remote_cid) {
  auto it = cid_to_remote_cid_map_.find(cid);
  if (it == cid_to_remote_cid_map_.end()) {
    return false;
  }

  *remote_cid = it->second;
  return true;
}

system/main/shim/l2cap.h

deleted100644 → 0
+0 −121
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.
 */

#pragma once

#include <cstdint>
#include <set>
#include <unordered_map>

#include "main/shim/dumpsys.h"
#include "stack/include/l2c_api.h"

namespace bluetooth {
namespace shim {
namespace legacy {

static constexpr uint16_t kInitialClassicDynamicPsm = 0x1001;
static constexpr uint16_t kFinalClassicDynamicPsm = 0xfeff;
static constexpr uint16_t kInitialClassicVirtualPsm = kInitialClassicDynamicPsm;
static constexpr uint16_t kFinalClassicVirtualPsm = 0x8000;
static constexpr uint16_t kInitialLeDynamicPsm = 0x0080;
static constexpr uint16_t kFinalLeDynamicPsm = 0x00ff;

class PsmManager {
 public:
  bool IsPsmRegistered(uint16_t psm) const;
  bool HasClient(uint16_t psm) const;
  void RegisterPsm(uint16_t psm, const tL2CAP_APPL_INFO& callbacks);
  void UnregisterPsm(uint16_t psm);
  const tL2CAP_APPL_INFO Callbacks(uint16_t psm);

 private:
  /**
   * Mapping of psm to client callback.
   *
   * The current API allows a client may reserve a psm but not
   * provide a callback which is reflected in a mapping of a
   * valid psm key entry but a nullptr value.
   *
   * A valid client is indicated with a valid psm key entry and a
   * non-nullptr value.
   */
  std::unordered_map<uint16_t, const tL2CAP_APPL_INFO> psm_to_callback_map_;
};

class L2cap {
 public:
  uint16_t RegisterService(uint16_t psm, const tL2CAP_APPL_INFO& callbacks,
                           bool enable_snoop, tL2CAP_ERTM_INFO* p_ertm_info,
                           uint16_t my_mtu, uint16_t required_remote_mtu);
  void UnregisterService(uint16_t psm);

  uint16_t CreateConnection(uint16_t psm, const RawAddress& raw_address);

  bool Write(uint16_t cid, BT_HDR* bt_hdr);

  void OnLocalInitiatedConnectionCreated(std::string string_address,
                                         uint16_t psm, uint16_t cid,
                                         uint16_t remote_cid, bool connected);
  void OnRemoteInitiatedConnectionCreated(std::string string_addresss,
                                          uint16_t psm, uint16_t cid,
                                          uint16_t remote_cid);

  uint16_t GetNextDynamicLePsm();

  uint16_t ConvertClientToRealPsm(uint16_t psm,
                                  bool is_outgoing_only_connection);
  uint16_t ConvertClientToRealPsm(uint16_t psm);
  void RemoveClientPsm(uint16_t client_psm);

  bool DisconnectRequest(uint16_t cid);

  bool GetRemoteCid(uint16_t cid, uint16_t* remote_cid);

  L2cap();
  ~L2cap();

  PsmManager& Classic();
  PsmManager& Le();

 private:
  uint16_t GetNextVirtualPsm(uint16_t real_psm);
  void SetDownstreamCallbacks(uint16_t cid);

  void Dump(int fd);

  PsmManager classic_;
  PsmManager le_;

  bool ConnectionExists(uint16_t cid) const;
  uint16_t CidToPsm(uint16_t cid) const;

  uint16_t le_dynamic_psm_;
  uint16_t classic_virtual_psm_;

  std::unordered_map<uint16_t,
                     std::function<void(std::function<void(uint16_t c)>)>>
      cid_to_postable_map_;
  std::set<uint16_t> cid_closing_set_;

  std::unordered_map<uint16_t, uint16_t> cid_to_psm_map_;
  std::unordered_map<uint16_t, uint16_t> cid_to_remote_cid_map_;
  std::unordered_map<uint16_t, uint16_t> client_psm_to_real_psm_map_;
};

}  // namespace legacy
}  // namespace shim
}  // namespace bluetooth