/* -*- 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 <grgsm/endian.h>
#include <grgsm/gsmtap.h>
#include <grgsm/gsm_constants.h>
#include "gen_test_ab_impl.h"

namespace gr {
  namespace gsm {

    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,
    };
  
    static uint8_t AB[] = { 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//    static uint8_t AB[] = {0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1};
// static uint8_t AB[] = { 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1};
//  static uint8_t AB[] = {1,1,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,0,1,0,1,0,1,1,1,0,0,0,0,1,1,1,0,0,1,0,0,0,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,1,0,0,1,0,1,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
//  ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
    gen_test_ab::sptr
    gen_test_ab::make()
    {
      return gnuradio::get_initial_sptr
        (new gen_test_ab_impl());
    }

    /*
     * The private constructor
     */
    gen_test_ab_impl::gen_test_ab_impl()
      : gr::block("gen_test_ab",
              gr::io_signature::make(0, 0, 0),
              gr::io_signature::make(0, 0, 0))
    {
        message_port_register_in(pmt::intern("bursts_in"));
        message_port_register_out(pmt::intern("bursts_out"));

        set_msg_handler(pmt::intern("bursts_in"),  boost::bind(&gen_test_ab_impl::generate_ab,   this, _1));
    }

    /*
     * Our virtual destructor.
     */
    gen_test_ab_impl::~gen_test_ab_impl()
    {
    }
    
    void gen_test_ab_impl::generate_ab(pmt::pmt_t burst)
    {
        uint8_t buf[sizeof(gsmtap_hdr) + 148];
        struct gsmtap_hdr *tap_header = (struct gsmtap_hdr *) buf;
        uint8_t *access_burst = buf + sizeof(gsmtap_hdr);

//        memset(access_burst, 0, 8); /* TB */
//        memcpy(access_burst + 8, rach_synch_seq, 41); /* sync seq */
//        memcpy(access_burst + 49, AB, 36); /* payload */
//        memset(access_burst + 85, 0, 63); /* TB + GP */
        
        memcpy(access_burst, AB, 148);
        
        gsmtap_hdr * header = (gsmtap_hdr *)(pmt::blob_data(pmt::cdr(burst)));
        uint32_t frame_nr = be32toh(header->frame_number);
        frame_nr = (frame_nr+51)% (26*51*2048);
        
        tap_header->version = GSMTAP_VERSION;
        tap_header->hdr_len = sizeof(gsmtap_hdr) / 4;
        tap_header->type = GSMTAP_TYPE_UM_BURST;
        tap_header->sub_type = GSMTAP_BURST_ACCESS;
        tap_header->frame_number = htobe32(frame_nr);
        tap_header->timeslot = header->timeslot;
        tap_header->arfcn = 0;
        
        pmt::pmt_t blob = pmt::make_blob(buf, sizeof(gsmtap_hdr) + BURST_SIZE);
        pmt::pmt_t pdu_header = pmt::make_dict();
        
        pmt::pmt_t new_msg = pmt::cons(pdu_header, blob);
        message_port_pub(pmt::intern("bursts_out"), new_msg);
    }
  } /* namespace gsm */
} /* namespace gr */

