/* -*- c++ -*- */
/*
 * @file
 * @author Piotr Krysik <ptrkrysik@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 "universal_ctrl_chans_demapper_impl.h"
#include <grgsm/endian.h>
#include <grgsm/gsmtap.h>
#include <set>

#define BURST_SIZE 148

namespace gr {
  namespace gsm {

    universal_ctrl_chans_demapper::sptr
    universal_ctrl_chans_demapper::make(unsigned int timeslot_nr, const std::vector<int> &downlink_starts_fn_mod51, const std::vector<int> &downlink_channel_types, const std::vector<int> &downlink_subslots, const std::vector<int> &uplink_starts_fn_mod51, const std::vector<int> &uplink_channel_types, const std::vector<int> &uplink_subslots)
    {     
      return gnuradio::get_initial_sptr
        (new universal_ctrl_chans_demapper_impl(timeslot_nr, downlink_starts_fn_mod51, downlink_channel_types, downlink_subslots, uplink_starts_fn_mod51, uplink_channel_types, uplink_subslots));
    }

    /*
     * The private constructor
     */
    universal_ctrl_chans_demapper_impl::universal_ctrl_chans_demapper_impl(unsigned int timeslot_nr, const std::vector<int> &downlink_starts_fn_mod51, const std::vector<int> &downlink_channel_types, const std::vector<int> &downlink_subslots, const std::vector<int> &uplink_starts_fn_mod51, const std::vector<int> &uplink_channel_types, const std::vector<int> &uplink_subslots)
      : gr::block("universal_ctrl_chans_demapper",
              gr::io_signature::make(0, 0, 0),
              gr::io_signature::make(0, 0, 0)),
        d_timeslot_nr(timeslot_nr),
        d_downlink_starts_fn_mod51(51, 0),
        d_downlink_channel_types(51, 0),
        d_downlink_subslots(102, 0),
        d_uplink_starts_fn_mod51(51, 0),
        d_uplink_channel_types(51, 0),
        d_uplink_subslots(102, 0)
    {
        if(downlink_starts_fn_mod51.size() != 51  ||
           downlink_channel_types.size()   != 51  ||
           downlink_subslots.size()        != 102 ||
           uplink_starts_fn_mod51.size()   != 51  ||
           uplink_channel_types.size()     != 51  ||
           uplink_subslots.size()          != 102 )
        {
            std::cout << "Check lengths of the vectors passed to the universal demapper - _starts_fn_mod15 and _sublots should have 51 elements, _subslots should have 102 elements" << std::endl;
            std::runtime_error("Check lengths of the vectors passed to the universal demapper - _starts_fn_mod15 and _sublots should have 51 elements, _subslots should have 102 elements");
        }
        std::copy(downlink_starts_fn_mod51.begin(), downlink_starts_fn_mod51.end(), d_downlink_starts_fn_mod51.begin());
        std::copy(downlink_channel_types.begin(), downlink_channel_types.end(), d_downlink_channel_types.begin());
        std::copy(downlink_subslots.begin(), downlink_subslots.end(), d_downlink_subslots.begin());
        std::copy(uplink_starts_fn_mod51.begin(), uplink_starts_fn_mod51.end(), d_uplink_starts_fn_mod51.begin());
        std::copy(uplink_channel_types.begin(), uplink_channel_types.end(), d_uplink_channel_types.begin());
        std::copy(uplink_subslots.begin(), uplink_subslots.end(), d_uplink_subslots.begin());
       
        message_port_register_in(pmt::mp("bursts"));
        set_msg_handler(pmt::mp("bursts"), boost::bind(&universal_ctrl_chans_demapper_impl::filter_ctrl_chans, this, _1));
        message_port_register_out(pmt::mp("bursts"));
    }

    /*
     * Our virtual destructor.
     */
    universal_ctrl_chans_demapper_impl::~universal_ctrl_chans_demapper_impl()
    {
    }
    
    void universal_ctrl_chans_demapper_impl::filter_ctrl_chans(pmt::pmt_t msg)
    {
        pmt::pmt_t header_plus_burst = pmt::cdr(msg);
        gsmtap_hdr * header = (gsmtap_hdr *)pmt::blob_data(header_plus_burst);

        if(header->timeslot==d_timeslot_nr)
        {
            int * starts_fn_mod51;
            int * channel_types;
            int * subslots;
            uint32_t * frame_numbers;
            pmt::pmt_t * bursts;                  
            
            uint32_t frame_nr = be32toh(header->frame_number); //get frame number
            uint32_t fn_mod51 = frame_nr % 51; //frame number modulo 51
            
            //crate new message
            int8_t new_msg[sizeof(gsmtap_hdr)+BURST_SIZE];
            gsmtap_hdr * new_hdr = (gsmtap_hdr*)new_msg;
            memcpy(new_msg, header, sizeof(gsmtap_hdr)+BURST_SIZE);
            pmt::pmt_t msg_binary_blob = pmt::make_blob(new_msg,sizeof(gsmtap_hdr)+BURST_SIZE);
            pmt::pmt_t msg_out = pmt::cons(pmt::PMT_NIL, msg_binary_blob);

            //get information if burst is from uplink or downlink            
            bool uplink_burst = (be16toh(header->arfcn) & 0x4000) ? true : false;

            //select right set of configuration and history for uplink or downlink
            if(uplink_burst) {
                starts_fn_mod51 = &d_uplink_starts_fn_mod51[0];
                channel_types = &d_uplink_channel_types[0];
                subslots = &d_uplink_subslots[0];
                frame_numbers = d_uplink_frame_numbers;
                bursts = d_uplink_bursts;
            } else {
                starts_fn_mod51 = &d_downlink_starts_fn_mod51[0];
                channel_types = &d_downlink_channel_types[0];
                subslots = &d_downlink_subslots[0];
                frame_numbers = d_downlink_frame_numbers;
                bursts = d_downlink_bursts;
            }
                      
            uint32_t fn51_start = starts_fn_mod51[fn_mod51];
            uint32_t fn51_stop = fn51_start + 3;
            uint32_t ch_type = channel_types[fn_mod51];

            if(ch_type != 0)
            {
                new_hdr->sub_type = ch_type;
            }
            new_hdr->sub_slot = subslots[fn_mod51 + (51 * (frame_nr % 2))];
            
            if(fn_mod51>=fn51_start && fn_mod51<=fn51_stop)
            {
                uint32_t ii = fn_mod51 - fn51_start;
                frame_numbers[ii] = frame_nr;
                bursts[ii] = msg_out;
            }
            
            if(fn_mod51==fn51_stop)
            {
                //check for a situation where some bursts were lost
                //in this situation frame numbers won't be consecutive
                bool frames_are_consecutive = true;
                for(int jj=1; jj<4; jj++)
                {
                    if((frame_numbers[jj] - frame_numbers[jj-1])!=1)
                    {
                        frames_are_consecutive = false;
                    }
                }
                if(frames_are_consecutive)
                {
                    //send bursts to the output
                    for(int jj=0; jj<4; jj++)
                    {
                        message_port_pub(pmt::mp("bursts"), bursts[jj]);
                    }
                } 
            }
        }
    }
  } /* namespace gsm */
} /* namespace gr */
