GNU Radio Manual and C++ API Reference 3.10.5.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>
15
16namespace gr {
17namespace 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 distinguises 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 */
151{
152public:
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