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

Commit 343df5dd authored by Chris Manton's avatar Chris Manton Committed by android-build-merger
Browse files

Merge "gd: Fix for l2cap connection on failure"

am: 5de25082

Change-Id: I6914a456964dbd0ffc73d57d7901951bd332d33b
parents 0d0816d3 5de25082
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -28,17 +28,17 @@ namespace bluetooth {
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 ConnectionCompleteCallback =
    std::function<void(std::string string_address, uint16_t psm, uint16_t cid, bool connected)>;
using ReadDataReadyCallback = std::function<void(uint16_t cid, std::vector<const uint8_t> data)>;

struct IL2cap {
  virtual void RegisterService(uint16_t psm, bool use_ertm, uint16_t mtu, ConnectionOpenCallback on_open,
                               std::promise<void> completed) = 0;
  virtual void RegisterService(uint16_t psm, bool use_ertm, uint16_t mtu, ConnectionCompleteCallback on_complete,
                               std::promise<void> registered) = 0;
  virtual void UnregisterService(uint16_t psm) = 0;

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

  virtual void SetReadDataReadyCallback(uint16_t cid, ReadDataReadyCallback on_data_ready) = 0;
+45 −37
Original line number Diff line number Diff line
@@ -52,6 +52,10 @@ constexpr char kModuleName[] = "shim::L2cap";
constexpr ConnectionInterfaceDescriptor kInvalidConnectionInterfaceDescriptor = 0;
constexpr ConnectionInterfaceDescriptor kStartConnectionInterfaceDescriptor = 64;
constexpr ConnectionInterfaceDescriptor kMaxConnections = UINT16_MAX - kStartConnectionInterfaceDescriptor - 1;

constexpr bool kConnectionFailed = false;
constexpr bool kConnectionOpened = true;

}  // namespace

using ServiceInterfaceCallback =
@@ -180,22 +184,23 @@ struct ConnectionInterfaceManager {
    return cid_to_interface_map_.size();
  }

  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 OnConnectionChanged(ConnectionCompleteCallback on_complete, hci::Address address, l2cap::Psm psm,
                           ConnectionInterfaceDescriptor cid, uint16_t status) {
    on_complete(address.ToString(), static_cast<uint16_t>(psm), static_cast<uint16_t>(cid), status);
  }

  void ConnectionOpened(ConnectionOpenCallback on_open, l2cap::Psm psm, ConnectionInterfaceDescriptor cid) {
  void ConnectionOpened(ConnectionCompleteCallback on_complete, 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));
    handler_->Post(common::BindOnce(&ConnectionInterfaceManager::OnConnectionChanged, common::Unretained(this),
                                    on_complete, address, psm, cid, kConnectionOpened));
  }

  void ConnectionFailed(ConnectionFailedCallback on_failed, hci::Address address, l2cap::Psm psm) {
  void ConnectionFailed(ConnectionCompleteCallback on_complete, hci::Address address, l2cap::Psm psm,
                        ConnectionInterfaceDescriptor cid) {
    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));
                                    std::move(on_complete), address, psm, cid, kConnectionFailed));
  }

  ConnectionInterfaceManager(os::Handler* handler);
@@ -287,16 +292,16 @@ bool ConnectionInterfaceManager::Write(ConnectionInterfaceDescriptor cid, std::u
class PendingConnection {
 public:
  PendingConnection(ConnectionInterfaceManager* connection_interface_manager, ConnectionInterfaceDescriptor cid,
                    l2cap::Psm psm, hci::Address address, ConnectionOpenCallback on_open,
                    std::promise<uint16_t> completed, std::function<void()> deleter)
                    l2cap::Psm psm, hci::Address address, ConnectionCompleteCallback on_complete,
                    std::function<void()> deleter)
      : connection_interface_manager_(connection_interface_manager), cid_(cid), psm_(psm), address_(address),
        on_open_(std::move(on_open)), completed_(std::move(completed)), deleter_(deleter) {}
        on_complete_(std::move(on_complete)), deleter_(deleter) {}

  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_);
    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_);
    connection_interface_manager_->ConnectionOpened(std::move(on_complete_), psm_, cid_);
    deleter_();
  }

@@ -318,8 +323,7 @@ class PendingConnection {
                  l2cap::ConnectionResponseResultText(result.l2cap_connection_response_result).c_str());
        break;
    }
    completed_.set_value(kInvalidConnectionInterfaceDescriptor);
    connection_interface_manager_->ConnectionFailed(std::move(on_open_), address_, psm_);
    connection_interface_manager_->ConnectionFailed(std::move(on_complete_), address_, psm_, cid_);
    connection_interface_manager_->FreeConnectionInterfaceDescriptor(cid_);
    deleter_();
  }
