blob: a5cc298b37d4b897cfb19612ab8043938c1a0751 [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 "src/virtualization/lib/vsh/client.h"
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/socket.h>
#include <zircon/status.h>
#include "src/virtualization/lib/vsh/util.h"
namespace vsh {
using ::fuchsia::virtualization::HostVsockEndpoint_Connect2_Result;
// static
fpromise::result<BlockingClient, zx_status_t> BlockingClient::Connect(
const fuchsia::virtualization::HostVsockEndpointSyncPtr& socket_endpoint, uint32_t port) {
HostVsockEndpoint_Connect2_Result result;
zx_status_t fidl_status = socket_endpoint->Connect2(port, &result);
if (result.is_err()) {
FX_LOGS(ERROR) << "Failed to connect to vshd: " << zx_status_get_string(result.err());
return fpromise::error(result.err());
}
if (fidl_status != ZX_OK) {
FX_LOGS(ERROR) << "FIDL error connecting to vshd: " << zx_status_get_string(fidl_status);
return fpromise::error(fidl_status);
}
return fpromise::ok(BlockingClient(std::move(result.response().socket)));
}
BlockingClient::BlockingClient(zx::socket socket) : vsock_(std::move(socket)) {}
zx_status_t BlockingClient::Setup(vm_tools::vsh::SetupConnectionRequest conn_req) {
vm_tools::vsh::SetupConnectionResponse conn_resp;
if (!SendMessage(vsock_, conn_req)) {
FX_LOGS(ERROR) << "Failed to send connection request";
return ZX_ERR_INTERNAL;
}
if (!RecvMessage(vsock_, &conn_resp)) {
FX_LOGS(ERROR) << "Failed to receive response from vshd, giving up after one try";
return ZX_ERR_INTERNAL;
}
if (conn_resp.status() != vm_tools::vsh::READY) {
FX_LOGS(ERROR) << "Server was unable to set up connection properly: "
<< conn_resp.description();
return ZX_ERR_INTERNAL;
}
status_ = conn_resp.status();
return ZX_OK;
}
fpromise::result<vm_tools::vsh::HostMessage, zx_status_t> BlockingClient::NextMessage() {
FX_CHECK(status_ == vm_tools::vsh::ConnectionStatus::READY);
vm_tools::vsh::HostMessage msg;
if (!RecvMessage(vsock_, &msg)) {
FX_LOGS(ERROR) << "Failed to receive response from vshd, giving up after one try";
return fpromise::error(ZX_ERR_INTERNAL);
}
if (msg.msg_case() == vm_tools::vsh::HostMessage::MsgCase::kStatusMessage) {
auto new_status = msg.status_message().status();
status_ = new_status;
}
return fpromise::ok(std::move(msg));
}
} // namespace vsh