blob: 157c67c628f8200e179e120d644c17e9659c0210 [file] [log] [blame]
// Copyright 2017 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_NETSVC_ETH_CLIENT_H_
#define SRC_BRINGUP_BIN_NETSVC_ETH_CLIENT_H_
#include <fidl/fuchsia.hardware.ethernet/cpp/wire.h>
#include <lib/async/cpp/wait.h>
#include <lib/zx/fifo.h>
#include <lib/zx/status.h>
#include <zircon/compiler.h>
#include <zircon/types.h>
class EthClient {
public:
static zx::status<std::unique_ptr<EthClient>> Create(
async_dispatcher_t* dispatcher, fidl::ClientEnd<fuchsia_hardware_ethernet::Device> client_end,
zx::vmo io_vmo, void* io_mem, fit::closure on_rx, fit::closure on_status,
fit::closure on_closed);
// Enqueue a packet for transmit.
zx_status_t QueueTx(void* cookie, void* data, size_t len);
// Process all transmitted buffers.
zx_status_t CompleteTx(void* ctx, void (*func)(void* ctx, void* cookie));
// Enqueue a packet for reception.
zx_status_t QueueRx(void* cookie, void* data, size_t len);
// Process all received buffers.
zx_status_t CompleteRx(void* ctx, void (*func)(async_dispatcher_t* dispatcher, void* ctx,
void* cookie, size_t len));
// Waits for rx signals, calling |on_rx| when rx frames are available and
// |on_status| when the device signals its online status has changed.
zx_status_t WatchRx(async_dispatcher_t* dispatcher, fit::closure on_rx, fit::closure on_status);
// Wait for completed tx packets.
//
// ZX_ERR_PEER_CLOSED - far side disconnected.
// ZX_ERR_TIMED_OUT - deadline lapsed.
// ZX_OK - completed packets are available.
zx_status_t WaitTx(zx::time deadline);
zx::status<fuchsia_hardware_ethernet::wire::DeviceStatus> GetStatus();
private:
void OnRxSignal(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
const zx_packet_signal_t* signal);
EthClient(async_dispatcher_t* dispatcher,
fidl::WireSyncClient<fuchsia_hardware_ethernet::Device> device, zx::fifo tx,
uint32_t tx_size, zx::fifo rx, uint32_t rx_size, void* io_mem, fit::closure on_rx,
fit::closure on_signal, fit::callback<void()> on_closed)
: device_(std::move(device)),
tx_fifo_(std::move(tx)),
rx_fifo_(std::move(rx)),
dispatcher_(dispatcher),
on_rx_(std::move(on_rx)),
on_signal_(std::move(on_signal)),
on_closed_(std::move(on_closed)),
rx_task_(this, rx_fifo_.get(),
ZX_FIFO_PEER_CLOSED | ZX_FIFO_READABLE |
fuchsia_hardware_ethernet::wire::kSignalStatus),
tx_size_(tx_size),
rx_size_(rx_size),
io_mem_(reinterpret_cast<uintptr_t>(io_mem)) {
zx_status_t status = rx_task_.Begin(dispatcher);
ZX_ASSERT_MSG(status == ZX_OK, "failed to schedule task %s", zx_status_get_string(status));
}
fidl::WireSyncClient<fuchsia_hardware_ethernet::Device> device_;
zx::fifo tx_fifo_;
zx::fifo rx_fifo_;
async_dispatcher_t* const dispatcher_;
const fit::closure on_rx_;
const fit::closure on_signal_;
fit::callback<void()> on_closed_;
async::WaitMethod<EthClient, &EthClient::OnRxSignal> rx_task_;
const uint32_t tx_size_;
const uint32_t rx_size_;
const uintptr_t io_mem_;
};
#endif // SRC_BRINGUP_BIN_NETSVC_ETH_CLIENT_H_