// Copyright 2020 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.bredr;

using fuchsia.hardware.audio;

type ScoErrorCode = strict enum {
    FAILURE = 1;
    CANCELLED = 2;
    INVALID_ARGUMENTS = 3;
    PARAMETERS_REJECTED = 4;
};

/// Codec parameter sets defined in the Hands-Free Profile specification (v1.8, section 5.7).
type HfpParameterSet = strict enum : uint8 {
    MSBC_T1 = 1;
    MSBC_T2 = 2;
    CVSD_S1 = 3;
    CVSD_S2 = 4;
    CVSD_S3 = 5;
    CVSD_S4 = 6;
    CVSD_D0 = 7;
    CVSD_D1 = 8;
};

/// The coding format used for synchronous connection data.
type CodingFormat = strict enum : uint8 {
    MULAW = 1;
    ALAW = 2;
    CVSD = 3;
    TRANSPARENT = 4;
    LINEAR_PCM = 5;
    MSBC = 6;
};

/// Indicates the audio transport that should be used for the data on a synchronous
/// connection.
type DataPath = strict enum : uint8 {
    /// The HCI transport. Data will be sent/received through the ScoConnection protocol.
    HOST = 1;

    /// Transport audio data directly between the controller and the audio hardware.
    /// The ScoConnection protocol will not be used to send/receive data.
    // TODO(fxbug.dev/62161): Document how offloading is configured.
    OFFLOAD = 2;

    /// The audio test mode transport. See Core Spec v5.2, Vol 4, Part E, Section 7.6.2 for details.
    TEST = 3;
};

type ScoConnectionParameters = table {
    /// Set of SCO parameters from the Hands-Free Profile specification.
    /// Required.
    1: parameter_set HfpParameterSet;

    /// The over-the-air coding format used for transmitted and received data.
    /// Required.
    2: air_coding_format CodingFormat;

    /// Frame size produced by the codec in the context of over-the-air coding.
    /// Required.
    3: air_frame_size uint16;

    /// Host-controller data rate in bytes/second.
    /// Required.
    4: io_bandwidth uint32;

    /// The coding format used over the transport.
    /// Required.
    5: io_coding_format CodingFormat;

    /// The number of bits in each sample/frame of data.
    /// Required.
    6: io_frame_size uint16;

    /// The data format over the transport for linear samples.
    /// Ignored for non-linear coding formats.
    /// Optional.
    /// SIGNED indicates 2's complement sign encoding.
    /// FLOAT is not supported.
    7: io_pcm_data_format fuchsia.hardware.audio.SampleFormat;

    /// For linear samples, indicates how many bit positions the MSB of the sample is away
    /// from the MSB of the data.
    /// Ignored for non-linear coding formats.
    /// Optional.
    /// Default: 0.
    8: io_pcm_sample_payload_msb_position uint8;

    /// The data transport.
    /// Required.
    9: path DataPath;

    /// Indicates the maximum data buffer size that may be sent.
    /// Optional. Only present after a connection has successfully been connected. Ignored when
    /// requesting a connection.
   10: max_tx_data_size uint16;
};

/// Inbound SCO data has a RxPacketStatus that indicates possible data loss or corruption.
type RxPacketStatus = strict enum : uint8 {
    /// The controller marked all data as "good data".
    CORRECTLY_RECEIVED_DATA = 0x0;
    /// Some of the data may have errors.
    POSSIBLY_INVALID_DATA = 0x1;
    /// All data was lost. The payload will be empty.
    NO_DATA_RECEIVED = 0x2;
    /// Some of the data was lost, and the lost regions of data will be set to 0.
    DATA_PARTIALLY_LOST = 0x3;
};

protocol ScoConnection {
    // Read the next inbound SCO payload.
    // Hangs until new data is received.
    // Only one Read request may be pending at a time. Additional requests will result in protocol
    // closure.
    Read() -> (struct {
        status_flag RxPacketStatus;
        data bytes:MAX;
    });

    // Write `data` to the SCO connection.
    // If Write tries to send more data than `max_tx_data_size`, the protocol will be closed.
    // Only one Write request may be pending at a time. Additional requests will result in protocol
    // closure.
    Write(struct {
        data bytes:MAX;
    }) -> ();
};

/// Represents an active synchronous connection request by a profile.
/// Either `Connected()` or `Error()` will be called and then server will close the protocol.
protocol ScoConnectionReceiver {
    /// Called upon successful connection establishment.
    /// `params` contains the parameters that were used to establish the connection.
    Connected(resource struct {
        connection client_end:ScoConnection;
        params ScoConnectionParameters;
    });

    /// Called when connection establishment fails or is cancelled by the host.
    Error(struct {
        error ScoErrorCode;
    });
};
