GNU Radio Manual and C++ API Reference  3.7.13.4
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 
25 #include <pmt/pmt.h>
26 #include <gnuradio/digital/api.h>
28 #include <gnuradio/logger.h>
29 #include <boost/enable_shared_from_this.hpp>
30 
31 namespace gr {
32  namespace 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  {
126  public:
127  typedef boost::shared_ptr<header_format_base> sptr;
128 
130  virtual ~header_format_base();
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 
192  protected:
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 */
Base header formatter class.
Definition: header_format_base.h:123
#define DIGITAL_API
Definition: gr-digital/include/gnuradio/digital/api.h:30
header_buffer d_hdr_reg
header_buffer object to hold header bits
Definition: header_format_base.h:196
state_t
Definition: header_format_base.h:193
sptr formatter()
Definition: header_format_base.h:133
gr::logger_ptr d_debug_logger
Definition: header_format_base.h:219
Include this header to use the message passing features.
Definition: logger.h:695
void * logger_ptr
Definition: logger.h:696
pmt::pmt_t d_info
info captured from the header
Definition: header_format_base.h:197
gr::logger_ptr d_logger
Definition: header_format_base.h:218
Helper class for handling payload headers.
Definition: header_buffer.h:167
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
boost::intrusive_ptr< pmt_base > pmt_t
typedef for shared pointer (transparent reference counting). See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
Definition: pmt.h:56