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