blob: 856b42e24b308fb3e947852878c80ad3f8a30903 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_CONNECTIVITY_BLUETOOTH_HCI_VENDOR_BROADCOM_BT_HCI_BROADCOM_H_
#define SRC_CONNECTIVITY_BLUETOOTH_HCI_VENDOR_BROADCOM_BT_HCI_BROADCOM_H_
#include <fidl/fuchsia.driver.framework/cpp/fidl.h>
#include <fidl/fuchsia.hardware.bluetooth/cpp/wire.h>
#include <fidl/fuchsia.hardware.serialimpl/cpp/driver/fidl.h>
#include <fidl/fuchsia.io/cpp/wire_test_base.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/executor.h>
#include <lib/async/cpp/wait.h>
#include <lib/driver/component/cpp/driver_base.h>
#include <lib/driver/component/cpp/node_add_args.h>
#include <lib/driver/devfs/cpp/connector.h>
#include <lib/sync/cpp/completion.h>
#include "packets.h"
namespace bt_hci_broadcom {
class BtHciBroadcom final
: public fdf::DriverBase,
public fidl::WireAsyncEventHandler<fuchsia_driver_framework::NodeController>,
public fidl::WireAsyncEventHandler<fuchsia_driver_framework::Node>,
public fidl::WireServer<fuchsia_hardware_bluetooth::Hci>,
public fidl::WireServer<fuchsia_hardware_bluetooth::Vendor> {
public:
explicit BtHciBroadcom(fdf::DriverStartArgs start_args,
fdf::UnownedSynchronizedDispatcher driver_dispatcher);
void Start(fdf::StartCompleter completer) override;
void PrepareStop(fdf::PrepareStopCompleter completer) override;
void handle_unknown_event(
fidl::UnknownEventMetadata<fuchsia_driver_framework::NodeController> metadata) override {}
void handle_unknown_event(
fidl::UnknownEventMetadata<fuchsia_driver_framework::Node> metadata) override {}
private:
static constexpr size_t kMacAddrLen = 6;
static const std::unordered_map<uint16_t, std::string> kFirmwareMap;
// fuchsia_hardware_bluetooth::Vendor protocol interface implementations.
void EncodeCommand(EncodeCommandRequestView request,
EncodeCommandCompleter::Sync& completer) override;
void OpenHci(OpenHciCompleter::Sync& completer) override;
void handle_unknown_method(
fidl::UnknownMethodMetadata<fuchsia_hardware_bluetooth::Vendor> metadata,
fidl::UnknownMethodCompleter::Sync& completer) override;
// fuchsia_hardware_bluetooth::Hci protocol interface implementations.
void OpenCommandChannel(OpenCommandChannelRequestView request,
OpenCommandChannelCompleter::Sync& completer) override;
void OpenAclDataChannel(OpenAclDataChannelRequestView request,
OpenAclDataChannelCompleter::Sync& completer) override;
void OpenScoDataChannel(OpenScoDataChannelRequestView request,
OpenScoDataChannelCompleter::Sync& completer) override;
void ConfigureSco(ConfigureScoRequestView request,
ConfigureScoCompleter::Sync& completer) override;
void ResetSco(ResetScoCompleter::Sync& completer) override;
void OpenIsoDataChannel(OpenIsoDataChannelRequestView request,
OpenIsoDataChannelCompleter::Sync& completer) override;
void OpenSnoopChannel(OpenSnoopChannelRequestView request,
OpenSnoopChannelCompleter::Sync& completer) override;
void handle_unknown_method(fidl::UnknownMethodMetadata<fuchsia_hardware_bluetooth::Hci> metadata,
fidl::UnknownMethodCompleter::Sync& completer) override;
void Connect(fidl::ServerEnd<fuchsia_hardware_bluetooth::Vendor> request);
// Truly private, internal helper methods:
zx_status_t ConnectToHciFidlProtocol();
zx_status_t ConnectToSerialFidlProtocol();
static void EncodeSetAclPriorityCommand(
fuchsia_hardware_bluetooth::wire::VendorSetAclPriorityParams params, void* out_buffer);
fpromise::promise<std::vector<uint8_t>, zx_status_t> SendCommand(const void* command,
size_t length);
// Waits for a "readable" signal from the command channel and reads the next event.
fpromise::promise<std::vector<uint8_t>, zx_status_t> ReadEvent();
fpromise::promise<void, zx_status_t> SetBaudRate(uint32_t baud_rate);
fpromise::promise<void, zx_status_t> SetBdaddr(const std::array<uint8_t, kMacAddrLen>& bdaddr);
fpromise::result<std::array<uint8_t, kMacAddrLen>, zx_status_t> GetBdaddrFromBootloader();
fpromise::promise<> LogControllerFallbackBdaddr();
fpromise::promise<void, zx_status_t> LoadFirmware();
fpromise::promise<void, zx_status_t> SendVmoAsCommands(zx::vmo vmo, size_t size, size_t offset);
fpromise::promise<void, zx_status_t> Initialize();
fpromise::promise<void, zx_status_t> OnInitializeComplete(zx_status_t status);
fpromise::promise<void, zx_status_t> AddNode();
void CompleteStart(zx_status_t status);
zx_status_t Bind();
uint32_t serial_pid_;
zx::channel command_channel_;
// true if underlying transport is UART
bool is_uart_;
std::optional<fdf::StartCompleter> start_completer_;
std::optional<async::Executor> executor_;
fidl::WireClient<fuchsia_hardware_bluetooth::Hci> hci_client_;
fdf::WireSyncClient<fuchsia_hardware_serialimpl::Device> serial_client_;
fidl::WireClient<fuchsia_driver_framework::Node> node_;
fidl::WireClient<fuchsia_driver_framework::NodeController> node_controller_;
fidl::WireClient<fuchsia_driver_framework::Node> child_node_;
fidl::ServerBindingGroup<fuchsia_hardware_bluetooth::Hci> hci_server_bindings_;
fidl::ServerBindingGroup<fuchsia_hardware_bluetooth::Vendor> vendor_binding_group_;
driver_devfs::Connector<fuchsia_hardware_bluetooth::Vendor> devfs_connector_;
};
} // namespace bt_hci_broadcom
#endif // SRC_CONNECTIVITY_BLUETOOTH_HCI_VENDOR_BROADCOM_BT_HCI_BROADCOM_H_