blob: defc36be4d7d9c1630410f595989a09bce7abea1 [file]
// Copyright 2021 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_FIDL_LLCPP_WIRE_MESSAGING_H_
#define LIB_FIDL_LLCPP_WIRE_MESSAGING_H_
#include <lib/fit/function.h>
#ifdef __Fuchsia__
#include <lib/fidl/llcpp/client_end.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/transaction.h>
#include <zircon/fidl.h>
#endif // __Fuchsia__
namespace fidl {
template <typename FidlMethod>
struct WireRequest;
template <typename FidlMethod>
struct WireResponse;
#ifdef __Fuchsia__
// WireSyncClient owns a client endpoint and exposes synchronous FIDL calls.
template <typename FidlProtocol>
class WireSyncClient;
// WireClient implements a client and exposes both synchronous and asynchronous
// calls.
template <typename FidlProtocol>
class WireClient;
// WireSyncEventHandler is used by synchronous clients to handle events for the
// given protocol.
template <typename FidlProtocol>
class WireSyncEventHandler;
// WireAsyncEventHandler is used by asynchronous clients and adds a callback
// for unbind completion on top of EventHandlerInterface.
template <typename FidlProtocol>
class WireAsyncEventHandler;
// WireServer is a pure-virtual interface to be implemented by a server.
// This interface uses typed channels (i.e. |fidl::ClientEnd<SomeProtocol>|
// and |fidl::ServerEnd<SomeProtocol>|).
template <typename FidlProtocol>
class WireServer;
// WireEventSender owns a server endpoint and exposes methods for sending
// events.
template <typename FidlProtocol>
class WireEventSender;
template <typename FidlMethod>
class WireResponseContext;
template <typename FidlMethod>
class WireResult;
template <typename FidlMethod>
class WireUnownedResult;
template <typename FidlMethod>
using WireClientCallback = ::fit::callback<void(::fidl::WireUnownedResult<FidlMethod>&&)>;
namespace internal {
// WireWeakEventSender borrows the server endpoint from a binding object and
// exposes methods for sending events.
template <typename FidlProtocol>
class WireWeakEventSender;
// WireClientImpl implements both synchronous and asynchronous FIDL calls,
// working together with the |::fidl::internal::ClientBase| class to safely
// borrow channel ownership from the binding object.
template <typename FidlProtocol>
class WireClientImpl;
template <typename FidlProtocol>
class WireEventHandlerInterface;
template <typename FidlProtocol>
class WireCaller;
template <typename FidlProtocol>
struct WireServerDispatcher;
template <typename FidlMethod>
class WireRequestView {
public:
WireRequestView(fidl::WireRequest<FidlMethod>* request) : request_(request) {}
fidl::WireRequest<FidlMethod>* operator->() const { return request_; }
private:
fidl::WireRequest<FidlMethod>* request_;
};
template <typename FidlMethod>
class WireCompleterBase;
template <typename FidlMethod>
struct WireMethodTypes {
using Completer = fidl::Completer<>;
};
template <typename FidlMethod>
using WireCompleter = typename fidl::internal::WireMethodTypes<FidlMethod>::Completer;
} // namespace internal
// |WireCall| is used to make method calls directly on a |fidl::ClientEnd|
// without having to set up a client. Call it like:
//
// fidl::WireCall(client_end).Method(args...);
template <typename FidlProtocol>
fidl::internal::WireCaller<FidlProtocol> WireCall(const fidl::ClientEnd<FidlProtocol>& client_end) {
return fidl::internal::WireCaller<FidlProtocol>(client_end.borrow());
}
// |WireCall| is used to make method calls directly on a |fidl::ClientEnd|
// without having to set up a client. Call it like:
//
// fidl::WireCall(client_end).Method(args...);
template <typename FidlProtocol>
fidl::internal::WireCaller<FidlProtocol> WireCall(
const fidl::UnownedClientEnd<FidlProtocol>& client_end) {
return fidl::internal::WireCaller<FidlProtocol>(client_end);
}
enum class DispatchResult;
// Dispatches the incoming message to one of the handlers functions in the protocol.
//
// This function should only be used in very low-level code, such as when manually
// dispatching a message to a server implementation.
//
// If there is no matching handler, it closes all the handles in |msg| and closes the channel with
// a |ZX_ERR_NOT_SUPPORTED| epitaph, before returning |fidl::DispatchResult::kNotFound|.
//
// Ownership of handles in |msg| are always transferred to the callee.
//
// The caller does not have to ensure |msg| has a |ZX_OK| status. It is idiomatic to pass a |msg|
// with potential errors; any error would be funneled through |InternalError| on the |txn|.
template <typename FidlProtocol>
fidl::DispatchResult WireDispatch(fidl::WireServer<FidlProtocol>* impl, fidl::IncomingMessage&& msg,
fidl::Transaction* txn) {
return fidl::internal::WireServerDispatcher<FidlProtocol>::Dispatch(impl, std::move(msg), txn);
}
// Attempts to dispatch the incoming message to a handler function in the server implementation.
//
// This function should only be used in very low-level code, such as when manually
// dispatching a message to a server implementation.
//
// If there is no matching handler, it returns |fidl::DispatchResult::kNotFound|, leaving the
// message and transaction intact. In all other cases, it consumes the message and returns
// |fidl::DispatchResult::kFound|. It is possible to chain multiple TryDispatch functions in this
// manner.
//
// The caller does not have to ensure |msg| has a |ZX_OK| status. It is idiomatic to pass a |msg|
// with potential errors; any error would be funneled through |InternalError| on the |txn|.
template <typename FidlProtocol>
fidl::DispatchResult WireTryDispatch(fidl::WireServer<FidlProtocol>* impl,
fidl::IncomingMessage& msg, fidl::Transaction* txn) {
return fidl::internal::WireServerDispatcher<FidlProtocol>::TryDispatch(impl, msg, txn);
}
#endif // __Fuchsia__
} // namespace fidl
#endif // LIB_FIDL_LLCPP_WIRE_MESSAGING_H_