summaryrefslogtreecommitdiff
path: root/gr-digital/include
diff options
context:
space:
mode:
Diffstat (limited to 'gr-digital/include')
-rw-r--r--gr-digital/include/digital/CMakeLists.txt39
-rw-r--r--gr-digital/include/digital/api.h2
-rw-r--r--gr-digital/include/digital/constellation.h2
-rw-r--r--gr-digital/include/digital/costas_loop_cc.h5
-rw-r--r--gr-digital/include/digital/crc32_bb.h60
-rw-r--r--gr-digital/include/digital/fll_band_edge_cc.h4
-rw-r--r--gr-digital/include/digital/header_payload_demux.h90
-rw-r--r--gr-digital/include/digital/ofdm_carrier_allocator_cvc.h107
-rw-r--r--gr-digital/include/digital/ofdm_chanest_vcvc.h95
-rw-r--r--gr-digital/include/digital/ofdm_cyclic_prefixer.h50
-rw-r--r--gr-digital/include/digital/ofdm_equalizer_base.h109
-rw-r--r--gr-digital/include/digital/ofdm_equalizer_simpledfe.h130
-rw-r--r--gr-digital/include/digital/ofdm_equalizer_static.h100
-rw-r--r--gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h62
-rw-r--r--gr-digital/include/digital/ofdm_serializer_vcc.h91
-rw-r--r--gr-digital/include/digital/ofdm_sync_sc_cfb.h78
-rw-r--r--gr-digital/include/digital/packet_header_default.h113
-rw-r--r--gr-digital/include/digital/packet_header_ofdm.h84
-rw-r--r--gr-digital/include/digital/packet_headergenerator_bb.h72
-rw-r--r--gr-digital/include/digital/packet_headerparser_b.h69
20 files changed, 1327 insertions, 35 deletions
diff --git a/gr-digital/include/digital/CMakeLists.txt b/gr-digital/include/digital/CMakeLists.txt
index 11cab88337..275da16d87 100644
--- a/gr-digital/include/digital/CMakeLists.txt
+++ b/gr-digital/include/digital/CMakeLists.txt
@@ -26,7 +26,7 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py "
#!${PYTHON_EXECUTABLE}
import sys, os, re
-sys.path.append('${GR_CORE_PYTHONPATH}')
+sys.path.append('${GR_RUNTIME_PYTHONPATH}')
os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
@@ -75,44 +75,57 @@ add_custom_target(digital_generated_includes DEPENDS
########################################################################
install(FILES
${generated_includes}
- api.h
- constellation.h
- crc32.h
- lfsr.h
- glfsr.h
- mpsk_snr_est.h
- simple_framer_sync.h
additive_scrambler_bb.h
+ api.h
binary_slicer_fb.h
clock_recovery_mm_cc.h
clock_recovery_mm_ff.h
cma_equalizer_cc.h
- cpmmod_bc.h
- constellation_receiver_cb.h
+ constellation.h
constellation_decoder_cb.h
+ constellation_receiver_cb.h
correlate_access_code_bb.h
correlate_access_code_tag_bb.h
costas_loop_cc.h
+ cpmmod_bc.h
+ crc32.h
+ crc32_bb.h
descrambler_bb.h
diff_decoder_bb.h
diff_encoder_bb.h
diff_phasor_cc.h
- framer_sink_1.h
fll_band_edge_cc.h
+ framer_sink_1.h
+ glfsr.h
glfsr_source_b.h
glfsr_source_f.h
+ header_payload_demux.h
kurtotic_equalizer_cc.h
+ lfsr.h
lms_dd_equalizer_cc.h
map_bb.h
metric_type.h
mpsk_receiver_cc.h
+ mpsk_snr_est.h
mpsk_snr_est_cc.h
+ ofdm_carrier_allocator_cvc.h
+ ofdm_chanest_vcvc.h
ofdm_cyclic_prefixer.h
+ ofdm_equalizer_base.h
+ ofdm_equalizer_simpledfe.h
+ ofdm_equalizer_static.h
ofdm_frame_acquisition.h
+ ofdm_frame_equalizer_vcvc.h
ofdm_frame_sink.h
ofdm_insert_preamble.h
ofdm_mapper_bcv.h
ofdm_sampler.h
+ ofdm_serializer_vcc.h
+ ofdm_sync_sc_cfb.h
+ packet_header_default.h
+ packet_header_ofdm.h
+ packet_headergenerator_bb.h
+ packet_headerparser_b.h
packet_sink.h
pfb_clock_sync_ccf.h
pfb_clock_sync_fff.h
@@ -120,8 +133,10 @@ install(FILES
probe_density_b.h
probe_mpsk_snr_est_c.h
scrambler_bb.h
- simple_framer.h
simple_correlator.h
+ simple_framer.h
+ simple_framer_sync.h
+ header_payload_demux.h
DESTINATION ${GR_INCLUDE_DIR}/gnuradio/digital
COMPONENT "digital_devel"
)
diff --git a/gr-digital/include/digital/api.h b/gr-digital/include/digital/api.h
index d45ace13f2..815f7b6627 100644
--- a/gr-digital/include/digital/api.h
+++ b/gr-digital/include/digital/api.h
@@ -22,7 +22,7 @@
#ifndef INCLUDED_DIGITAL_API_H
#define INCLUDED_DIGITAL_API_H
-#include <gruel/attributes.h>
+#include <attributes.h>
#ifdef gnuradio_digital_EXPORTS
# define DIGITAL_API __GR_ATTR_EXPORT
diff --git a/gr-digital/include/digital/constellation.h b/gr-digital/include/digital/constellation.h
index ee7a704eb6..a7a2ec2023 100644
--- a/gr-digital/include/digital/constellation.h
+++ b/gr-digital/include/digital/constellation.h
@@ -82,7 +82,7 @@ namespace gr {
//! Calculates metrics for all points in the constellation.
//! For use with the viterbi algorithm.
- virtual void calc_metric(const gr_complex *sample, float *metric, trellis_metric_type_t type);
+ virtual void calc_metric(const gr_complex *sample, float *metric, gr::digital::trellis_metric_type_t type);
virtual void calc_euclidean_metric(const gr_complex *sample, float *metric);
virtual void calc_hard_symbol_metric(const gr_complex *sample, float *metric);
diff --git a/gr-digital/include/digital/costas_loop_cc.h b/gr-digital/include/digital/costas_loop_cc.h
index bad6de9363..252f39914a 100644
--- a/gr-digital/include/digital/costas_loop_cc.h
+++ b/gr-digital/include/digital/costas_loop_cc.h
@@ -24,6 +24,7 @@
#define INCLUDED_DIGITAL_COSTAS_LOOP_CC_H
#include <digital/api.h>
+#include <blocks/control_loop.h>
#include <gr_sync_block.h>
namespace gr {
@@ -54,7 +55,9 @@ namespace gr {
* stream 1 is the baseband I and Q;
* stream 2 is the normalized frequency of the loop
*/
- class DIGITAL_API costas_loop_cc : virtual public gr_sync_block
+ class DIGITAL_API costas_loop_cc
+ : virtual public gr_sync_block,
+ virtual public blocks::control_loop
{
public:
// gr::digital::costas_loop_cc::sptr
diff --git a/gr-digital/include/digital/crc32_bb.h b/gr-digital/include/digital/crc32_bb.h
new file mode 100644
index 0000000000..4bfac76070
--- /dev/null
+++ b/gr-digital/include/digital/crc32_bb.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_DIGITAL_CRC32_BB_H
+#define INCLUDED_DIGITAL_CRC32_BB_H
+
+#include <digital/api.h>
+#include <gr_tagged_stream_block.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Byte-stream CRC block
+ * \ingroup digital
+ *
+ * Input: stream of bytes, which form a packet. The first byte of the packet
+ * has a tag with key "length" and the value being the number of bytes in the
+ * packet.
+ *
+ * Output: The same bytes as incoming, but trailing a CRC32 of the packet.
+ * The tag is re-set to the new length.
+ */
+ class DIGITAL_API crc32_bb : virtual public gr_tagged_stream_block
+ {
+ public:
+ typedef boost::shared_ptr<crc32_bb> sptr;
+
+ /*!
+ * \param check Set to true if you want to check CRC, false to create CRC.
+ * \param lengthtagname Length tag key
+ */
+ static sptr make(bool check=false, const std::string& lengthtagname="packet_len");
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_CRC32_BB_H */
+
diff --git a/gr-digital/include/digital/fll_band_edge_cc.h b/gr-digital/include/digital/fll_band_edge_cc.h
index 1a9fd0bf88..7b823630ed 100644
--- a/gr-digital/include/digital/fll_band_edge_cc.h
+++ b/gr-digital/include/digital/fll_band_edge_cc.h
@@ -25,7 +25,7 @@
#include <digital/api.h>
#include <gr_sync_block.h>
-#include <gri_control_loop.h>
+#include <blocks/control_loop.h>
namespace gr {
namespace digital {
@@ -84,7 +84,7 @@ namespace gr {
*/
class DIGITAL_API fll_band_edge_cc
: virtual public gr_sync_block,
- virtual public gri_control_loop
+ virtual public blocks::control_loop
{
public:
// gr::digital::fll_band_edge_cc::sptr
diff --git a/gr-digital/include/digital/header_payload_demux.h b/gr-digital/include/digital/header_payload_demux.h
new file mode 100644
index 0000000000..014e0304a2
--- /dev/null
+++ b/gr-digital/include/digital/header_payload_demux.h
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/* Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DIGITAL_HEADER_PAYLOAD_DEMUX_H
+#define INCLUDED_DIGITAL_HEADER_PAYLOAD_DEMUX_H
+
+#include <digital/api.h>
+#include <gr_block.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Header/Payload demuxer.
+ * \ingroup digital
+ *
+ * This block is designed to handle packets from a bursty transmission.
+ * Input 0 takes a continuous transmission of samples.
+ * If used, input 1 is a trigger signal. In this case, a 1 on input 1
+ * is a trigger. Otherwise, a tag with the key specified in \p trigger_tag_key
+ * is used as a trigger (its value is irrelevant).
+ *
+ * Until a trigger signal is detected, all samples are dropped onto the floor.
+ * Once a trigger is detected, a total of \p header_len items are copied to output 0.
+ * The block then stalls until it receives a message on the message port
+ * \p header_data. The message must be a PMT dictionary; all key/value pairs are
+ * copied as tags to the first item of the payload (which is assumed to be the
+ * first item after the header).
+ * The value corresponding to the key specified in \p length_tag_key is read
+ * and taken as the payload length. The payload, together with the header data
+ * as tags, is then copied to output 1.
+ *
+ * If specified, \p guard_interval items are discarded before every symbol.
+ * This is useful for demuxing bursts of OFDM signals.
+ *
+ * Any tags on the input stream are copied to the corresponding output *if* they're
+ * on an item that is propagated. Note that a tag on the header items is copied to the
+ * header stream; that means the header-parsing block must handle these tags if they
+ * should go on the payload.
+ * A special case are tags on items that make up the guard interval. These are copied
+ * to the first item of the following symbol.
+ */
+ class DIGITAL_API header_payload_demux : virtual public gr_block
+ {
+ public:
+ typedef boost::shared_ptr<header_payload_demux> sptr;
+
+ /*!
+ * \param header_len Number of symbols per header
+ * \param items_per_symbol Number of items per symbol
+ * \param guard_interval Number of items between two consecutive symbols
+ * \param length_tag_key Key of the frame length tag
+ * \param trigger_tag_key Key of the trigger tag
+ * \param output_symbols Output symbols (true) or items (false)?
+ * \param itemsize Item size (bytes per item)
+ */
+ static sptr make(
+ int header_len,
+ int items_per_symbol,
+ int guard_interval=0,
+ const std::string &length_tag_key="frame_len",
+ const std::string &trigger_tag_key="",
+ bool output_symbols=false,
+ size_t itemsize=sizeof(gr_complex)
+ );
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_HEADER_PAYLOAD_DEMUX_H */
+
diff --git a/gr-digital/include/digital/ofdm_carrier_allocator_cvc.h b/gr-digital/include/digital/ofdm_carrier_allocator_cvc.h
new file mode 100644
index 0000000000..9c743e66b3
--- /dev/null
+++ b/gr-digital/include/digital/ofdm_carrier_allocator_cvc.h
@@ -0,0 +1,107 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_H
+#define INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_H
+
+#include <digital/api.h>
+#include <gr_tagged_stream_block.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Create frequency domain OFDM symbols from complex values, add pilots.
+ * \ingroup ofdm_blk
+ *
+ * This block turns a stream of complex, scalar modulation symbols into vectors
+ * which are the input for an IFFT in an OFDM transmitter. It also supports the
+ * possibility of placing pilot symbols onto the carriers.
+ *
+ * The carriers can be allocated freely, if a carrier is not allocated, it is set
+ * to zero. This allows doing OFDMA-style carrier allocations.
+ *
+ * Input: A tagged stream of complex scalars. The first item must have a tag
+ * containing the number of complex symbols in this frame.
+ * Output: A tagged stream of complex vectors of length fft_len. This can directly
+ * be connected to an FFT block. Make sure to set this block to 'reverse'
+ * for the IFFT. If \p output_is_shifted is true, the FFT block must activate
+ * FFT shifting, otherwise, set shifting to false. If given, sync words are
+ * prepended to the output. Note that sync words are prepended verbatim,
+ * make sure they are shifted (or not).
+ *
+ * Carrier indexes are always such that index 0 is the DC carrier (note: you should
+ * not allocate this carrier). The carriers below the DC carrier are either indexed
+ * with negative numbers, or with indexes larger than \p fft_len/2. Index -1 and index
+ * \p fft_len-1 both identify the carrier below the DC carrier.
+ *
+ */
+ class DIGITAL_API ofdm_carrier_allocator_cvc : virtual public gr_tagged_stream_block
+ {
+ public:
+ typedef boost::shared_ptr<ofdm_carrier_allocator_cvc> sptr;
+
+ virtual std::string len_tag_key() = 0;
+ virtual const int fft_len() = 0;
+ virtual std::vector<std::vector<int> > occupied_carriers() = 0;
+
+ /*
+ * \param fft_len FFT length, is also the maximum width of the OFDM symbols, the
+ * output vector size and maximum value for elements in
+ * \p occupied_carriers and \p pilot_carriers.
+ * \param occupied_carriers A vector of vectors of indexes. Example: if
+ * occupied_carriers = ((1, 2, 3), (1, 2, 4)), the first
+ * three input symbols will be mapped to carriers 1, 2
+ * and 3. After that, a new OFDM symbol is started. The next
+ * three input symbols will be placed onto carriers 1, 2
+ * and 4 of the second OFDM symbol. The allocation then
+ * starts from the beginning.
+ * Order matters! The first input symbol is always mapped
+ * onto occupied_carriers[0][0].
+ * \param pilot_carriers The position of the pilot symbols. Same as occupied_carriers,
+ * but the actual symbols are taken from pilot_symbols instead
+ * of the input stream.
+ * \param pilot_symbols The pilot symbols which are placed onto the pilot carriers.
+ * pilot_symbols[0][0] is placed onto the first OFDM symbol, on
+ * carrier index pilot_carriers[0][0] etc.
+ * \param sync_words OFDM symbols that are prepended to the OFDM frame (usually for
+ * synchronisation purposes, e.g. OFDM symbols with every second
+ * sub-carrier being idle). Is a vector of complex vectors of length
+ * \p fft_len
+ * \param len_tag_key The key of the tag identifying the length of the input packet.
+ */
+ static sptr make(
+ int fft_len,
+ const std::vector<std::vector<int> > &occupied_carriers,
+ const std::vector<std::vector<int> > &pilot_carriers,
+ const std::vector<std::vector<gr_complex> > &pilot_symbols,
+ const std::vector<std::vector<gr_complex> > &sync_words,
+ const std::string &len_tag_key = "packet_len",
+ const bool output_is_shifted=true);
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_H */
+
diff --git a/gr-digital/include/digital/ofdm_chanest_vcvc.h b/gr-digital/include/digital/ofdm_chanest_vcvc.h
new file mode 100644
index 0000000000..0c29d630da
--- /dev/null
+++ b/gr-digital/include/digital/ofdm_chanest_vcvc.h
@@ -0,0 +1,95 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H
+#define INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H
+
+#include <digital/api.h>
+#include <gr_block.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Estimate channel and coarse frequency offset for OFDM from preambles
+ * \ingroup ofdm_blk
+ * \ingroup sync_blk
+ *
+ * Input: OFDM symbols (in frequency domain). The first one (or two) symbols are expected
+ * to be synchronisation symbols, which are used to estimate the coarse freq offset
+ * and the initial equalizer taps (these symbols are removed from the stream).
+ * The following \p n_data_symbols are passed through unmodified (the actual equalisation
+ * must be done elsewhere).
+ * Output: The data symbols, without the synchronisation symbols.
+ * The first data symbol passed through has two tags:
+ * 'ofdm_sync_carr_offset' (integer), the coarse frequency offset as number of carriers,
+ * and 'ofdm_sync_eq_taps' (complex vector).
+ * Any tags attached to the synchronisation symbols are attached to the first data
+ * symbol. All other tags are propagated normally.
+ *
+ * This block assumes the frequency offset is even (i.e. an integer multiple of 2).
+ *
+ * [1] Schmidl, T.M. and Cox, D.C., "Robust frequency and timing synchronization for OFDM",
+ * Communications, IEEE Transactions on, 1997.
+ * [2] K.D. Kammeyer, "Nachrichtenuebertragung," Chapter. 16.3.2.
+ */
+ class DIGITAL_API ofdm_chanest_vcvc : virtual public gr_block
+ {
+ public:
+ typedef boost::shared_ptr<ofdm_chanest_vcvc> sptr;
+
+ /*
+ * \param sync_symbol1 First synchronisation symbol in the frequency domain. Its length must be
+ * the FFT length. For Schmidl & Cox synchronisation, every second sub-carrier
+ * has to be zero.
+ * \param sync_symbol2 Second synchronisation symbol in the frequency domain. Must be equal to
+ * the FFT length, or zero length if only one synchronisation symbol is used.
+ * Using this symbol is how synchronisation is described in [1]. Leaving this
+ * empty forces us to interpolate the equalizer taps.
+ * If you are using an unusual sub-carrier configuration (e.g. because of OFDMA),
+ * this sync symbol is used to identify the active sub-carriers. If you only
+ * have one synchronisation symbol, set the active sub-carriers to a non-zero
+ * value in here, and also set \p force_one_sync_symbol parameter to true.
+ * \param n_data_symbols The number of data symbols following each set of synchronisation symbols.
+ * Must be at least 1.
+ * \param eq_noise_red_len If non-zero, noise reduction for the equalizer taps is done according
+ * to [2]. In this case, it is the channel influence time in number of
+ * samples. A good value is usually the length of the cyclic prefix.
+ * \param max_carr_offset Limit the number of sub-carriers the frequency offset can maximally be.
+ * Leave this zero to try all possibilities.
+ * \param force_one_sync_symbol See \p sync_symbol2.
+ */
+ static sptr make(
+ const std::vector<gr_complex> &sync_symbol1,
+ const std::vector<gr_complex> &sync_symbol2,
+ int n_data_symbols,
+ int eq_noise_red_len=0,
+ int max_carr_offset=-1,
+ bool force_one_sync_symbol=false
+ );
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H */
+
diff --git a/gr-digital/include/digital/ofdm_cyclic_prefixer.h b/gr-digital/include/digital/ofdm_cyclic_prefixer.h
index 551d1ee834..6292d62697 100644
--- a/gr-digital/include/digital/ofdm_cyclic_prefixer.h
+++ b/gr-digital/include/digital/ofdm_cyclic_prefixer.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
-/*
- * Copyright 2004-2006,2011,2012 Free Software Foundation, Inc.
+/*
+ * Copyright 2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -24,34 +24,48 @@
#define INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H
#include <digital/api.h>
-#include <gr_sync_interpolator.h>
+#include <gr_tagged_stream_block.h>
namespace gr {
namespace digital {
-
+
/*!
- * \brief adds a cyclic prefix vector to an input size long ofdm
- * symbol(vector) and converts vector to a stream output_size
- * long.
+ * \brief Adds a cyclic prefix and performs pulse shaping on OFDM symbols.
* \ingroup ofdm_blk
+ *
+ * Input: OFDM symbols (in the time domain, i.e. after the IFFT). Optionally,
+ * entire frames can be processed. In this case, \p len_tag_key must be
+ * specified which holds the key of the tag that denotes how
+ * many OFDM symbols are in a frame.
+ * Output: A stream of (scalar) complex symbols, which include the cyclic prefix
+ * and the pulse shaping.
+ * Note: If complete frames are processed, and \p rolloff_len is greater
+ * than zero, the final OFDM symbol is followed by the delay line of
+ * the pulse shaping.
+ *
+ * The pulse shape is a raised cosine in the time domain.
*/
- class DIGITAL_API ofdm_cyclic_prefixer : virtual public gr_sync_interpolator
+ class DIGITAL_API ofdm_cyclic_prefixer : virtual public gr_tagged_stream_block
{
- public:
- // gr::digital::ofdm_cyclic_prefixer::sptr
+ public:
typedef boost::shared_ptr<ofdm_cyclic_prefixer> sptr;
/*!
- * Make an OFDM cyclic prefix adder block.
- *
- * \param input_size size of the input symbol
- * \param output_size output of the symbol
- * (CP len = output_size - input_size)
+ * \param input_size FFT length (i.e. length of the OFDM symbols)
+ * \param output_size FFT length + cyclic prefix length (in samples)
+ * \param rolloff_len Length of the rolloff flank in samples
+ * \param len_tag_key For framed processing the key of the length tag
*/
- static sptr make(size_t input_size, size_t output_size);
+ static sptr make(
+ size_t input_size,
+ size_t output_size,
+ int rolloff_len=0,
+ const std::string &len_tag_key=""
+ );
};
- } /* namespace digital */
-} /* namespace gr */
+ } // namespace digital
+} // namespace gr
#endif /* INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H */
+
diff --git a/gr-digital/include/digital/ofdm_equalizer_base.h b/gr-digital/include/digital/ofdm_equalizer_base.h
new file mode 100644
index 0000000000..0e23eb381f
--- /dev/null
+++ b/gr-digital/include/digital/ofdm_equalizer_base.h
@@ -0,0 +1,109 @@
+/* -*- c++ -*- */
+/* Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DIGITAL_OFDM_EQUALIZER_BASE_H
+#define INCLUDED_DIGITAL_OFDM_EQUALIZER_BASE_H
+
+#include <digital/api.h>
+#include <gr_tags.h>
+#include <gr_complex.h>
+#include <boost/enable_shared_from_this.hpp>
+
+namespace gr {
+ namespace digital {
+
+ /* \brief Base class for implementation details of frequency-domain OFDM equalizers.
+ * \ingroup ofdm_blk
+ * \ingroup eq_blk
+ */
+ class DIGITAL_API ofdm_equalizer_base
+ : public boost::enable_shared_from_this<ofdm_equalizer_base>
+ {
+ protected:
+ int d_fft_len;
+ int d_carr_offset;
+
+ public:
+ typedef boost::shared_ptr<ofdm_equalizer_base> sptr;
+
+ ofdm_equalizer_base(int fft_len);
+ ~ofdm_equalizer_base();
+
+ //! Reset the channel information state knowledge
+ virtual void reset() = 0;
+ //! Set the carrier offset in integer multiples
+ void set_carrier_offset(int offset) { d_carr_offset = offset; };
+ virtual void equalize(
+ gr_complex *frame,
+ int n_sym,
+ const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(),
+ const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()) = 0;
+ //! Return the current channel state
+ virtual void get_channel_state(std::vector<gr_complex> &taps) = 0;
+ int fft_len() { return d_fft_len; };
+ sptr base() { return shared_from_this(); };
+ };
+
+
+ /* \brief Base class for implementation details of 1-dimensional OFDM FDEs which use pilot tones.
+ * \ingroup digital
+ *
+ */
+ class DIGITAL_API ofdm_equalizer_1d_pilots : public ofdm_equalizer_base
+ {
+ protected:
+ //! If \p d_occupied_carriers[k][l] is true, symbol k, carrier l is carrying data.
+ // (this is a different format than occupied_carriers!)
+ std::vector<bool> d_occupied_carriers;
+ //! If \p d_pilot_carriers[k][l] is true, symbol k, carrier l is carrying data.
+ // (this is a different format than pilot_carriers!)
+ std::vector<std::vector<bool> > d_pilot_carriers;
+ //! If \p d_pilot_carriers[k][l] is true, d_pilot_symbols[k][l] is its tx'd value.
+ // (this is a different format than pilot_symbols!)
+ std::vector<std::vector<gr_complex> > d_pilot_symbols;
+ //! In case the frame doesn't begin with OFDM symbol 0, this is the index of the first symbol
+ int d_symbols_skipped;
+ //! The current position in the set of pilot symbols
+ int d_pilot_carr_set;
+ //! Vector of length d_fft_len saving the current channel state (on the occupied carriers)
+ std::vector<gr_complex> d_channel_state;
+
+ public:
+ typedef boost::shared_ptr<ofdm_equalizer_1d_pilots> sptr;
+
+ ofdm_equalizer_1d_pilots(
+ int fft_len,
+ const std::vector<std::vector<int> > &occupied_carriers,
+ const std::vector<std::vector<int> > &pilot_carriers,
+ const std::vector<std::vector<gr_complex> > &pilot_symbols,
+ int symbols_skipped,
+ bool input_is_shifted);
+ ~ofdm_equalizer_1d_pilots();
+
+ void reset();
+ void get_channel_state(std::vector<gr_complex> &taps);
+ };
+
+ } /* namespace digital */
+} /* namespace gr */
+
+#endif /* INCLUDED_DIGITAL_OFDM_EQUALIZER_BASE_H */
+
diff --git a/gr-digital/include/digital/ofdm_equalizer_simpledfe.h b/gr-digital/include/digital/ofdm_equalizer_simpledfe.h
new file mode 100644
index 0000000000..9d286576bc
--- /dev/null
+++ b/gr-digital/include/digital/ofdm_equalizer_simpledfe.h
@@ -0,0 +1,130 @@
+/* -*- c++ -*- */
+/* Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DIGITAL_OFDM_EQUALIZER_SIMPLEDFE_H
+#define INCLUDED_DIGITAL_OFDM_EQUALIZER_SIMPLEDFE_H
+
+#include <digital/api.h>
+#include <digital/constellation.h>
+#include <digital/ofdm_equalizer_base.h>
+
+namespace gr {
+ namespace digital {
+
+ /* \brief Simple decision feedback equalizer for OFDM.
+ * \ingroup ofdm_blk
+ * \ingroup eq_blk
+ *
+ * Equalizes an OFDM signal symbol by symbol using knowledge of the
+ * complex modulations symbols.
+ * For every symbol, the following steps are performed:
+ * - On every sub-carrier, decode the modulation symbol
+ * - Use the difference between the decoded symbol and the received symbol
+ * to update the channel state on this carrier
+ * - Whenever a pilot symbol is found, it uses the known pilot symbol to
+ * update the channel state.
+ *
+ * This equalizer makes a lot of assumptions:
+ * - The initial channel state is good enough to decode the first
+ * symbol without error (unless the first symbol only consists of pilot
+ * tones)
+ * - The channel changes only very slowly, such that the channel state
+ * from one symbol is enough to decode the next
+ * - SNR low enough that equalization will always suffice to correctly
+ * decode a symbol
+ * If these assumptions are not met, the most common error is that the
+ * channel state is estimated incorrectly during equalization; after that,
+ * all subsequent symbols will be completely wrong.
+ *
+ * Note that the equalized symbols are *exact points* on the constellation.
+ * This means soft information of the modulation symbols is lost after the
+ * equalization, which is suboptimal for channel codes that use soft decision.
+ *
+ */
+ class DIGITAL_API ofdm_equalizer_simpledfe : public ofdm_equalizer_1d_pilots
+ {
+ public:
+ typedef boost::shared_ptr<ofdm_equalizer_simpledfe> sptr;
+
+ ofdm_equalizer_simpledfe(
+ int fft_len,
+ const gr::digital::constellation_sptr &constellation,
+ const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(),
+ const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(),
+ const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(),
+ int symbols_skipped = 0,
+ float alpha = 0.1,
+ bool input_is_shifted = true);
+
+ ~ofdm_equalizer_simpledfe();
+
+ void equalize(gr_complex *frame,
+ int n_sym,
+ const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(),
+ const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>());
+
+ /*
+ * \param fft_len FFT length
+ * \param constellation The constellation object describing the modulation used
+ * on the subcarriers (e.g. QPSK). This is used to decode
+ * the individual symbols.
+ * \param occupied_carriers List of occupied carriers, see ofdm_carrier_allocator
+ * for a description.
+ * \param pilot_carriers Position of pilot symbols, see ofdm_carrier_allocator
+ * for a description.
+ * \param pilot_symbols Value of pilot symbols, see ofdm_carrier_allocator
+ * for a description.
+ * \param alpha Averaging coefficient (in a nutshell, if \f$H_{i,k}\f$ is the channel
+ * state for carrier i and symbol k,
+ * \f$H_{i,k+1} = \alpha H_{i,k} + (1 - \alpha) H_{i,k+1}\f$. Make this
+ * larger if there's more noise, but keep in mind that larger values
+ * of alpha mean slower response to channel changes).
+ * \param symbols_skipped Starting position within occupied_carriers and pilot_carriers.
+ * If the first symbol of the frame was removed (e.g. to decode the
+ * header), set this make sure the pilot symbols are correctly
+ * identified.
+ * \param input_is_shifted Set this to false if the input signal is not shifted, i.e.
+ * the first input items is on the DC carrier.
+ * Note that a lot of the OFDM receiver blocks operate on shifted
+ * signals!
+ */
+ static sptr make(
+ int fft_len,
+ const gr::digital::constellation_sptr &constellation,
+ const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(),
+ const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(),
+ const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(),
+ int symbols_skipped=0,
+ float alpha=0.1,
+ bool input_is_shifted=true
+ );
+
+ private:
+ gr::digital::constellation_sptr d_constellation;
+ //! Averaging coefficient
+ float d_alpha;
+ };
+
+ } /* namespace digital */
+} /* namespace gr */
+
+#endif /* INCLUDED_DIGITAL_OFDM_EQUALIZER_SIMPLEDFE_H */
+
diff --git a/gr-digital/include/digital/ofdm_equalizer_static.h b/gr-digital/include/digital/ofdm_equalizer_static.h
new file mode 100644
index 0000000000..67586be6fb
--- /dev/null
+++ b/gr-digital/include/digital/ofdm_equalizer_static.h
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/* Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DIGITAL_OFDM_EQUALIZER_STATIC_H
+#define INCLUDED_DIGITAL_OFDM_EQUALIZER_STATIC_H
+
+#include <digital/api.h>
+#include <digital/constellation.h>
+#include <digital/ofdm_equalizer_base.h>
+
+namespace gr {
+ namespace digital {
+
+ /* \brief Very simple static equalizer for OFDM.
+ * \ingroup ofdm_blk
+ * \ingroup eq_blk
+ *
+ * This is an extremely simple equalizer. It will only work for high-SNR, very, very
+ * slowly changing channels.
+ * It simply divides the signal with the currently known channel state. Whenever
+ * a pilot symbol comes around, it updates the channel state on that particular
+ * carrier by dividing the received symbol with the known pilot symbol.
+ */
+ class DIGITAL_API ofdm_equalizer_static : public ofdm_equalizer_1d_pilots
+ {
+ public:
+ typedef boost::shared_ptr<ofdm_equalizer_static> sptr;
+
+ ofdm_equalizer_static(
+ int fft_len,
+ const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(),
+ const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(),
+ const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(),
+ int symbols_skipped = 0,
+ bool input_is_shifted = true
+ );
+ ~ofdm_equalizer_static();
+
+ /*! \brief Divide the input signal with the current channel state.
+ *
+ * Does the following (and nothing else):
+ * - Divide every OFDM symbol with the current channel state
+ * - If a pilot symbol is found, re-set the channel state by dividing the received
+ * symbol with the known pilot symbol
+ */
+ void equalize(gr_complex *frame,
+ int n_sym,
+ const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(),
+ const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>());
+
+ /*
+ * \param fft_len FFT length
+ * \param occupied_carriers List of occupied carriers, see ofdm_carrier_allocator
+ * for a description.
+ * \param pilot_carriers Position of pilot symbols, see ofdm_carrier_allocator
+ * for a description.
+ * \param pilot_symbols Value of pilot symbols, see ofdm_carrier_allocator
+ * for a description.
+ * \param symbols_skipped Starting position within occupied_carriers and pilot_carriers.
+ * If the first symbol of the frame was removed (e.g. to decode the
+ * header), set this make sure the pilot symbols are correctly
+ * identified.
+ * \param input_is_shifted Set this to false if the input signal is not shifted, i.e.
+ * the first input items is on the DC carrier.
+ * Note that a lot of the OFDM receiver blocks operate on shifted
+ * signals!
+ */
+ static sptr make(
+ int fft_len,
+ const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(),
+ const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(),
+ const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(),
+ int symbols_skipped = 0,
+ bool input_is_shifted = true
+ );
+ };
+
+ } /* namespace digital */
+} /* namespace gr */
+
+#endif /* INCLUDED_DIGITAL_OFDM_EQUALIZER_STATIC_H */
+
diff --git a/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h b/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h
new file mode 100644
index 0000000000..de74d325ad
--- /dev/null
+++ b/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/* Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_OFDM_FRAME_EQUALIZER_VCVC_H
+#define INCLUDED_OFDM_FRAME_EQUALIZER_VCVC_H
+
+#include <digital/api.h>
+#include <digital/ofdm_equalizer_base.h>
+#include <gr_tagged_stream_block.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief OFDM frame equalizer
+ * \ingroup ofdm
+ *
+ * Performs equalization in one or two dimensions on a tagged OFDM frame.
+ * Input: a tagged series of OFDM symbols.
+ * Output: The same as the input, but equalized.
+ */
+ class DIGITAL_API ofdm_frame_equalizer_vcvc : virtual public gr_tagged_stream_block
+ {
+ public:
+ typedef boost::shared_ptr<ofdm_frame_equalizer_vcvc> sptr;
+
+ /*!
+ * \param equalizer The equalizer object that will do the actual work
+ * \param len_tag_key Length tag key
+ * \param propagate_channel_state If true, the channel state after the last symbol
+ * will be added to the first symbol as a tag
+ */
+ static sptr make(
+ ofdm_equalizer_base::sptr equalizer,
+ const std::string &len_tag_key = "frame_len",
+ bool propagate_channel_state=false
+ );
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_OFDM_FRAME_EQUALIZER_VCVC_H */
+
diff --git a/gr-digital/include/digital/ofdm_serializer_vcc.h b/gr-digital/include/digital/ofdm_serializer_vcc.h
new file mode 100644
index 0000000000..c4dc36ec06
--- /dev/null
+++ b/gr-digital/include/digital/ofdm_serializer_vcc.h
@@ -0,0 +1,91 @@
+/* -*- c++ -*- */
+/* Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DIGITAL_OFDM_SERIALIZER_VCC_H
+#define INCLUDED_DIGITAL_OFDM_SERIALIZER_VCC_H
+
+#include <digital/api.h>
+#include <gr_tagged_stream_block.h>
+#include <digital/ofdm_carrier_allocator_cvc.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Serializes complex modulations symbols from OFDM sub-carriers
+ * \ingroup ofdm_blk
+ *
+ * This is the inverse block to the carrier_allocator_cvc. It outputs the
+ * complex data symbols as a tagged stream, discarding the pilot symbols.
+ *
+ * If given, two different tags are parsed: The first key (\p len_tag_key)
+ * specifies the number of OFDM symbols in the frame at the input. The
+ * second key (\p packet_len_tag_key) specifies the number of complex symbols
+ * that are coded into this frame. If given, this second key is then used
+ * at the output, otherwise, \p len_tag_key is used.
+ * If both are given, the packet length specifies the maximum number of
+ * output items, and the frame length specifies the exact number of
+ * consumed input items.
+ *
+ * Input: Complex vectors of length \p fft_len
+ * Output: Complex scalars, in the same order as specified in occupied_carriers.
+ */
+ class DIGITAL_API ofdm_serializer_vcc : virtual public gr_tagged_stream_block
+ {
+ public:
+ typedef boost::shared_ptr<ofdm_serializer_vcc> sptr;
+
+ /*!
+ * \param fft_len FFT length
+ * \param occupied_carriers See ofdm_carrier_allocator_cvc.
+ * \param len_tag_key The key of the tag identifying the length of the input frame in OFDM symbols.
+ * \param packet_len_tag_key The key of the tag identifying the number of complex symbols in this packet.
+ * \param symbols_skipped If the first symbol is not allocated as in \p occupied_carriers[0], set this
+ * \param input_is_shifted If the input has the DC carrier on index 0 (i.e. it is not FFT shifted), set this to false
+ */
+ static sptr make(
+ int fft_len,
+ const std::vector<std::vector<int> > &occupied_carriers,
+ const std::string &len_tag_key="frame_len",
+ const std::string &packet_len_tag_key="",
+ int symbols_skipped=0,
+ bool input_is_shifted=true
+ );
+
+ /*!
+ * \param allocator The carrier allocator block of which this shall be the inverse
+ * \param packet_len_tag_key The key of the tag identifying the number of complex symbols in this packet.
+ * \param symbols_skipped If the first symbol is not allocated as in \p occupied_carriers[0], set this
+ * \param input_is_shifted If the input has the DC carrier on index 0 (i.e. it is not FFT shifted), set this to false
+ */
+ static sptr make(
+ const gr::digital::ofdm_carrier_allocator_cvc::sptr &allocator,
+ const std::string &packet_len_tag_key="",
+ int symbols_skipped=0,
+ bool input_is_shifted=true
+ );
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_OFDM_SERIALIZER_VCC_H */
+
diff --git a/gr-digital/include/digital/ofdm_sync_sc_cfb.h b/gr-digital/include/digital/ofdm_sync_sc_cfb.h
new file mode 100644
index 0000000000..0c5c46f38d
--- /dev/null
+++ b/gr-digital/include/digital/ofdm_sync_sc_cfb.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_H
+#define INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_H
+
+#include <digital/api.h>
+#include <gr_hier_block2.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Schmidl & Cox synchronisation for OFDM
+ * \ingroup ofdm_blk
+ * \ingroup sync_blk
+ *
+ * Input: complex samples.
+ * Output 0: Fine frequency offset, scaled by the OFDM symbol duration.
+ * This is \f$\hat{\varphi}\f$ in [1]. The normalized frequency
+ * offset is then 2.0*output0/fft_len.
+ * Output 1: Beginning of the first OFDM symbol after the first (doubled) OFDM
+ * symbol. The beginning is marked with a 1 (it's 0 everywhere else).
+ *
+ * The evaluation of the coarse frequency offset is *not* done in this block.
+ * Also, the initial equalizer taps are not calculated here.
+ *
+ * Note that we use a different normalization factor in the timing metric than
+ * the authors do in their original work[1]. If the timing metric (8) is
+ * \f[
+ * M(d) = \frac{|P(d)|^2}{(R(d))^2},
+ * \f]
+ * we calculate the normalization as
+ * \f[
+ * R(d) = \frac{1}{2} \sum_{k=0}^{N-1} |r_{k+d}|^2,
+ * \f]
+ * i.e., we estimate the energy from *both* half-symbols. This avoids spurious detects
+ * at the end of a burst, when the energy level suddenly drops.
+ *
+ * [1] Schmidl, T.M. and Cox, D.C., "Robust frequency and timing synchronization for OFDM",
+ * Communications, IEEE Transactions on, 1997.
+ */
+ class DIGITAL_API ofdm_sync_sc_cfb : virtual public gr_hier_block2
+ {
+ public:
+ typedef boost::shared_ptr<ofdm_sync_sc_cfb> sptr;
+
+ /*! \param fft_len FFT length
+ * \param cp_len Length of the guard interval (cyclic prefix) in samples
+ */
+ static sptr make(int fft_len, int cp_len);
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_H */
+
diff --git a/gr-digital/include/digital/packet_header_default.h b/gr-digital/include/digital/packet_header_default.h
new file mode 100644
index 0000000000..d69a0f30a6
--- /dev/null
+++ b/gr-digital/include/digital/packet_header_default.h
@@ -0,0 +1,113 @@
+/* -*- c++ -*- */
+/* Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DIGITAL_PACKET_HEADER_DEFAULT_H
+#define INCLUDED_DIGITAL_PACKET_HEADER_DEFAULT_H
+
+#include <gr_tags.h>
+#include <digital/api.h>
+#include <boost/enable_shared_from_this.hpp>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Default header formatter for digital packet transmission.
+ * \ingroup digital
+ *
+ * For bursty/packetized digital transmission, packets are usually prepended
+ * with a packet header, containing the number of bytes etc.
+ * This class is not a block, but a tool to create these packet header.
+ *
+ * This is a default packet header (see header_formatter()) for a description
+ * on the header format). To create other header, derive packet header creator
+ * classes from this function.
+ *
+ * gr::digital::packet_headergenerator_bb uses header generators derived from
+ * this class to create packet headers from data streams.
+ */
+ class DIGITAL_API packet_header_default : public boost::enable_shared_from_this<gr::digital::packet_header_default>
+ {
+ public:
+ typedef boost::shared_ptr<packet_header_default> sptr;
+
+ packet_header_default(
+ long header_len,
+ const std::string &len_tag_key="packet_len",
+ const std::string &num_tag_key="packet_num",
+ int bits_per_byte=1);
+ ~packet_header_default();
+
+ sptr base() { return shared_from_this(); };
+ sptr formatter() { return shared_from_this(); };
+
+ void set_header_num(unsigned header_num) { d_header_number = header_num; };
+ long header_len() { return d_header_len; };
+ pmt::pmt_t len_tag_key() { return d_len_tag_key; };
+
+ /*!
+ * \brief Encodes the header information in the given tags into bits and places them into \p out
+ *
+ * Uses the following header format:
+ * Bits 0-11: The packet length (what was stored in the tag with key \p len_tag_key)
+ * Bits 12-27: The header number (counts up everytime this function is called)
+ * Bit 28: Even parity bit
+ * All other bits: Are set to zero
+ *
+ * If the header length is smaller than 29, bits are simply left out. For this
+ * reason, they always start with the LSB.
+ */
+ bool header_formatter(
+ long packet_len,
+ unsigned char *out,
+ const std::vector<gr_tag_t> &tags=std::vector<gr_tag_t>()
+ );
+
+ /*!
+ * \brief Inverse function to header_formatter().
+ *
+ * Reads the bit stream in \in and writes a corresponding tag into \p tags.
+ *
+ */
+ bool header_parser(
+ const unsigned char *header,
+ std::vector<gr_tag_t> &tags);
+
+ static sptr make(
+ long header_len,
+ const std::string &len_tag_key="packet_len",
+ const std::string &num_tag_key="packet_num",
+ int bits_per_byte=1);
+
+ protected:
+ long d_header_len;
+ pmt::pmt_t d_len_tag_key;
+ pmt::pmt_t d_num_tag_key;
+ int d_bits_per_byte;
+ unsigned d_header_number;
+ unsigned d_mask;
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_PACKET_HEADER_DEFAULT_H */
+
diff --git a/gr-digital/include/digital/packet_header_ofdm.h b/gr-digital/include/digital/packet_header_ofdm.h
new file mode 100644
index 0000000000..9f70900b49
--- /dev/null
+++ b/gr-digital/include/digital/packet_header_ofdm.h
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/* Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DIGITAL_PACKET_HEADER_OFDM_H
+#define INCLUDED_DIGITAL_PACKET_HEADER_OFDM_H
+
+#include <vector>
+#include <digital/api.h>
+#include <digital/packet_header_default.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Header utility for OFDM signals.
+ * \ingroup ofdm_blk
+ *
+ */
+ class DIGITAL_API packet_header_ofdm : public packet_header_default
+ {
+ public:
+ typedef boost::shared_ptr<packet_header_ofdm> sptr;
+
+ packet_header_ofdm(
+ const std::vector<std::vector<int> > &occupied_carriers,
+ int n_syms,
+ const std::string &len_tag_key="packet_len",
+ const std::string &frame_len_tag_key="frame_len",
+ const std::string &num_tag_key="packet_num",
+ int bits_per_sym=1);
+ ~packet_header_ofdm();
+
+ /*!
+ * \brief Inverse function to header_formatter().
+ *
+ * Does the same as packet_header_default::header_parser(), but
+ * adds another tag that stores the number of OFDM symbols in the
+ * packet.
+ * Note that there is usually no linear connection between the number
+ * of OFDM symbols and the packet length, because, a packet might
+ * finish mid-OFDM-symbol.
+ */
+ bool header_parser(
+ const unsigned char *header,
+ std::vector<gr_tag_t> &tags);
+
+ static sptr make(
+ const std::vector<std::vector<int> > &occupied_carriers,
+ int n_syms,
+ const std::string &len_tag_key="packet_len",
+ const std::string &frame_len_tag_key="frame_len",
+ const std::string &num_tag_key="packet_num",
+ int bits_per_sym=1);
+
+
+ protected:
+ pmt::pmt_t d_frame_len_tag_key;
+ const std::vector<std::vector<int> > d_occupied_carriers; //!< Which carriers/symbols carry data
+ int d_syms_per_set; //!< Helper variable: Total number of elements in d_occupied_carriers
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_PACKET_HEADER_OFDM_H */
+
diff --git a/gr-digital/include/digital/packet_headergenerator_bb.h b/gr-digital/include/digital/packet_headergenerator_bb.h
new file mode 100644
index 0000000000..cec860fd55
--- /dev/null
+++ b/gr-digital/include/digital/packet_headergenerator_bb.h
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/* Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_PACKET_HEADERGENERATOR_BB_H
+#define INCLUDED_PACKET_HEADERGENERATOR_BB_H
+
+#include <digital/api.h>
+#include <gr_tagged_stream_block.h>
+#include <digital/packet_header_default.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Generates a header for a tagged, streamed packet.
+ * \ingroup digital
+ *
+ * Input: A tagged stream. This is consumed entirely, it is not appended
+ * to the output stream.
+ * Output: An tagged stream containing the header. The details on the header
+ * are set in a header formatter object (of type packet_header_default
+ * or a subclass thereof). If only a number of bits is specified, a
+ * default header is generated (see packet_header_default).
+ */
+ class DIGITAL_API packet_headergenerator_bb : virtual public gr_tagged_stream_block
+ {
+ public:
+ typedef boost::shared_ptr<packet_headergenerator_bb> sptr;
+
+ /* \param header_formatter A header formatter object.
+ * \param len_tag_key Length tag key. Note that for header generation,
+ * it is irrelevant which tag names are set in the
+ * formatter object, only this value is relevant!
+ */
+ static sptr make(
+ const packet_header_default::sptr &header_formatter,
+ const std::string &len_tag_key="packet_len"
+ );
+
+ /* \param header_len If this value is given, a packet_header_default
+ * object is used to generate the header. This is
+ * the number of bits per header.
+ * \param len_tag_key Length tag key.
+ */
+ static sptr make(
+ long header_len,
+ const std::string &len_tag_key = "packet_len");
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_PACKET_HEADERGENERATOR_BB_H */
+
diff --git a/gr-digital/include/digital/packet_headerparser_b.h b/gr-digital/include/digital/packet_headerparser_b.h
new file mode 100644
index 0000000000..2dc6a80717
--- /dev/null
+++ b/gr-digital/include/digital/packet_headerparser_b.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/* Copyright 2012 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_DIGITAL_PACKET_HEADERPARSER_B_H
+#define INCLUDED_DIGITAL_PACKET_HEADERPARSER_B_H
+
+#include <digital/api.h>
+#include <gr_sync_block.h>
+#include <digital/packet_header_default.h>
+
+namespace gr {
+ namespace digital {
+
+ /*!
+ * \brief Post header metadata as a PMT
+ * \ingroup digital
+ *
+ * In a sense, this is the inverse block to packet_headergenerator_bb.
+ * The difference is, the parsed header is not output as a stream,
+ * but as a PMT dictionary, which is published to message port with
+ * the id "header_data".
+ * The dictionary consists of the tags created by the header formatter
+ * object. You should be able to use the exact same formatter object
+ * as used on the Tx side in the packet_headergenerator_bb.
+ *
+ * If only a header length is given, this block uses the default header
+ * format.
+ */
+ class DIGITAL_API packet_headerparser_b : virtual public gr_sync_block
+ {
+ public:
+ typedef boost::shared_ptr<packet_headerparser_b> sptr;
+
+ /*!
+ * \param header_formatter Header object. This should be the same as used for
+ * packet_headergenerator_bb.
+ */
+ static sptr make(const gr::digital::packet_header_default::sptr &header_formatter);
+
+ /*!
+ * \param header_len Number of bytes per header
+ * \param len_tag_key Length Tag Key
+ */
+ static sptr make(long header_len, const std::string &len_tag_key);
+ };
+
+ } // namespace digital
+} // namespace gr
+
+#endif /* INCLUDED_DIGITAL_PACKET_HEADERPARSER_B_H */
+