@@ -329,7 +333,7 @@ class PendingConnection {
  const ConnectionInterfaceDescriptor cid_;
  const l2cap::Psm psm_;
  const hci::Address address_;
  ConnectionOpenCallback on_open_;
  ConnectionCompleteCallback on_complete_;
  std::promise<uint16_t> completed_;
  std::function<void()> deleter_;
};
@@ -337,17 +341,17 @@ class PendingConnection {
class ServiceInterface {
 public:
  ServiceInterface(ConnectionInterfaceManager* connection_interface_manager, l2cap::Psm psm,
                   ConnectionOpenCallback on_open, std::promise<void> completed)
      : connection_interface_manager_(connection_interface_manager), psm_(psm), on_open_(on_open),
        completed_(std::move(completed)) {}
                   ConnectionCompleteCallback on_complete, std::promise<void> registered)
      : connection_interface_manager_(connection_interface_manager), psm_(psm), on_complete_(on_complete),
        registered_(std::move(registered)) {}

  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_);
    LOG_DEBUG("Service is registered for psm:%hd", psm_);
    service_ = std::move(service);
    completed_.set_value();
    registered_.set_value();
  }

  void OnConnectionOpen(std::unique_ptr<l2cap::classic::DynamicChannel> channel) {
@@ -355,7 +359,7 @@ class ServiceInterface {
              psm_);
    ConnectionInterfaceDescriptor cid = connection_interface_manager_->AllocateConnectionInterfaceDescriptor();
    connection_interface_manager_->AddConnection(cid, std::move(channel));
    connection_interface_manager_->ConnectionOpened(std::move(on_open_), psm_, cid);
    connection_interface_manager_->ConnectionOpened(on_complete_, psm_, cid);
  }

  l2cap::SecurityPolicy GetSecurityPolicy() const {
@@ -374,8 +378,8 @@ class ServiceInterface {
 private:
  ConnectionInterfaceManager* connection_interface_manager_;
  const l2cap::Psm psm_;
  ConnectionOpenCallback on_open_;
  std::promise<void> completed_;
  ConnectionCompleteCallback on_complete_;
  std::promise<void> registered_;

  std::unique_ptr<l2cap::classic::DynamicChannelService> service_;

@@ -384,11 +388,11 @@ class ServiceInterface {

struct L2cap::impl {
  void RegisterService(l2cap::Psm psm, l2cap::classic::DynamicChannelConfigurationOption option,
                       ConnectionOpenCallback on_open, std::promise<void> completed);
                       ConnectionCompleteCallback on_complete, std::promise<void> registered);
  void UnregisterService(l2cap::Psm psm);

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

  void SetReadDataReadyCallback(ConnectionInterfaceDescriptor cid, ReadDataReadyCallback on_data_ready);
@@ -445,11 +449,11 @@ void L2cap::impl::Dump(int fd) {
}

void L2cap::impl::RegisterService(l2cap::Psm psm, l2cap::classic::DynamicChannelConfigurationOption option,
                                  ConnectionOpenCallback on_open, std::promise<void> completed) {
                                  ConnectionCompleteCallback on_complete, std::promise<void> registered) {
  ASSERT(psm_to_service_interface_map_.find(psm) == psm_to_service_interface_map_.end());

  auto service_interface =
      std::make_shared<ServiceInterface>(&connection_interface_manager_, psm, on_open, std::move(completed));
      std::make_shared<ServiceInterface>(&connection_interface_manager_, psm, on_complete, std::move(registered));
  psm_to_service_interface_map_.emplace(psm, service_interface);

  service_interface->RegisterService(
@@ -466,14 +470,18 @@ void L2cap::impl::UnregisterService(l2cap::Psm psm) {
  psm_to_service_interface_map_.erase(psm);
}

void L2cap::impl::CreateConnection(l2cap::Psm psm, hci::Address address, ConnectionOpenCallback on_open,
                                   std::promise<uint16_t> completed) {
void L2cap::impl::CreateConnection(l2cap::Psm psm, hci::Address address, ConnectionCompleteCallback on_complete,
                                   std::promise<uint16_t> created) {
  ConnectionInterfaceDescriptor cid = connection_interface_manager_.AllocateConnectionInterfaceDescriptor();
  completed.set_value(cid);
  created.set_value(cid);

  if (cid == kInvalidConnectionInterfaceDescriptor) {
    LOG_WARN("No resources to create a connection");
    return;
  }

  auto pending_connection = std::make_shared<PendingConnection>(
      &connection_interface_manager_, cid, psm, address, std::move(on_open), std::move(completed),
      [this, address, psm]() {
      &connection_interface_manager_, cid, psm, address, std::move(on_complete), [this, address, psm]() {
        ASSERT(!endpoint_to_pending_connection_map_[HashEndpoint(address, psm)].empty());
        endpoint_to_pending_connection_map_[HashEndpoint(address, psm)].pop_front();
        if (endpoint_to_pending_connection_map_[HashEndpoint(address, psm)].empty()) {
@@ -511,7 +519,7 @@ void L2cap::impl::SendLoopbackResponse(std::function<void()> function) {
  function();
}

void L2cap::RegisterService(uint16_t raw_psm, bool use_ertm, uint16_t mtu, ConnectionOpenCallback on_open,
void L2cap::RegisterService(uint16_t raw_psm, bool use_ertm, uint16_t mtu, ConnectionCompleteCallback on_complete,
                            std::promise<void> completed) {
  l2cap::Psm psm{raw_psm};
  l2cap::classic::DynamicChannelConfigurationOption option;
@@ -521,7 +529,7 @@ void L2cap::RegisterService(uint16_t raw_psm, bool use_ertm, uint16_t mtu, Conne
  }
  option.incoming_mtu = mtu;
  GetHandler()->Post(common::BindOnce(&L2cap::impl::RegisterService, common::Unretained(pimpl_.get()), psm, option,
                                      on_open, std::move(completed)));
                                      on_complete, std::move(completed)));
}

void L2cap::UnregisterService(uint16_t raw_psm) {
@@ -529,14 +537,14 @@ void L2cap::UnregisterService(uint16_t raw_psm) {
  GetHandler()->Post(common::Bind(&L2cap::impl::UnregisterService, common::Unretained(pimpl_.get()), psm));
}

void L2cap::CreateConnection(uint16_t raw_psm, const std::string address_string, ConnectionOpenCallback on_open,
void L2cap::CreateConnection(uint16_t raw_psm, const std::string address_string, ConnectionCompleteCallback on_complete,
                             std::promise<uint16_t> completed) {
  l2cap::Psm psm{raw_psm};
  hci::Address address;
  hci::Address::FromString(address_string, address);

  GetHandler()->Post(common::BindOnce(&L2cap::impl::CreateConnection, common::Unretained(pimpl_.get()), psm, address,
                                      on_open, std::move(completed)));
                                      on_complete, std::move(completed)));
}

void L2cap::CloseConnection(uint16_t raw_cid) {
+4 −4
Original line number Diff line number Diff line
@@ -29,12 +29,12 @@ namespace shim {

class L2cap : public bluetooth::Module, public bluetooth::shim::IL2cap {
 public:
  void RegisterService(uint16_t psm, bool use_ertm, uint16_t mtu, ConnectionOpenCallback on_open,
                       std::promise<void> completed) override;
  void RegisterService(uint16_t psm, bool use_ertm, uint16_t mtu, ConnectionCompleteCallback on_complete,
                       std::promise<void> registered) override;
  void UnregisterService(uint16_t psm) override;

  void CreateConnection(uint16_t psm, const std::string address_string, ConnectionOpenCallback on_open,
                        std::promise<uint16_t> completed) override;
  void CreateConnection(uint16_t psm, const std::string address_string, ConnectionCompleteCallback on_complete,
                        std::promise<uint16_t> created) override;
  void CloseConnection(uint16_t cid) override;

  void SetReadDataReadyCallback(uint16_t cid, ReadDataReadyCallback on_data_ready) override;
+5 −6
Original line number Diff line number Diff line
@@ -244,7 +244,7 @@ uint16_t bluetooth::shim::legacy::L2cap::CreateConnection(
      std::bind(
          &bluetooth::shim::legacy::L2cap::OnLocalInitiatedConnectionCreated,
          this, std::placeholders::_1, std::placeholders::_2,
          std::placeholders::_3),
          std::placeholders::_3, std::placeholders::_4),
      std::move(connect_completed));

  uint16_t cid = completed.get();
@@ -264,17 +264,16 @@ uint16_t bluetooth::shim::legacy::L2cap::CreateConnection(
}

void bluetooth::shim::legacy::L2cap::OnLocalInitiatedConnectionCreated(
    std::string string_address, uint16_t psm, uint16_t cid) {
    std::string string_address, uint16_t psm, uint16_t cid, bool connected) {
  LOG_DEBUG(LOG_TAG,
            "Sending connection confirm to the upper stack but really "
            "a connection to %s has already been done cid:%hd",
            string_address.c_str(), cid);
  uint16_t status = kConnectionFail;
  if (cid != kInvalidConnectionInterfaceDescriptor) {
  if (connected) {
    SetDownstreamCallbacks(cid);
    status = kConnectionSuccess;
  }
  Classic().Callbacks(psm)->pL2CA_ConnectCfm_Cb(cid, status);
  Classic().Callbacks(psm)->pL2CA_ConnectCfm_Cb(
      cid, connected ? (kConnectionSuccess) : (kConnectionFail));
}

bool bluetooth::shim::legacy::L2cap::Write(uint16_t cid, BT_HDR* bt_hdr) {
+2 −1
Original line number Diff line number Diff line
@@ -68,7 +68,8 @@ class L2cap {
  bool Write(uint16_t cid, BT_HDR* bt_hdr);

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

Loading