#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @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.
#
#

from gnuradio import blocks
from gnuradio import eng_notation
from gnuradio import gr
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from math import pi
from optparse import OptionParser

import grgsm
import osmosdr
import pmt
import signal
import sys


class grgsm_capture(gr.top_block):

    def __init__(self, fc, gain, samp_rate, ppm, arfcn, cfile=None, burst_file=None, band=None, verbose=False, rec_length=None, args=""):

        gr.top_block.__init__(self, "Gr-gsm Capture")
                
        ##################################################
        # Parameters
        ##################################################
        self.fc = fc
        self.gain = gain
        self.samp_rate = samp_rate
        self.ppm = ppm
        self.arfcn = arfcn
        self.cfile = cfile
        self.burst_file = burst_file
        self.band = band
        self.verbose = verbose
        self.shiftoff = shiftoff = 400e3
        self.rec_length = rec_length
        
        ##################################################
        # Processing Blocks
        ##################################################

        self.rtlsdr_source = osmosdr.source( args="numchan=" + str(1) + " " + "" )
        self.rtlsdr_source.set_sample_rate(samp_rate)
        self.rtlsdr_source.set_center_freq(fc - shiftoff, 0)
        self.rtlsdr_source.set_freq_corr(ppm, 0)
        self.rtlsdr_source.set_dc_offset_mode(2, 0)
        self.rtlsdr_source.set_iq_balance_mode(2, 0)
        self.rtlsdr_source.set_gain_mode(True, 0)
        self.rtlsdr_source.set_gain(gain, 0)
        self.rtlsdr_source.set_if_gain(20, 0)
        self.rtlsdr_source.set_bb_gain(20, 0)
        self.rtlsdr_source.set_antenna("", 0)
        self.rtlsdr_source.set_bandwidth(250e3+abs(shiftoff), 0)
        self.blocks_rotator = blocks.rotator_cc(-2*pi*shiftoff/samp_rate)
        
        if self.rec_length is not None:
            self.blocks_head_0 = blocks.head(gr.sizeof_gr_complex, int(samp_rate*rec_length))
        
        if self.verbose or self.burst_file:
            self.gsm_receiver = grgsm.receiver(4, ([self.arfcn]), ([]))
            self.gsm_input = grgsm.gsm_input(
                ppm=0,
                osr=4,
                fc=fc,
                samp_rate_in=samp_rate,
            )
            self.gsm_clock_offset_control = grgsm.clock_offset_control(fc-shiftoff)

        if self.burst_file:
            self.gsm_burst_file_sink = grgsm.burst_file_sink(self.burst_file)

        if self.cfile:
            self.blocks_file_sink = blocks.file_sink(gr.sizeof_gr_complex*1, self.cfile, False)
            self.blocks_file_sink.set_unbuffered(False)

        if self.verbose:
            self.gsm_bursts_printer_0 = grgsm.bursts_printer(pmt.intern(""),
                                                             False, False, False, False)

        ##################################################
        # Connections
        ##################################################

        if self.rec_length is not None: #if recording length is defined connect head block after the source
            self.connect((self.rtlsdr_source, 0), (self.blocks_head_0, 0))
            self.connect((self.blocks_head_0, 0), (self.blocks_rotator, 0))
        else:
            self.connect((self.rtlsdr_source, 0), (self.blocks_rotator, 0))

        if self.cfile:
            self.connect((self.blocks_rotator, 0), (self.blocks_file_sink, 0))

        if self.verbose or self.burst_file:
            self.connect((self.gsm_input, 0), (self.gsm_receiver, 0))
            self.connect((self.blocks_rotator, 0), (self.gsm_input, 0))
            self.msg_connect(self.gsm_clock_offset_control, "ppm", self.gsm_input, "ppm_in")
            self.msg_connect(self.gsm_receiver, "measurements", self.gsm_clock_offset_control, "measurements")

            if self.burst_file:
                self.msg_connect(self.gsm_receiver, "C0", self.gsm_burst_file_sink, "in")
            if self.verbose:
                self.msg_connect(self.gsm_receiver, "C0", self.gsm_bursts_printer_0, "bursts")

    def get_fc(self):
        return self.fc

    def set_fc(self, fc):
        self.fc = fc
        if self.verbose or self.burst_file:
            self.gsm_input.set_fc(self.fc)
            
    def get_arfcn(self):
        return self.arfcn

    def set_arfcn(self, arfcn):
        self.arfcn = arfcn
        if self.verbose or self.burst_file:
            self.gsm_receiver.set_cell_allocation([self.arfcn])
            if options.band:
                new_freq = grgsm.arfcn.arfcn2downlink(self.arfcn, self.band)
            else:
                for band in grgsm.arfcn.get_bands():
                    if grgsm.arfcn.is_valid_arfcn(arfcn, band):
                        new_freq = grgsm.arfcn.arfcn2downlink(arfcn, band)
                        break
            self.set_fc(new_freq)

    def get_gain(self):
        return self.gain

    def set_gain(self, gain):
        self.gain = gain

    def get_samp_rate(self):
        return self.samp_rate

    def set_samp_rate(self, samp_rate):
        self.samp_rate = samp_rate
        self.rtlsdr_source.set_sample_rate(self.samp_rate)
        if self.verbose or self.burst_file:
            self.gsm_input.set_samp_rate_in(self.samp_rate)

    def get_ppm(self):
        return self.ppm

    def set_ppm(self, ppm):
        self.ppm = ppm
        self.set_ppm_slider(self.ppm)

    def get_rec_length(self):
        return self.rec_length

    def set_rec_length(self, rec_length):
        self.rec_length = rec_length
        self.blocks_head_0.set_length(int(self.samp_rate*self.rec_length))


