| // 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. |
| |
| #include "parent-driver.h" |
| |
| // [START bind_imports] |
| #include <bind/examples/gizmo/bind/cpp/bind.h> |
| #include <bind/examples/gizmo/cpp/bind.h> |
| #include <bind/fuchsia/device/fs/cpp/bind.h> |
| // [END bind_imports] |
| |
| namespace parent_driver { |
| |
| zx::result<> ParentDriver::Start() { |
| node_.Bind(std::move(node()), dispatcher()); |
| gizmo_server_ = std::make_shared<GizmoServer>(); |
| |
| // Add gizmo examples_gizmo::Service to outgoing. |
| { |
| examples_gizmo::Service::InstanceHandler handler( |
| {.testing = [this](fidl::ServerEnd<examples_gizmo::TestingProtocol> server_end) -> void { |
| GizmoServer::BindDeviceClient(gizmo_server_, dispatcher(), std::move(server_end)); |
| }}); |
| |
| auto result = outgoing()->AddService<examples_gizmo::Service>(std::move(handler)); |
| if (result.is_error()) { |
| FDF_SLOG(ERROR, "Failed to add service", KV("status", result.status_string())); |
| return result.take_error(); |
| } |
| } |
| |
| auto result = AddChild(); |
| if (result.status_value() != ZX_OK) { |
| return result; |
| } |
| |
| return zx::ok(); |
| } |
| |
| zx::result<> ParentDriver::AddChild() { |
| fidl::Arena arena; |
| |
| // Offer `examples.gizmo.Service` to the driver that binds to the node. |
| auto offers = fidl::VectorView<fuchsia_component_decl::wire::Offer>(arena, 1); |
| offers[0] = fdf::MakeOffer<examples_gizmo::Service>(arena, component::kDefaultInstance); |
| |
| // Set the properties of the node that the child will bind to based on the child-driver.bind |
| auto properties = fidl::VectorView<fuchsia_driver_framework::wire::NodeProperty>(arena, 6); |
| // [START add_bind_properties] |
| properties[0] = |
| fdf::MakeProperty(arena, 1 /* BIND_PROTOCOL */, bind_fuchsia_acpi::BIND_PROTOCOL_DEVICE); |
| properties[1] = fdf::MakeProperty(arena, bind_fuchsia_acpi::HID, "GOOG"); |
| properties[2] = fdf::MakeProperty(arena, bind_examples_gizmo_bind::MODELNAME, "GIZMO3000"); |
| properties[3] = fdf::MakeProperty(arena, bind_examples_gizmo_bind::GIZMOTYPE, |
| bind_examples_gizmo_bind::GIZMOTYPE_MEM_64K); |
| // [END add_bind_properties] |
| |
| // We are not actually offering the Exporter protocol to the child, nor using it from the child. |
| // This is just to demonstrate access to these values through the auto-generated bind library. |
| // [START add_fidl_bind_properties] |
| properties[4] = fdf::MakeProperty(arena, bind_fuchsia_device_fs::EXPORTER, |
| bind_fuchsia_device_fs::EXPORTER_ZIRCONTRANSPORT); |
| properties[5] = fdf::MakeProperty(arena, bind_examples_gizmo::TESTINGPROTOCOL, |
| bind_examples_gizmo::TESTINGPROTOCOL_ZIRCONTRANSPORT); |
| // [END add_fidl_bind_properties] |
| |
| auto args = fuchsia_driver_framework::wire::NodeAddArgs::Builder(arena) |
| .name(arena, "bindlib-child") |
| .offers(offers) |
| .properties(properties) |
| .Build(); |
| |
| // Create endpoints of the `NodeController` for the node. |
| auto endpoints = fidl::CreateEndpoints<fuchsia_driver_framework::NodeController>(); |
| if (endpoints.is_error()) { |
| FDF_SLOG(ERROR, "Failed to create endpoint", KV("status", endpoints.status_string())); |
| return zx::error(endpoints.status_value()); |
| } |
| |
| auto result = node_.sync()->AddChild(args, std::move(endpoints->server), {}); |
| if (!result.ok()) { |
| FDF_SLOG(ERROR, "Failed to add child", KV("status", result.status_string())); |
| return zx::error(result.status()); |
| } |
| |
| return zx::ok(); |
| } |
| |
| } // namespace parent_driver |
| |
| FUCHSIA_DRIVER_RECORD_CPP_V2(fdf::Record<parent_driver::ParentDriver>); |