aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xapps/helpers/grgsm_capture280
1 files changed, 113 insertions, 167 deletions
diff --git a/apps/helpers/grgsm_capture b/apps/helpers/grgsm_capture
index b1b85a7..f698205 100755
--- a/apps/helpers/grgsm_capture
+++ b/apps/helpers/grgsm_capture
@@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-
# @file
# @author (C) 2015 by Roman Khassraf <rkhassraf@gmail.com>
+# (C) 2019 by Piotr Krysik <ptrkrysik@gmail.com>
# @section LICENSE
#
# Gr-gsm is free software; you can redistribute it and/or modify
@@ -26,217 +27,162 @@ 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
+from optparse import OptionParser, OptionGroup
import osmosdr
-import pmt
+import time
+import grgsm
import signal
import sys
-
class grgsm_capture(gr.top_block):
-
- def __init__(self, fc, gain, samp_rate, ppm, arfcn, cfile=None, burst_file=None, verbose=False, rec_length=None, args=""):
-
+ def __init__(self,
+ freq,
+ gain=30,
+ samp_rate=1e6,
+ rec_length=float('Inf'),
+ freq_corr=0,
+ output_filename=None,
+ bandwidth=0,
+ bb_gain=20,
+ if_gain=20,
+ antenna="",
+ device_args=""):
gr.top_block.__init__(self, "Gr-gsm Capture")
-
+
##################################################
- # Parameters
+ # Setting up RF source
##################################################
- 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.verbose = verbose
- self.shiftoff = shiftoff = 400e3
- self.rec_length = rec_length
-
+
+ self.sdr_source = \
+ osmosdr.source(args="numchan=1" + device_args )
+ self.sdr_source.set_sample_rate(samp_rate)
+ self.sdr_source.set_center_freq(freq, 0)
+ self.sdr_source.set_freq_corr(freq_corr, 0)
+ self.sdr_source.set_dc_offset_mode(2, 0)
+ self.sdr_source.set_iq_balance_mode(2, 0)
+ self.sdr_source.set_gain_mode(True, 0)
+ self.sdr_source.set_gain(gain, 0)
+ self.sdr_source.set_if_gain(if_gain, 0)
+ self.sdr_source.set_bb_gain(bb_gain, 0)
+ self.sdr_source.set_antenna("", 0)
+ if bandwidth != 0:
+ self.sdr_source.set_bandwidth(bandwidth, 0)
+
##################################################
- # Processing Blocks
+ # The rest of processing blocks
##################################################
- self.rtlsdr_source = osmosdr.source( args="numchan=" + str(1) + " " + args )
- 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, samp_rate, osr=4)
-
- 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)
+ if rec_length != float('Inf'):
+ self.head = \
+ blocks.head(gr.sizeof_gr_complex, int(samp_rate*rec_length))
+
+ self.file_sink = blocks.file_sink(gr.sizeof_gr_complex*1, \
+ output_filename, False)
+ self.file_sink.set_unbuffered(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))
+ if rec_length != float('Inf'): #if recording length is not infinite
+ #connect head block after the source
+ self.connect((self.sdr_source, 0), (self.head, 0))
+ self.connect((self.head, 0), (self.file_sink, 0))
else:
- self.connect((self.rtlsdr_source, 0), (self.blocks_rotator, 0))
+ self.connect((self.sdr_source, 0), (self.file_sink, 0))
- if self.cfile:
- self.connect((self.blocks_rotator, 0), (self.blocks_file_sink, 0))
+if __name__ == '__main__':
- 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, "ctrl", self.gsm_input, "ctrl_in")
- self.msg_connect(self.gsm_receiver, "measurements", self.gsm_clock_offset_control, "measurements")
+ parser = OptionParser(option_class=eng_option, usage="%prog [options] output_filename",
+ description="RTL-SDR capturing app of gr-gsm.")
- 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")
+ parser.add_option("-f", "--freq", dest="freq", type="eng_float",
+ help="Set frequency [default=%default]")
- def get_fc(self):
- return self.fc
+ parser.add_option("-a", "--arfcn", dest="arfcn", type="intx",
+ help="Set ARFCN instead of frequency (for PCS1900 add"
+ "0x8000 (2**15) to the ARFCN number)")
- 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
+ parser.add_option("-g", "--gain", dest="gain", type="eng_float",
+ default=eng_notation.num_to_str(30),
+ help="Set gain [default=%default]")
- def set_arfcn(self, arfcn):
- self.arfcn = arfcn
- if self.verbose or self.burst_file:
- self.gsm_receiver.set_cell_allocation([self.arfcn])
- new_freq = grgsm.arfcn.arfcn2downlink(self.arfcn)
- self.set_fc(new_freq)
+ parser.add_option("-s", "--samp-rate", dest="samp_rate", type="eng_float",
+ default=eng_notation.num_to_str(1000000),
+ help="Set samp_rate [default=%default]")
- def get_gain(self):
- return self.gain
+ parser.add_option("-T", "--rec-length", dest="rec_length", type="float",
+ default='Inf', help="Set length of recording in seconds "
+ "[default=infinity]")
- def set_gain(self, gain):
- self.gain = gain
+ parser.add_option("-p", "--freq-corr", dest="freq_corr", type="eng_float",
+ default="0", help="Set frequency correction in"
+ " ppm [default=%default]")
- def get_samp_rate(self):
- return self.samp_rate
+ osmogroup = OptionGroup(parser, 'Additional osmosdr source options',
+ "Options specific to a subset of SDR receivers "
+ "supported by osmosdr source.")
- 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)
+ osmogroup.add_option("-w", "--bandwidth", dest="bandwidth", type="eng_float",
+ default="0", help="Set bandwidth [default=samp_rate]")
- def get_ppm(self):
- return self.ppm
+ osmogroup.add_option("", "--bb-gain", dest="bb_gain", type="eng_float",
+ default=eng_notation.num_to_str(20),
+ help="Set baseband gain [default=%default]")
- def set_ppm(self, ppm):
- self.ppm = ppm
- self.set_ppm_slider(self.ppm)
+ osmogroup.add_option("", "--if-gain", dest="if_gain", type="eng_float",
+ default=eng_notation.num_to_str(20),
+ help="Set intermediate freque gain [default=%default]")
- def get_rec_length(self):
- return self.rec_length
+ osmogroup.add_option("", "--ant", dest="antenna", type="string",
+ default="", help="Set antenna "
+ "[default=%default]")
- 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))
+ osmogroup.add_option("", "--args", dest="device_args", type="string",
+ default="", help="Set device arguments "
+ "[default=%default]")
+ parser.add_option_group(osmogroup)
-if __name__ == '__main__':
+ (options, args) = parser.parse_args()
- parser = OptionParser(option_class=eng_option, usage="%prog [options]",
- description="RTL-SDR capturing app of gr-gsm.")
+ if not args:
+ parser.error("Please provide an output file name to save the captured data\n")
- 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 (for PCS1900 add 0x8000 (2**15) to the ARFCN number)")
-
- 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(1000000),
- 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")
-
- 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]")
+ output_filename = args[0]
+
+ if (options.freq is None and options.arfcn is None) or \
+ (options.freq 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")
- (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
+ freq = 0
if options.arfcn:
if not grgsm.arfcn.is_valid_arfcn(options.arfcn):
parser.error("ARFCN is not valid\n")
else:
- arfcn = options.arfcn
- fc = grgsm.arfcn.arfcn2downlink(arfcn)
- elif options.fc:
- fc = options.fc
- arfcn = grgsm.arfcn.downlink2arfcn(options.fc)
-
- 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, verbose=options.verbose,
- rec_length=options.rec_length, args=options.args)
-
+ freq = grgsm.arfcn.arfcn2downlink(options.arfcn)
+ elif options.freq:
+ freq = options.freq
+
+ tb = grgsm_capture(freq=freq,
+ gain=options.gain,
+ freq_corr=options.freq_corr,
+ samp_rate=options.samp_rate,
+ output_filename=output_filename,
+ rec_length=options.rec_length,
+ bandwidth=options.bandwidth,
+ bb_gain=options.bb_gain,
+ if_gain=options.if_gain,
+ antenna=options.antenna,
+ device_args=options.device_args)
+
def signal_handler(signal, frame):
tb.stop()
- tb.wait()
+ tb.wait()
sys.exit(0)
-
+
signal.signal(signal.SIGINT, signal_handler)
tb.start()