blob: da640b656c833bf4122cae2187be13992738ade9 [file] [log] [blame]
// Copyright 2017 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_CORE_BT_HOST_HCI_DEVICE_WRAPPER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_HCI_DEVICE_WRAPPER_H_
#include <fuchsia/hardware/bluetooth/c/fidl.h>
#include <fuchsia/hardware/bt/hci/c/banjo.h>
#include <fuchsia/hardware/bt/vendor/c/banjo.h>
#include <lib/fit/function.h>
#include <lib/fit/result.h>
#include <lib/zx/channel.h>
#include <zircon/status.h>
#include <zircon/types.h>
#include <optional>
#include <fbl/macros.h>
#include <fbl/unique_fd.h>
#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
namespace bt::hci {
// A DeviceWrapper abstracts over a Bluetooth HCI device object and its fidl
// interface.
class DeviceWrapper {
public:
virtual ~DeviceWrapper() = default;
// Returns the command/event channel handle for this device. Returns an
// invalid handle on failure.
virtual zx::channel GetCommandChannel() = 0;
// Returns the ACL data channel handle for this device. Returns an invalid
// handle on failure.
virtual zx::channel GetACLDataChannel() = 0;
virtual bt_vendor_features_t GetVendorFeatures() = 0;
virtual fit::result<DynamicByteBuffer> EncodeVendorCommand(bt_vendor_command_t command,
bt_vendor_params_t& params) {
return fit::error();
};
};
// A DeviceWrapper that obtains channels by invoking bt-hci fidl requests on a
// devfs file descriptor.
class FidlDeviceWrapper : public DeviceWrapper {
public:
// |device| must be a valid channel connected to a Bluetooth HCI device.
explicit FidlDeviceWrapper(zx::channel device);
~FidlDeviceWrapper() override = default;
// DeviceWrapper overrides. These methods directly return the handle obtained
// via the corresponding fidl request.
zx::channel GetCommandChannel() override;
zx::channel GetACLDataChannel() override;
bt_vendor_features_t GetVendorFeatures() override { return 0; };
private:
zx::channel device_;
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FidlDeviceWrapper);
};
// A DeviceWrapper that calls bt-hci and bt-vendor DDK protocol ops.
class DdkDeviceWrapper : public DeviceWrapper {
public:
// The contents of |hci| must remain valid while this object is in use.
explicit DdkDeviceWrapper(const bt_hci_protocol_t& hci,
std::optional<bt_vendor_protocol_t> vendor);
~DdkDeviceWrapper() override = default;
// DeviceWrapper overrides:
zx::channel GetCommandChannel() override;
zx::channel GetACLDataChannel() override;
bt_vendor_features_t GetVendorFeatures() override;
fit::result<DynamicByteBuffer> EncodeVendorCommand(bt_vendor_command_t command,
bt_vendor_params_t& params) override;
private:
bt_hci_protocol_t hci_proto_;
std::optional<bt_vendor_protocol_t> vendor_proto_;
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(DdkDeviceWrapper);
};
// A pass-through DeviceWrapper that returns the channel endpoints that it is
// initialized with. This is useful for test scenarios.
class DummyDeviceWrapper : public DeviceWrapper {
public:
// The constructor takes ownership of the provided channels and simply returns
// them when asked for them. |vendor_features| will be returned by GetVendorFeatures() and calls
// to EncodeVendorCommand() are forwarded to |vendor_encode_cb|.
using EncodeCallback =
fit::function<fit::result<DynamicByteBuffer>(bt_vendor_command_t, bt_vendor_params_t)>;
DummyDeviceWrapper(zx::channel cmd_channel, zx::channel acl_data_channel,
bt_vendor_features_t vendor_features = 0,
EncodeCallback vendor_encode_cb = nullptr);
~DummyDeviceWrapper() override = default;
// DeviceWrapper overrides. Since these methods simply forward the handles
// they were initialized with, the internal handles will be moved and
// invalidated after the first call to these methods. Subsequent calls will
// always return an invalid handle.
zx::channel GetCommandChannel() override;
zx::channel GetACLDataChannel() override;
bt_vendor_features_t GetVendorFeatures() override { return vendor_features_; }
fit::result<DynamicByteBuffer> EncodeVendorCommand(bt_vendor_command_t command,
bt_vendor_params_t& params) override;
private:
zx::channel cmd_channel_;
zx::channel acl_data_channel_;
bt_vendor_features_t vendor_features_;
EncodeCallback vendor_encode_cb_;
DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(DummyDeviceWrapper);
};
} // namespace bt::hci
#endif // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_HCI_DEVICE_WRAPPER_H_