Loading...
Searching...
No Matches
header_payload_demux.h
Go to the documentation of this file.
/* -*- c++ -*- */
/* Copyright 2012-2016 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifndef INCLUDED_DIGITAL_HEADER_PAYLOAD_DEMUX_H
#define INCLUDED_DIGITAL_HEADER_PAYLOAD_DEMUX_H
#include <gnuradio/block.h>
#include <gnuradio/digital/api.h>
namespace gr {
namespace digital {
/*!
* \brief Header/Payload demuxer (HPD).
* \ingroup packet_operators_blk
*
* \details
* This block is designed to demultiplex packets from a bursty transmission.
* The typical application for this block is the case when you are receiving
* packets with yet-to-determine length. This block will pass the header
* section to other blocks for demodulation. Using the information from the
* demodulated header, it will then output the payload. The beginning of the
* header needs to be identified by a trigger signal (see below).
*
* \section hpd_theory_of_ops Theory of Operation
*
* Input 0 takes a continuous transmission of samples (items).
* Input 1 is an optional input for the trigger signal (mark beginning of
* packets). In this case, a non-zero value on input 1 identifies the beginning of a
* packet. Otherwise, a tag with the key specified in \p trigger_tag_key is used as a
* trigger (its value is irrelevant).
*
* Until a trigger signal is detected, all samples are dropped onto the floor.
* Once a trigger is detected, a total of \p header_len items are copied to output 0.
* The block then stalls until it receives a message on the message port
* \p header_data. The message must be a PMT dictionary; all key/value pairs are
* copied as tags to the first item of the payload (which is assumed to be the
* first item after the header).
* The value corresponding to the key specified in \p length_tag_key is read
* and taken as the payload length. The payload, together with the header data
* as tags, is then copied to output 1.
*
* If the header demodulation fails, the header must send a PMT with value
* pmt::PMT_F. The state gets reset and the header is ignored.
*
* \section hpd_item_sizes Symbols, Items and Item Sizes
*
* To generically and transparently handle different kinds of modulations,
* including OFDM, this block distinguishes between \b symbols and \b items.
*
* Items are what are consumed at the input. Anything that uses complex samples
* will therefore use an itemsize of `sizeof(gr_complex)`. Symbols are a way of
* grouping items. In OFDM, we usually don't care about individual samples, but
* we do care about full OFDM symbols, so we set \p items_per_symbol to the
* IFFT / FFT length of the OFDM modulator / demodulator.
* For single-carrier modulations, this value can be set to the number of
* samples per symbol, to handle data in number of symbols, or to 1 to
* handle data in number of samples.
* If specified, \p guard_interval items are discarded before every symbol.
* This is useful for demuxing bursts of OFDM signals.
*
* On the output, we can deal with symbols directly by setting \p output_symbols
* to true. In that case, the output item size is the <em>symbol size</em>.
*
* \b Example: OFDM with 48 sub-carriers, using a length-64 IFFT on the
* modulator, and a cyclic-prefix length of 16 samples. In this case,
* \p itemsize is `sizeof(gr_complex)`, because we're receiving complex
* samples. One OFDM symbol has 64 samples, hence \p items_per_symbol is
* set to 64, and \p guard_interval to 16. The header length is specified
* in number of OFDM symbols. Because we want to deal with full OFDM
* symbols, we set \p output_symbols to true.
*
* \b Example: PSK-modulated signals, with 4 samples per symbol. Again,
* \p itemsize is `sizeof(gr_complex)` because we're still dealing with
* complex samples. \p items_per_symbol is 4, because one item is one
* sample. \p guard_interval must be set to 0. The header length is
* given in number of PSK symbols.
*
* \section hpd_uncertainty Handling timing uncertainty on the trigger
*
* By default, the assumption is made that the trigger arrives on *exactly*
* the sample that the header starts. These triggers typically come from
* timing synchronization algorithms which may be suboptimal, and have a
* known timing uncertainty (e.g., we know the trigger might be a sample
* too early or too late).
*
* The demuxer has an option for this case, the \p header_padding. If this
* value is non-zero, it specifies the number of items that are prepended
* and appended to the header before copying it to the header output.
*
* Example: Say our synchronization algorithm can be off by up to two
* samples, and the header length is 20 samples. So we set \p header_len
* to 20, and \p header_padding to 2.
* Now assume a trigger arrives on sample index 100. We copy a total of
* 24 samples to the header port, starting at sample index 98.
*
* The payload is *not* padded. Let's say the header demod reports a
* payload length of 100. In the previous examples, we would copy 100
* samples to the payload port, starting at sample index 120 (this means
* the padded samples appended to the header are copied to both ports!).
* However, the header demodulator has the option to specify a payload
* offset, which cannot exceed the padding value. To do this, include
* a key `payload_offset` in the message sent back to the HPD. A negative
* value means the payload starts earlier than otherwise.
* (If you wanted to always pad the payload, you could set `payload_offset`
* to `-header_padding` and increase the reported length of the payload).
*
* Because the padding is specified in number of items, and not symbols,
* this value can only be multiples of the number of items per symbol *if*
* either \p output_symbols is true, or a guard interval is specified (or
* both). Note that in practice, it is rare that both a guard interval is
* specified *and* a padding value is required. The difference between the
* padding value and a guard interval is that a guard interval is part of
* the signal, and comes with *every* symbol, whereas the header padding
* is added to only the header, and is not by design.
*
* \section hpd_tag_handling Tag Handling
*
* Any tags on the input stream are copied to the corresponding output *if* they're
* on an item that is propagated. Note that a tag on the header items is copied to the
* header stream; that means the header-parsing block must handle these tags if they
* should go on the payload.
* A special case are tags on items that make up the guard interval. These are copied
* to the first item of the following symbol.
* If a tag is situated very close to the end of the payload, it might be unclear if
* it belongs to this packet or the following. In this case, it is possible that the
* tag might be propagated twice.
*
* Tags outside of packets are generally discarded. If there are tags that
* carry important information that must not be list, there are two
* additional mechanisms to preserve the tags:
* - Timing tags might be relevant to know \b when a packet was received. By
* specifying the name of a timestamp tag and the sample rate at this block, it
* keeps track of the time and will add the time to the first item of every packet.
* The name of the timestamp tag is usually 'rx_time' (see, e.g.,
* gr::uhd::usrp_source::make()).
* The time value must be specified in the UHD time format.
* - Other tags are simply stored and updated. As an example, the user might want to know
* the rx frequency, which UHD stores in the rx_freq tag. In this case, add the tag name
* 'rx_freq' to the list of \p special_tags. This block will then always save the most
* current value of 'rx_freq' and add it to the beginning of every packet.
*
*/
class DIGITAL_API header_payload_demux : virtual public block
{
public:
typedef std::shared_ptr<header_payload_demux> sptr;
/*!
* \param header_len Number of symbols per header
* \param items_per_symbol Number of items per symbol
* \param guard_interval Number of items between two consecutive symbols
* \param length_tag_key Key of the frame length tag
* \param trigger_tag_key Key of the trigger tag
* \param output_symbols Output symbols (true) or items (false)?
* \param itemsize Item size (bytes per item)
* \param timing_tag_key The name of the tag with timing information, usually
* 'rx_time' or empty (this means timing info is discarded) \param samp_rate Sampling
* rate at the input. Necessary to calculate the rx time of packets. \param
* special_tags A vector of strings denoting tags which shall be preserved (see \ref
* hpd_tag_handling) \param header_padding A number of items that is appended and
* prepended to the header.
*/
static sptr
make(const int header_len,
const int items_per_symbol = 1,
const int guard_interval = 0,
const std::string& length_tag_key = "frame_len",
const std::string& trigger_tag_key = "",
const bool output_symbols = false,
const size_t itemsize = sizeof(gr_complex),
const std::string& timing_tag_key = "",
const double samp_rate = 1.0,
const std::vector<std::string>& special_tags = std::vector<std::string>(),
const size_t header_padding = 0);
};
} // namespace digital
} // namespace gr
#endif /* INCLUDED_DIGITAL_HEADER_PAYLOAD_DEMUX_H */
gr::block::block
block(void)
Definition gnuradio-runtime/include/gnuradio/block.h:806
gr::digital::header_payload_demux
Header/Payload demuxer (HPD).
Definition header_payload_demux.h:151
gr::digital::header_payload_demux::sptr
std::shared_ptr< header_payload_demux > sptr
Definition header_payload_demux.h:153
gr::digital::header_payload_demux::make
static sptr make(const int header_len, const int items_per_symbol=1, const int guard_interval=0, const std::string &length_tag_key="frame_len", const std::string &trigger_tag_key="", const bool output_symbols=false, const size_t itemsize=sizeof(gr_complex), const std::string &timing_tag_key="", const double samp_rate=1.0, const std::vector< std::string > &special_tags=std::vector< std::string >(), const size_t header_padding=0)
block.h
api.h
DIGITAL_API
#define DIGITAL_API
Definition gr-digital/include/gnuradio/digital/api.h:18
gr_complex
std::complex< float > gr_complex
Definition gr_complex.h:15
gr::digital
Definition adaptive_algorithm.h:22
gr
GNU Radio logging wrapper.
Definition basic_block.h:29