Initial draft of pcap injector.
git-svn-id: http://op25.osmocom.org/svn/trunk@271 65a5c917-d112-43f1-993d-58c26a4786be
This commit is contained in:
parent
47656f6e94
commit
db70451cb1
|
@ -102,7 +102,7 @@ class file_c4fm_rx (gr.top_block):
|
|||
self.connect(decoder, audio_sink)
|
||||
except Exception:
|
||||
sink = gr.null_sink(gr.sizeof_float)
|
||||
self.connect(decoder, null);
|
||||
self.connect(decoder, sink)
|
||||
|
||||
|
||||
# Adjust the channel offset
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#
|
||||
# Copyright 2005,2006,2007 Free Software Foundation, Inc.
|
||||
#
|
||||
# OP25 4-Level Modulator Block # Copyright 2009, KA1RBI
|
||||
# OP25 4-Level Modulator Block
|
||||
# Copyright 2009, KA1RBI
|
||||
#
|
||||
# coeffs for shaping and cosine filters from Eric Ramsey thesis
|
||||
#
|
||||
|
@ -44,7 +45,7 @@ _def_log = False
|
|||
# modulator
|
||||
# /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class p25_mod(gr.hier_block2):
|
||||
class p25_mod_bf(gr.hier_block2):
|
||||
|
||||
def __init__(self,
|
||||
output_sample_rate=_def_output_sample_rate,
|
||||
|
@ -70,11 +71,11 @@ class p25_mod(gr.hier_block2):
|
|||
@type reverse: bool
|
||||
@param verbose: Print information about modulator?
|
||||
@type verbose: bool
|
||||
@param debug: Print modualtion data to files?
|
||||
@param debug: Print modulation data to files?
|
||||
@type debug: bool
|
||||
"""
|
||||
|
||||
gr.hier_block2.__init__(self, "p25_fm_mod",
|
||||
gr.hier_block2.__init__(self, "p25_c4fm_mod_bf",
|
||||
gr.io_signature(1, 1, gr.sizeof_char), # Input signature
|
||||
gr.io_signature(1, 1, gr.sizeof_float)) # Output signature
|
||||
|
||||
|
@ -151,7 +152,7 @@ class p25_mod(gr.hier_block2):
|
|||
"""
|
||||
parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw,
|
||||
help="set RRC excess bandwith factor [default=%default] (PSK)")
|
||||
add_options=staticmethod(add_options)
|
||||
add_options=staticmethod(add_options)
|
||||
|
||||
|
||||
def extract_kwargs_from_options(options):
|
||||
|
@ -160,6 +161,7 @@ class p25_mod(gr.hier_block2):
|
|||
"""
|
||||
return modulation_utils.extract_kwargs_from_options(dqpsk_mod.__init__,
|
||||
('self',), options)
|
||||
|
||||
extract_kwargs_from_options=staticmethod(extract_kwargs_from_options)
|
||||
|
||||
#
|
||||
|
|
|
@ -108,7 +108,7 @@ class usrp_c4fm_rx (gr.top_block):
|
|||
self.connect(decoder, audio_sink)
|
||||
except Exception:
|
||||
sink = gr.null_sink(gr.sizeof_float)
|
||||
self.connect(decoder, null);
|
||||
self.connect(decoder, sink)
|
||||
|
||||
|
||||
# Adjust the channel offset
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2011 Steve Glass.
|
||||
#
|
||||
# This file is part of GNU Radio and part of OP25
|
||||
#
|
||||
# This program 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.
|
||||
#
|
||||
# It 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 this; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
|
||||
import math
|
||||
import sys
|
||||
import wx
|
||||
|
||||
from gnuradio import audio
|
||||
from gnuradio import eng_notation
|
||||
from gnuradio import gr
|
||||
from gnuradio import op25
|
||||
from gnuradio import op25_c4fm_mod
|
||||
from gnuradio import usrp
|
||||
from gnuradio.eng_option import eng_option
|
||||
|
||||
|
||||
"""
|
||||
Simple tx-from-pcap-file utility.
|
||||
"""
|
||||
class usrp_c4fm_tx_block(gr.top_block):
|
||||
|
||||
def __init__(self, subdev_spec, freq, subdev_gain, filename, delay, repeat):
|
||||
|
||||
gr.top_block.__init__ (self)
|
||||
|
||||
# important vars (to be calculated from USRP when available
|
||||
dac_rate = 128e6
|
||||
usrp_interp = 400
|
||||
usrp_rate = dac_rate / usrp_interp # 320KS/s
|
||||
sw_interp = 10
|
||||
channel_rate = usrp_rate / sw_interp # 32 kS/s
|
||||
|
||||
# open the pcap source
|
||||
pcap = op25.pcap_source_b(filename, delay, repeat)
|
||||
# ToDo: consider octet -> symbol unpacking in flow graph
|
||||
|
||||
c4fm = op25_c4fm_mod.p25_mod(output_sample_rate=channel_rate, log=False, verbose=False)
|
||||
self.connect(pcap, c4fm)
|
||||
|
||||
# setup low pass filter + interpolator
|
||||
interp_factor = self.usrp_rate / self.channel_rate
|
||||
low_pass = 2.88e3
|
||||
interp_taps = gr.firdes.low_pass(1.0, self.usrp_rate, low_pass, low_pass * 0.1, gr.firdes.WIN_HANN)
|
||||
interpolator = gr.interp_fir_filter_fff (int(interp_factor), interp_taps)
|
||||
self.connect(c4fm, interpolator)
|
||||
|
||||
# frequency modulator
|
||||
max_dev = 12.5e3
|
||||
k = 2 * math.pi * max_dev / self.usrp_rate
|
||||
adjustment = 1.5 # adjust for proper c4fm deviation level
|
||||
fm = gr.frequency_modulator_fc(k * adjustment)
|
||||
self.connect(interpolator, fm)
|
||||
|
||||
# amplify signal
|
||||
gain = gr.multiply_const_cc(4000)
|
||||
self.connect(fm, gain)
|
||||
|
||||
# # configure USRP
|
||||
u = usrp.sink_c()
|
||||
if subdev_spec is None:
|
||||
subdev_spec = usrp.pick_tx_subdevice(u)
|
||||
u.set_mux(usrp.determine_tx_mux_value(u, subdev_spec))
|
||||
subdev = usrp.selected_subdev(u, subdev_spec)
|
||||
print "Using TX d'board %s" % (subdev.side_and_name(),)
|
||||
|
||||
if gain is None:
|
||||
g = subdev.gain_range()
|
||||
gain = float(g[0] + g[1]) / 2
|
||||
subdev.set_gain(self.subdev.gain_range()[0])
|
||||
u.tune(subdev.which(), subdev, freq)
|
||||
self.connect(gain, u)
|
||||
subdev.set_enable(True)
|
||||
|
||||
# sink = gr.null_sink(gr.sizeof_float)
|
||||
# self.connect(gain, sink)
|
||||
|
||||
|
||||
# inject frames
|
||||
#
|
||||
if __name__ == '__main__':
|
||||
|
||||
from optparse import OptionParser
|
||||
parser = OptionParser (option_class=eng_option)
|
||||
parser.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
|
||||
help="select USRP Tx side A or B")
|
||||
parser.add_option("-f", "--freq", type="eng_float", default=None,
|
||||
help="set Tx frequency to FREQ [required]")
|
||||
parser.add_option("-g", "--gain", type="eng_float", default=None,
|
||||
help="set device gain")
|
||||
parser.add_option("-p", "--pcap-file", default="",
|
||||
help="packet capture file [required]")
|
||||
parser.add_option("-d", "--delay", type="int", default=0,
|
||||
help="delay before TX of first symbol [default=%default]")
|
||||
parser.add_option("-r","--repeat", action="store_true", default=False,
|
||||
help="continuously replay input file [default=%default]")
|
||||
(options, args) = parser.parse_args ()
|
||||
if options.freq is None:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
rx = usrp_c4fm_tx_block(options.subdev_spec, options.freq, options.gain, options.pcap_file, options.delay, options.repeat)
|
||||
rx.run()
|
||||
except KeyboardInterrupt:
|
||||
rx.subdev.set_enable(False)
|
Reference in New Issue