// 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.
library fuchsia.bluetooth.avdtp;

using fuchsia.bluetooth as bt;

/// Control service for an AVDTP Peer.
@discoverable
protocol PeerManager {
    /// Connects to the server specified by a `peer_id`.
    /// On success, `handle` will be used for initiating PeerController procedures.
    /// On peer disconnect, the handle will be dropped and closed on the server side.
    GetPeer(resource struct {
        peer_id bt.PeerId;
        handle server_end:PeerController;
    });

    /// Returns the `bt.PeerId` of each currently connected peer.
    ConnectedPeers() -> (struct {
        peer_ids vector<bt.PeerId>:MAX_PICONET_SIZE;
    });

    /// Incoming connection events from the AVDTP peer.
    /// Returns the [`fuchsia.bluetooth..PeerId`] of the newly connected peer.
    -> OnPeerConnected(struct {
        peer_id bt.PeerId;
    });
};

/// PeerController is an indirect control protocol used for driving the AVDTP library.
/// This protocol provides the client with an interface for initiating AVDTP commands
/// out of band. To drive end-to-end functionality of AVDTP see
/// [bt-profiles](//src/connectivity/bluetooth/profiles).
/// * `error PeerError` indicates a procedure failure.
/// The current Get*() & SetConfiguration() methods can be interpreted as only initiating an AVDTP
/// procedure. The implementations of the Get*() and SetConfiguration() methods use generic
/// capabilities and stream information.
protocol PeerController {
    /// Initiate a stream configuration procedure.
    /// No configuration information is specified because generic config information will
    /// be used to initiate the procedure.
    SetConfiguration() -> (struct {}) error PeerError;

    /// Initiate a procedure to get the configuration information of the peer stream.
    /// The result is discarded because PeerController only initiates the procedure.
    GetConfiguration() -> (struct {}) error PeerError;

    /// Initiate a suspend request to the stream.
    /// This command will not resume nor reconfigure the stream.
    SuspendStream() -> (struct {}) error PeerError;

    /// A "chained" set of procedures on the current stream.
    /// SuspendStream() followed by ReconfigureStream().
    /// Reconfigure() configures the stream that is currently open.
    SuspendAndReconfigure() -> (struct {}) error PeerError;

    /// Initiate stream establishment with the peer.
    EstablishStream() -> (struct {}) error PeerError;

    /// Release the current stream that is owned by the peer.
    /// If the streaming channel doesn't exist, no action will be taken.
    ReleaseStream() -> (struct {}) error PeerError;

    /// Initiate an abort procedure on the current stream.
    /// If the streaming channel doesn't exist, no action will be taken.
    AbortStream() -> (struct {}) error PeerError;

    /// Start streaming media on the current stream that is owned by the peer.
    /// If the streaming channel doesn't exist, no action will be taken.
    StartStream() -> (struct {}) error PeerError;

    /// Initiate a reconfiguration procedure for the current stream.
    /// No configuration information is specified because a generic set of config
    /// information will be used to initiate the procedure.
    ReconfigureStream() -> (struct {}) error PeerError;

    /// Initiate a procedure to get the capabilities of the peer.
    /// The result is discarded because PeerController only initiates the procedure.
    GetCapabilities() -> (struct {}) error PeerError;

    /// Initiate a procedure to get the capabilities of the peer.
    /// The result is discarded because PeerController only initiates the procedure.
    GetAllCapabilities() -> (struct {}) error PeerError;
};
