| // Copyright 2023 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 LIB_COMPONENT_INCOMING_CPP_PROTOCOL_H_ |
| #define LIB_COMPONENT_INCOMING_CPP_PROTOCOL_H_ |
| |
| #include <fidl/fuchsia.io/cpp/wire.h> |
| #include <lib/component/incoming/cpp/internal.h> |
| #include <lib/zx/channel.h> |
| #include <lib/zx/result.h> |
| |
| #include <string_view> |
| #include <type_traits> |
| #include <utility> |
| |
| namespace component { |
| |
| // Opens the directory containing incoming services in the component's incoming |
| // namespace. |
| // |
| // `path` must be absolute, containing a leading "/". Defaults to "/svc". |
| // |
| // # Errors |
| // |
| // * `ZX_ERR_BAD_PATH`: `path` is too long. |
| // * `ZX_ERR_NOT_FOUND`: `path` was not found in the incoming namespace. |
| zx::result<fidl::ClientEnd<fuchsia_io::Directory>> OpenServiceRoot( |
| std::string_view path = component::kServiceDirectory); |
| |
| // Connects to the FIDL Protocol in the component's incoming namespace. |
| // |
| // `server_end` is the channel used for the server connection. |
| // |
| // `path` must be absolute, containing a leading "/". Default to "/svc/{name}" |
| // where `{name}` is the fully qualified name of the FIDL Protocol. |
| // |
| // The operation completes asynchronously, which means a zx::ok() result does |
| // not ensure that the requested protocol actually exists. |
| // |
| // # Errors |
| // |
| // * `ZX_ERR_INVALID_ARGS`: `path` is too long. |
| // * `ZX_ERR_NOT_FOUND`: A prefix of `path` cannot be found in the namespace. |
| template <typename Protocol, typename = std::enable_if_t<fidl::IsProtocolV<Protocol>>> |
| zx::result<> Connect(fidl::ServerEnd<Protocol> server_end, |
| std::string_view path = fidl::DiscoverableProtocolDefaultPath<Protocol>) { |
| return internal::ConnectRaw(server_end.TakeChannel(), path); |
| } |
| |
| // Connects to the FIDL Protocol in the component's incoming namespace and |
| // returns a client end. |
| // |
| // `path` must be absolute, containing a leading "/". Default to "/svc/{name}" |
| // where `{name}` is the fully qualified name of the FIDL Protocol. |
| // |
| // The operation completes asynchronously, which means a zx::ok() result does |
| // not ensure that the requested protocol actually exists. |
| // |
| // # Errors |
| // |
| // * `ZX_ERR_INVALID_ARGS`: `path` is too long. |
| // * `ZX_ERR_NOT_FOUND`: A prefix of `path` cannot be found in the namespace. |
| template <typename Protocol, typename = std::enable_if_t<fidl::IsProtocolV<Protocol>>> |
| zx::result<fidl::ClientEnd<Protocol>> Connect( |
| std::string_view path = fidl::DiscoverableProtocolDefaultPath<Protocol>) { |
| auto endpoints = fidl::CreateEndpoints<Protocol>(); |
| if (endpoints.is_error()) { |
| return endpoints.take_error(); |
| } |
| |
| if (auto result = Connect<Protocol>(std::move(endpoints->server), path); result.is_error()) { |
| return result.take_error(); |
| } |
| |
| return zx::ok(std::move(endpoints->client)); |
| } |
| |
| // Connects to the FIDL Protocol in the directory `svc_dir`. |
| // |
| // `server_end` is the channel used for the server connection. |
| // |
| // `name` must be a valid entry in `svc_dir`. |
| // |
| // The operation completes asynchronously, which means a zx::ok() result does |
| // not ensure that the requested protocol actually exists. |
| // |
| // # Errors |
| // |
| // * `ZX_ERR_INVALID_ARGS`: `name` is too long. |
| template <typename Protocol, typename = std::enable_if_t<fidl::IsProtocolV<Protocol>>> |
| zx::result<> ConnectAt(fidl::UnownedClientEnd<fuchsia_io::Directory> svc_dir, |
| fidl::ServerEnd<Protocol> server_end, |
| std::string_view name = fidl::DiscoverableProtocolName<Protocol>) { |
| return internal::ConnectAtRaw(svc_dir, server_end.TakeChannel(), name); |
| } |
| |
| // Connects to the FIDL Protocol in the directory `svc_dir`. Returns a client |
| // end to the protocol connection. |
| // |
| // `name` must be a valid entry in `svc_dir`. |
| // |
| // The operation completes asynchronously, which means a zx::ok() result does |
| // not ensure that the requested protocol actually exists. |
| // |
| // # Errors |
| // |
| // * `ZX_ERR_INVALID_ARGS`: `name` is too long. |
| template <typename Protocol, typename = std::enable_if_t<fidl::IsProtocolV<Protocol>>> |
| zx::result<fidl::ClientEnd<Protocol>> ConnectAt( |
| fidl::UnownedClientEnd<fuchsia_io::Directory> svc_dir, |
| std::string_view name = fidl::DiscoverableProtocolName<Protocol>) { |
| auto endpoints = fidl::CreateEndpoints<Protocol>(); |
| if (endpoints.is_error()) { |
| return endpoints.take_error(); |
| } |
| |
| if (auto result = ConnectAt<Protocol>(svc_dir, std::move(endpoints->server), name); |
| result.is_error()) { |
| return result.take_error(); |
| } |
| |
| return zx::ok(std::move(endpoints->client)); |
| } |
| |
| } // namespace component |
| |
| #endif // LIB_COMPONENT_INCOMING_CPP_PROTOCOL_H_ |