GNU Radio Manual and C++ API Reference  3.10.9.1
The Free & Open Software Radio Ecosystem
header_payload_demux.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /* Copyright 2012-2016 Free Software Foundation, Inc.
3  *
4  * This file is part of GNU Radio
5  *
6  * SPDX-License-Identifier: GPL-3.0-or-later
7  *
8  */
9 
10 #ifndef INCLUDED_DIGITAL_HEADER_PAYLOAD_DEMUX_H
11 #define INCLUDED_DIGITAL_HEADER_PAYLOAD_DEMUX_H
12 
13 #include <gnuradio/block.h>
14 #include <gnuradio/digital/api.h>
15 
16 namespace gr {
17 namespace digital {
18 
19 /*!
20  * \brief Header/Payload demuxer (HPD).
21  * \ingroup packet_operators_blk
22  *
23  * \details
24  * This block is designed to demultiplex packets from a bursty transmission.
25  * The typical application for this block is the case when you are receiving
26  * packets with yet-to-determine length. This block will pass the header
27  * section to other blocks for demodulation. Using the information from the
28  * demodulated header, it will then output the payload. The beginning of the
29  * header needs to be identified by a trigger signal (see below).
30  *
31  * \section hpd_theory_of_ops Theory of Operation
32  *
33  * Input 0 takes a continuous transmission of samples (items).
34  * Input 1 is an optional input for the trigger signal (mark beginning of
35  * packets). In this case, a non-zero value on input 1 identifies the beginning of a
36  * packet. Otherwise, a tag with the key specified in \p trigger_tag_key is used as a
37  * trigger (its value is irrelevant).
38  *
39  * Until a trigger signal is detected, all samples are dropped onto the floor.
40  * Once a trigger is detected, a total of \p header_len items are copied to output 0.
41  * The block then stalls until it receives a message on the message port
42  * \p header_data. The message must be a PMT dictionary; all key/value pairs are
43  * copied as tags to the first item of the payload (which is assumed to be the
44  * first item after the header).
45  * The value corresponding to the key specified in \p length_tag_key is read
46  * and taken as the payload length. The payload, together with the header data
47  * as tags, is then copied to output 1.
48  *
49  * If the header demodulation fails, the header must send a PMT with value
50  * pmt::PMT_F. The state gets reset and the header is ignored.
51  *
52  * \section hpd_item_sizes Symbols, Items and Item Sizes
53  *
54  * To generically and transparently handle different kinds of modulations,
55  * including OFDM, this block distinguishes between \b symbols and \b items.
56  *
57  * Items are what are consumed at the input. Anything that uses complex samples
58  * will therefore use an itemsize of `sizeof(gr_complex)`. Symbols are a way of
59  * grouping items. In OFDM, we usually don't care about individual samples, but
60  * we do care about full OFDM symbols, so we set \p items_per_symbol to the
61  * IFFT / FFT length of the OFDM modulator / demodulator.
62  * For single-carrier modulations, this value can be set to the number of
63  * samples per symbol, to handle data in number of symbols, or to 1 to
64  * handle data in number of samples.
65  * If specified, \p guard_interval items are discarded before every symbol.
66  * This is useful for demuxing bursts of OFDM signals.
67  *
68  * On the output, we can deal with symbols directly by setting \p output_symbols
69  * to true. In that case, the output item size is the <em>symbol size</em>.
70  *
71  * \b Example: OFDM with 48 sub-carriers, using a length-64 IFFT on the
72  * modulator, and a cyclic-prefix length of 16 samples. In this case,
73  * \p itemsize is `sizeof(gr_complex)`, because we're receiving complex
74  * samples. One OFDM symbol has 64 samples, hence \p items_per_symbol is
75  * set to 64, and \p guard_interval to 16. The header length is specified
76  * in number of OFDM symbols. Because we want to deal with full OFDM
77  * symbols, we set \p output_symbols to true.
78  *
79  * \b Example: PSK-modulated signals, with 4 samples per symbol. Again,
80  * \p itemsize is `sizeof(gr_complex)` because we're still dealing with
81  * complex samples. \p items_per_symbol is 4, because one item is one
82  * sample. \p guard_interval must be set to 0. The header length is
83  * given in number of PSK symbols.
84  *
85  * \section hpd_uncertainty Handling timing uncertainty on the trigger
86  *
87  * By default, the assumption is made that the trigger arrives on *exactly*
88  * the sample that the header starts. These triggers typically come from
89  * timing synchronization algorithms which may be suboptimal, and have a
90  * known timing uncertainty (e.g., we know the trigger might be a sample
91  * too early or too late).
92  *
93  * The demuxer has an option for this case, the \p header_padding. If this
94  * value is non-zero, it specifies the number of items that are prepended
95  * and appended to the header before copying it to the header output.
96  *
97  * Example: Say our synchronization algorithm can be off by up to two
98  * samples, and the header length is 20 samples. So we set \p header_len
99  * to 20, and \p header_padding to 2.
100  * Now assume a trigger arrives on sample index 100. We copy a total of
101  * 24 samples to the header port, starting at sample index 98.
102  *
103  * The payload is *not* padded. Let's say the header demod reports a
104  * payload length of 100. In the previous examples, we would copy 100
105  * samples to the payload port, starting at sample index 120 (this means
106  * the padded samples appended to the header are copied to both ports!).
107  * However, the header demodulator has the option to specify a payload
108  * offset, which cannot exceed the padding value. To do this, include
109  * a key `payload_offset` in the message sent back to the HPD. A negative
110  * value means the payload starts earlier than otherwise.
111  * (If you wanted to always pad the payload, you could set `payload_offset`
112  * to `-header_padding` and increase the reported length of the payload).
113  *
114  * Because the padding is specified in number of items, and not symbols,
115  * this value can only be multiples of the number of items per symbol *if*
116  * either \p output_symbols is true, or a guard interval is specified (or
117  * both). Note that in practice, it is rare that both a guard interval is
118  * specified *and* a padding value is required. The difference between the
119  * padding value and a guard interval is that a guard interval is part of
120  * the signal, and comes with *every* symbol, whereas the header padding
121  * is added to only the header, and is not by design.
122  *
123  * \section hpd_tag_handling Tag Handling
124  *
125  * Any tags on the input stream are copied to the corresponding output *if* they're
126  * on an item that is propagated. Note that a tag on the header items is copied to the
127  * header stream; that means the header-parsing block must handle these tags if they
128  * should go on the payload.
129  * A special case are tags on items that make up the guard interval. These are copied
130  * to the first item of the following symbol.
131  * If a tag is situated very close to the end of the payload, it might be unclear if
132  * it belongs to this packet or the following. In this case, it is possible that the
133  * tag might be propagated twice.
134  *
135  * Tags outside of packets are generally discarded. If there are tags that
136  * carry important information that must not be list, there are two
137  * additional mechanisms to preserve the tags:
138  * - Timing tags might be relevant to know \b when a packet was received. By
139  * specifying the name of a timestamp tag and the sample rate at this block, it
140  * keeps track of the time and will add the time to the first item of every packet.
141  * The name of the timestamp tag is usually 'rx_time' (see, e.g.,
142  * gr::uhd::usrp_source::make()).
143  * The time value must be specified in the UHD time format.
144  * - Other tags are simply stored and updated. As an example, the user might want to know
145  * the rx frequency, which UHD stores in the rx_freq tag. In this case, add the tag name
146  * 'rx_freq' to the list of \p special_tags. This block will then always save the most
147  * current value of 'rx_freq' and add it to the beginning of every packet.
148  *
149  */
150 class DIGITAL_API header_payload_demux : virtual public block
151 {
152 public:
153  typedef std::shared_ptr<header_payload_demux> sptr;
154 
155  /*!
156  * \param header_len Number of symbols per header
157  * \param items_per_symbol Number of items per symbol
158  * \param guard_interval Number of items between two consecutive symbols
159  * \param length_tag_key Key of the frame length tag
160  * \param trigger_tag_key Key of the trigger tag
161  * \param output_symbols Output symbols (true) or items (false)?
162  * \param itemsize Item size (bytes per item)
163  * \param timing_tag_key The name of the tag with timing information, usually
164  * 'rx_time' or empty (this means timing info is discarded) \param samp_rate Sampling
165  * rate at the input. Necessary to calculate the rx time of packets. \param
166  * special_tags A vector of strings denoting tags which shall be preserved (see \ref
167  * hpd_tag_handling) \param header_padding A number of items that is appended and
168  * prepended to the header.
169  */
170  static sptr
171  make(const int header_len,
172  const int items_per_symbol = 1,
173  const int guard_interval = 0,
174  const std::string& length_tag_key = "frame_len",
175  const std::string& trigger_tag_key = "",
176  const bool output_symbols = false,
177  const size_t itemsize = sizeof(gr_complex),
178  const std::string& timing_tag_key = "",
179  const double samp_rate = 1.0,
180  const std::vector<std::string>& special_tags = std::vector<std::string>(),
181  const size_t header_padding = 0);
182 };
183 
184 } // namespace digital
185 } // namespace gr
186 
187 #endif /* INCLUDED_DIGITAL_HEADER_PAYLOAD_DEMUX_H */
The abstract base class for all 'terminal' processing blocks.
Definition: gnuradio-runtime/include/gnuradio/block.h:63
Header/Payload demuxer (HPD).
Definition: header_payload_demux.h:151
std::shared_ptr< header_payload_demux > sptr
Definition: header_payload_demux.h:153
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)
#define DIGITAL_API
Definition: gr-digital/include/gnuradio/digital/api.h:18
std::complex< float > gr_complex
Definition: gr_complex.h:15
GR_RUNTIME_API size_t itemsize(types::vector_type type)
GNU Radio logging wrapper.
Definition: basic_block.h:29