syntax = "proto3";

package dmacontroller;
import "datatypes.proto";

service DMAControllerService {
    /**
    * @brief request a limited grpc stream of acquired data
    *
    * Will start data acquisition for a given amount of samples.
    * The sample width is given by the hardware (see @link GetBytesPerSample @endlink). \n
    * If multiple channels are transmitted in time domain multiplex,
    * individual channels can be selected by passing a list of channel indices
    * to the channels parameter. An empty list will select all channels. \n
    * 
    * Note that this will affect the data rate. Especially for low sample rates it  
    * must be passed (see @link StreamRequest @endlink) to avoid timeouts. \n
    * 
    * For early cancellation see @link StreamContinuous @endlink).
    * 
    * @param msg Combination of Endpoint index, sample count, channel list and sample rate
    * (see @link StreamRequest @endlink).
    *
    * @returns binary stream of acquired data. Note: the lost sample count is enclosed in
    * the trailing metadata with the key 'lost-in-hardware'.
    **/
    rpc Snapshot         (StreamRequest) returns (stream AcquiredData) {}

    /**
    * @brief request limited data acquisition to a file on the platform
    * 
    * Will start data acquisition to a file on the platform for a given amount of samples.
    * Please see @link Snapshot @endlink for further details. \n
    *
    * @param msg Combination of a nested @link StreamRequest @endlink as well as the
    * name, subdirectory and disk type of the target target file. 
    *
    * @returns @link LostSamples @endlink number of samples lost due to overflow in the
    * hardware buffer fifo.
    **/
    rpc FileSnapshot     (FileStreamRequest) returns (LostSamples) {}

    /**
    * @brief request a continuous grpc stream of acquired data
    *
    * Will start transmitting data until the grpc stream is cancelled on client side. \n
    *
    * See @link Snapshot @endlink for more details.
    * 
    * @param msg @link StreamRequest @endlink
    **/
    rpc ContinuousStream (StreamRequest) returns (stream AcquiredData) {}
    
    /**
    * @brief request a continuous data acquisition to a file on the platform
    *
    * Will start transmitting data until the grpc call is cancelled on client side. \n
    *
    * See @link Snapshot @endlink for more details.
    * 
    * @param msg @link FileStreamRequest @endlink
    *
    * @returns @link LostSamples @endlink number of samples lost due to overflow in the
    * hardware buffer fifo.
    **/    
    rpc ContinuousFileStream(FileStreamRequest) returns (LostSamples) {}
    
    /**
    * @brief request a limited grpc stream of acquired data and additional metadata
    *
    * Will start data acquisition for a given amount of samples (See @link Snapshot @endlink)
    * The additional metadata contains the relative data fifo high watermark, which represents
    * the maximum fill level (normalized to 1.0) of the data fifo while the data was processed.
    * Further the sample loss accumulated lost sample count is transmitted.
    * 
    * For early cancellation see @link StreamContinuous @endlink).
    * 
    * @param msg Combination of Endpoint index, sample count, channel list and sample rate
    * (see @link StreamRequest @endlink).
    *
    * @returns binary stream of acquired data and metadata with each block of bytes. 
    * Note: the lost sample count is enclosed in the trailing metadata with the key 'lost-in-hardware'.
    **/
    rpc SnapshotWithMetadata (StreamRequest) returns (stream AcquiredAndMetaData) {}

    /**
    * @brief request a continuous grpc stream of acquired data with additional metadata
    *
    * see @link SnapshotWithMetadata @endlink for the stream response and @link ContinuousStream @endlink
    *
    * @param msg Combination of Endpoint index, sample count, channel list and sample rate
    * (see @link StreamRequest @endlink).
    *
    * @returns binary stream of acquired data and metadata with each block of bytes. 
    * Note: the lost sample count is enclosed in the trailing metadata with the key 'lost-in-hardware'.
    **/
    rpc ContinuousStreamWithMetadata (StreamRequest) returns (stream AcquiredAndMetaData) {}

    /**
    * @brief request binary stream of file content
    *
    * Will stream the contents of a file e. g. generated by @link FileSnapshot @endlink or
    * @link ContinuousFileStream @endlink.
    *
    * @param Combination of file name, subdirectory and disk type.
    * The path is built as follows <mount_dir(disk_type)>/DMAController/<sub_path(if set)>/<FileName> \n
    * The mount directories for different disk types are configured in the servicehub configuration file. See @link FileWriteCommand @endlink.
    * 
    * @returns binary stream of file content
    **/
    rpc FileDownload (FileRequest) returns (stream AcquiredData) {}

    /**
    * @brief get the width of one sample in bytes
    *
    * @returns sample word width in byte
    **/
    rpc GetBytesPerSample(sdr.datatypes.EndpointIndex) returns (sdr.datatypes.UInt) {}

    /**
    * @brief get the number of parallel data streams
    *
    * @returns number of parallel data streams
    **/
    rpc GetParallelStreams(sdr.datatypes.EndpointIndex) returns (sdr.datatypes.UInt) {}

}

enum DiskType {
    SD = 0;
    SSD = 2;
    USB = 3;
    RAMDISK=4;
}

message StreamRequest
{
    sdr.datatypes.EndpointIndex index = 1;        
    uint64 count=2;                 // total number of requested samples (all channels)
    repeated uint32 channels = 3;   // list of channel indices
    repeated uint32 subChains = 4;   // list of sub chain indices
    double sampleRate = 5;          // sample rate in samples per second.
    double timeout = 6;             // Timeout in seconds for stochastic data
    double acquisitionTime = 7;     // acquisition_time in sec
    bool packageMode = 8;           // defines whether tdm-data or events are stored
}

message AcquiredData{
    bytes value = 1;                // binary data
}

message AcquiredAndMetaData{
    bytes value = 1;                    // binary data
    double data_fifo_highwatermark = 2; // relative data fifo high watermark
    uint32 lost_samples = 3;            // number of samples lost in hardware due to overflow in fifo buffer
}

message FileRequest{
    string FileName = 1;            // name of target file
    string SubPath = 2;             // subdirectory of target file
    DiskType DiskType = 3;          // target disk type
}

message FileStreamRequest
{
    StreamRequest streamrequest = 1; // see @link StreamRequest @endlink    
    string FileName = 2;   // name including file extension
    DiskType DiskType = 3; // Disk type must match device mounted in directory specified in servicehub_conf.json \n Mount point is not checked.
    string SubPath = 4;    // subdirectory (will be created if non-existent)             
}

message LostSamples
{
    uint32 Hardware = 1;  // number of samples lost in hardware due to overflow in fifo buffer
}
