// 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.overnet;

// Overnet forms a mesh network of peer devices which can proxy some Zircon objects between
// said devices.

using fuchsia.overnet.protocol;
using zx;

/// Interfaces applicable to consuming services from other devices
@discoverable
protocol ServiceConsumer {
    /// Returns a list of all peers that are connected to this Overnet.
    /// If this list has not been updated since the last call to this method, it waits until
    /// new data is available.
    /// Concurrent calls to ListPeers will result in channel closure.
    ListPeers() -> (struct {
        peers vector<Peer>:MAX;
    });
    /// Connect `chan` to some external service on `node` with name `service_name`.
    ConnectToService(resource struct {
        node fuchsia.overnet.protocol.NodeId;
        service_name string:fuchsia.overnet.protocol.MAX_SERVICE_NAME_LENGTH;
        chan zx.handle:CHANNEL;
    });
};

/// Interfaces applicable to sharing services with ServiceConsumer's
@discoverable
protocol ServicePublisher {
    /// Register a new service to be exported by Overnet.
    /// If an existing service has the same `service_name`, it's replaced by this service.
    PublishService(resource struct {
        service_name string:fuchsia.overnet.protocol.MAX_SERVICE_NAME_LENGTH;
        provider client_end:ServiceProvider;
    });
};

/// Interfaces applicable to controlling an Overnet mesh
@discoverable
protocol MeshController {
    /// Attach a socket as a new link.
    AttachSocketLink(resource struct {
        socket zx.handle:SOCKET;
    });
};

/// A ServiceProvider is a factory for one service.
protocol ServiceProvider {
    /// Connect `chan` to the service (called in response to Overnet.ConnectToService).
    /// `info` provides additional data about the connection request.
    ConnectToService(resource struct {
        chan zx.handle:CHANNEL;
        info ConnectionInfo;
    });
};

/// Protocol spoken by the host implementation to access various sub-interfaces.
protocol HostOvernet {
    ConnectServiceConsumer(resource struct {
        svc server_end:ServiceConsumer;
    });
    ConnectServicePublisher(resource struct {
        svc server_end:ServicePublisher;
    });
    ConnectMeshController(resource struct {
        svc server_end:MeshController;
    });
};

/// A `Peer` describes one device on the Overnet mesh.
type Peer = struct {
    /// The address of the peer on the Overnet mesh.
    id fuchsia.overnet.protocol.NodeId;
    /// A special peer is returned for this device, and is marked with `is_self` true.
    is_self bool;
    /// A description of the peer (includes, for example, a service list).
    description fuchsia.overnet.protocol.PeerDescription;
};

/// Information provided to a ServiceProvider about an incoming connection.
type ConnectionInfo = table {
    /// The peer address initiating this connection.
    1: peer fuchsia.overnet.protocol.NodeId;
};
