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

Commit 8b0522f3 authored by Antoine SOULIER's avatar Antoine SOULIER
Browse files

GD/HCI: Add fallback handler for vendor specific event

Bug: 360924438
Test: mma -j32
Flag: com.android.bluetooth.flags.hci_vendor_specific_extension
Change-Id: I095107e7d2d070799399a69a7d21bd83d6b1ab2e
parent 444208a0
Loading
Loading
Loading
Loading
+57 −6
Original line number Diff line number Diff line
@@ -27,26 +27,77 @@
namespace bluetooth {
namespace hci_vs {

using hci::CommandCompleteView;
using hci::CommandStatusOrCompleteView;
using hci::CommandStatusView;
using hci::OpCode;
using hci::VendorSpecificEventView;

std::unique_ptr<BluetoothHciVendorSpecificInterface> hciVendorSpecificInterface;

static void CommandStatusOrCompleteCallback(BluetoothHciVendorSpecificCallbacks* callbacks,
                                            Cookie cookie,
                                            CommandStatusOrCompleteView status_or_complete) {
  if (std::holds_alternative<CommandStatusView>(status_or_complete)) {
    auto view = std::get<CommandStatusView>(status_or_complete);
    auto ocf = static_cast<uint16_t>(view.GetCommandOpCode()) & 0x3ff;
    auto status = static_cast<uint8_t>(view.GetStatus());
    callbacks->commandStatusDelivery(ocf, status, cookie);

  } else if (std::holds_alternative<CommandCompleteView>(status_or_complete)) {
    auto view = std::get<CommandCompleteView>(status_or_complete);
    auto ocf = static_cast<uint16_t>(view.GetCommandOpCode()) & 0x3ff;
    std::vector<uint8_t> return_parameters(view.GetPayload().begin(), view.GetPayload().end());
    callbacks->commandCompleteDelivery(ocf, return_parameters, cookie);
  }
}

static void EventCallback(BluetoothHciVendorSpecificCallbacks* callbacks,
                          VendorSpecificEventView view) {
  const uint8_t aosp_reserved_codes_range[] = {0x50, 0x60};
  auto code = static_cast<uint8_t>(view.GetSubeventCode());
  if (code >= aosp_reserved_codes_range[0] && code < aosp_reserved_codes_range[1]) {
    return;
  }

  std::vector<uint8_t> data(view.GetPayload().begin(), view.GetPayload().end());
  callbacks->eventDelivery(code, data);
}

class BluetoothHciVendorSpecificInterfaceImpl
    : public bluetooth::hci_vs::BluetoothHciVendorSpecificInterface {
  ~BluetoothHciVendorSpecificInterfaceImpl() override = default;

  void init(BluetoothHciVendorSpecificCallbacks* callbacks) override {
    log::info("BluetoothHciVendorSpecificInterfaceImpl");
    this->callbacks = callbacks;
    log::assert_that(callbacks != nullptr, "callbacks cannot be null");
    callbacks_ = callbacks;

    shim::GetHciLayer()->RegisterDefaultVendorSpecificEventHandler(
            get_main()->Bind(EventCallback, callbacks_));
  }

  void sendCommand(uint16_t ocf, std::vector<uint8_t> parameters, Cookie cookie) override {
    // TODO: Send HCI Command
    (void)ocf;
    (void)parameters;
    (void)cookie;
    if (callbacks_ == nullptr) {
      log::error("not initialized");
      return;
    }

    if (ocf & ~0x3ff) {
      log::error("invalid vendor-specific op-code");
      return;
    }

    const uint16_t ogf_vendor_specific = 0x3f;
    auto op_code = static_cast<OpCode>((ogf_vendor_specific << 10) | ocf);

    shim::GetHciLayer()->EnqueueCommand(
            hci::CommandBuilder::Create(op_code, std::make_unique<packet::RawBuilder>(parameters)),
            get_main()->BindOnce(CommandStatusOrCompleteCallback, callbacks_, std::move(cookie)));
  }

private:
  BluetoothHciVendorSpecificCallbacks* callbacks = nullptr;
  BluetoothHciVendorSpecificCallbacks* callbacks_ = nullptr;
};

BluetoothHciVendorSpecificInterface* getBluetoothHciVendorSpecificInterface() {
+5 −0
Original line number Diff line number Diff line
@@ -65,6 +65,11 @@ public:

  virtual void UnregisterEventHandler(EventCode event_code) = 0;

  virtual void RegisterDefaultVendorSpecificEventHandler(
          common::ContextualCallback<void(VendorSpecificEventView)> handler) = 0;

  virtual void UnregisterDefaultVendorSpecificEventHandler() = 0;

  virtual void RegisterLeEventHandler(
          SubeventCode subevent_code,
          common::ContextualCallback<void(LeMetaEventView)> event_handler) = 0;
+21 −3
Original line number Diff line number Diff line
@@ -400,6 +400,12 @@ struct HciLayer::impl {
    vs_event_handlers_.erase(vs_event_handlers_.find(event));
  }

  void register_vs_event_default(ContextualCallback<void(VendorSpecificEventView)> handler) {
    vs_event_default_handler_ = std::move(handler);
  }

  void unregister_vs_event_default() { vs_event_default_handler_.reset(); }

  static void abort_after_root_inflammation(uint8_t vse_error) {
    log::fatal("Root inflammation with reason 0x{:02x}", vse_error);
  }
@@ -524,11 +530,13 @@ struct HciLayer::impl {
    VendorSpecificEventView vs_event_view = VendorSpecificEventView::Create(event);
    log::assert_that(vs_event_view.IsValid(), "assert failed: vs_event_view.IsValid()");
    VseSubeventCode subevent_code = vs_event_view.GetSubeventCode();
    if (vs_event_handlers_.find(subevent_code) == vs_event_handlers_.end()) {
    if (vs_event_handlers_.find(subevent_code) != vs_event_handlers_.end()) {
      vs_event_handlers_[subevent_code](vs_event_view);
    } else if (vs_event_default_handler_.has_value()) {
      (*vs_event_default_handler_)(vs_event_view);
    } else {
      log::warn("Unhandled vendor specific event of type {}", VseSubeventCodeText(subevent_code));
      return;
    }
    vs_event_handlers_[subevent_code](vs_event_view);
  }

  hal::HciHal* hal_;
@@ -540,6 +548,7 @@ struct HciLayer::impl {
  std::map<EventCode, ContextualCallback<void(EventView)>> event_handlers_;
  std::map<SubeventCode, ContextualCallback<void(LeMetaEventView)>> le_event_handlers_;
  std::map<VseSubeventCode, ContextualCallback<void(VendorSpecificEventView)>> vs_event_handlers_;
  std::optional<ContextualCallback<void(VendorSpecificEventView)>> vs_event_default_handler_;

  OpCode waiting_command_{OpCode::NONE};
  uint8_t command_credits_{1};  // Send reset first
@@ -655,6 +664,15 @@ void HciLayer::UnregisterVendorSpecificEventHandler(VseSubeventCode event) {
  CallOn(impl_, &impl::unregister_vs_event, event);
}

void HciLayer::RegisterDefaultVendorSpecificEventHandler(
        ContextualCallback<void(VendorSpecificEventView)> handler) {
  CallOn(impl_, &impl::register_vs_event_default, handler);
}

void HciLayer::UnregisterDefaultVendorSpecificEventHandler() {
  CallOn(impl_, &impl::unregister_vs_event_default);
}

void HciLayer::on_disconnection_complete(EventView event_view) {
  auto disconnection_view = DisconnectionCompleteView::Create(event_view);
  if (!disconnection_view.IsValid()) {
+5 −0
Original line number Diff line number Diff line
@@ -84,6 +84,11 @@ public:

  virtual void UnregisterVendorSpecificEventHandler(VseSubeventCode event);

  virtual void RegisterDefaultVendorSpecificEventHandler(
          common::ContextualCallback<void(VendorSpecificEventView)> handler);

  virtual void UnregisterDefaultVendorSpecificEventHandler();

  virtual void RegisterForDisconnects(
          common::ContextualCallback<void(uint16_t, hci::ErrorCode)> on_disconnect);

+3 −0
Original line number Diff line number Diff line
@@ -57,6 +57,9 @@ public:
              (VseSubeventCode, common::ContextualCallback<void(VendorSpecificEventView)>),
              (override));
  MOCK_METHOD((void), UnregisterVendorSpecificEventHandler, (VseSubeventCode), (override));
  MOCK_METHOD((void), RegisterDefaultVendorSpecificEventHandler,
              (common::ContextualCallback<void(VendorSpecificEventView)>), (override));
  MOCK_METHOD((void), UnregisterDefaultVendorSpecificEventHandler, (), (override));
  MOCK_METHOD((SecurityInterface*), GetSecurityInterface,
              (common::ContextualCallback<void(EventView)> event_handler), (override));