/* -*- c++ -*- */
/* @file
 * @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 <boost/lexical_cast.hpp>

#include "udp_socket.h"
#include "trx_impl.h"

#define BURST_SIZE     148
#define DATA_IF_MTU    160

namespace gr {
  namespace grgsm {

    trx::sptr
    trx::make(
      const std::string &remote_addr,
      const std::string &base_port)
    {
      int base_port_int = boost::lexical_cast<int> (base_port);

      return gnuradio::get_initial_sptr
        (new trx_impl(remote_addr, base_port_int));
    }

    /*
     * The private constructor
     */
    trx_impl::trx_impl(const std::string &remote_addr, int base_port)
    : gr::block("trx",
        gr::io_signature::make(0, 0, 0),
        gr::io_signature::make(0, 0, 0))
    {
        message_port_register_in(pmt::mp("bursts"));
        message_port_register_out(pmt::mp("bursts"));

        // Bind a port handler
        set_msg_handler(pmt::mp("bursts"),
          boost::bind(&trx_impl::handle_dl_burst, this, _1));

        // Prepare port numbers
        std::string clck_src_port = boost::lexical_cast<std::string> (base_port + 0);
        std::string clck_dst_port = boost::lexical_cast<std::string> (base_port + 100);
        std::string data_src_port = boost::lexical_cast<std::string> (base_port + 2);
        std::string data_dst_port = boost::lexical_cast<std::string> (base_port + 102);

        // Init DATA & CLCK interfaces
        d_data_sock = new udp_socket(remote_addr,
          data_src_port, data_dst_port, DATA_IF_MTU);
        d_clck_sock = new udp_socket(remote_addr,
          clck_src_port, clck_dst_port, DATA_IF_MTU);

        // Bind DATA interface handler
        d_data_sock->udp_rx_handler = boost::bind(
          &trx_impl::handle_ul_burst, this, _1, _2);
    }

    /*
     * Our virtual destructor.
     */
    trx_impl::~trx_impl()
    {
        // Release all UDP sockets and free memory
        delete d_data_sock;
        delete d_clck_sock;
    }

    /*
     * Create an UDP payload with clock indication
     */
    void
    trx_impl::clck_ind_send(uint32_t frame_nr)
    {
      char buf[20];
      size_t n;

      n = snprintf(buf, 20, "IND CLOCK %u", frame_nr);
      d_clck_sock->udp_send((uint8_t *) buf, n + 1);
    }

    /*
     * Create an UDP payload with burst bits
     * and some channel data.
     */
    void
    trx_impl::burst_pack(pmt::pmt_t msg, uint8_t *buf)
    {
      pmt::pmt_t header_plus_burst = pmt::cdr(msg);

      // Extract GSMTAP header from message
      gsmtap_hdr *header = (gsmtap_hdr *)
        pmt::blob_data(header_plus_burst);

      // Pack timeslot index
      buf[0] = header->timeslot;

      // Extract frame number
      uint32_t frame_nr = be32toh(header->frame_number);

      // HACK: send clock indications every 51-th frame
      if (frame_nr % 51 == 0)
        clck_ind_send(frame_nr);

      // Pack frame number
      buf[1] = (frame_nr >> 24) & 0xff;
      buf[2] = (frame_nr >> 16) & 0xff;
      buf[3] = (frame_nr >>  8) & 0xff;
      buf[4] = (frame_nr >>  0) & 0xff;

      // Pack RSSI (-dBm)
      buf[5] = -(uint8_t) header->signal_dbm;

      // Pack correlator timing offset (TOA)
      // FIXME: where to find this value?
      buf[6] = 0;
      buf[7] = 0;

      // Extract bits {0..1} from message
      // Despite GR-GSM uses int8_t, they are not real sbits {-127..127}
      uint8_t *burst = (uint8_t *)
        (pmt::blob_data(header_plus_burst)) + sizeof(gsmtap_hdr);

      // Convert to transceiver interface specific bits {255..0}
      for (int i = 0; i < 148; i++)
        buf[8 + i] = burst[i] ? 255 : 0;

      // Fill two unused bytes
      buf[156] = 0x00;
      buf[157] = 0x00;
    }

    void
    trx_impl::handle_dl_burst(pmt::pmt_t msg)
    {
      // 8 bytes of header + 148 bytes of burst
      // + two unused, but required bytes
      // otherwise bursts would be rejected
      uint8_t buf[158];

      // Compose a new UDP payload with burst
      burst_pack(msg, buf);

      // Send a burst
      d_data_sock->udp_send(buf, 158);
    }

    void
    trx_impl::handle_ul_burst(uint8_t *payload, size_t len)
    {
      // Check length according to the protocol
      if (len != 154)
        return;

      /* Make sure TS index is correct */
      if (payload[0] >= 8)
        return;

      /* Unpack and check frame number */
      uint32_t fn = (payload[1] << 24)
        | (payload[2] << 16)
        | (payload[3] << 8)
        | payload[4];

      if (fn >= 2715648)
        return;

      // Prepare a buffer for GSMTAP header and burst
      uint8_t buf[sizeof(gsmtap_hdr) + BURST_SIZE];

      // Set up pointer to GSMTAP header structure
      struct gsmtap_hdr *header = (struct gsmtap_hdr *) buf;
      memset(header, 0x00, sizeof(struct gsmtap_hdr));

      // Fill in basic info
      header->version = GSMTAP_VERSION;
      header->hdr_len = sizeof(gsmtap_hdr) / 4;
      header->type = GSMTAP_TYPE_UM_BURST;

      // Set timeslot index and frame number
      header->timeslot = payload[0];
      header->frame_number = htobe32(fn);

      // HACK: use GSMTAP_BURST_NORMAL for now
      // FIXME: We will need to distinguish between RACN and NORMAL
      header->sub_type = GSMTAP_BURST_NORMAL;

      // Copy burst bits (0 & 1) for source message
      memcpy(buf + sizeof(gsmtap_hdr), payload + 6, BURST_SIZE);

      // Create a pmt blob
      pmt::pmt_t blob = pmt::make_blob(buf, sizeof(gsmtap_hdr) + BURST_SIZE);
      pmt::pmt_t msg = pmt::cons(pmt::PMT_NIL, blob);

      /* Send a message to the output */
      message_port_pub(pmt::mp("bursts"), msg);
    }

  } /* namespace grgsm */
} /* namespace gr */
