/* -*- c++ -*- */
/*
 * @file
 * @author 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 <grgsm/gsmtap.h>
#include <unistd.h>
#include <map>
#include <endian.h>
#include <boost/foreach.hpp>

#include "extract_immediate_assignment_impl.h"

namespace gr {
  namespace gsm {
    boost::mutex extract_immediate_assignment_mutex;

    void extract_immediate_assignment_impl::process_message(pmt::pmt_t msg){
        pmt::pmt_t message_plus_header_blob = pmt::cdr(msg);
        uint8_t * message_plus_header = (uint8_t *)pmt::blob_data(message_plus_header_blob);
        gsmtap_hdr * header = (gsmtap_hdr *)message_plus_header;
        uint8_t * msg_elements = (uint8_t *)(message_plus_header+sizeof(gsmtap_hdr));
        uint32_t frame_nr = be32toh(header->frame_number);

        if(msg_elements[2]==0x3f)
        {
            immediate_assignment current;
            current.frame_nr = frame_nr;

            /*
                channel description, see table 10.23 in GSM 04.08

                msg_elements[4], octet 2 in specs

                5 bits channel type
                    ignored in TBF
                    00001   TCH/F
                    0001T   TCH/H, subchannel/TDMA offset T
                    001TT   SDCCH/4, subchannel/TDMA offset TT
                    01TTT   SDCCH/8, subchannel/TDMA offset TTT
                3 bits timeslot number TN
            */
            current.timeslot = (msg_elements[4] & 7);

            uint8_t channeltype = (msg_elements[4] >> 3);
            uint8_t mode = msg_elements[3] & (1 << 4);
            if (mode == 0)
            {
                if (channeltype >= 8)
                {
                    current.channel_type = "SDCCH/8";
                    current.subchannel = (channeltype & 7);
                }
                else if (channeltype >= 4 && channeltype <= 7)
                {
                    current.channel_type = "SDCCH/4";
                    current.subchannel = (channeltype & 3);
                }
                else if (channeltype >= 2 && channeltype <= 3)
                {
                    current.channel_type = "TCH/H";
                    current.subchannel = (channeltype & 1);
                }
                else
                {
                    current.channel_type = "TCH/F";
                }
            }
            else
            {
                current.channel_type = "GPRS - Temporary Block Flow TBF";
            }

            /*
                msg_elements[5], msg_elements[6] are octets 3 and 4 in specs

                    3 bits training sequence (we dont process this for the moment)
                    1 bit hopping channel H

                    if H = 0:
                        2 bit spare
                        2 bit high part of single channel arfcn

                        8 bit low part of single channel arfcn

                    if H = 1:
                        4 bit high part of MAIO

                        2 bit low part of MAIO
                        6bit HSN
            */
            current.hopping = (msg_elements[5] >> 4) & 1;
            if (current.hopping)
            {
                uint8_t maio = (msg_elements[5] & 0xf) << 2;
                maio |= (msg_elements[6] >> 6);
                current.maio = maio;
                current.hsn = (msg_elements[6] & 0x3f);
            }
            else
            {
                uint16_t arfcn = (msg_elements[5] & 3) << 8;
                arfcn |= msg_elements[6];
                current.arfcn = arfcn;
            }

            // TODO: add option where request reference is set as ID,
            // so we get only one immediate assignment per reference
            /*
                msg_elements[7 - 9], octets 5 - 7 in specs : request reference, maybe later

                msg_elements[10]:   timing advance
            */
            current.timing_advance = msg_elements[10];

            /*
                msg_elements[11 - 20]:   mobile allocation, flexible length, see 10.5.2.21
            */
            uint8_t mobile_allocation_len = msg_elements[11];
            if (mobile_allocation_len > 0)
            {
                std::string ma;
                for (int i=0; i<mobile_allocation_len; i++)
                {
                    for (int j=0; j<8; j++)
                    {
                        ma.push_back('0' + ((msg_elements[12 + i] >> (7-j)) & 0x1));
                    }
                }
                current.mobile_allocation = ma;
            }

            d_assignment_map[current.frame_nr] = current;

            if (d_print_immediate_assignments)
            {
                std::cout << "\n------------------------------------------------\n" << std::endl;
                std::cout << "FrameNr: " << (unsigned)current.frame_nr << std::endl;
                std::cout << "Channel type: " << current.channel_type << std::endl;
                std::cout << "Timeslot: " << (unsigned)current.timeslot << std::endl;
                // Dont print subchannel if mode == 1 or if the assigned channel is TCH/F
                if (mode == 0 && channeltype >= 2)
                {
                    std::cout << "Subchannel: " << (unsigned)current.subchannel << std::endl;
                }
                std::cout << "Hopping: " << (unsigned)current.hopping << std::endl;
                if (current.hopping)
                {
                    std::cout << "MAIO: " << (unsigned)current.maio << std::endl;
                    std::cout << "HSN: " << (unsigned)current.hsn << std::endl;
                    std::cout << "Mobile Allocation: " << current.mobile_allocation << std::endl;
                }
                else
                {
                    std::cout << "ARFCN: " << (unsigned)current.arfcn << std::endl;
                }
                std::cout << "Timing Advance: " << (unsigned)current.timing_advance << std::endl;
            }
        }
    }

    std::vector<int> extract_immediate_assignment_impl::get_frame_numbers()
    {
        std::vector<int> fnrs;
        BOOST_FOREACH(immediate_assignment_map::value_type &i, d_assignment_map)
        {
            fnrs.push_back(i.second.frame_nr);
        }
        return fnrs;
    }

    std::vector<std::string> extract_immediate_assignment_impl::get_channel_types()
    {
        std::vector<std::string> types;
        BOOST_FOREACH(immediate_assignment_map::value_type &i, d_assignment_map)
        {
            types.push_back(i.second.channel_type);
        }
        return types;
    }

    std::vector<int> extract_immediate_assignment_impl::get_timeslots()
    {
        std::vector<int> timeslots;
        BOOST_FOREACH(immediate_assignment_map::value_type &i, d_assignment_map)
        {
            timeslots.push_back(i.second.timeslot);
        }
        return timeslots;
    }

    std::vector<int> extract_immediate_assignment_impl::get_subchannels()
    {
        std::vector<int> subchannels;
        BOOST_FOREACH(immediate_assignment_map::value_type &i, d_assignment_map)
        {
            subchannels.push_back(i.second.subchannel);
        }
        return subchannels;
    }

    std::vector<int> extract_immediate_assignment_impl::get_hopping()
    {
        std::vector<int> hopping;
        BOOST_FOREACH(immediate_assignment_map::value_type &i, d_assignment_map)
        {
            hopping.push_back(i.second.hopping);
        }
        return hopping;
    }

    std::vector<int> extract_immediate_assignment_impl::get_maios()
    {
        std::vector<int> maios;
        BOOST_FOREACH(immediate_assignment_map::value_type &i, d_assignment_map)
        {
            maios.push_back(i.second.maio);
        }
        return maios;
    }

    std::vector<int> extract_immediate_assignment_impl::get_hsns()
    {
        std::vector<int> hsns;
        BOOST_FOREACH(immediate_assignment_map::value_type &i, d_assignment_map)
        {
            hsns.push_back(i.second.hsn);
        }
        return hsns;
    }

    std::vector<int> extract_immediate_assignment_impl::get_arfcns()
    {
        std::vector<int> arfcns;
        BOOST_FOREACH(immediate_assignment_map::value_type &i, d_assignment_map)
        {
            arfcns.push_back(i.second.arfcn);
        }
        return arfcns;
    }

    std::vector<int> extract_immediate_assignment_impl::get_timing_advances()
    {
        std::vector<int> tas;
        BOOST_FOREACH(immediate_assignment_map::value_type &i, d_assignment_map)
        {
            tas.push_back(i.second.timing_advance);
        }
        return tas;
    }

    std::vector<std::string> extract_immediate_assignment_impl::get_mobile_allocations()
    {
        std::vector<std::string> mobile_allocations;
        BOOST_FOREACH(immediate_assignment_map::value_type &i, d_assignment_map)
        {
            mobile_allocations.push_back(i.second.mobile_allocation);
        }
        return mobile_allocations;
    }

    extract_immediate_assignment::sptr
    extract_immediate_assignment::make(bool print_immediate_assignments)
    {
      return gnuradio::get_initial_sptr
        (new extract_immediate_assignment_impl(print_immediate_assignments));
    }

    /*
     * The private constructor
     */
    extract_immediate_assignment_impl::extract_immediate_assignment_impl(bool print_immediate_assignments)
      : gr::block("extract_immediate_assignment",
              gr::io_signature::make(0, 0, 0),
              gr::io_signature::make(0, 0, 0))
    {
        d_print_immediate_assignments = print_immediate_assignments;
        message_port_register_in(pmt::mp("msgs"));
        set_msg_handler(pmt::mp("msgs"), boost::bind(&extract_immediate_assignment_impl::process_message, this, _1));
    }

    /*
     * Our virtual destructor.
     */
    extract_immediate_assignment_impl::~extract_immediate_assignment_impl()
    {
    }
  } /* namespace gsm */
} /* namespace gr */

