// Copyright 2024 The Pigweed Authors // // 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 // // https://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 #include #include #include #include "pw_bluetooth_sapphire/fuchsia/bt_hci_virtual/emulator.h" #include "pw_bluetooth_sapphire/fuchsia/bt_hci_virtual/loopback.h" namespace bt_hci_virtual { // The VirtualController class implements the // fuchsia.hardware.bluetooth.VirtualController API. It is used to created two // devices: the EmulatorDevice and/or the LoopbackDevice. The EmulatorDevice is // used for Bluetooth integration tests, and the LoopbackDevice is used by // RootCanal for PTS-bot. // // VirtualController publishes itself as a DFv2 driver and starts a device node // to bind to said driver. It can create a EmulatorDevice/LoopbackDevice which // can then use the VirtualController's child node // |virtual_controller_child_node_| to publish its own children node that would // represent the EmulatorDevice/LoopbackDevice. // // EmulatorDevice/LoopbackDevice then implements and serves the FIDL protocols // that their client needs. For more details, refer to // go/bluetooth-virtual-driver-doc. class VirtualController : public fdf::DriverBase, public fidl::WireAsyncEventHandler< fuchsia_driver_framework::NodeController>, public fidl::WireAsyncEventHandler, public fidl::WireServer { public: explicit VirtualController( fdf::DriverStartArgs start_args, fdf::UnownedSynchronizedDispatcher driver_dispatcher); // fdf::DriverBase overrides: zx::result<> Start() override; void handle_unknown_event( fidl::UnknownEventMetadata metadata) override {} void handle_unknown_event( fidl::UnknownEventMetadata metadata) override {} private: // fuchsia_hardware_bluetooth::VirtualController overrides: void CreateEmulator(CreateEmulatorCompleter::Sync& completer) override; void CreateLoopbackDevice( CreateLoopbackDeviceRequestView request, CreateLoopbackDeviceCompleter::Sync& completer) override; void handle_unknown_method( fidl::UnknownMethodMetadata metadata, fidl::UnknownMethodCompleter::Sync& completer) override; void Connect( fidl::ServerEnd request); // Helpers functions to add DFv2 device nodes zx_status_t AddVirtualControllerChildNode( fuchsia_driver_framework::wire::NodeAddArgs args); zx_status_t AddLoopbackChildNode( fuchsia_driver_framework::wire::NodeAddArgs args); zx_status_t AddEmulatorChildNode( fuchsia_driver_framework::wire::NodeAddArgs args, EmulatorDevice* emulator_device); std::unique_ptr emulator_device_; std::unique_ptr loopback_device_; // VirtualController fidl::WireClient node_; fidl::WireClient node_controller_; fidl::WireClient virtual_controller_child_node_; driver_devfs::Connector devfs_connector_; fidl::ServerBindingGroup virtual_controller_binding_group_; // LoopbackDevice fidl::WireClient loopback_node_controller_; fidl::WireClient loopback_child_node_; // EmulatorDevice fidl::WireClient emulator_node_controller_; fidl::WireClient emulator_child_node_; }; } // namespace bt_hci_virtual