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

Commit d8a529b1 authored by Zach Johnson's avatar Zach Johnson
Browse files

Use templates to simplify command interfaces for HCI

Test: fuzz/run --host bluetooth_gd_hci_fuzz_test
Change-Id: I1a10be92ac4dd135bd0887d60b1100f7a1698bcc
parent 7cab7cf5
Loading
Loading
Loading
Loading
+22 −31
Original line number Diff line number Diff line
@@ -17,25 +17,14 @@
#pragma once

#include "common/callback.h"
#include "hci/command_interface.h"
#include "hci/hci_packets.h"
#include "os/utils.h"

namespace bluetooth {
namespace hci {

class AclConnectionInterface {
 public:
  AclConnectionInterface() = default;
  virtual ~AclConnectionInterface() = default;
  DISALLOW_COPY_AND_ASSIGN(AclConnectionInterface);

  virtual void EnqueueCommand(std::unique_ptr<ConnectionManagementCommandBuilder> command,
                              common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) = 0;

  virtual void EnqueueCommand(std::unique_ptr<ConnectionManagementCommandBuilder> command,
                              common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) = 0;

  static constexpr EventCode AclConnectionEvents[] = {
constexpr EventCode AclConnectionEvents[] = {
    EventCode::CONNECTION_PACKET_TYPE_CHANGED,
    EventCode::ROLE_CHANGE,
    EventCode::CONNECTION_COMPLETE,
@@ -55,6 +44,8 @@ class AclConnectionInterface {
    EventCode::ENCRYPTION_CHANGE,
    EventCode::LINK_SUPERVISION_TIMEOUT_CHANGED,
};
};

typedef CommandInterface<ConnectionManagementCommandBuilder> AclConnectionInterface;

}  // namespace hci
}  // namespace bluetooth
+41 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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 "common/callback.h"
#include "hci/hci_packets.h"
#include "os/handler.h"
#include "os/utils.h"

namespace bluetooth {
namespace hci {

template <typename T>
class CommandInterface {
 public:
  CommandInterface() = default;
  virtual ~CommandInterface() = default;
  DISALLOW_COPY_AND_ASSIGN(CommandInterface);

  virtual void EnqueueCommand(std::unique_ptr<T> command, common::OnceCallback<void(CommandCompleteView)> on_complete,
                              os::Handler* handler) = 0;

  virtual void EnqueueCommand(std::unique_ptr<T> command, common::OnceCallback<void(CommandStatusView)> on_status,
                              os::Handler* handler) = 0;
};
}  // namespace hci
}  // namespace bluetooth
+20 −104
Original line number Diff line number Diff line
@@ -97,103 +97,19 @@ void on_hci_timeout(OpCode op_code) {
}
}  // namespace

class AclConnectionManagerInterfaceImpl : public AclConnectionInterface {
template <typename T>
class CommandInterfaceImpl : public CommandInterface<T> {
 public:
  explicit AclConnectionManagerInterfaceImpl(HciLayer& hci) : hci_(hci) {}
  ~AclConnectionManagerInterfaceImpl() override = default;
  explicit CommandInterfaceImpl(HciLayer& hci) : hci_(hci) {}
  ~CommandInterfaceImpl() override = default;

