GNU Radio Manual and C++ API Reference  3.10.9.1
The Free & Open Software Radio Ecosystem
header_format_default.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /* Copyright 2015-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_FORMAT_DEFAULT_H
11 #define INCLUDED_DIGITAL_HEADER_FORMAT_DEFAULT_H
12 
13 #include <gnuradio/digital/api.h>
16 #include <gnuradio/logger.h>
17 #include <pmt/pmt.h>
18 
19 namespace gr {
20 namespace digital {
21 
22 /*!
23  * \brief Default header formatter for PDU formatting.
24  * \ingroup packet_operators_blk
25  *
26  * \details
27  * Used to handle the default packet header.
28  *
29  * See the parent class header_format_base for details of how
30  * these classes operate.
31  *
32  * The default header created in this base class consists of an
33  * access code and the packet length. The length is encoded as a
34  * 16-bit value repeated twice:
35  *
36  * \verbatim
37  | access code | hdr | payload |
38  \endverbatim
39  *
40  * Where the access code is <= 64 bits and hdr is:
41  *
42  * \verbatim
43  | 0 -- 15 | 16 -- 31 |
44  | pkt len | pkt len |
45  \endverbatim
46  *
47  * The access code and header are formatted for network byte order.
48  *
49  * This header generator does not calculate or append a CRC to the
50  * packet. Use the CRC32 Async block for that before adding the
51  * header. The header's length will then measure the payload plus
52  * the CRC length (4 bytes for a CRC32).
53  *
54  * The default header parser produces a PMT dictionary that
55  * contains the following keys. All formatter blocks MUST produce
56  * these two values in any dictionary.
57  *
58  * \li "payload symbols": the number of symbols in the
59  * payload. The payload decoder will have to know how this relates
60  * to the number of bits received. This block knows nothing about
61  * the payload modulation or the number of bits/symbol. Use the
62  * gr::digital::header_format_counter for that purpose.
63  *
64  * \sa header_format_counter
65  * \sa header_format_crc
66  * \sa header_format_ofdm
67  */
69 {
70 public:
71  typedef std::shared_ptr<header_format_default> sptr;
72  header_format_default(const std::string& access_code, int threshold, int bps);
74 
75  /*!
76  * Creates a header from the access code and packet length and
77  * creates an output header as a PMT vector in the form:
78  *
79  * \verbatim
80  | access code | pkt len | pkt len |
81  \endverbatim
82  *
83  * \param nbytes_in The length (in bytes) of the \p input payload
84  * \param input An array of unsigned chars of the packet payload
85  * \param output A pmt::u8vector with the new header prepended
86  * onto the input data.
87  * \param info A pmt::dict containing meta data and info about
88  * the PDU (generally from the metadata portion of the
89  * input PDU). Data can be extracted from this for the
90  * header formatting or inserted.
91  */
92  bool format(int nbytes_in,
93  const unsigned char* input,
94  pmt::pmt_t& output,
95  pmt::pmt_t& info) override;
96 
97  /*!
98  * Parses a header of the form:
99  *
100  * \verbatim
101  | access code | pkt len | pkt len | payload |
102  \endverbatim
103  *
104  * This is implemented as a state machine that starts off
105  * searching for the access code. Once found, the access code is
106  * used to find the start of the packet and the following
107  * header. This default header encodes the length of the payload
108  * a 16 bit integer twice. The state machine finds the header
109  * and checks that both payload length values are the same. It
110  * then goes into its final state that reads in the payload
111  * (based on the payload length) and produces a payload as a PMT
112  * u8 vector of packed bytes.
113  *
114  * \param nbits_in The number of bits in the input array.
115  * \param input The input as hard decision bits.
116  * \param info A vector of pmt::dicts to hold any meta data or
117  * info about the PDU. When parsing the header, the
118  * formatter can add info from the header into this dict.
119  * Each packet has a single PMT dictionary of info, so
120  * the vector length is the number of packets received
121  * extracted during one call to this parser function.
122  * \param nbits_processed Number of input bits actually
123  * processed; If all goes well, this is nbits_in. A
124  * premature return after a bad header could be less than
125  * this.
126  */
127  bool parse(int nbits_in,
128  const unsigned char* input,
129  std::vector<pmt::pmt_t>& info,
130  int& nbits_processed) override;
131 
132  /*!
133  * Returns the length of the formatted header in bits.
134  */
135  size_t header_nbits() const override;
136 
137  /*!
138  * Updates the access code. Must be a string of 1's and 0's and
139  * <= 64 bits.
140  */
141  bool set_access_code(const std::string& access_code);
142 
143  /*!
144  * Returns the formatted access code as a 64-bit register.
145  */
146  unsigned long long access_code() const;
147 
148  /*!
149  * Sets the threshold for number of access code bits can be in
150  * error before detection. Defaults to 0.
151  */
152  void set_threshold(unsigned int thresh = 0);
153 
154  /*!
155  * Returns threshold value for access code detection.
156  */
157  unsigned int threshold() const;
158 
159  /*!
160  * Factory to create an async packet header formatter; returns
161  * an sptr to the object.
162  *
163  * \param access_code An access code that is used to find and
164  * synchronize the start of a packet. Used in the parser and in
165  * other blocks like a corr_est block that helps trigger the
166  * receiver. Can be up to 64-bits long.
167  * \param threshold How many bits can be wrong in the access
168  * code and still count as correct.
169  * \param bps The number of bits/second used in the payload's
170  * modulator.
171  */
172  static sptr make(const std::string& access_code, int threshold, int bps = 1);
173 
174 protected:
175  uint64_t d_access_code; //!< register to hold the access code
176  size_t d_access_code_len; //!< length in bits of the access code
177 
178  uint16_t d_bps; //!< bits/sec of payload modulation
179 
180  unsigned long long d_data_reg; //!< used to look for access_code
181  unsigned long long d_mask; /*!< masks access_code bits (top N bits are set where
182  N is the number of bits in the access code) */
183  unsigned int d_threshold; //!< how many bits may be wrong in sync vector
184 
185  int d_pkt_len; //!< Length of the packet to put into the output buffer
186  int d_pkt_count; //!< Number of bytes bits already received
187 
188  int d_nbits; //!< num bits processed since reset
189 
190  //! Access code found, start getting the header
191  void enter_have_sync() override;
192 
193  //! Header found, setup for pulling in the hard decision bits
194  void enter_have_header(int payload_len) override;
195 
196  //! Verify that the header is valid
197  bool header_ok() override;
198 
199  /*! Get info from the header; return payload length and package
200  * rest of data in d_info dictionary.
201  */
202  int header_payload() override;
203 };
204 
205 } // namespace digital
206 } // namespace gr
207 
208 #endif /* INCLUDED_DIGITAL_HEADER_FORMAT_DEFAULT_H */
Base header formatter class.
Definition: header_format_base.h:112
std::shared_ptr< header_format_base > sptr
Definition: header_format_base.h:114
Default header formatter for PDU formatting.
Definition: header_format_default.h:69
size_t d_access_code_len
length in bits of the access code
Definition: header_format_default.h:176
bool parse(int nbits_in, const unsigned char *input, std::vector< pmt::pmt_t > &info, int &nbits_processed) override
uint16_t d_bps
bits/sec of payload modulation
Definition: header_format_default.h:178
int d_nbits
num bits processed since reset
Definition: header_format_default.h:188
unsigned int threshold() const
void enter_have_header(int payload_len) override
Header found, setup for pulling in the hard decision bits.
static sptr make(const std::string &access_code, int threshold, int bps=1)
void enter_have_sync() override
Access code found, start getting the header.
unsigned long long d_mask
Definition: header_format_default.h:181
void set_threshold(unsigned int thresh=0)
unsigned long long access_code() const
unsigned long long d_data_reg
used to look for access_code
Definition: header_format_default.h:180
size_t header_nbits() const override
bool format(int nbytes_in, const unsigned char *input, pmt::pmt_t &output, pmt::pmt_t &info) override
int d_pkt_len
Length of the packet to put into the output buffer.
Definition: header_format_default.h:185
std::shared_ptr< header_format_default > sptr
Definition: header_format_default.h:71
unsigned int d_threshold
how many bits may be wrong in sync vector
Definition: header_format_default.h:183
uint64_t d_access_code
register to hold the access code
Definition: header_format_default.h:175
bool header_ok() override
Verify that the header is valid.
int d_pkt_count
Number of bytes bits already received.
Definition: header_format_default.h:186
header_format_default(const std::string &access_code, int threshold, int bps)
bool set_access_code(const std::string &access_code)
#define DIGITAL_API
Definition: gr-digital/include/gnuradio/digital/api.h:18
GNU Radio logging wrapper.
Definition: basic_block.h:29
std::shared_ptr< pmt_base > pmt_t
typedef for shared pointer (transparent reference counting).
Definition: pmt.h:83