// Copyright 2018 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.

library fuchsia.hardware.vsock;

using zx;

// Vsock address where 'local' always means the driver and 'remote' always means
// the device. As such there is no 'local_cid' as it can only ever be the driver cid
// and so specifying is redundant and a source of errors.
[ForDeprecatedCBindings]
struct Addr {
    uint32 local_port;
    uint32 remote_cid;
    uint32 remote_port;
};

// Callbacks sent from the device to whomever registered them (typically a service)
// in response to events from host.
[ForDeprecatedCBindings]
protocol Callbacks {
    // Indicates a 'request' op was received from the host. One of Device.SendResponse
    // or Device.SendRst should be done in response to this.
    Request(Addr addr);
    // Indicates a response was received for a connection that was trying to be
    // established from Device.SendRequest.
    Response(Addr addr);
    // Indicates a 'rst' op was received from the host, and that the driver has
    // has freed the resources for any potential connection relating to `addr`.
    Rst(Addr addr);
    // Indicates a 'shutdown' op was received from the host.
    Shutdown(Addr addr);
    // Indicates a 'transport reset' op was received from the host. Responding to
    // this method indicates that you have processed all preceding Callbacks and
    // dropped any active connections.
    TransportReset(uint32 new_cid) -> ();
    // Indicates that a previous Device.SendVmo request has completed.
    SendVmoComplete(Addr addr);
};

// Low level vsock device operations. Users of this interface are responsible for
// adhering to the vsock protocol and must use ensure they do not reuse addresses
// for active connections, perform SendRst and SendResponse only when it is correct
// to do so, etc.
[ForDeprecatedCBindings]
protocol Device {
    // Causes the device to start and gives it Callbacks to use for forwarding messages
    // from the host. The rest of the methods on this interface are only valid to use
    // after calling Start and whilst the passed Callbacks remain valid. The device
    // will stop if it detects the other end of the Callbacks channel has closed.
    Start(Callbacks cb) -> (zx.status status);
    // Will send a request to open a connection with the remote specified in the
    // `addr`. The `data` socket is stored and will be used for data transmission
    // should the connection get established successfully, otherwise it will close
    // the handle. The `status` returned indicates whether the request was sent
    // successfully. Callbacks.Response or Callbacks.Rst will be called to indicate
    // if the connection was successfully established or not.
    SendRequest(Addr addr, zx.handle:SOCKET data) -> (zx.status status);
    // Request a shutdown to begin for the connection indicated by the given `addr`.
    // This immediately stops any data from being sent on the connection, although
    // data may still be received up until Callbacks.Rst is called to indicate the
    // shutdown has complete. This is only valid on a connection established with
    // SendRequest or SendResponse.
    SendShutdown(Addr addr) -> (zx.status status);
    // Request a rst be sent to the host. The device will also release the resources
    // for any connection that may exist for `addr`.
    SendRst(Addr addr) -> (zx.status status);
    // Causes a 'response' to get sent to the host, gives the driver a `data` socket
    // to use for sending and receiving data on the established connection. It is
    // only correct to use this in response to a Callbacks.Request.
    SendResponse(Addr addr, zx.handle:SOCKET data) -> (zx.status status);
    // Query the current context id of the driver. The local CID is never needed
    // in interactions with the same device, and retrieving it is only useful for
    // debugging or if you have some other communication channel to a different host
    // and you would like to send them your CID to then establish a vsock connection on.
    GetCid() -> (uint32 local_cid);
    // Send the contents of a vmo over an already established connection. A
    // connection may only have a single outstanding vmo at a time, and trying
    // to send whilst one is already in progress will generate an error. If there
    // is pending data to transmit in the `data` socket of a connection and there
    // is a vmo pending then it is undefined which one will be sent. Once the vmo
    // contents have finished sending Callbacks.SendVmoComplete will be called.
    SendVmo(Addr addr, zx.handle:VMO vmo, uint64 off, uint64 len) -> (zx.status status);
};
