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

Commit e325a3e8 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I3c04cd9c,I1f97ac20

* changes:
  RootCanal: ReadDefaultLinkPolicySettings
  HCI: Allow multiple connection callbacks in tests
parents f52df440 09051ad9
Loading
Loading
Loading
Loading
+103 −87
Original line number Diff line number Diff line
@@ -38,9 +38,7 @@ namespace bluetooth {
namespace hci {
namespace facade {

class AclManagerFacadeService : public AclManagerFacade::Service,
                                public ::bluetooth::hci::ConnectionCallbacks,
                                public ::bluetooth::hci::ConnectionManagementCallbacks {
class AclManagerFacadeService : public AclManagerFacade::Service, public ::bluetooth::hci::ConnectionCallbacks {
 public:
  AclManagerFacadeService(AclManager* acl_manager, ::bluetooth::os::Handler* facade_handler)
      : acl_manager_(acl_manager), facade_handler_(facade_handler) {
@@ -50,7 +48,7 @@ class AclManagerFacadeService : public AclManagerFacade::Service,
  ~AclManagerFacadeService() override {
    std::unique_lock<std::mutex> lock(acl_connections_mutex_);
    for (auto connection : acl_connections_) {
      connection.second->GetAclQueueEnd()->UnregisterDequeue();
      connection.second.connection_->GetAclQueueEnd()->UnregisterDequeue();
    }
  }

@@ -75,7 +73,7 @@ class AclManagerFacadeService : public AclManagerFacade::Service,
      LOG_ERROR("Invalid handle");
      return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid handle");
    } else {
      connection->second->Disconnect(DisconnectReason::REMOTE_USER_TERMINATED_CONNECTION);
      connection->second.connection_->Disconnect(DisconnectReason::REMOTE_USER_TERMINATED_CONNECTION);
      return ::grpc::Status::OK;
    }
  }
@@ -88,7 +86,7 @@ class AclManagerFacadeService : public AclManagerFacade::Service,
      LOG_ERROR("Invalid handle");
      return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid handle");
    } else {
      connection->second->AuthenticationRequested();
      connection->second.connection_->AuthenticationRequested();
      return ::grpc::Status::OK;
    }
  };
@@ -115,7 +113,7 @@ class AclManagerFacadeService : public AclManagerFacade::Service,
        return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid handle");
      } else {
        // TODO: This is unsafe because connection may have gone
        connection->second->GetAclQueueEnd()->RegisterEnqueue(
        connection->second.connection_->GetAclQueueEnd()->RegisterEnqueue(
            facade_handler_, common::Bind(&AclManagerFacadeService::enqueue_packet, common::Unretained(this),
                                          common::Unretained(request), common::Passed(std::move(promise))));
      }
@@ -128,7 +126,9 @@ class AclManagerFacadeService : public AclManagerFacade::Service,
  }

  std::unique_ptr<BasePacketBuilder> enqueue_packet(const AclData* request, std::promise<void> promise) {
    acl_connections_[request->handle()]->GetAclQueueEnd()->UnregisterEnqueue();
    auto connection = acl_connections_.find(request->handle());
    ASSERT_LOG(connection != acl_connections_.end(), "handle %d", request->handle());
    connection->second.connection_->GetAclQueueEnd()->UnregisterEnqueue();
    std::unique_ptr<RawBuilder> packet =
        std::make_unique<RawBuilder>(std::vector<uint8_t>(request->payload().begin(), request->payload().end()));
    promise.set_value();
@@ -173,24 +173,44 @@ class AclManagerFacadeService : public AclManagerFacade::Service,
    std::unique_lock<std::mutex> lock(acl_connections_mutex_);
    auto addr = connection->GetAddress();
    std::shared_ptr<::bluetooth::hci::ClassicAclConnection> shared_connection = std::move(connection);
    acl_connections_.emplace(to_handle(current_connection_request_), shared_connection);
    uint16_t handle = to_handle(current_connection_request_);
    acl_connections_.emplace(std::pair(handle, Connection(handle, shared_connection)));
    auto remote_address = shared_connection->GetAddress().ToString();
    shared_connection->GetAclQueueEnd()->RegisterDequeue(
        facade_handler_, common::Bind(&AclManagerFacadeService::on_incoming_classic_acl, common::Unretained(this),
                                      shared_connection, to_handle(current_connection_request_)));
                                      shared_connection, handle));
    shared_connection->RegisterDisconnectCallback(
        common::BindOnce(&AclManagerFacadeService::on_disconnect, common::Unretained(this), shared_connection,
                         current_connection_request_),
        facade_handler_);
    shared_connection->RegisterCallbacks(this, facade_handler_);
    std::unique_ptr<BasePacketBuilder> builder = ConnectionCompleteBuilder::Create(
        ErrorCode::SUCCESS, to_handle(current_connection_request_), addr, LinkType::ACL, Enable::DISABLED);
    auto callbacks = acl_connections_.find(handle)->second.GetCallbacks();
    shared_connection->RegisterCallbacks(callbacks, facade_handler_);
    std::unique_ptr<BasePacketBuilder> builder =
        ConnectionCompleteBuilder::Create(ErrorCode::SUCCESS, handle, addr, LinkType::ACL, Enable::DISABLED);
    ConnectionEvent success;
    success.set_event(builder_to_string(std::move(builder)));
    per_connection_events_[current_connection_request_]->OnIncomingEvent(success);
    current_connection_request_++;
  }

  void OnConnectFail(Address address, ErrorCode reason) override {
    std::unique_ptr<BasePacketBuilder> builder =
        ConnectionCompleteBuilder::Create(reason, 0, address, LinkType::ACL, Enable::DISABLED);
    ConnectionEvent fail;
    fail.set_event(builder_to_string(std::move(builder)));
    per_connection_events_[current_connection_request_]->OnIncomingEvent(fail);
    current_connection_request_++;
  }

  class Connection : public ::bluetooth::hci::ConnectionManagementCallbacks {
   public:
    Connection(uint16_t handle, std::shared_ptr<ClassicAclConnection> connection)
        : handle_(handle), connection_(std::move(connection)) {}

    ConnectionManagementCallbacks* GetCallbacks() {
      return this;
    }

    void OnMasterLinkKeyComplete(KeyFlag key_flag) override {
      LOG_DEBUG("key_flag:%s", KeyFlagText(key_flag).c_str());
    }
@@ -203,15 +223,6 @@ class AclManagerFacadeService : public AclManagerFacade::Service,
      LOG_DEBUG("link_policy_settings:%d", link_policy_settings);
    }

  void OnConnectFail(Address address, ErrorCode reason) override {
    std::unique_ptr<BasePacketBuilder> builder =
        ConnectionCompleteBuilder::Create(reason, 0, address, LinkType::ACL, Enable::DISABLED);
    ConnectionEvent fail;
    fail.set_event(builder_to_string(std::move(builder)));
    per_connection_events_[current_connection_request_]->OnIncomingEvent(fail);
    current_connection_request_++;
  }

    void OnConnectionPacketTypeChanged(uint16_t packet_type) override {
      LOG_DEBUG("OnConnectionPacketTypeChanged packet_type:%d", packet_type);
    }
