3
# Copyright 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
5
# This file is part of GNU Radio
7
# GNU Radio is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3, or (at your option)
12
# GNU Radio is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
17
# You should have received a copy of the GNU General Public License
18
# along with GNU Radio; see the file COPYING. If not, write to
19
# the Free Software Foundation, Inc., 51 Franklin Street,
20
# Boston, MA 02110-1301, USA.
23
from gnuradio import gr, gru, modulation_utils
24
from gnuradio import eng_notation
25
from gnuradio.eng_option import eng_option
26
from optparse import OptionParser
28
import random, time, struct, sys, math
31
from transmit_path import transmit_path
32
from receive_path import receive_path
34
class my_top_block(gr.top_block):
35
def __init__(self, mod_class, demod_class, rx_callback, options):
36
gr.top_block.__init__(self)
40
SNR = 10.0**(options.snr/10.0)
41
frequency_offset = options.frequency_offset
43
power_in_signal = abs(options.tx_amplitude)**2
44
noise_power = power_in_signal/SNR
45
noise_voltage = math.sqrt(noise_power)
47
self.txpath = transmit_path(mod_class, options)
48
self.throttle = gr.throttle(gr.sizeof_gr_complex, options.sample_rate)
49
self.rxpath = receive_path(demod_class, rx_callback, options)
52
self.channel = gr.channel_model(noise_voltage, frequency_offset, 1.01)
54
if options.discontinuous:
56
self.zeros = gr.vector_source_c(z, True)
57
packet_size = 5*((4+8+4+1500+4) * 8)
58
self.mux = gr.stream_mux(gr.sizeof_gr_complex, [packet_size-0, int(9e5)])
61
self.connect(self.txpath, (self.mux,0))
62
self.connect(self.zeros, (self.mux,1))
63
self.connect(self.mux, self.channel, self.rxpath)
66
self.connect(self.txpath, self.channel, self.rxpath)
70
self.connect(self.txpath, self.throttle, self.rxpath)
73
# /////////////////////////////////////////////////////////////////////////////
75
# /////////////////////////////////////////////////////////////////////////////
79
global n_rcvd, n_right
84
def rx_callback(ok, payload):
85
global n_rcvd, n_right
86
(pktno,) = struct.unpack('!H', payload[0:2])
91
print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % (
92
ok, pktno, n_rcvd, n_right)
93
# print payload[2:len(payload)]
95
def send_pkt(payload='', eof=False):
96
return tb.txpath.send_pkt(payload, eof)
99
mods = modulation_utils.type_1_mods()
100
demods = modulation_utils.type_1_demods()
102
parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
103
expert_grp = parser.add_option_group("Expert")
104
channel_grp = parser.add_option_group("Channel")
106
parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(),
108
help="Select modulation from: %s [default=%%default]"
109
% (', '.join(mods.keys()),))
111
parser.add_option("-s", "--size", type="eng_float", default=1500,
112
help="set packet size [default=%default]")
113
parser.add_option("-M", "--megabytes", type="eng_float", default=1.0,
114
help="set megabytes to transmit [default=%default]")
115
parser.add_option("","--discontinuous", action="store_true", default=False,
116
help="enable discontinous transmission (bursts of 5 packets)")
118
channel_grp.add_option("", "--sample-rate", type="eng_float", default=1e5,
119
help="set speed of channel/simulation rate to RATE [default=%default]")
120
channel_grp.add_option("", "--snr", type="eng_float", default=30,
121
help="set the SNR of the channel in dB [default=%default]")
122
channel_grp.add_option("", "--frequency-offset", type="eng_float", default=0,
123
help="set frequency offset introduced by channel [default=%default]")
124
channel_grp.add_option("", "--seed", action="store_true", default=False,
125
help="use a random seed for AWGN noise [default=%default]")
127
transmit_path.add_options(parser, expert_grp)
128
receive_path.add_options(parser, expert_grp)
130
for mod in mods.values():
131
mod.add_options(expert_grp)
132
for demod in demods.values():
133
demod.add_options(expert_grp)
135
(options, args) = parser.parse_args ()
141
r = gr.enable_realtime_scheduling()
143
print "Warning: failed to enable realtime scheduling"
145
# Create an instance of a hierarchical block
146
tb = my_top_block(mods[options.modulation], demods[options.modulation], rx_callback, options)
149
# generate and send packets
150
nbytes = int(1e6 * options.megabytes)
153
pkt_size = int(options.size)
156
send_pkt(struct.pack('!H', pktno & 0xffff) + (pkt_size - 2) * chr(pktno & 0xff))
164
if __name__ == '__main__':
167
except KeyboardInterrupt: