blob: aa1114fc6737692433fc79011068a0b4f2d1665e [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.
#ifndef SRC_BRINGUP_BIN_PTYSVC_PTY_CLIENT_H_
#define SRC_BRINGUP_BIN_PTYSVC_PTY_CLIENT_H_
#include <fidl/fuchsia.device/cpp/wire.h>
#include <fidl/fuchsia.hardware.pty/cpp/wire.h>
#include <lib/zx/eventpair.h>
#include "fifo.h"
#include "pty-server.h"
class PtyClient : public fidl::WireServer<fuchsia_hardware_pty::Device> {
public:
PtyClient(std::shared_ptr<PtyServer>, uint32_t id, zx::eventpair local, zx::eventpair remote);
zx_status_t Read(void* data, size_t count, size_t* out_actual);
zx_status_t Write(const void* data, size_t count, size_t* out_actual);
void AddConnection(fidl::ServerEnd<fuchsia_hardware_pty::Device> request);
// fuchsia.hardware.pty.Device.
void Clone2(Clone2RequestView request, Clone2Completer::Sync& completer) final;
void Close(CloseCompleter::Sync& completer) final;
void Query(QueryCompleter::Sync& completer) final;
void Read(ReadRequestView request, ReadCompleter::Sync& completer) final;
void Write(WriteRequestView request, WriteCompleter::Sync& completer) final;
void Describe(DescribeCompleter::Sync& completer) final;
void OpenClient(OpenClientRequestView request, OpenClientCompleter::Sync& completer) final;
void ClrSetFeature(ClrSetFeatureRequestView request,
ClrSetFeatureCompleter::Sync& completer) final;
void GetWindowSize(GetWindowSizeCompleter::Sync& completer) final;
void MakeActive(MakeActiveRequestView request, MakeActiveCompleter::Sync& completer) final;
void ReadEvents(ReadEventsCompleter::Sync& completer) final;
void SetWindowSize(SetWindowSizeRequestView request,
SetWindowSizeCompleter::Sync& completer) final;
Fifo* rx_fifo() { return &rx_fifo_; }
void AssertHangupSignal() {
ClearSetFlags(0, kFlagPeerClosed);
local_.signal_peer(static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kWritable),
static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kHangup));
}
void AssertActiveHungup() {
local_.signal_peer(0, static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kOob |
fuchsia_device::wire::DeviceSignal::kHangup));
}
void AssertReadableSignal() {
local_.signal_peer(0, static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kReadable));
}
void AssertWritableSignal() {
local_.signal_peer(0, static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kWritable));
}
void AssertEventSignal() {
local_.signal_peer(0, static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kOob));
}
void DeAssertReadableSignal() {
local_.signal_peer(static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kReadable), 0);
}
void DeAssertWritableSignal() {
local_.signal_peer(static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kWritable), 0);
}
void DeAssertEventSignal() {
local_.signal_peer(static_cast<zx_signals_t>(fuchsia_device::wire::DeviceSignal::kOob), 0);
}
void ClearSetFlags(uint32_t clr, uint32_t set) { flags_ = (flags_ & ~clr) | set; }
uint32_t flags() const { return flags_; }
[[nodiscard]] bool in_raw_mode() const { return flags_ & kFlagRawMode; }
[[nodiscard]] bool is_peer_closed() const { return flags_ & kFlagPeerClosed; }
// Ensure READABLE/WRITABLE signals are properly asserted based on active
// status and rx_fifo status.
void AdjustSignals();
[[nodiscard]] bool is_active() { return server().is_active(*this); }
[[nodiscard]] bool is_control() { return server().is_control(*this); }
PtyServer& server() { return *server_; }
private:
zx_status_t WriteChunk(const void* buf, size_t count, size_t* actual);
std::shared_ptr<PtyServer> server_;
const uint32_t id_;
// remote_ is signaled to indicate to client connections various status
// conditions.
zx::eventpair local_, remote_;
static constexpr uint32_t kFlagRawMode = 0x00000001u;
static_assert(kFlagRawMode == fuchsia_hardware_pty::wire::kFeatureRaw);
static constexpr uint32_t kFlagPeerClosed = 0x00000002u;
uint32_t flags_ = 0;
Fifo rx_fifo_;
fidl::ServerBindingGroup<fuchsia_hardware_pty::Device> bindings_;
};
#endif // SRC_BRINGUP_BIN_PTYSVC_PTY_CLIENT_H_