@@ -248,7 +259,8 @@ class AclManagerFacadeService : public AclManagerFacade::Service,
      LOG_DEBUG(
          "OnFlowSpecificationComplete flow_direction:%d. service_type:%d, token_rate:%d, token_bucket_size:%d, "
          "peak_bandwidth:%d, access_latency:%d",
        (uint8_t)flow_direction, (uint8_t)service_type, token_rate, token_bucket_size, peak_bandwidth, access_latency);
          (uint8_t)flow_direction, (uint8_t)service_type, token_rate, token_bucket_size, peak_bandwidth,
          access_latency);
    }

    void OnFlushOccurred() override {
@@ -291,11 +303,15 @@ class AclManagerFacadeService : public AclManagerFacade::Service,
      LOG_DEBUG("OnReadClockComplete clock:%d, accuracy:%d", clock, accuracy);
    }

    uint16_t handle_;
    std::shared_ptr<ClassicAclConnection> connection_;
  };

 private:
  AclManager* acl_manager_;
  ::bluetooth::os::Handler* facade_handler_;
  mutable std::mutex acl_connections_mutex_;
  std::map<uint16_t, std::shared_ptr<ClassicAclConnection>> acl_connections_;
  std::map<uint16_t, Connection> acl_connections_;
  ::bluetooth::grpc::GrpcEventQueue<AclData> pending_acl_data_{"FetchAclData"};
  std::vector<std::unique_ptr<::bluetooth::grpc::GrpcEventQueue<ConnectionEvent>>> per_connection_events_;
  uint32_t current_connection_request_{0};
