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

Commit a28dd57f authored by Chris Manton's avatar Chris Manton
Browse files

gd shim layer changes

Bug: 144171652
Test: bluetooth_test_gd

Change-Id: If56602e1a90d692435b4366b98c959cc4a13e09f
parent 610f7012
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -34,7 +34,10 @@ using ReadDataReadyCallback = std::function<void(uint16_t cid, std::vector<const

struct IL2cap {
  virtual void RegisterService(uint16_t psm, ConnectionOpenCallback on_open, std::promise<void> completed) = 0;
  virtual void UnregisterService(uint16_t psm) = 0;

  virtual void CreateConnection(uint16_t psm, const std::string address, std::promise<uint16_t> completed) = 0;
  virtual void CloseConnection(uint16_t cid) = 0;

  virtual void SetReadDataReadyCallback(uint16_t cid, ReadDataReadyCallback on_data_ready) = 0;
  virtual void SetConnectionClosedCallback(uint16_t cid, ConnectionClosedCallback on_closed) = 0;
+192 −113
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <functional>
#include <future>
#include <memory>
#include <mutex>
#include <queue>
#include <unordered_map>
#include <vector>
@@ -47,6 +48,11 @@ static const ConnectionInterfaceDescriptor kInvalidConnectionInterfaceDescriptor
static const ConnectionInterfaceDescriptor kStartConnectionInterfaceDescriptor = 64;
static const ConnectionInterfaceDescriptor kMaxConnections = UINT16_MAX - kStartConnectionInterfaceDescriptor - 1;

using ServiceInterfaceCallback =
    std::function<void(l2cap::Psm psm, l2cap::classic::DynamicChannelManager::RegistrationResult result)>;
using ConnectionInterfaceCallback =
    std::function<void(l2cap::Psm psm, std::unique_ptr<l2cap::classic::DynamicChannel>)>;

std::unique_ptr<packet::RawBuilder> MakeUniquePacket(const uint8_t* data, size_t len) {
  packet::RawBuilder builder;
  std::vector<uint8_t> bytes(data, data + len);
@@ -60,7 +66,7 @@ class ConnectionInterface {
  ConnectionInterface(ConnectionInterfaceDescriptor cid, std::unique_ptr<l2cap::classic::DynamicChannel> channel,
                      os::Handler* handler)
      : cid_(cid), channel_(std::move(channel)), handler_(handler), on_data_ready_callback_(nullptr),
        on_connection_closed_callback_(nullptr) {
        on_connection_closed_callback_(nullptr), address_(channel_->GetDevice()) {
    channel_->RegisterOnCloseCallback(
        handler_, common::BindOnce(&ConnectionInterface::OnConnectionClosed, common::Unretained(this)));
    channel_->GetQueueUpEnd()->RegisterDequeue(
@@ -69,10 +75,7 @@ class ConnectionInterface {
  }

  ~ConnectionInterface() {
    if (dequeue_registered_) {
      channel_->GetQueueUpEnd()->UnregisterDequeue();
      dequeue_registered_ = false;
    }
    ASSERT(!dequeue_registered_);
  }

  void OnReadReady() {
@@ -86,11 +89,10 @@ class ConnectionInterface {
    on_data_ready_callback_(cid_, data);
  }

  void OnConnectionClosed(hci::ErrorCode error_code) {
    LOG_DEBUG("Channel interface closed reason:%s cid:%hd device:%s", hci::ErrorCodeText(error_code).c_str(), cid_,
              channel_->GetDevice().ToString().c_str());
    ASSERT(on_connection_closed_callback_ != nullptr);
    on_connection_closed_callback_(cid_, static_cast<int>(error_code));
  void SetReadDataReadyCallback(ReadDataReadyCallback on_data_ready) {
    ASSERT(on_data_ready != nullptr);
    ASSERT(on_data_ready_callback_ == nullptr);
    on_data_ready_callback_ = on_data_ready;
  }

  std::unique_ptr<packet::BasePacketBuilder> WriteReady() {
@@ -103,17 +105,8 @@ class ConnectionInterface {
    return data;
  }

  void SetReadDataReadyCallback(ReadDataReadyCallback on_data_ready) {
    ASSERT(on_data_ready_callback_ == nullptr);
    on_data_ready_callback_ = on_data_ready;
  }

  void SetConnectionClosedCallback(::bluetooth::shim::ConnectionClosedCallback on_connection_closed) {
    ASSERT(on_connection_closed_callback_ == nullptr);
    on_connection_closed_callback_ = on_connection_closed;
  }

  void Write(std::unique_ptr<packet::RawBuilder> packet) {
    LOG_DEBUG("Writing packet cid:%hd size:%zd", cid_, packet->size());
    write_queue_.push(std::move(packet));
    if (!enqueue_registered_) {
      enqueue_registered_ = true;
@@ -123,18 +116,36 @@ class ConnectionInterface {
  }

  void Close() {
    ASSERT(write_queue_.empty());
    if (dequeue_registered_) {
      channel_->GetQueueUpEnd()->UnregisterDequeue();
      dequeue_registered_ = false;
    }
    ASSERT(write_queue_.empty());
    channel_->Close();
  }

  void OnConnectionClosed(hci::ErrorCode error_code) {
    LOG_DEBUG("Channel interface closed reason:%s cid:%hd device:%s", hci::ErrorCodeText(error_code).c_str(), cid_,
              address_.ToString().c_str());
    ASSERT(on_connection_closed_callback_ != nullptr);
    on_connection_closed_callback_(cid_, static_cast<int>(error_code));
  }

  void SetConnectionClosedCallback(::bluetooth::shim::ConnectionClosedCallback on_connection_closed) {
    ASSERT(on_connection_closed != nullptr);
    ASSERT(on_connection_closed_callback_ == nullptr);
    on_connection_closed_callback_ = std::move(on_connection_closed);
  }

 private:
  ConnectionInterfaceDescriptor cid_;
  std::unique_ptr<l2cap::classic::DynamicChannel> channel_;
  const ConnectionInterfaceDescriptor cid_;
  const std::unique_ptr<l2cap::classic::DynamicChannel> channel_;
  os::Handler* handler_;

  ReadDataReadyCallback on_data_ready_callback_;
  ::bluetooth::shim::ConnectionClosedCallback on_connection_closed_callback_;
  ConnectionClosedCallback on_connection_closed_callback_;

  const hci::Address address_;

  std::queue<std::unique_ptr<packet::PacketBuilder<hci::kLittleEndian>>> write_queue_;

@@ -152,7 +163,6 @@ struct ConnectionInterfaceManager {

  bool Write(ConnectionInterfaceDescriptor cid, std::unique_ptr<packet::RawBuilder> packet);

  bool HasResources() const;
  void SetHandler(os::Handler* handler) {
    handler_ = handler;
  }
@@ -168,38 +178,50 @@ struct ConnectionInterfaceManager {
  ConnectionInterfaceDescriptor current_connection_interface_descriptor_;
  os::Handler* handler_;

  bool HasResources() const;
  bool Exists(ConnectionInterfaceDescriptor id) const;
  ConnectionInterfaceDescriptor AllocateConnectionInterfaceDescriptor();
};

ConnectionInterfaceManager::ConnectionInterfaceManager()
    : current_connection_interface_descriptor_(kStartConnectionInterfaceDescriptor) {}

ConnectionInterfaceDescriptor ConnectionInterfaceManager::AddChannel(
    std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
bool ConnectionInterfaceManager::Exists(ConnectionInterfaceDescriptor cid) const {
  return cid_to_interface_map_.find(cid) != cid_to_interface_map_.end();
}

ConnectionInterfaceDescriptor ConnectionInterfaceManager::AllocateConnectionInterfaceDescriptor() {
  ASSERT(HasResources());
  while (Exists(current_connection_interface_descriptor_)) {
    if (++current_connection_interface_descriptor_ == kInvalidConnectionInterfaceDescriptor) {
      current_connection_interface_descriptor_ = kStartConnectionInterfaceDescriptor;
    }
  }
  auto channel_interface =
      std::make_unique<ConnectionInterface>(current_connection_interface_descriptor_, std::move(channel), handler_);
  cid_to_interface_map_[current_connection_interface_descriptor_] = std::move(channel_interface);
  return current_connection_interface_descriptor_;
  return current_connection_interface_descriptor_++;
}

ConnectionInterfaceDescriptor ConnectionInterfaceManager::AddChannel(
    std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
  if (!HasResources()) {
    return kInvalidConnectionInterfaceDescriptor;
  }
  ConnectionInterfaceDescriptor cid = AllocateConnectionInterfaceDescriptor();

  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::RemoveConnection(ConnectionInterfaceDescriptor cid) {
  ASSERT(cid_to_interface_map_.erase(cid) == 1);
  ASSERT(cid_to_interface_map_.count(cid) == 1);
  cid_to_interface_map_.find(cid)->second->Close();
  cid_to_interface_map_.erase(cid);
}

bool ConnectionInterfaceManager::HasResources() const {
  return cid_to_interface_map_.size() < kMaxConnections;
}

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

void ConnectionInterfaceManager::SetReadDataReadyCallback(ConnectionInterfaceDescriptor cid,
                                                          ReadDataReadyCallback on_data_ready) {
  ASSERT(Exists(cid));
@@ -220,59 +242,75 @@ bool ConnectionInterfaceManager::Write(ConnectionInterfaceDescriptor cid, std::u
  return true;
}

struct ServiceManager {
class ServiceInterface {
 public:
  void AddService(l2cap::Psm psm, std::unique_ptr<l2cap::classic::DynamicChannelService> service);
  void RemoveService(l2cap::Psm psm);

  ServiceManager() = default;
  ServiceInterface(uint16_t psm, ServiceInterfaceCallback register_callback,
                   ConnectionInterfaceCallback connection_callback)
      : psm_(psm), register_callback_(register_callback), connection_callback_(connection_callback) {}

 private:
  std::unordered_map<l2cap::Psm, std::unique_ptr<l2cap::classic::DynamicChannelService>> psm_to_service_map_;

  bool Exists(l2cap::Psm psm) const;
};
  void OnRegistrationComplete(l2cap::classic::DynamicChannelManager::RegistrationResult result,
                              std::unique_ptr<l2cap::classic::DynamicChannelService> service) {
    ASSERT(service_ == nullptr);
    ASSERT(psm_ == service->GetPsm());
    LOG_DEBUG("Registration is complete for psm:%hd", psm_);
    service_ = std::move(service);
    register_callback_(psm_, result);
  }

void ServiceManager::AddService(l2cap::Psm psm, std::unique_ptr<l2cap::classic::DynamicChannelService> service) {
  ASSERT(psm_to_service_map_.find(psm) == psm_to_service_map_.end());
  psm_to_service_map_[psm] = std::move(service);
  void OnConnectionOpen(std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
    LOG_DEBUG("Connection is open to device:%s for psm:%hd", channel->GetDevice().ToString().c_str(), psm_);
    connection_callback_(psm_, std::move(channel));
  }

void ServiceManager::RemoveService(l2cap::Psm psm) {
  ASSERT(psm_to_service_map_.erase(psm) == 1);
  l2cap::SecurityPolicy GetSecurityPolicy() const {
    return security_policy_;
  }

bool ServiceManager::Exists(l2cap::Psm psm) const {
  return psm_to_service_map_.find(psm) != psm_to_service_map_.end();
  void RegisterService(
      std::function<void(l2cap::Psm, l2cap::SecurityPolicy security_policy,
                         l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete,
                         l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_connection_open)>
          func) {
    func(psm_, security_policy_, common::BindOnce(&ServiceInterface::OnRegistrationComplete, common::Unretained(this)),
         common::Bind(&ServiceInterface::OnConnectionOpen, common::Unretained(this)));
  }

 private:
  const l2cap::Psm psm_;
  std::unique_ptr<l2cap::classic::DynamicChannelService> service_;
  const l2cap::SecurityPolicy security_policy_;
  ServiceInterfaceCallback register_callback_;
  ConnectionInterfaceCallback connection_callback_;
};

struct L2cap::impl {
  void RegisterService(l2cap::Psm psm, ConnectionOpenCallback on_open, std::promise<void> completed);
  void UnregisterService(l2cap::Psm psm);

  void CreateConnection(l2cap::Psm psm, hci::Address address, std::promise<uint16_t> completed);
  void CloseConnection(ConnectionInterfaceDescriptor cid);

  void OnRegistrationComplete(l2cap::classic::DynamicChannelManager::RegistrationResult result,
                              std::unique_ptr<l2cap::classic::DynamicChannelService> service);
  void OnConnectionOpen(std::unique_ptr<l2cap::classic::DynamicChannel> channel);
  void OnConnectionFailure(l2cap::classic::DynamicChannelManager::ConnectionResult result);
  void OnConnectionOpenNever(std::unique_ptr<l2cap::classic::DynamicChannel> channel);
  void OnConnectionFailureNever(l2cap::classic::DynamicChannelManager::ConnectionResult result);

  bool Write(ConnectionInterfaceDescriptor cid, std::unique_ptr<packet::RawBuilder> packet);

  impl(L2cap& module, l2cap::classic::L2capClassicModule* l2cap_module);
  ConnectionInterfaceManager connection_interface_manager_;
  ServiceManager service_manager_;

 private:
  void SyncConnectionOpen(ConnectionInterfaceDescriptor cid);
  void OpenConnection(l2cap::Psm psm, ConnectionInterfaceDescriptor cid);

 private:
  L2cap& module_;
  l2cap::classic::L2capClassicModule* l2cap_module_{nullptr};

  std::unordered_map<l2cap::Psm, ConnectionOpenCallback> psm_to_connection_open_map_;

  std::unique_ptr<l2cap::classic::DynamicChannelManager> dynamic_channel_manager_;

  std::queue<std::promise<void>> register_completed_queue_;
  std::queue<std::promise<uint16_t>> connect_completed_queue_;
  std::unordered_map<l2cap::Psm, std::shared_ptr<ServiceInterface>> psm_to_service_interface_map_;
  std::unordered_map<l2cap::Psm, ConnectionOpenCallback> psm_to_on_open_map_;

  std::mutex mutex_;
  std::unordered_map<l2cap::Psm, std::promise<void>> psm_to_register_complete_map_;
  std::unordered_map<l2cap::Psm, std::queue<std::promise<uint16_t>>> psm_to_connect_completed_queue_;

  os::Handler* handler_;
};
@@ -284,40 +322,12 @@ L2cap::impl::impl(L2cap& module, l2cap::classic::L2capClassicModule* l2cap_modul
  connection_interface_manager_.SetHandler(handler_);
}

void L2cap::impl::OnRegistrationComplete(l2cap::classic::DynamicChannelManager::RegistrationResult result,
                                         std::unique_ptr<l2cap::classic::DynamicChannelService> service) {
  LOG_DEBUG("Registration is complete");
  ASSERT(!register_completed_queue_.empty());
  auto completed = std::move(register_completed_queue_.front());
  register_completed_queue_.pop();
  completed.set_value();

  service_manager_.AddService(service->GetPsm(), std::move(service));
}

void L2cap::impl::SyncConnectionOpen(ConnectionInterfaceDescriptor cid) {
  ASSERT(!connect_completed_queue_.empty());
  auto completed = std::move(connect_completed_queue_.front());
  connect_completed_queue_.pop();
  completed.set_value(cid);
void L2cap::impl::OnConnectionOpenNever(std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
  ASSERT(false);
}

void L2cap::impl::OnConnectionOpen(std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
  LOG_DEBUG("Connection is open to connect_queue_size:%zd device:%s", connect_completed_queue_.size(),
            channel->GetDevice().ToString().c_str());

  ConnectionInterfaceDescriptor cid = kInvalidConnectionInterfaceDescriptor;
  if (connection_interface_manager_.HasResources()) {
    cid = connection_interface_manager_.AddChannel(std::move(channel));
  }
  if (!connect_completed_queue_.empty()) {
    SyncConnectionOpen(cid);
  }
  // TODO(cmanton) Inform legacy psm service that a new connection is
  // available
}

void L2cap::impl::OnConnectionFailure(l2cap::classic::DynamicChannelManager::ConnectionResult result) {
void L2cap::impl::OnConnectionFailureNever(l2cap::classic::DynamicChannelManager::ConnectionResult result) {
  ASSERT(false);
  switch (result.connection_result_code) {
    case l2cap::classic::DynamicChannelManager::ConnectionResultCode::SUCCESS:
      LOG_WARN("Connection failed result:success hci:%s", hci::ErrorCodeText(result.hci_error).c_str());
@@ -333,32 +343,91 @@ void L2cap::impl::OnConnectionFailure(l2cap::classic::DynamicChannelManager::Con
                l2cap::ConnectionResponseResultText(result.l2cap_connection_response_result).c_str());
      break;
  }
  auto completed = std::move(connect_completed_queue_.front());
  connect_completed_queue_.pop();
  completed.set_value(kInvalidConnectionInterfaceDescriptor);
}

void L2cap::impl::RegisterService(l2cap::Psm psm, ConnectionOpenCallback on_open, std::promise<void> completed) {
  l2cap::SecurityPolicy security_policy;
  register_completed_queue_.push(std::move(completed));
void L2cap::impl::OpenConnection(l2cap::Psm psm, ConnectionInterfaceDescriptor cid) {
  LOG_INFO("About to call back to client indicating open connection psm:%hd cid:%hd", psm, cid);
  psm_to_on_open_map_[psm](psm, cid, [cid](std::function<void(uint16_t cid)> func) {
    LOG_DEBUG("About to run postable on this thread and inform sdp that connection is open");
    func(cid);
  });
}

  psm_to_connection_open_map_[psm] = std::move(on_open);
void L2cap::impl::RegisterService(l2cap::Psm psm, ConnectionOpenCallback on_open, std::promise<void> completed) {
  ASSERT(psm_to_service_interface_map_.find(psm) == psm_to_service_interface_map_.end());
  ASSERT(psm_to_register_complete_map_.find(psm) == psm_to_register_complete_map_.end());
  ASSERT(psm_to_on_open_map_.find(psm) == psm_to_on_open_map_.end());

  psm_to_on_open_map_[psm] = on_open;

  psm_to_service_interface_map_.emplace(
      psm, std::make_shared<ServiceInterface>(
               psm,
               [this](l2cap::Psm psm, l2cap::classic::DynamicChannelManager::RegistrationResult result) {
                 LOG_DEBUG("Service has been registered");
                 ASSERT(psm_to_register_complete_map_.find(psm) != psm_to_register_complete_map_.end());
                 {
                   std::unique_lock<std::mutex> lock(mutex_);
                   auto completed = std::move(psm_to_register_complete_map_[psm]);
                   psm_to_register_complete_map_.erase(psm);
                   completed.set_value();
                 }
               },

               [this](l2cap::Psm psm, std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
                 ConnectionInterfaceDescriptor cid = connection_interface_manager_.AddChannel(std::move(channel));
                 LOG_DEBUG("Connection has been opened cid:%hd psm:%hd", cid, psm);
                 {
                   // If initiated locally unblock requestor that
                   // we now have a connection by providing the
                   // cid.
                   std::unique_lock<std::mutex> lock(mutex_);
                   if (psm_to_connect_completed_queue_.find(psm) != psm_to_connect_completed_queue_.end()) {
                     if (!psm_to_connect_completed_queue_[psm].empty()) {
                       LOG_DEBUG("Locally initiated, so inform waiting client of the cid %hd", cid);
                       auto completed = std::move(psm_to_connect_completed_queue_[psm].front());
                       psm_to_connect_completed_queue_[psm].pop();
                       completed.set_value(cid);
                     }
                   }
                   std::this_thread::yield();
                 }
                 if (cid != kInvalidConnectionInterfaceDescriptor) {
                   handler_->Post(common::BindOnce(&L2cap::impl::OpenConnection, common::Unretained(this), psm, cid));
                 }
                 usleep(10);
               }));

  bool rc = dynamic_channel_manager_->RegisterService(
      psm, security_policy, common::BindOnce(&L2cap::impl::OnRegistrationComplete, common::Unretained(this)),
      common::Bind(&L2cap::impl::OnConnectionOpen, common::Unretained(this)), handler_);
  psm_to_service_interface_map_.find(psm)->second->RegisterService(
      [this](l2cap::Psm psm, l2cap::SecurityPolicy security_policy,
             l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete,
             l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_connection_open) {
        bool rc = dynamic_channel_manager_->RegisterService(psm, security_policy, std::move(on_registration_complete),
                                                            on_connection_open, handler_);
        ASSERT_LOG(rc == true, "Failed to register classic service");
      });
}

void L2cap::impl::UnregisterService(l2cap::Psm psm) {
  psm_to_service_interface_map_.erase(psm);
}

void L2cap::impl::CreateConnection(l2cap::Psm psm, hci::Address address, std::promise<uint16_t> completed) {
  LOG_INFO("Creating connection to psm:%hd device:%s", psm, address.ToString().c_str());
  connect_completed_queue_.push(std::move(completed));
  {
    std::unique_lock<std::mutex> lock(mutex_);
    psm_to_connect_completed_queue_[psm].push(std::move(completed));
  }
  bool rc = dynamic_channel_manager_->ConnectChannel(
      address, psm, common::Bind(&L2cap::impl::OnConnectionOpen, common::Unretained(this)),
      common::Bind(&L2cap::impl::OnConnectionFailure, common::Unretained(this)), handler_);
      address, psm, common::Bind(&L2cap::impl::OnConnectionOpenNever, common::Unretained(this)),
      common::Bind(&L2cap::impl::OnConnectionFailureNever, common::Unretained(this)), handler_);
  ASSERT_LOG(rc == true, "Failed to create classic connection channel");
}

void L2cap::impl::CloseConnection(ConnectionInterfaceDescriptor cid) {
  connection_interface_manager_.RemoveConnection(cid);
}

bool L2cap::impl::Write(ConnectionInterfaceDescriptor cid, std::unique_ptr<packet::RawBuilder> packet) {
  return connection_interface_manager_.Write(cid, std::move(packet));
}
@@ -368,6 +437,11 @@ void L2cap::RegisterService(uint16_t raw_psm, ConnectionOpenCallback on_open, st
  pimpl_->RegisterService(psm, on_open, std::move(completed));
}

void L2cap::UnregisterService(uint16_t raw_psm) {
  l2cap::Psm psm{raw_psm};
  pimpl_->UnregisterService(psm);
}

void L2cap::CreateConnection(uint16_t raw_psm, const std::string address_string, std::promise<uint16_t> completed) {
  l2cap::Psm psm{raw_psm};
  hci::Address address;
@@ -376,6 +450,11 @@ void L2cap::CreateConnection(uint16_t raw_psm, const std::string address_string,
  return pimpl_->CreateConnection(psm, address, std::move(completed));
}

void L2cap::CloseConnection(uint16_t raw_cid) {
  ConnectionInterfaceDescriptor cid(raw_cid);
  return pimpl_->CloseConnection(cid);
}

void L2cap::SetReadDataReadyCallback(uint16_t cid, ReadDataReadyCallback on_data_ready) {
  pimpl_->connection_interface_manager_.SetReadDataReadyCallback(static_cast<ConnectionInterfaceDescriptor>(cid),
                                                                 on_data_ready);
+3 −0
Original line number Diff line number Diff line
@@ -30,7 +30,10 @@ namespace shim {
class L2cap : public bluetooth::Module, public bluetooth::shim::IL2cap {
 public:
  void RegisterService(uint16_t psm, ConnectionOpenCallback on_open, std::promise<void> completed) override;
  void UnregisterService(uint16_t psm) override;

  void CreateConnection(uint16_t psm, const std::string address, std::promise<uint16_t> completed) override;
  void CloseConnection(uint16_t cid) override;

  void SetReadDataReadyCallback(uint16_t cid, ReadDataReadyCallback on_data_ready) override;
  void SetConnectionClosedCallback(uint16_t cid, ConnectionClosedCallback on_closed) override;
+4 −0
Original line number Diff line number Diff line
@@ -34,11 +34,15 @@ void TestGdShimL2cap::RegisterService(
  completed.set_value();
}

void TestGdShimL2cap::UnregisterService(uint16_t psm) {}

void TestGdShimL2cap::CreateConnection(uint16_t psm, const std::string address,
                                       std::promise<uint16_t> completed) {
  completed.set_value(cid_);
}

void TestGdShimL2cap::CloseConnection(uint16_t cid) {}

void TestGdShimL2cap::SetReadDataReadyCallback(
    uint16_t cid, bluetooth::shim::ReadDataReadyCallback on_data_ready) {}

+2 −0
Original line number Diff line number Diff line
@@ -30,8 +30,10 @@ class TestGdShimL2cap : public bluetooth::shim::IL2cap {
  void RegisterService(uint16_t psm,
                       bluetooth::shim::ConnectionOpenCallback on_open,
                       std::promise<void> completed) override;
  void UnregisterService(uint16_t psm);
  void CreateConnection(uint16_t psm, const std::string address,
                        std::promise<uint16_t> completed) override;
  void CloseConnection(uint16_t cid);
  void SetReadDataReadyCallback(
      uint16_t cid,
      bluetooth::shim::ReadDataReadyCallback on_data_ready) override;