syntax = "proto3";
import "google/protobuf/empty.proto";
package serosystems.proto.v3.grx.spectrumd;
option java_package = "de.serosystems.proto.v3.grx.spectrumd";
option java_outer_classname = "SpectrumDProto";
/*
* This is a service for measuring spectrum occupancy.
* For that, (fft_size) samples are taken and transformed into frequency domain.
* We call this an FFT block. Then (aggregation_factor) of those blocks are
* aggregated (avg and peak=max). We call this an aggregated FFT block.
* Regarding those aggregated FFT blocks, different services are derived:
* - GetAggregatedFFTProperties() returns the fixed parameters used for
* transformation and aggregation,
* - GetAggregatedFFTBlockStream() returns a stream of aggregated FFT blocks,
* - GetWaterfallJPEG() gathers multiple FFT blocks into an waterfall plot,
* returning the plot rendered in a JPEG,
* - GetWaterfallJPEGStream() returns a stream of such rendered plots,
* - GetChannelPowerStream() re-aggregates aggregated FFT blocks over a longer
* period and for a frequency range (we call that a channel).
*/
/*
* Aggregated FFT properties.
* Response of GetAggregatedFFTProperties() call.
*/
message AggregatedFFTProperties {
/* Center Frequency [Hz]. */
uint32 center_frequency = 1;
/*
* Sample rate [Hz].
* Observed band is [-sample_rate/2,+sample_rate/2),
* centered at (center_frequency).
*/
uint32 sample_rate = 2;
/*
* FFT size, i.e. number of samples used in a single FFT block.
* This translates directly into the number of frequency bins of the FFT
* result. Each bin has bandwidth (sample_rate / fft_size).
* Thinking of a waterfall plot, this is the number of steps of the x axis
* (frequency).
*/
uint32 fft_size = 3;
/*
* Number of FFT blocks aggregated into an aggregated FFT block.
* The duration observed for a single FFT block is
* (fft_size / sample_rate). Accordingly, the duration observed for an
* aggregated FFT block is (aggregation_factor * fft_size / sample_rate).
*/
uint32 aggregation_factor = 4;
}
/*
* Aggregated (avg/peak) FFT block, basically one line of a waterfall plot.
* Has observation duration (aggregation_factor * fft_size / sample_rate).
* Response of GetAggregatedFFTBlock() call.
*/
message AggregatedFFTBlock {
/*
* Averaged FFT bins [dBm].
* Each bin has bandwidth (sample_rate / fft_size) and is averaged over
* a duration of (aggregation_factor * fft_size / sample_rate).
* The FFT bins are centered around center_frequency, i.e.
* first element corresponds to (center_frequency - 0.5 * sample_rate),
* last element corresponds to
* (center_frequency + (0.5 - 1/fft_size) * sample_rate),
* and the center frequency is found at index (fft_size/2).
* The number of FFT bins is fixed to (fft_size).
*/
repeated float bins_avg = 1;
/*
* Aggregated (peak=max) FFT bins [dBm].
* Each bin has bandwidth (sample_rate / fft_size) and is the maximum
* observed over a duration of
* (aggregation_factor * fft_size / sample_rate).
* The FFT bins are centered around center_frequency, i.e.
* first element corresponds to center_frequency - 0.5 * sample_rate,
* last element corresponds to
* (center_frequency + (0.5 - 1/fft_size) * sample_rate),
* and the center frequency is found at index (fft_size/2).
* The number of FFT bins is fixed to fft_size.
*
* Important note: intermediate peak results are highly compressed (using a
* logarithmic representation), thus you will almost certainly note
* "steps" in the data. Small values might be smaller than the average
* values or they might even be -inf, due to a low resolution for low
* values.
* In such cases, the average value represents a "better" peak.
* This should not be an issue for strong signals, though.
*/
repeated float bins_peak = 2;
}
/*
* Request of GetWaterfallJPEG() and GetWaterfallJPEGStream() calls.
*/
message GetWaterfallJPEGRequest {
/*
* Number of lines of the rendered image, defining the JPEG height [px].
* The service records num_lines aggregated FFT block messages and renders
* them as JPEG. Each line corresponds to one aggregated FFT block.
* The duration shown in the waterfall plot corresponds to
* (lines * aggregation_factor * fft_size / sample_rate)
* which is also the duration needed for the call to return.
*/
uint32 num_lines = 1;
/* Lower limit of the color scale [dBm]. */
float min_level = 2;
/* Upper limit of the color scale [dBm]. */
float max_level = 3;
/* JPEG quality [%]. */
uint32 jpeg_quality = 4;
/* Aggregation type for aggregated FFT blocks. */
enum AggregationType {
/* Aggregate blocks by average. */
AVERAGE = 0;
/* Aggregate blocks by peak. */
PEAK = 1;
}
/* Aggregation type for aggregated FFT blocks. */
AggregationType aggregation_type = 5;
}
/*
* Waterfall plot rendered as a JPEG image.
* Response of GetWaterfallJPEG() and GetWaterfallJPEGStream() calls.
*/
message WaterfallJPEGImage {
/*
* Timestamp [s since epoch UTC] for the bottom line in the JPEG.
*/
uint64 timestamp = 1;
/*
* JPEG image for waterfall plot, rendered from top (first block) to bottom
* (last block).
*/
bytes image = 2;
}
/* Request of GetChannelPowerStream() call. */
message ChannelPowerRequest {
/*
* Additional aggregation factor for channel power measurements.
* The total aggregation factor will be this factor multiplied by
* (aggregation_factor).
* The response is measured over a period of
* (channel_aggregation_factor * aggregation_factor * fft_size
* / sample_rate). This is also the time needed for the call to return.
*/
uint32 channel_aggregation_factor = 1;
/*
* Lower bin index of the FFT to be included in the result.
* See also documentation of AggregatedFFTBlock.bins_avg.
*/
uint32 lower_bin = 2;
/*
* Upper bin index of the FFT to be included in the result.
* See also documentation of AggregatedFFTBlock.bins_avg.
*/
uint32 upper_bin = 3;
}
/* Response of GetChannelPowerStream() call. */
message ChannelPower {
/*
* Timestamp [s since epoch UTC] when the measurement was finished.
*/
uint64 timestamp = 1;
/*
* Average channel power [dBm].
* Average over all
* (channel_aggregation_factor * aggregation_factor) FFT blocks,
* averaged over the channel.
*/
float average_channel_power = 2;
/*
* Peak average channel power [dBm], peak over averages:
* Peak over AggregatedFFTBlock.bins_avg averaged over the channel.
*/
float peak_average_channel_power = 3;
/*
* Peak power [dBm].
* Peak over all
* (channel_aggregation_factor * aggregation_factor) FFTs,
* averaged over the channel.
* Please observe the notes on AggregatedFFTBlock.bins_peak when
* interpreting the data.
*/
float peak_channel_power = 4;
}
/* Spectrum daemon service definition. Port 5306. */
service Spectrumd {
/* Request the aggregated FFT properties, they do not change over time. */
rpc GetAggregatedFFTProperties (google.protobuf.Empty) returns (AggregatedFFTProperties);
/* Request a stream of aggregated (avg/peak) FFT blocks. */
rpc GetAggregatedFFTBlockStream (google.protobuf.Empty) returns (stream AggregatedFFTBlock);
/* Request a single waterfall plot as JPEG image. */
rpc GetWaterfallJPEG (GetWaterfallJPEGRequest) returns (WaterfallJPEGImage);
/* Request a stream of waterfall plots as JPEG images. */
rpc GetWaterfallJPEGStream (GetWaterfallJPEGRequest) returns (stream WaterfallJPEGImage);
/* Request a stream of channel occupancy measurements. */
rpc GetChannelPowerStream (ChannelPowerRequest) returns (stream ChannelPower);
}