+30 −20
Original line number Diff line number Diff line
@@ -38,9 +38,7 @@ namespace bluetooth {
namespace hci {
namespace facade {

class LeAclManagerFacadeService : public LeAclManagerFacade::Service,
                                  public ::bluetooth::hci::LeConnectionCallbacks,
                                  public ::bluetooth::hci::LeConnectionManagementCallbacks {
class LeAclManagerFacadeService : public LeAclManagerFacade::Service, public ::bluetooth::hci::LeConnectionCallbacks {
 public:
  LeAclManagerFacadeService(AclManager* acl_manager, ::bluetooth::os::Handler* facade_handler)
      : acl_manager_(acl_manager), facade_handler_(facade_handler) {
@@ -49,8 +47,8 @@ class LeAclManagerFacadeService : public LeAclManagerFacade::Service,

  ~LeAclManagerFacadeService() override {
    std::unique_lock<std::mutex> lock(acl_connections_mutex_);
    for (auto connection : acl_connections_) {
      connection.second->GetAclQueueEnd()->UnregisterDequeue();
    for (auto& conn : acl_connections_) {
      conn.second.connection_->GetAclQueueEnd()->UnregisterDequeue();
    }
  }

@@ -76,7 +74,7 @@ class LeAclManagerFacadeService : public LeAclManagerFacade::Service,
      LOG_ERROR("Invalid handle");
      return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid handle");
    } else {
      connection->second->Disconnect(DisconnectReason::REMOTE_USER_TERMINATED_CONNECTION);
      connection->second.connection_->Disconnect(DisconnectReason::REMOTE_USER_TERMINATED_CONNECTION);
      return ::grpc::Status::OK;
    }
  }
@@ -102,7 +100,7 @@ class LeAclManagerFacadeService : public LeAclManagerFacade::Service,
        LOG_ERROR("Invalid handle");
        return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid handle");
      } else {
        connection->second->GetAclQueueEnd()->RegisterEnqueue(
        connection->second.connection_->GetAclQueueEnd()->RegisterEnqueue(
            facade_handler_, common::Bind(&LeAclManagerFacadeService::enqueue_packet, common::Unretained(this),
                                          common::Unretained(request), common::Passed(std::move(promise))));
      }
@@ -121,7 +119,9 @@ class LeAclManagerFacadeService : public LeAclManagerFacade::Service,
  }

  std::unique_ptr<BasePacketBuilder> enqueue_packet(const LeAclData* request, std::promise<void> promise) {
    acl_connections_[request->handle()]->GetAclQueueEnd()->UnregisterEnqueue();
    auto connection = acl_connections_.find(request->handle());
    ASSERT_LOG(connection != acl_connections_.end(), "handle %d", request->handle());
    connection->second.connection_->GetAclQueueEnd()->UnregisterEnqueue();
    std::unique_ptr<RawBuilder> packet =
        std::make_unique<RawBuilder>(std::vector<uint8_t>(request->payload().begin(), request->payload().end()));
    promise.set_value();
@@ -169,15 +169,13 @@ class LeAclManagerFacadeService : public LeAclManagerFacade::Service,
    std::unique_lock<std::mutex> lock(acl_connections_mutex_);
    auto addr = address_with_type.GetAddress();
    std::shared_ptr<::bluetooth::hci::LeAclConnection> shared_connection = std::move(connection);
    acl_connections_.emplace(to_handle(current_connection_request_), shared_connection);
    uint16_t handle = to_handle(current_connection_request_);
    acl_connections_.emplace(std::pair(handle, Connection(handle, shared_connection)));
    shared_connection->GetAclQueueEnd()->RegisterDequeue(
        facade_handler_, common::Bind(&LeAclManagerFacadeService::on_incoming_acl, common::Unretained(this),
                                      shared_connection, to_handle(current_connection_request_)));
    shared_connection->RegisterDisconnectCallback(
        common::BindOnce(&LeAclManagerFacadeService::on_disconnect, common::Unretained(this), shared_connection,
                         current_connection_request_),
        facade_handler_);
    shared_connection->RegisterCallbacks(this, facade_handler_);
    auto callbacks = acl_connections_.find(handle)->second.GetCallbacks();
    shared_connection->RegisterCallbacks(callbacks, facade_handler_);
    {
      std::unique_ptr<BasePacketBuilder> builder =
          LeConnectionCompleteBuilder::Create(ErrorCode::SUCCESS, to_handle(current_connection_request_), Role::MASTER,
@@ -198,17 +196,29 @@ class LeAclManagerFacadeService : public LeAclManagerFacade::Service,
    current_connection_request_++;
  }

  class Connection : public ::bluetooth::hci::LeConnectionManagementCallbacks {
   public:
    Connection(uint16_t handle, std::shared_ptr<LeAclConnection> connection)
        : handle_(handle), connection_(std::move(connection)) {}
    void OnConnectionUpdate(uint16_t connection_interval, uint16_t connection_latency,
                            uint16_t supervision_timeout) override {
      LOG_DEBUG("interval: 0x%hx, latency: 0x%hx, timeout 0x%hx", connection_interval, connection_latency,
                supervision_timeout);
    }

    LeConnectionManagementCallbacks* GetCallbacks() {
      return this;
    }

    uint16_t handle_;
    std::shared_ptr<LeAclConnection> connection_;
  };

 private:
  AclManager* acl_manager_;
  ::bluetooth::os::Handler* facade_handler_;
  mutable std::mutex acl_connections_mutex_;
  std::map<uint16_t, std::shared_ptr<LeAclConnection>> acl_connections_;
  std::map<uint16_t, Connection> acl_connections_;
  ::bluetooth::grpc::GrpcEventQueue<LeAclData> pending_acl_data_{"FetchAclData"};
  std::vector<std::unique_ptr<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>>> per_connection_events_;
  uint32_t current_connection_request_{0};
+17 −1
Original line number Diff line number Diff line
@@ -147,6 +147,8 @@ DualModeController::DualModeController(const std::string& properties_filename, u
  SET_HANDLER(OpCode::SNIFF_MODE, SniffMode);
  SET_HANDLER(OpCode::EXIT_SNIFF_MODE, ExitSniffMode);
  SET_HANDLER(OpCode::QOS_SETUP, QosSetup);
  SET_HANDLER(OpCode::READ_DEFAULT_LINK_POLICY_SETTINGS,
              ReadDefaultLinkPolicySettings);
  SET_HANDLER(OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS,
              WriteDefaultLinkPolicySettings);
  SET_HANDLER(OpCode::FLOW_SPECIFICATION, FlowSpecification);
@@ -1010,14 +1012,28 @@ void DualModeController::QosSetup(CommandPacketView command) {
  send_event_(std::move(packet));
}

void DualModeController::ReadDefaultLinkPolicySettings(
    CommandPacketView command) {
  auto command_view = gd_hci::ReadDefaultLinkPolicySettingsView::Create(
      gd_hci::ConnectionManagementCommandView::Create(command));
  ASSERT(command_view.IsValid());
  uint16_t settings = link_layer_controller_.ReadDefaultLinkPolicySettings();
  auto packet =
      bluetooth::hci::ReadDefaultLinkPolicySettingsCompleteBuilder::Create(
          kNumCommandPackets, ErrorCode::SUCCESS, settings);
  send_event_(std::move(packet));
}

void DualModeController::WriteDefaultLinkPolicySettings(
    CommandPacketView command) {
  auto command_view = gd_hci::WriteDefaultLinkPolicySettingsView::Create(
      gd_hci::ConnectionManagementCommandView::Create(command));
  ASSERT(command_view.IsValid());
  ErrorCode status = link_layer_controller_.WriteDefaultLinkPolicySettings(
      command_view.GetDefaultLinkPolicySettings());
  auto packet =
      bluetooth::hci::WriteDefaultLinkPolicySettingsCompleteBuilder::Create(
          kNumCommandPackets, ErrorCode::SUCCESS);
          kNumCommandPackets, status);
  send_event_(std::move(packet));
}

+3 −0
Original line number Diff line number Diff line
@@ -205,6 +205,9 @@ class DualModeController : public Device {
  // 7.2.10
  void WriteLinkPolicySettings(CommandPacketView args);

  // 7.2.11
  void ReadDefaultLinkPolicySettings(CommandPacketView args);

  // 7.2.12
  void WriteDefaultLinkPolicySettings(CommandPacketView args);

+13 −1
Original line number Diff line number Diff line
@@ -904,7 +904,6 @@ void LinkLayerController::IncomingLeConnectCompletePacket(

void LinkLayerController::IncomingLeScanPacket(
    model::packets::LinkLayerPacketView incoming) {

  auto to_send = model::packets::LeScanResponseBuilder::Create(
      properties_.GetLeAddress(), incoming.GetSourceAddress(),
      static_cast<model::packets::AddressType>(properties_.GetLeAddressType()),
@@ -1616,6 +1615,19 @@ ErrorCode LinkLayerController::WriteLinkPolicySettings(uint16_t handle,
  return ErrorCode::SUCCESS;
}

ErrorCode LinkLayerController::WriteDefaultLinkPolicySettings(
    uint16_t settings) {
  if (settings > 7 /* Sniff + Hold + Role switch */) {
    return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
  }
  default_link_policy_settings_ = settings;
  return ErrorCode::SUCCESS;
}

uint16_t LinkLayerController::ReadDefaultLinkPolicySettings() {
  return default_link_policy_settings_;
}

ErrorCode LinkLayerController::FlowSpecification(
    uint16_t handle, uint8_t flow_direction, uint8_t service_type,
    uint32_t /* token_rate */, uint32_t /* token_bucket_size */,
Loading