  void EnqueueCommand(std::unique_ptr<ConnectionManagementCommandBuilder> command,
                      common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override {
  void EnqueueCommand(std::unique_ptr<T> command, common::OnceCallback<void(CommandCompleteView)> on_complete,
                      os::Handler* handler) override {
    hci_.EnqueueCommand(std::move(command), std::move(on_complete), handler);
  }

  void EnqueueCommand(std::unique_ptr<ConnectionManagementCommandBuilder> command,
                      common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override {
    hci_.EnqueueCommand(std::move(command), std::move(on_status), handler);
  }
  HciLayer& hci_;
};

class SecurityInterfaceImpl : public SecurityInterface {
 public:
  explicit SecurityInterfaceImpl(HciLayer& hci) : hci_(hci) {}
  ~SecurityInterfaceImpl() override = default;

  void EnqueueCommand(std::unique_ptr<SecurityCommandBuilder> command,
                      common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override {
    hci_.EnqueueCommand(std::move(command), std::move(on_complete), handler);
  }

  void EnqueueCommand(std::unique_ptr<SecurityCommandBuilder> command,
                      common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override {
    hci_.EnqueueCommand(std::move(command), std::move(on_status), handler);
  }
  HciLayer& hci_;
};

class LeAclConnectionManagerInterfaceImpl : public LeAclConnectionInterface {
 public:
  explicit LeAclConnectionManagerInterfaceImpl(HciLayer& hci) : hci_(hci) {}
  ~LeAclConnectionManagerInterfaceImpl() override = default;

  void EnqueueCommand(std::unique_ptr<LeConnectionManagementCommandBuilder> command,
                      common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override {
    hci_.EnqueueCommand(std::move(command), std::move(on_complete), handler);
  }

  void EnqueueCommand(std::unique_ptr<LeConnectionManagementCommandBuilder> command,
                      common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override {
    hci_.EnqueueCommand(std::move(command), std::move(on_status), handler);
  }
  HciLayer& hci_;
};

class LeSecurityInterfaceImpl : public LeSecurityInterface {
 public:
  explicit LeSecurityInterfaceImpl(HciLayer& hci) : hci_(hci) {}
  ~LeSecurityInterfaceImpl() override = default;

  void EnqueueCommand(std::unique_ptr<LeSecurityCommandBuilder> command,
                      common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override {
    hci_.EnqueueCommand(std::move(command), std::move(on_complete), handler);
  }

  void EnqueueCommand(std::unique_ptr<LeSecurityCommandBuilder> command,
                      common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override {
    hci_.EnqueueCommand(std::move(command), std::move(on_status), handler);
  }
  HciLayer& hci_;
};

class LeAdvertisingInterfaceImpl : public LeAdvertisingInterface {
 public:
  explicit LeAdvertisingInterfaceImpl(HciLayer& hci) : hci_(hci) {}
  ~LeAdvertisingInterfaceImpl() override = default;

  void EnqueueCommand(std::unique_ptr<LeAdvertisingCommandBuilder> command,
                      common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override {
    hci_.EnqueueCommand(std::move(command), std::move(on_complete), handler);
  }

  void EnqueueCommand(std::unique_ptr<LeAdvertisingCommandBuilder> command,
                      common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override {
    hci_.EnqueueCommand(std::move(command), std::move(on_status), handler);
  }
  HciLayer& hci_;
};

class LeScanningInterfaceImpl : public LeScanningInterface {
 public:
  explicit LeScanningInterfaceImpl(HciLayer& hci) : hci_(hci) {}
  ~LeScanningInterfaceImpl() override = default;

  void EnqueueCommand(std::unique_ptr<LeScanningCommandBuilder> command,
                      common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override {
    hci_.EnqueueCommand(std::move(command), std::move(on_complete), handler);
  }

  void EnqueueCommand(std::unique_ptr<LeScanningCommandBuilder> command,
                      common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override {
  void EnqueueCommand(std::unique_ptr<T> command, common::OnceCallback<void(CommandStatusView)> on_status,
                      os::Handler* handler) override {
    hci_.EnqueueCommand(std::move(command), std::move(on_status), handler);
  }
  HciLayer& hci_;
@@ -457,12 +373,12 @@ struct HciLayer::impl : public hal::HciHalCallbacks {
  HciLayer& module_;

  // Interfaces
  AclConnectionManagerInterfaceImpl acl_connection_manager_interface_{module_};
  LeAclConnectionManagerInterfaceImpl le_acl_connection_manager_interface_{module_};
  SecurityInterfaceImpl security_interface{module_};
  LeSecurityInterfaceImpl le_security_interface{module_};
  LeAdvertisingInterfaceImpl le_advertising_interface{module_};
  LeScanningInterfaceImpl le_scanning_interface{module_};
  CommandInterfaceImpl<ConnectionManagementCommandBuilder> acl_connection_manager_interface_{module_};
  CommandInterfaceImpl<LeConnectionManagementCommandBuilder> le_acl_connection_manager_interface_{module_};
  CommandInterfaceImpl<SecurityCommandBuilder> security_interface{module_};
  CommandInterfaceImpl<LeSecurityCommandBuilder> le_security_interface{module_};
  CommandInterfaceImpl<LeAdvertisingCommandBuilder> le_advertising_interface{module_};
  CommandInterfaceImpl<LeScanningCommandBuilder> le_scanning_interface{module_};

  // Command Handling
  std::list<CommandQueueEntry> command_queue_;
@@ -519,7 +435,7 @@ void HciLayer::UnregisterLeEventHandler(SubeventCode subevent_code) {
AclConnectionInterface* HciLayer::GetAclConnectionInterface(common::Callback<void(EventPacketView)> event_handler,
                                                            common::Callback<void(uint16_t, ErrorCode)> on_disconnect,
                                                            os::Handler* handler) {
  for (const auto event : AclConnectionInterface::AclConnectionEvents) {
  for (const auto event : AclConnectionEvents) {
    RegisterEventHandler(event, event_handler, handler);
  }
  return &impl_->acl_connection_manager_interface_;
@@ -528,7 +444,7 @@ AclConnectionInterface* HciLayer::GetAclConnectionInterface(common::Callback<voi
LeAclConnectionInterface* HciLayer::GetLeAclConnectionInterface(
    common::Callback<void(LeMetaEventView)> event_handler, common::Callback<void(uint16_t, ErrorCode)> on_disconnect,
    os::Handler* handler) {
  for (const auto event : LeAclConnectionInterface::LeConnectionManagementEvents) {
  for (const auto event : LeConnectionManagementEvents) {
    RegisterLeEventHandler(event, event_handler, handler);
  }
  return &impl_->le_acl_connection_manager_interface_;
@@ -536,7 +452,7 @@ LeAclConnectionInterface* HciLayer::GetLeAclConnectionInterface(

SecurityInterface* HciLayer::GetSecurityInterface(common::Callback<void(EventPacketView)> event_handler,
                                                  os::Handler* handler) {
  for (const auto event : SecurityInterface::SecurityEvents) {
  for (const auto event : SecurityEvents) {
    RegisterEventHandler(event, event_handler, handler);
  }
  return &impl_->security_interface;
@@ -544,7 +460,7 @@ SecurityInterface* HciLayer::GetSecurityInterface(common::Callback<void(EventPac

LeSecurityInterface* HciLayer::GetLeSecurityInterface(common::Callback<void(LeMetaEventView)> event_handler,
                                                      os::Handler* handler) {
  for (const auto subevent : LeSecurityInterface::LeSecurityEvents) {
  for (const auto subevent : LeSecurityEvents) {
    RegisterLeEventHandler(subevent, event_handler, handler);
  }
  return &impl_->le_security_interface;
@@ -552,7 +468,7 @@ LeSecurityInterface* HciLayer::GetLeSecurityInterface(common::Callback<void(LeMe

LeAdvertisingInterface* HciLayer::GetLeAdvertisingInterface(common::Callback<void(LeMetaEventView)> event_handler,
                                                            os::Handler* handler) {
  for (const auto subevent : LeAdvertisingInterface::LeAdvertisingEvents) {
  for (const auto subevent : LeAdvertisingEvents) {
    RegisterLeEventHandler(subevent, event_handler, handler);
  }
  return &impl_->le_advertising_interface;
@@ -560,7 +476,7 @@ LeAdvertisingInterface* HciLayer::GetLeAdvertisingInterface(common::Callback<voi

LeScanningInterface* HciLayer::GetLeScanningInterface(common::Callback<void(LeMetaEventView)> event_handler,
                                                      os::Handler* handler) {
  for (const auto subevent : LeScanningInterface::LeScanningEvents) {
  for (const auto subevent : LeScanningEvents) {
    RegisterLeEventHandler(subevent, event_handler, handler);
  }
  return &impl_->le_scanning_interface;
+4 −3
Original line number Diff line number Diff line
@@ -37,17 +37,18 @@
namespace bluetooth {
namespace hci {

class HciLayer : public Module {
class HciLayer : public Module, public CommandInterface<CommandPacketBuilder> {
 public:
  HciLayer();
  virtual ~HciLayer();
  DISALLOW_COPY_AND_ASSIGN(HciLayer);

  virtual void EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,
                              common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler);
                              common::OnceCallback<void(CommandCompleteView)> on_complete,
                              os::Handler* handler) override;

  virtual void EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,
                              common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler);
                              common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override;

  virtual common::BidiQueueEnd<AclPacketBuilder, AclPacketView>* GetAclQueueEnd();

+7 −19
Original line number Diff line number Diff line
@@ -16,31 +16,19 @@

#pragma once

#include "common/callback.h"
#include "hci/command_interface.h"
#include "hci/hci_packets.h"
#include "os/handler.h"
#include "os/utils.h"

namespace bluetooth {
namespace hci {

class LeAclConnectionInterface {
 public:
  LeAclConnectionInterface() = default;
  virtual ~LeAclConnectionInterface() = default;
  DISALLOW_COPY_AND_ASSIGN(LeAclConnectionInterface);

  virtual void EnqueueCommand(std::unique_ptr<LeConnectionManagementCommandBuilder> command,
                              common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) = 0;

  virtual void EnqueueCommand(std::unique_ptr<LeConnectionManagementCommandBuilder> command,
                              common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) = 0;

  static constexpr SubeventCode LeConnectionManagementEvents[] = {
constexpr SubeventCode LeConnectionManagementEvents[] = {
    SubeventCode::CONNECTION_COMPLETE,
    SubeventCode::ENHANCED_CONNECTION_COMPLETE,
    SubeventCode::CONNECTION_UPDATE_COMPLETE,
};
};

typedef CommandInterface<LeConnectionManagementCommandBuilder> LeAclConnectionInterface;

}  // namespace hci
}  // namespace bluetooth
Loading