blob: 1804d2ded54bbed0ce4e757d4fc052d57576a23e [file] [log] [blame]
// Copyright 2019 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 <fuchsia/examples/llcpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/service/llcpp/service.h>
#include <lib/sys/cpp/component_context.h>
#include <iostream>
using fuchsia_examples::Echo;
using fuchsia_examples::EchoService;
fidl::InterfaceHandle<fuchsia::io::Directory> StartEchoServer(
sys::ComponentContext* context,
fidl::InterfaceRequest<fuchsia::sys::ComponentController> controller) {
fidl::InterfaceHandle<fuchsia::io::Directory> svc;
fuchsia::sys::LaunchInfo info{
.url = "fuchsia-pkg://fuchsia.com/echo-hlcpp-service-server#meta/echo-server.cmx",
.directory_request = svc.NewRequest().TakeChannel(),
};
auto launcher = context->svc()->Connect<fuchsia::sys::Launcher>();
launcher->CreateComponent(std::move(info), std::move(controller));
return svc;
}
zx::status<> llcpp_example(fidl::UnownedClientEnd<fuchsia_io::Directory> svc) {
zx::status<EchoService::ServiceClient> open_result =
llcpp::sys::OpenServiceAt<EchoService>(std::move(svc));
if (open_result.is_error()) {
std::cerr << "failed to open default instance of EchoService: " << open_result.status_string()
<< std::endl;
return open_result.take_error();
}
EchoService::ServiceClient service = std::move(open_result.value());
zx::status<fidl::ClientEnd<Echo>> connect_result = service.connect_regular_echo();
if (connect_result.is_error()) {
std::cerr << "failed to connect to member protocol regular_echo of EchoService: "
<< connect_result.status_string() << std::endl;
return connect_result.take_error();
}
fidl::WireSyncClient<Echo> client = fidl::BindSyncClient(std::move(connect_result.value()));
fidl::WireResult<Echo::EchoString> echo_result = client.EchoString(fidl::StringView("hello"));
if (!echo_result.ok()) {
std::cerr << "failed to make EchoString call to member protocol regular_echo of EchoService: "
<< echo_result.error() << std::endl;
return zx::error(ZX_ERR_IO);
}
auto response = echo_result.Unwrap();
std::string result_string(response->response.data(), response->response.size());
if (result_string != "hello") {
std::cerr << "got unexpected response '" << result_string << "'. expected 'hello'."
<< std::endl;
return zx::error(ZX_ERR_INTERNAL);
}
return zx::ok();
}
int main(int argc, const char** argv) {
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
auto context = sys::ComponentContext::CreateAndServeOutgoingDirectory();
// Start the echo service.
//
// In a real system, the service would be offered to the client instead of
// being started by the client.
fuchsia::sys::ComponentControllerPtr controller;
auto svc = StartEchoServer(context.get(), controller.NewRequest());
// Convert the typed handle to LLCPP types.
auto llsvc = fidl::ClientEnd<fuchsia_io::Directory>(svc.TakeChannel());
zx::status<> result = llcpp_example(llsvc);
if (result.is_error()) {
std::cerr << "llcpp_example failed with status: " << result.status_string() << std::endl;
return 1;
}
return 0;
}