/* -*- c++ -*- */
/*
 * Copyright 2013 Free Software Foundation, Inc.
 *
 * This file is part of GNU Radio
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *
 */

#ifndef INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H
#define INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H

#include <gnuradio/block.h>
#include <gnuradio/digital/api.h>

namespace gr {
namespace digital {

/*! Estimate channel and coarse frequency offset for OFDM from preambles
 * \ingroup ofdm_blk
 * \ingroup synchronizers_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 as expected.
 *
 * Note: The vector on ofdm_sync_eq_taps is already frequency-corrected, whereas
 * the rest is not.
 *
 * 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 block
{
public:
    typedef std::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 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 */