if __name__ == '__main__':

    parser = OptionParser(option_class=eng_option, usage="%prog [options]",
                          description="RTL-SDR capturing app of gr-gsm.")

    parser.add_option("-f", "--fc", dest="fc", type="eng_float", 
                      help="Set frequency [default=%default]")
    
    parser.add_option("-a", "--arfcn", dest="arfcn", type="intx", 
                      help="Set ARFCN instead of frequency. In some cases you may have to provide the GSM band also")
    
    parser.add_option("-g", "--gain", dest="gain", type="eng_float", 
                      default=eng_notation.num_to_str(30),
                      help="Set gain [default=%default]")
    
    parser.add_option("-s", "--samp-rate", dest="samp_rate", type="eng_float", 
                      default=eng_notation.num_to_str(2000000.052982),
                      help="Set samp_rate [default=%default]")
    
    parser.add_option("-p", "--ppm", dest="ppm", type="intx", default=0,
                      help="Set ppm [default=%default]")
    
    parser.add_option("-b", "--burst-file", dest="burst_file", 
                      help="File where the captured bursts are saved")
    
    parser.add_option("-c", "--cfile", dest="cfile", 
                      help="File where the captured data are saved")
    
    bands_list = ", ".join(grgsm.arfcn.get_bands())
    parser.add_option("--band", dest="band", 
                      help="Specify the GSM band for the frequency.\nAvailable bands are: " + bands_list + ".\nIf no band is specified, it will be determined automatically, defaulting to 0." )
    
    parser.add_option("", "--args", dest="args", type="string", default="",
        help="Set device arguments [default=%default]")

    parser.add_option("-v", "--verbose", action="store_true", 
                      help="If set, the captured bursts are printed to stdout")

    parser.add_option("-T", "--rec-length", dest="rec_length", type="eng_float",
        help="Set length of recording in seconds [default=%default]")

    (options, args) = parser.parse_args()
    
    if options.cfile is None and options.burst_file is None:
        parser.error("Please provide a cfile or a burst file (or both) to save the captured data\n")
        
    if (options.fc is None and options.arfcn is None) or (options.fc is not None and options.arfcn is not None):
        parser.error("You have to provide either a frequency or an ARFCN (but not both).\n")
        
    arfcn = 0
    fc = 939.4e6
    if options.arfcn:
        if options.band:
            if options.band not in grgsm.arfcn.get_bands():
                parser.error("Invalid GSM band\n")
            elif not grgsm.arfcn.is_valid_arfcn(options.arfcn, options.band):
                parser.error("ARFCN is not valid in the specified band\n")
            else:
                arfcn = options.arfcn
                fc = grgsm.arfcn.arfcn2downlink(arfcn, options.band)
        else:
            arfcn = options.arfcn
            for band in grgsm.arfcn.get_bands():
                if grgsm.arfcn.is_valid_arfcn(arfcn, band):
                    fc = grgsm.arfcn.arfcn2downlink(arfcn, band)
                    break
    elif options.fc:
        fc = options.fc
        if options.band:
            if options.band not in grgsm.arfcn.get_bands():
                parser.error("Invalid GSM band\n")
            elif not grgsm.arfcn.is_valid_downlink(options.fc, options.band):
                parser.error("Frequency is not valid in the specified band\n")
            else:
                arfcn = grgsm.arfcn.downlink2arfcn(options.fc, options.band)
        else:
            for band in grgsm.arfcn.get_bands():
                if grgsm.arfcn.is_valid_downlink(options.fc, band):
                    arfcn = grgsm.arfcn.downlink2arfcn(options.fc, band)
                    break
     
    tb = grgsm_capture(fc=fc, gain=options.gain, samp_rate=options.samp_rate,
                         ppm=options.ppm, arfcn=arfcn, cfile=options.cfile, 
                         burst_file=options.burst_file, band=options.band, verbose=options.verbose,
                         rec_length=options.rec_length)
    
    def signal_handler(signal, frame):
        tb.stop()
        tb.wait()        
        sys.exit(0)
        
    signal.signal(signal.SIGINT, signal_handler)

    tb.start()
    tb.wait()
