/* -*- c++ -*- */
/* @file
 * @author Piotr Krysik <ptrkrysik@gmail.com>
 * @author Vadim Yanitskiy <axilirator@gmail.com>
 * @section LICENSE
 * 
 * Gr-gsm 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.
 * 
 * Gr-gsm 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 gr-gsm; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street,
 * Boston, MA 02110-1301, USA.
 * 
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gnuradio/io_signature.h>
#include <grgsm/gsmtap.h>

#include "txtime_setter_impl.h"

#define UNKNOWN_FN 0xffffffff
#define MAX_EARLY_TIME_DIFF 10.0

namespace gr {
  namespace gsm {

    txtime_setter::sptr
    txtime_setter::make(
      uint32_t init_fn, uint64_t init_time_secs,
      double init_time_fracs, uint64_t time_hint_secs,
      double time_hint_fracs, double timing_advance,
      double delay_correction)
    {
      return gnuradio::get_initial_sptr
        (new txtime_setter_impl(init_fn, init_time_secs,
          init_time_fracs, time_hint_secs, time_hint_fracs,
          timing_advance, delay_correction));
    }

    /*
     * The private constructor
     */
    txtime_setter_impl::txtime_setter_impl(
      uint32_t init_fn, uint64_t init_time_secs,
      double init_time_fracs, uint64_t time_hint_secs,
      double time_hint_fracs, double timing_advance,
      double delay_correction
    ) : gr::block("txtime_setter",
          gr::io_signature::make(0, 0, 0),
          gr::io_signature::make(0, 0, 0)),
        d_time_hint(time_hint_secs,time_hint_fracs),
        d_time_ref(init_time_secs,init_time_fracs),
        d_delay_correction(delay_correction),
        d_timing_advance(timing_advance),
        d_fn_ref(init_fn),
        d_ts_ref(0)
    {
        // Register I/O ports
        message_port_register_in(pmt::mp("fn_time"));
        message_port_register_in(pmt::mp("bursts_in"));
        message_port_register_out(pmt::mp("bursts_out"));

        // Bind message handlers
        set_msg_handler(pmt::mp("fn_time"),
          boost::bind(&txtime_setter_impl::process_fn_time_reference,
            this, _1));
        set_msg_handler(pmt::mp("bursts_in"),
          boost::bind(&txtime_setter_impl::process_txtime_of_burst,
            this, _1));
    }

    /*
     * Our virtual destructor.
     */
    txtime_setter_impl::~txtime_setter_impl()
    {
    }
    
    void txtime_setter_impl::process_fn_time_reference(pmt::pmt_t msg)
    {
      pmt::pmt_t not_found = pmt::intern("not_found");
      pmt::pmt_t fn_time, time_hint;

      fn_time = pmt::dict_ref(msg,
        pmt::intern("fn_time"), not_found);
      time_hint = pmt::dict_ref(msg,
        pmt::intern("fn_time"), not_found);

      if (fn_time != not_found) {
        uint32_t fn_ref = static_cast<uint32_t>
          (pmt::to_uint64(pmt::car(pmt::car(fn_time))));
        uint32_t ts = static_cast<uint32_t>
          (pmt::to_uint64(pmt::cdr(pmt::car(fn_time))));
        uint64_t time_secs = pmt::to_uint64(
          pmt::car(pmt::cdr(fn_time)));
        double time_fracs = pmt::to_double(
          pmt::cdr(pmt::cdr(fn_time)));

        set_fn_time_reference(fn_ref, ts, time_secs, time_fracs);
      } else if (time_hint != not_found) {
        set_time_hint(pmt::to_uint64(pmt::car(fn_time)),
          pmt::to_double(pmt::cdr(fn_time)));
      }
    }

    void txtime_setter_impl::process_txtime_of_burst(pmt::pmt_t msg_in)
    {
      if (d_fn_ref != UNKNOWN_FN)
      {
        pmt::pmt_t blob = pmt::cdr(msg_in);

        // Extract GSMTAP header from message
        gsmtap_hdr *header = (gsmtap_hdr *) pmt::blob_data(blob);
        uint32_t frame_nr = be32toh(header->frame_number);
        uint32_t ts_num = header->timeslot;

        time_format txtime = fn_time_delta_cpp(d_fn_ref, d_time_ref,
          frame_nr, d_time_hint, ts_num, d_ts_ref);

        time_spec_t txtime_spec = time_spec_t(txtime.first, txtime.second);
        txtime_spec -= d_delay_correction;
        txtime_spec -= d_timing_advance;

        time_spec_t current_time_estimate = time_spec_t(d_time_hint.first, d_time_hint.second);

        if (txtime_spec <= current_time_estimate) { // Drop too late bursts
          std::cout << "lB" << std::flush;
        } else if (txtime_spec > current_time_estimate + MAX_EARLY_TIME_DIFF) { // Drop too early bursts
          std::cout << "eB" << std::flush;      //TODO: too early condition might happen when changing BTSes.
                                                //Wrong fn_time is applied to new or old bursts in such situation.
                                                //This solution is not perfect as MS might be blocked upto 
                                                //MAX_EARLY_TIME_DIFF seconds.
                                                //Better solution would be to indentify fn_time and burst coming
                                                //from given BTS (i.e. based on ARFCN) and dropping bursts for which
                                                //the bts_id doesn't match with bts_id of fn_time.
        } else { //process bursts that are in the right time-frame
          pmt::pmt_t tags_dict = pmt::dict_add(
            pmt::make_dict(),
            pmt::intern("tx_time"),
            pmt::make_tuple(
              pmt::from_uint64(txtime_spec.get_full_secs()),
              pmt::from_double(txtime_spec.get_frac_secs()))
          );

          tags_dict = pmt::dict_add(tags_dict,
            pmt::intern("fn"), pmt::from_uint64(frame_nr));
          tags_dict = pmt::dict_add(tags_dict,
            pmt::intern("ts"), pmt::from_uint64(ts_num));

          // Send a message to the output
          pmt::pmt_t msg_out = pmt::cons(tags_dict, pmt::cdr(msg_in));
          message_port_pub(pmt::mp("bursts_out"), msg_out);
        }
      }
    }

    void txtime_setter_impl::set_fn_time_reference(
      uint32_t fn, uint32_t ts, uint64_t time_secs,
      double time_fracs)
    {
      d_fn_ref = fn;
      d_ts_ref = ts;
      d_time_ref = std::make_pair(time_secs, time_fracs);
      set_time_hint(time_secs, time_fracs);
    }

    void txtime_setter_impl::set_time_hint(
      uint64_t time_hint_secs, double time_hint_fracs)
    {
      d_time_hint = std::make_pair(time_hint_secs, time_hint_fracs);
    }

    void txtime_setter_impl::set_delay_correction(double delay_correction)
    {
      d_delay_correction = delay_correction;
    }

    void txtime_setter_impl::set_timing_advance(double timing_advance)
    {
      d_timing_advance = timing_advance;
    }

  } /* namespace gsm */
} /* namespace gr */
