198 lines
7.5 KiB
Python
Executable File
198 lines
7.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# -*- 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
|
|
# 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 optparse import OptionParser, OptionGroup
|
|
import osmosdr
|
|
import time
|
|
import grgsm
|
|
import signal
|
|
import sys
|
|
|
|
class grgsm_capture(gr.top_block):
|
|
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")
|
|
|
|
##################################################
|
|
# Setting up RF source
|
|
##################################################
|
|
|
|
self.sdr_source = osmosdr.source(args="numchan=" + str(1) + " " +
|
|
str(grgsm.device.get_default_args(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)
|
|
|
|
##################################################
|
|
# The rest of processing blocks
|
|
##################################################
|
|
|
|
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 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.sdr_source, 0), (self.file_sink, 0))
|
|
|
|
if __name__ == '__main__':
|
|
|
|
parser = OptionParser(option_class=eng_option, usage="%prog [options] output_filename",
|
|
description="RTL-SDR capturing app of gr-gsm.")
|
|
|
|
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",
|
|
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("-T", "--rec-length", dest="rec_length", type="float",
|
|
default='Inf', help="Set length of recording in seconds "
|
|
"[default=infinity]")
|
|
|
|
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]. Use --list-devices the view the available devices")
|
|
|
|
osmogroup.add_option("-l", "--list-devices", action="store_true",
|
|
help="List available SDR devices, use --args to specify hints")
|
|
|
|
parser.add_option_group(osmogroup)
|
|
|
|
(options, args) = parser.parse_args()
|
|
|
|
if options.list_devices:
|
|
grgsm.device.print_devices(options.device_args)
|
|
sys.exit(0)
|
|
|
|
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
|
|
freq = 0
|
|
if options.arfcn:
|
|
if not grgsm.arfcn.is_valid_arfcn(options.arfcn):
|
|
parser.error("ARFCN is not valid\n")
|
|
else:
|
|
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()
|
|
sys.exit(0)
|
|
|
|
signal.signal(signal.SIGINT, signal_handler)
|
|
|
|
tb.start()
|
|
tb.wait()
|