/* -*- 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 "grgsm/misc_utils/udp_socket.h"
#include "trx_burst_if_impl.h"

#define BURST_SIZE     148
#define DATA_IF_MTU    160

/**
 * 41-bit RACH synchronization sequence
 * GSM 05.02 Chapter 5.2.7 Access burst (AB)
 */
static uint8_t rach_synch_seq[] = {
  0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
  1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0,
  1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
};

namespace gr {
  namespace gsm {

    trx_burst_if::sptr
    trx_burst_if::make(
      const std::string &bind_addr,
      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_burst_if_impl(bind_addr, remote_addr,
          base_port_int));
    }

    /*
     * The private constructor
     */
    trx_burst_if_impl::trx_burst_if_impl(
      const std::string &bind_addr,
      const std::string &remote_addr,
      int base_port
    ) : gr::block("trx_burst_if",
        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_burst_if_impl::handle_dl_burst, this, _1));

        // Prepare port numbers
        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 interface
        d_data_sock = new udp_socket(bind_addr, data_src_port,
          remote_addr, data_dst_port, DATA_IF_MTU);

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

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

    /*
     * Check if burst is a RACH burst
     */
    bool trx_burst_if_impl::detect_rach(uint8_t *burst)
    {
      // Compare synchronization sequence
      for (int i = 0; i < 41; i++)
        if (burst[i + 8] != rach_synch_seq[i])
          return false;

      // Make sure TB and GP are filled by 0x00
      for (int i = 0; i < 63; i++)
        if (burst[i + 85] != 0x00)
          return false;

      return true;
    }

    /*
     * Create an UDP payload with burst bits
     * and some channel data.
     */
    void
    trx_burst_if_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);

      // 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_burst_if_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_burst_if_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);

      // Check if one is a RACH burst
      header->sub_type = detect_rach(payload + 6) ?
        GSMTAP_BURST_ACCESS : 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 gsm */
} /* namespace gr */
