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

Commit 1bfe4632 authored by Chris Manton's avatar Chris Manton
Browse files

gd: Repair and clean up rfcomm client/server tests

Bug: 144170448
Test: Run ctsverified for both client and server under Gd

Change-Id: Ia17eab4c4121fddf9bc9feb895d25566c765d17b
parent 7f40aab9
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ namespace shim {

using ConnectionClosedCallback = std::function<void(uint16_t cid, int error_code)>;
using ConnectionOpenCallback = std::function<void(std::string string_address, uint16_t psm, uint16_t cid)>;
using ConnectionFailedCallback = ConnectionOpenCallback;
using ReadDataReadyCallback = std::function<void(uint16_t cid, std::vector<const uint8_t> data)>;

struct IL2cap {
@@ -44,8 +45,6 @@ struct IL2cap {
  virtual void SetConnectionClosedCallback(uint16_t cid, ConnectionClosedCallback on_closed) = 0;

  virtual void Write(uint16_t cid, const uint8_t* data, size_t len) = 0;
  virtual void WriteFlushable(uint16_t cid, const uint8_t* data, size_t len) = 0;
  virtual void WriteNonFlushable(uint16_t cid, const uint8_t* data, size_t len) = 0;

  virtual void SendLoopbackResponse(std::function<void()>) = 0;
  virtual ~IL2cap() {}
+32 −54
Original line number Diff line number Diff line
@@ -138,6 +138,10 @@ class ConnectionInterface {
    on_connection_closed_callback_ = std::move(on_connection_closed);
  }

  hci::Address GetRemoteAddress() const {
    return address_;
  }

 private:
  const ConnectionInterfaceDescriptor cid_;
  const std::unique_ptr<l2cap::classic::DynamicChannel> channel_;
@@ -156,9 +160,7 @@ class ConnectionInterface {

struct ConnectionInterfaceManager {
 public:
  ConnectionInterfaceDescriptor AddChannel(std::unique_ptr<l2cap::classic::DynamicChannel> channel);
  ConnectionInterfaceDescriptor AddChannel(ConnectionInterfaceDescriptor cid,
                                           std::unique_ptr<l2cap::classic::DynamicChannel> channel);
  void AddConnection(ConnectionInterfaceDescriptor cid, std::unique_ptr<l2cap::classic::DynamicChannel> channel);
  void RemoveConnection(ConnectionInterfaceDescriptor cid);

  void SetReadDataReadyCallback(ConnectionInterfaceDescriptor cid, ReadDataReadyCallback on_data_ready);
@@ -170,26 +172,22 @@ struct ConnectionInterfaceManager {
    return cid_to_interface_map_.size();
  }

  void GeneralCallback(ConnectionOpenCallback on_open, hci::Address address, l2cap::Psm psm,
  void OnConnectionChanged(ConnectionOpenCallback on_open, hci::Address address, l2cap::Psm psm,
                           ConnectionInterfaceDescriptor cid) {
    on_open(address.ToString(), static_cast<uint16_t>(psm), static_cast<uint16_t>(cid));
  }

  void ConnectionOpened(ConnectionOpenCallback on_open, hci::Address address, l2cap::Psm psm,
                        ConnectionInterfaceDescriptor cid) {
    LOG_DEBUG("address:%s psm:%hd cid:%hd", address.ToString().c_str(), psm, cid);
    handler_->Post(common::BindOnce(&ConnectionInterfaceManager::GeneralCallback, common::Unretained(this), on_open,
  void ConnectionOpened(ConnectionOpenCallback on_open, l2cap::Psm psm, ConnectionInterfaceDescriptor cid) {
    hci::Address address = cid_to_interface_map_[cid]->GetRemoteAddress();
    LOG_DEBUG("Connection opened address:%s psm:%hd cid:%hd", address.ToString().c_str(), psm, cid);
    handler_->Post(common::BindOnce(&ConnectionInterfaceManager::OnConnectionChanged, common::Unretained(this), on_open,
                                    address, psm, cid));
    // TODO(cmanton) queue this pending connection address/psm tuple up for deletion
    // There may be multiple, so only remove one
  }

  void ConnectionFailed(ConnectionOpenCallback on_open, hci::Address address, l2cap::Psm psm) {
    LOG_DEBUG("Connection Failed");
    // TODO(cmanton) queue this pending connection address/psm tuple up for deletion
    // There may be multiple, so only remove one
    handler_->Post(common::BindOnce(&ConnectionInterfaceManager::GeneralCallback, common::Unretained(this), on_open,
                                    address, psm, kInvalidConnectionInterfaceDescriptor));
  void ConnectionFailed(ConnectionFailedCallback on_failed, hci::Address address, l2cap::Psm psm) {
    LOG_DEBUG("Connection failed address:%s psm:%hd", address.ToString().c_str(), psm);
    handler_->Post(common::BindOnce(&ConnectionInterfaceManager::OnConnectionChanged, common::Unretained(this),
                                    std::move(on_failed), address, psm, kInvalidConnectionInterfaceDescriptor));
  }

  ConnectionInterfaceManager(os::Handler* handler);
@@ -202,7 +200,7 @@ struct ConnectionInterfaceManager {
  ConnectionInterfaceDescriptor current_connection_interface_descriptor_;

  bool HasResources() const;
  bool ChannelExists(ConnectionInterfaceDescriptor id) const;
  bool ConnectionExists(ConnectionInterfaceDescriptor id) const;
  bool CidExists(ConnectionInterfaceDescriptor id) const;

  std::unordered_map<ConnectionInterfaceDescriptor, std::unique_ptr<ConnectionInterface>> cid_to_interface_map_;
@@ -214,7 +212,7 @@ struct ConnectionInterfaceManager {
ConnectionInterfaceManager::ConnectionInterfaceManager(os::Handler* handler)
    : handler_(handler), current_connection_interface_descriptor_(kStartConnectionInterfaceDescriptor) {}

bool ConnectionInterfaceManager::ChannelExists(ConnectionInterfaceDescriptor cid) const {
bool ConnectionInterfaceManager::ConnectionExists(ConnectionInterfaceDescriptor cid) const {
  return cid_to_interface_map_.find(cid) != cid_to_interface_map_.end();
}

@@ -222,11 +220,6 @@ bool ConnectionInterfaceManager::CidExists(ConnectionInterfaceDescriptor cid) co
  return active_cid_set_.find(cid) != active_cid_set_.end();
}

void ConnectionInterfaceManager::FreeConnectionInterfaceDescriptor(ConnectionInterfaceDescriptor cid) {
  ASSERT(CidExists(cid));
  active_cid_set_.erase(cid);
}

ConnectionInterfaceDescriptor ConnectionInterfaceManager::AllocateConnectionInterfaceDescriptor() {
  ASSERT(HasResources());
  while (CidExists(current_connection_interface_descriptor_)) {
@@ -238,20 +231,15 @@ ConnectionInterfaceDescriptor ConnectionInterfaceManager::AllocateConnectionInte
  return current_connection_interface_descriptor_++;
}

ConnectionInterfaceDescriptor ConnectionInterfaceManager::AddChannel(
    std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
  if (!HasResources()) {
    return kInvalidConnectionInterfaceDescriptor;
  }
  ConnectionInterfaceDescriptor cid = AllocateConnectionInterfaceDescriptor();
  return AddChannel(cid, std::move(channel));
void ConnectionInterfaceManager::FreeConnectionInterfaceDescriptor(ConnectionInterfaceDescriptor cid) {
  ASSERT(CidExists(cid));
  active_cid_set_.erase(cid);
}

ConnectionInterfaceDescriptor ConnectionInterfaceManager::AddChannel(
    ConnectionInterfaceDescriptor cid, std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
  auto channel_interface = std::make_unique<ConnectionInterface>(cid, std::move(channel), handler_);
  cid_to_interface_map_[cid] = std::move(channel_interface);
  return cid;
void ConnectionInterfaceManager::AddConnection(ConnectionInterfaceDescriptor cid,
                                               std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
  ASSERT(cid_to_interface_map_.count(cid) == 0);
  cid_to_interface_map_.emplace(cid, std::make_unique<ConnectionInterface>(cid, std::move(channel), handler_));
}

void ConnectionInterfaceManager::RemoveConnection(ConnectionInterfaceDescriptor cid) {
@@ -267,18 +255,18 @@ bool ConnectionInterfaceManager::HasResources() const {

void ConnectionInterfaceManager::SetReadDataReadyCallback(ConnectionInterfaceDescriptor cid,
                                                          ReadDataReadyCallback on_data_ready) {
  ASSERT(ChannelExists(cid));
  ASSERT(ConnectionExists(cid));
  return cid_to_interface_map_[cid]->SetReadDataReadyCallback(on_data_ready);
}

void ConnectionInterfaceManager::SetConnectionClosedCallback(ConnectionInterfaceDescriptor cid,
                                                             ConnectionClosedCallback on_closed) {
  ASSERT(ChannelExists(cid));
  ASSERT(ConnectionExists(cid));
  return cid_to_interface_map_[cid]->SetConnectionClosedCallback(on_closed);
}

bool ConnectionInterfaceManager::Write(ConnectionInterfaceDescriptor cid, std::unique_ptr<packet::RawBuilder> packet) {
  if (!ChannelExists(cid)) {
  if (!ConnectionExists(cid)) {
    return false;
  }
  cid_to_interface_map_[cid]->Write(std::move(packet));
@@ -295,8 +283,9 @@ class PendingConnection {

  void OnConnectionOpen(std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
    LOG_DEBUG("Local initiated connection is open to device:%s for psm:%hd", address_.ToString().c_str(), psm_);
    connection_interface_manager_->AddChannel(cid_, std::move(channel));
    connection_interface_manager_->ConnectionOpened(std::move(on_open_), address_, psm_, cid_);
    ASSERT_LOG(address_ == channel->GetDevice(), " Expected remote device does not match actual remote device");
    connection_interface_manager_->AddConnection(cid_, std::move(channel));
    connection_interface_manager_->ConnectionOpened(std::move(on_open_), psm_, cid_);
    deleter_();
  }

@@ -353,10 +342,9 @@ class ServiceInterface {
  void OnConnectionOpen(std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
    LOG_DEBUG("Remote initiated connection is open from device:%s for psm:%hd", channel->GetDevice().ToString().c_str(),
              psm_);
    hci::Address address = channel->GetDevice();
    ConnectionInterfaceDescriptor cid = connection_interface_manager_->AllocateConnectionInterfaceDescriptor();
    connection_interface_manager_->AddChannel(cid, std::move(channel));
    connection_interface_manager_->ConnectionOpened(on_open_, address, psm_, cid);
    connection_interface_manager_->AddConnection(cid, std::move(channel));
    connection_interface_manager_->ConnectionOpened(std::move(on_open_), psm_, cid);
  }

  l2cap::SecurityPolicy GetSecurityPolicy() const {
@@ -541,16 +529,6 @@ void L2cap::Write(uint16_t raw_cid, const uint8_t* data, size_t len) {
  GetHandler()->Post(common::BindOnce(&L2cap::impl::Write, common::Unretained(pimpl_.get()), cid, std::move(packet)));
}

void L2cap::WriteFlushable(uint16_t raw_cid, const uint8_t* data, size_t len) {
  LOG_WARN("UNIMPLEMENTED Write flushable");
  return Write(raw_cid, data, len);
}

void L2cap::WriteNonFlushable(uint16_t raw_cid, const uint8_t* data, size_t len) {
  LOG_WARN("UNIMPLEMENTED Write non flushable");
  return Write(raw_cid, data, len);
}

void L2cap::SendLoopbackResponse(std::function<void()> function) {
  GetHandler()->Post(common::BindOnce(&L2cap::impl::SendLoopbackResponse, common::Unretained(pimpl_.get()), function));
}
+0 −2
Original line number Diff line number Diff line
@@ -41,8 +41,6 @@ class L2cap : public bluetooth::Module, public bluetooth::shim::IL2cap {
  void SetConnectionClosedCallback(uint16_t cid, ConnectionClosedCallback on_closed) override;

  void Write(uint16_t cid, const uint8_t* data, size_t len) override;
  void WriteFlushable(uint16_t cid, const uint8_t* data, size_t len) override;
  void WriteNonFlushable(uint16_t cid, const uint8_t* data, size_t len) override;

  void SendLoopbackResponse(std::function<void()>) override;

+3 −7
Original line number Diff line number Diff line
@@ -113,19 +113,15 @@ bool bluetooth::shim::L2CA_ErtmConnectRsp(const RawAddress& p_bd_addr,
                                          uint8_t id, uint16_t lcid,
                                          uint16_t result, uint16_t status,
                                          tL2CAP_ERTM_INFO* p_ertm_info) {
  LOG_INFO(LOG_TAG,
           "UNIMPLEMENTED %s addr:%s id:%hhd lcid:%hd result:%hd status:%hd "
           "p_ertm_info:%p",
           __func__, p_bd_addr.ToString().c_str(), id, lcid, result, status,
  return shim_l2cap.ConnectResponse(p_bd_addr, id, lcid, result, status,
                                    p_ertm_info);
  return false;
}

bool bluetooth::shim::L2CA_ConnectRsp(const RawAddress& p_bd_addr, uint8_t id,
                                      uint16_t lcid, uint16_t result,
                                      uint16_t status) {
  return bluetooth::shim::L2CA_ErtmConnectRsp(p_bd_addr, id, lcid, result,
                                              status, NULL);
                                              status, nullptr);
}

bool bluetooth::shim::L2CA_ConfigReq(uint16_t cid, tL2CAP_CFG_INFO* cfg_info) {
+36 −23
Original line number Diff line number Diff line
@@ -31,30 +31,30 @@ constexpr uint16_t kInvalidConnectionInterfaceDescriptor = 0;
constexpr uint8_t kUnusedId = 0;
constexpr uint16_t kUnusedResult = 0;

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

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

void bluetooth::legacy::shim::PsmData::RegisterPsm(
void bluetooth::legacy::shim::PsmManager::RegisterPsm(
    uint16_t psm, const tL2CAP_APPL_INFO* callbacks) {
  CHECK(!HasClient(psm));
  psm_to_callback_map_[psm] = callbacks;
}

void bluetooth::legacy::shim::PsmData::RegisterPsm(uint16_t psm) {
void bluetooth::legacy::shim::PsmManager::RegisterPsm(uint16_t psm) {
  RegisterPsm(psm, nullptr);
}

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

const tL2CAP_APPL_INFO* bluetooth::legacy::shim::PsmData::Callbacks(
const tL2CAP_APPL_INFO* bluetooth::legacy::shim::PsmManager::Callbacks(
    uint16_t psm) {
  CHECK(HasClient(psm));
  return psm_to_callback_map_[psm];
@@ -65,11 +65,11 @@ bluetooth::legacy::shim::L2cap::L2cap()
      le_dynamic_psm_(kInitialLeDynamicPsm),
      classic_virtual_psm_(kInitialClassicVirtualPsm) {}

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

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

@@ -77,6 +77,11 @@ bool bluetooth::legacy::shim::L2cap::ConnectionExists(uint16_t cid) const {
  return cid_to_psm_map_.find(cid) != cid_to_psm_map_.end();
}

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

uint16_t bluetooth::legacy::shim::L2cap::ConvertClientToRealPsm(
    uint16_t client_psm, bool is_outgoing_only_connection) {
  if (!is_outgoing_only_connection) {
@@ -196,8 +201,15 @@ void bluetooth::legacy::shim::L2cap::UnregisterService(uint16_t psm) {
             "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(LOG_TAG,
               "  Unregistering service with active channels psm:%hd cid:%hd",
               psm, entry.first);
    }
  }

  LOG_DEBUG(LOG_TAG, "Unregistering service on psm:%hd", psm);
  // TODO(cmanton) Check for open channels before unregistering
  bluetooth::shim::GetL2cap()->UnregisterService(psm);
  Classic().UnregisterPsm(psm);
}
@@ -235,7 +247,6 @@ uint16_t bluetooth::legacy::shim::L2cap::CreateConnection(
              " connection_interface_descriptor:%hd",
              psm, raw_address.ToString().c_str(), cid);
    CHECK(!ConnectionExists(cid));
    cid_to_callback_map_[cid] = Classic().Callbacks(psm);
    cid_to_psm_map_[cid] = psm;
  }
  return cid;
@@ -275,29 +286,26 @@ void bluetooth::legacy::shim::L2cap::SetDownstreamCallbacks(uint16_t cid) {
            static_cast<BT_HDR*>(osi_calloc(data.size() + kBtHdrSize));
        std::copy(data.begin(), data.end(), bt_hdr->data);
        bt_hdr->len = data.size();
        CHECK(cid_to_callback_map_.find(cid) != cid_to_callback_map_.end());
        cid_to_callback_map_[cid]->pL2CA_DataInd_Cb(cid, bt_hdr);
        classic_.Callbacks(CidToPsm(cid))->pL2CA_DataInd_Cb(cid, bt_hdr);
      });

  bluetooth::shim::GetL2cap()->SetConnectionClosedCallback(
      cid, [this](uint16_t cid, int error_code) {
        LOG_DEBUG(LOG_TAG, "OnChannel closed callback cid:%hd", cid);
        if (cid_to_callback_map_.find(cid) == cid_to_callback_map_.end()) {
        if (!ConnectionExists(cid)) {
          LOG_WARN(LOG_TAG, "%s Unexpected channel closure cid:%hd", __func__,
                   cid);
          return;
        }
        CHECK(cid_to_psm_map_.find(cid) != cid_to_psm_map_.end());
        cid_to_psm_map_.erase(cid);

        if (cid_closing_set_.count(cid) == 1) {
          cid_closing_set_.erase(cid);
          cid_to_callback_map_[cid]->pL2CA_DisconnectCfm_Cb(cid, kUnusedResult);
          classic_.Callbacks(CidToPsm(cid))
              ->pL2CA_DisconnectCfm_Cb(cid, kUnusedResult);
        } else {
          cid_to_callback_map_[cid]->pL2CA_DisconnectInd_Cb(
              cid, kDisconnectResponseRequired);
          classic_.Callbacks(CidToPsm(cid))
              ->pL2CA_DisconnectInd_Cb(cid, kDisconnectResponseRequired);
        }
        cid_to_callback_map_.erase(cid);
        cid_to_psm_map_.erase(cid);
      });
}

@@ -314,8 +322,8 @@ bool bluetooth::legacy::shim::L2cap::ConnectResponse(

bool bluetooth::legacy::shim::L2cap::ConfigRequest(
    uint16_t cid, const tL2CAP_CFG_INFO* config_info) {
  CHECK(ConnectionExists(cid));
  LOG_INFO(LOG_TAG, "Received config request from upper layer cid:%hd", cid);
  CHECK(ConnectionExists(cid));

  bluetooth::shim::GetL2cap()->SendLoopbackResponse([this, cid]() {
    CHECK(ConnectionExists(cid));
@@ -329,8 +337,8 @@ bool bluetooth::legacy::shim::L2cap::ConfigRequest(
        .ext_flow_spec_present = false,
        .flags = 0,
    };
    cid_to_callback_map_[cid]->pL2CA_ConfigCfm_Cb(cid, &cfg_info);
    cid_to_callback_map_[cid]->pL2CA_ConfigInd_Cb(cid, &cfg_info);
    classic_.Callbacks(CidToPsm(cid))->pL2CA_ConfigCfm_Cb(cid, &cfg_info);
    classic_.Callbacks(CidToPsm(cid))->pL2CA_ConfigInd_Cb(cid, &cfg_info);
  });
  return true;
}
@@ -347,6 +355,11 @@ bool bluetooth::legacy::shim::L2cap::ConfigResponse(

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