Change in gr-gsm[master]: Major simplification and some argument changes in grgsm_capture

Piotr Krysik gerrit-no-reply at lists.osmocom.org
Fri Mar 1 16:09:54 UTC 2019


Piotr Krysik has uploaded this change for review. ( https://gerrit.osmocom.org/13090


Change subject: Major simplification and some argument changes in grgsm_capture
......................................................................

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
---
M apps/helpers/grgsm_capture
1 file changed, 117 insertions(+), 171 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/gr-gsm refs/changes/90/13090/1

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 at gmail.com>
+#         (C) 2019 by Piotr Krysik <ptrkrysik at gmail.com>
 # @section LICENSE
 #
 # Gr-gsm is free software; you can redistribute it and/or modify
@@ -26,217 +27,162 @@
 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
-        ##################################################
-        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
-        
-        ##################################################
-        # Processing Blocks
+        # Setting up RF source
         ##################################################
 
-        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)
+        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)
 
-        if self.burst_file:
-            self.gsm_burst_file_sink = grgsm.burst_file_sink(self.burst_file)
+        ##################################################
+        # The rest of processing blocks
+        ##################################################
 
-        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 rec_length != float('Inf'):
+            self.head = \
+                    blocks.head(gr.sizeof_gr_complex, int(samp_rate*rec_length))
 
-        if self.verbose:
-            self.gsm_bursts_printer_0 = grgsm.bursts_printer(pmt.intern(""),
-                                                             False, False, False, False)
+        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))
-
-        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, "ctrl", self.gsm_input, "ctrl_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])
-            new_freq = grgsm.arfcn.arfcn2downlink(self.arfcn)
-            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))
-
+            self.connect((self.sdr_source, 0), (self.file_sink, 0))
 
 if __name__ == '__main__':
 
-    parser = OptionParser(option_class=eng_option, usage="%prog [options]",
+    parser = OptionParser(option_class=eng_option, usage="%prog [options] output_filename",
                           description="RTL-SDR capturing app of gr-gsm.")
 
-    parser.add_option("-f", "--fc", dest="fc", type="eng_float", 
+    parser.add_option("-f", "--freq", dest="freq", 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", 
+
+    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", 
+
+    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="float",
+                      default='Inf', help="Set length of recording in seconds "
+                      "[default=infinity]")
 
-    parser.add_option("-T", "--rec-length", dest="rec_length", type="eng_float",
-        help="Set length of recording in seconds [default=%default]")
+    parser.add_option("-p", "--freq-corr", dest="freq_corr", type="eng_float",
+                      default="0", help="Set frequency correction in"
+                      " ppm [default=%default]")
+
+    osmogroup = OptionGroup(parser, 'Additional osmosdr source options',
+                      "Options specific to a subset of SDR receivers "
+                      "supported by osmosdr source.")
+
+    osmogroup.add_option("-w", "--bandwidth", dest="bandwidth", type="eng_float",
+                      default="0", help="Set bandwidth [default=samp_rate]")
+
+    osmogroup.add_option("", "--bb-gain", dest="bb_gain", type="eng_float",
+                      default=eng_notation.num_to_str(20),
+                      help="Set baseband gain [default=%default]")
+
+    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]")
+
+    osmogroup.add_option("", "--ant", dest="antenna", type="string",
+                      default="", help="Set antenna "
+                      "[default=%default]")
+
+    osmogroup.add_option("", "--args", dest="device_args", type="string",
+                      default="", help="Set device arguments "
+                      "[default=%default]")
+
+    parser.add_option_group(osmogroup)
 
     (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")
-        
+
+    if not args:
+        parser.error("Please provide an output file name to save the captured data\n")
+
+    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")
+
     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()

-- 
To view, visit https://gerrit.osmocom.org/13090
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: gr-gsm
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I092a43eaddb09a99c6cc05fde13f0ae94d9e0251
Gerrit-Change-Number: 13090
Gerrit-PatchSet: 1
Gerrit-Owner: Piotr Krysik <ptrkrysik at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190301/96e97e8d/attachment-0001.html>


More information about the gerrit-log mailing list