GNU Radio Manual and C++ API Reference 3.7.14.0
The Free & Open Software Radio Ecosystem
header_format_base.h
Go to the documentation of this file.
1/* -*- c++ -*- */
2/* Copyright 2016 Free Software Foundation, Inc.
3 *
4 * This file is part of GNU Radio
5 *
6 * GNU Radio is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
10 *
11 * GNU Radio is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Radio; see the file COPYING. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street,
19 * Boston, MA 02110-1301, USA.
20 */
21
22#ifndef INCLUDED_DIGITAL_HEADER_FORMAT_BASE_H
23#define INCLUDED_DIGITAL_HEADER_FORMAT_BASE_H
24
27#include <gnuradio/logger.h>
28#include <pmt/pmt.h>
29#include <boost/enable_shared_from_this.hpp>
30
31namespace gr {
32namespace digital {
33
34/*!
35 * \brief Base header formatter class.
36 * \ingroup packet_operators_blk
37 *
38 * \details
39 *
40 * Creates a base class that other packet formatters will inherit
41 * from. The child classes create and parse protocol-specific
42 * headers. To add a new protocol processing class, create a class
43 * that inherits from this and overload the necessary
44 * functions. The main functions to overload are:
45 *
46 * \li header_format_base::format: takes in a payload and
47 * creates a header from it.
48 *
49 * \li header_format_base::parse: receive bits and extract
50 * the header info. These are expected to be hard bits (0 or 1)
51 * that have either been sliced or gone through an FEC decoder.
52 *
53 * \li header_format_base::header_nbits: the number of bits
54 * in the full header (including an access code).
55 *
56 * \li header_format_base::header_ok: checks to see if the
57 * received header is ok. Since the header often specifies the
58 * length of the frame to decode next, it is important that this
59 * information be correct.
60 *
61 * \li header_format_base::header_payload: unpacks the header
62 * register (from the class header_buffer) as a set of bits into
63 * its component parts of the header. For example, this may find
64 * and extract the frame length field as a 16-bit value and/or
65 * flags related to the type of modulation and FEC codes used in
66 * the frame's payload.
67 *
68 * Protected functions of this class that the child class should
69 * overload include:
70 *
71 * \li enter_search
72 * \li enter_have_sync
73 * \li enter_have_header
74 *
75 * These three function represent the different states of the
76 * parsing state machine. Expected behavior is that the protocol
77 * has some known word that we are first looking for the identify
78 * the start of the frame. The parsing FSM starts in a state to
79 * search for the beginning of the header, normally by looking for
80 * a known word (i.e., the access code). Then it changes state to
81 * read in the full header. We expect that the protocol provides
82 * the length of the header for processing, so the parsing looks
83 * pulls in the full length of the header. Then it changes state
84 * to the "have header" state for checking and processing. The
85 * base class provides the basic functionality for this state
86 * machine. However, most likely, each child class must manage
87 * these states for themselves.
88 *
89 * This class is specifically designed to work with packets/frames
90 * in the asynchronous PDU architecture of GNU Radio. See the
91 * packet_format_async block for formatting the headers onto
92 * payloads and packet_parse_b block for parsing headers in a
93 * receiver.
94 *
95 * The Packet Format block takes in a PDU and uses a formatter
96 * class derived from this class to add a header onto the
97 * packet. The Packet Format blocks takes in the PDU, unpacks the
98 * message, and passes it to a formatter class' format function,
99 * which builds a header based on the payload. The header is
100 * passed back and emitted from formatter block as a separate
101 * output. The async format block, packet_format_async, has two
102 * message output ports. The 'header' port passes the header out
103 * as a PDU and the 'payload' passes the payload out as a PDU. The
104 * flowgraph can then separately modulate and combine these two
105 * pieces in the follow-on processing.
106 *
107 * The packet_sync_b block uses the formatter class by calling the
108 * 'parse' function to parse the received packet headers. This
109 * parser block is a sink for the data stream and emits a message
110 * from an 'info' port that contains an PMT dictionary of the
111 * information in the header. The formatter class determines the
112 * dictionary keys.
113 *
114 * This is the base class for dealing with formatting headers for
115 * different protocols and purposes. For other header formatting
116 * behaviors, create a child class from here and overload the
117 * format, parse, and parsing state machine functions as
118 * necessary.
119 *
120 * \sa header_format_default
121 * \sa header_format_counter
122 */
124 : public boost::enable_shared_from_this<gr::digital::header_format_base>
125{
126public:
127 typedef boost::shared_ptr<header_format_base> sptr;
128
131
132 sptr base() { return shared_from_this(); };
133 sptr formatter() { return shared_from_this(); };
134
135 /*!
136 * Function to creates a header. The child classes overload this
137 * function to format the header in the protocol-specific way.
138 *
139 * \param nbytes_in The length (in bytes) of the \p input payload
140 * \param input An array of unsigned chars of the packet payload
141 * \param output A pmt::u8vector with the new header prepended
142 * onto the input data.
143 * \param info A pmt::dict containing meta data and info about
144 * the PDU (generally from the metadata portion of the
145 * input PDU). Data can be extracted from this for the
146 * header formatting or inserted.
147 *
148 * MUST be overloaded.
149 */
150 virtual bool format(int nbytes_in,
151 const unsigned char* input,
152 pmt::pmt_t& output,
153 pmt::pmt_t& info) = 0;
154
155 /*!
156 * Parses a header. This function is overloaded in the child
157 * class, which knows how to convert the incoming hard bits (0's
158 * and 1's) back into a packet header.
159 *
160 * \param nbits_in The number of bits in the input array.
161 * \param input The input as hard decision bits.
162 * \param info A vector of pmt::dicts to hold any meta data or
163 * info about the PDU. When parsing the header, the
164 * formatter can add info from the header into this dict.
165 * Each packet has a single PMT dictionary of info, so
166 * the vector length is the number of packets received
167 * extracted during one call to this parser function.
168 * \param nbits_processed Number of input bits actually
169 * processed; If all goes well, this is nbits_in. A
170 * premature return after a bad header could be less than
171 * this.
172 *
173 * MUST be overloaded.
174 */
175 virtual bool parse(int nbits_in,
176 const unsigned char* input,
177 std::vector<pmt::pmt_t>& info,
178 int& nbits_processed) = 0;
179
180 /*!
181 * Returns the length of the formatted header in bits.
182 * MUST be overloaded.
183 */
184 virtual size_t header_nbits() const = 0;
185
186 /*!
187 * Returns the length of the formatted header in bytes.
188 * Auto-calculated from the overloaded header_nbits().
189 */
190 size_t header_nbytes() const;
191
192protected:
193 enum state_t { STATE_SYNC_SEARCH, STATE_HAVE_SYNC };
194
195 state_t d_state; //!< state of the state machine
196 header_buffer d_hdr_reg; //!< header_buffer object to hold header bits
197 pmt::pmt_t d_info; //!< info captured from the header
198
199 //! Enter Search state of the state machine to find the access code.
200 virtual void enter_search();
201
202 //! Access code found, start getting the header
203 virtual void enter_have_sync();
204
205 //! Header found, setup for pulling in the hard decision bits
206 virtual void enter_have_header(int payload_len);
207
208 //! Verify that the header is valid
209 virtual bool header_ok() = 0;
210
211 /*! Get info from the header; return payload length and package
212 * rest of data in d_info dictionary.
213 */
214 virtual int header_payload() = 0;
215
216 /*! Used by blocks to access the logger system.
217 */
220};
221
222} // namespace digital
223} // namespace gr
224
225#endif /* INCLUDED_DIGITAL_HEADER_FORMAT_BASE_H */
Helper class for handling payload headers.
Definition: header_buffer.h:169
Base header formatter class.
Definition: header_format_base.h:125
pmt::pmt_t d_info
info captured from the header
Definition: header_format_base.h:197
gr::logger_ptr d_debug_logger
Definition: header_format_base.h:219
virtual bool header_ok()=0
Verify that the header is valid.
gr::logger_ptr d_logger
Definition: header_format_base.h:218
header_buffer d_hdr_reg
header_buffer object to hold header bits
Definition: header_format_base.h:196
virtual size_t header_nbits() const =0
virtual void enter_have_sync()
Access code found, start getting the header.
virtual bool format(int nbytes_in, const unsigned char *input, pmt::pmt_t &output, pmt::pmt_t &info)=0
sptr base()
Definition: header_format_base.h:132
boost::shared_ptr< header_format_base > sptr
Definition: header_format_base.h:127
state_t d_state
state of the state machine
Definition: header_format_base.h:195
state_t
Definition: header_format_base.h:193
virtual void enter_have_header(int payload_len)
Header found, setup for pulling in the hard decision bits.
virtual void enter_search()
Enter Search state of the state machine to find the access code.
sptr formatter()
Definition: header_format_base.h:133
virtual bool parse(int nbits_in, const unsigned char *input, std::vector< pmt::pmt_t > &info, int &nbits_processed)=0
#define DIGITAL_API
Definition: gr-digital/include/gnuradio/digital/api.h:30
Include this header to use the message passing features.
Definition: basic_block.h:45
void * logger_ptr
Definition: logger.h:696
boost::intrusive_ptr< pmt_base > pmt_t
typedef for shared pointer (transparent reference counting). See http://www.boost....
Definition: pmt.h:56