aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Krysik <ptrkrysik@gmail.com>2018-09-20 14:49:27 +0200
committerPiotr Krysik <ptrkrysik@gmail.com>2019-03-01 17:03:15 +0000
commit81ba56f59dcefb2d39d023c68d3a077b4a321520 (patch)
tree84f7d5bcd8aed74290f2c421a3ac7cf30fafe572
parent57431ed50cb3e2530e6f5337fea9a98c4e6b4b2d (diff)
Major simplification and some argument changes in grgsm_capture
grmgs_capture tried to do too many things for a simple recorder. It was simplified by removing the receiver and ability to save data to bursts files. All other stuff that is not necessary for recording signal to disk was also removed: -setters/getters, -storing of parameters that never will be changed. The 'fc' parameter name was changed to 'freq' to follow GNU Radio guidelines. The 'shiftoff' parameter was removed. 'bb_gain' and 'if_gain' parameters were added. Variables specific to some of SDR's like: -gains at different stages, -bandwidth (not all devices can set it), -antennas (some devices have just one, some not), were moved to separate options group. What is left to be exposed is: -dc_offset_mode, -iq_balance_mode, -gain_mode. Change-Id: I092a43eaddb09a99c6cc05fde13f0ae94d9e0251
-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()