/* -*- c++ -*- */
/* @file
 * @author (C) 2015 by Roman Khassraf <rkhassraf@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 "burst_source_impl.h"
#include "stdio.h"
#include <boost/scoped_ptr.hpp>
#include <grgsm/gsmtap.h>
#include <grgsm/endian.h>

namespace gr {
  namespace gsm {

    burst_source::sptr
    burst_source::make(const std::vector<int> &framenumbers,
            const std::vector<int> &timeslots,
            const std::vector<std::string> &burst_data)
    {
      return gnuradio::get_initial_sptr
        (new burst_source_impl(framenumbers, timeslots, burst_data));
    }

    /*
     * The private constructor
     */
    burst_source_impl::burst_source_impl(const std::vector<int> &framenumbers,
            const std::vector<int> &timeslots,
            const std::vector<std::string> &burst_data)
      : gr::block("burst_source",
              gr::io_signature::make(0, 0, 0),
              gr::io_signature::make(0, 0, 0)),
              d_finished(false)
    {
        message_port_register_out(pmt::mp("out"));
        set_framenumbers(framenumbers);
        set_timeslots(timeslots);
        set_burst_data(burst_data);
    }

    /*
     * Our virtual destructor.
     */
    burst_source_impl::~burst_source_impl()
    {
        if (d_finished == false){
            d_finished = true;
        }
    }

    void burst_source_impl::set_framenumbers(const std::vector<int> &framenumbers)
    {
        d_framenumbers = framenumbers;
    }

    void  burst_source_impl::set_timeslots(const std::vector<int> &timeslots)
    {
        d_timeslots = timeslots;
    }

    void burst_source_impl::set_burst_data(const std::vector<std::string> &burst_data)
    {
        d_burst_data = burst_data;
    }

    bool burst_source_impl::start()
    {
        d_finished = false;
        d_thread = boost::shared_ptr<gr::thread::thread>
            (new gr::thread::thread(boost::bind(&burst_source_impl::run, this)));
        return block::start();
    }

    bool burst_source_impl::stop()
    {
        d_finished = true;
        d_thread->interrupt();
        d_thread->join();
        return block::stop();
    }

    bool burst_source_impl::finished()
    {
        return d_finished;
    }

    void burst_source_impl::run()
    {
        for (int i=0; i<d_burst_data.size(); i++)
        {
            if (d_burst_data[i].length() == BURST_SIZE &&
                d_timeslots[i] >= 0 && d_timeslots[i] <= 7 &&
                d_framenumbers[i] >= 0 && d_framenumbers[i] <= (26 * 51 * 2048 - 1))
            {
                boost::scoped_ptr<gsmtap_hdr> tap_header(new gsmtap_hdr());

                tap_header->version = GSMTAP_VERSION;
                tap_header->hdr_len = sizeof(gsmtap_hdr)/4;
                tap_header->type = GSMTAP_TYPE_UM_BURST;
                tap_header->timeslot = d_timeslots[i];
                tap_header->frame_number = htobe32(d_framenumbers[i]);
                tap_header->sub_type = GSMTAP_BURST_NORMAL;
                tap_header->arfcn = 0;
                tap_header->signal_dbm = 0;
                tap_header->snr_db = 0;

                uint8_t burst[BURST_SIZE];

                for (int j=0; j<BURST_SIZE; j++)
                {
                    if (d_burst_data[i][j] == '0')
                    {
                        burst[j] = 0;
                    }
                    else
                    {
                        burst[j] = 1;
                    }
                }

                int8_t header_plus_burst[sizeof(gsmtap_hdr) + BURST_SIZE];
                memcpy(header_plus_burst, tap_header.get(), sizeof(gsmtap_hdr));
                memcpy(header_plus_burst + sizeof(gsmtap_hdr), burst, BURST_SIZE);

                pmt::pmt_t blob_header_plus_burst = pmt::make_blob(header_plus_burst, sizeof(gsmtap_hdr) + BURST_SIZE);
                pmt::pmt_t msg = pmt::cons(pmt::PMT_NIL, blob_header_plus_burst);

                message_port_pub(pmt::mp("out"), msg);
            }
        }
        post(pmt::mp("system"), pmt::cons(pmt::mp("done"), pmt::from_long(1)));
    }
  } /* namespace gsm */
} /* namespace gr */


