[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r5850 - in grc/branches/jblum_work: examples notes src
From: |
jblum |
Subject: |
[Commit-gnuradio] r5850 - in grc/branches/jblum_work: examples notes src src/SignalBlockDefs |
Date: |
Tue, 26 Jun 2007 18:32:04 -0600 (MDT) |
Author: jblum
Date: 2007-06-26 18:32:02 -0600 (Tue, 26 Jun 2007)
New Revision: 5850
Modified:
grc/branches/jblum_work/examples/packet_mod_demod.grc.xml
grc/branches/jblum_work/examples/selector.grc.xml
grc/branches/jblum_work/examples/valve.grc.xml
grc/branches/jblum_work/examples/variable_sink.grc.xml
grc/branches/jblum_work/notes/notes.txt
grc/branches/jblum_work/src/Editor.py
grc/branches/jblum_work/src/ExecFlowGraph.py
grc/branches/jblum_work/src/SignalBlockDefs/Filters.py
grc/branches/jblum_work/src/SignalBlockDefs/GraphicalSinks.py
grc/branches/jblum_work/src/SignalBlockDefs/Misc.py
grc/branches/jblum_work/src/SignalBlockDefs/Modulators.py
grc/branches/jblum_work/src/SignalBlockDefs/Packet.py
grc/branches/jblum_work/src/SignalBlockDefs/SignalBlockConstants.py
grc/branches/jblum_work/src/SignalBlockDefs/SignalBlockTree.py
grc/branches/jblum_work/src/SignalBlockDefs/Sinks.py
Log:
switched to hier2, added tun sink
Modified: grc/branches/jblum_work/examples/packet_mod_demod.grc.xml
===================================================================
--- grc/branches/jblum_work/examples/packet_mod_demod.grc.xml 2007-06-26
21:56:12 UTC (rev 5849)
+++ grc/branches/jblum_work/examples/packet_mod_demod.grc.xml 2007-06-27
00:32:02 UTC (rev 5850)
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<flow_graph>
- <timestamp>1182405771.77</timestamp>
+ <timestamp>1182897586.7</timestamp>
<hostname>tiggle</hostname>
<version>0.70 alpha</version>
<valid>True</valid>
Modified: grc/branches/jblum_work/examples/selector.grc.xml
===================================================================
--- grc/branches/jblum_work/examples/selector.grc.xml 2007-06-26 21:56:12 UTC
(rev 5849)
+++ grc/branches/jblum_work/examples/selector.grc.xml 2007-06-27 00:32:02 UTC
(rev 5850)
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<flow_graph>
- <timestamp>1182711123.75</timestamp>
+ <timestamp>1182902366.59</timestamp>
<hostname>tiggle</hostname>
<version>0.70 alpha</version>
<valid>True</valid>
Modified: grc/branches/jblum_work/examples/valve.grc.xml
===================================================================
--- grc/branches/jblum_work/examples/valve.grc.xml 2007-06-26 21:56:12 UTC
(rev 5849)
+++ grc/branches/jblum_work/examples/valve.grc.xml 2007-06-27 00:32:02 UTC
(rev 5850)
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<flow_graph>
- <timestamp>1182711684.9</timestamp>
+ <timestamp>1182897525.03</timestamp>
<hostname>tiggle</hostname>
<version>0.70 alpha</version>
<valid>True</valid>
Modified: grc/branches/jblum_work/examples/variable_sink.grc.xml
===================================================================
--- grc/branches/jblum_work/examples/variable_sink.grc.xml 2007-06-26
21:56:12 UTC (rev 5849)
+++ grc/branches/jblum_work/examples/variable_sink.grc.xml 2007-06-27
00:32:02 UTC (rev 5850)
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<flow_graph>
- <timestamp>1182223110.14</timestamp>
+ <timestamp>1182877130.19</timestamp>
<hostname>tiggle</hostname>
<version>0.70 alpha</version>
<valid>True</valid>
Modified: grc/branches/jblum_work/notes/notes.txt
===================================================================
--- grc/branches/jblum_work/notes/notes.txt 2007-06-26 21:56:12 UTC (rev
5849)
+++ grc/branches/jblum_work/notes/notes.txt 2007-06-27 00:32:02 UTC (rev
5850)
@@ -7,8 +7,6 @@
-tun/tap block (with input and output)
############ Known Problems: ####################
--fg.stop() doesnt kill running threads
--abort core dump with throw std exception
-file save, ask for overwrite even when appending file extension
-blocks need to fix themselves when they go out of bounds, like in a resize
-socket controllers should be intelligent on shrinkage
Modified: grc/branches/jblum_work/src/Editor.py
===================================================================
--- grc/branches/jblum_work/src/Editor.py 2007-06-26 21:56:12 UTC (rev
5849)
+++ grc/branches/jblum_work/src/Editor.py 2007-06-27 00:32:02 UTC (rev
5850)
@@ -44,6 +44,7 @@
import xml.dom.minidom
import xml.dom.ext
import gnuradio
+ import gnuradio.gr.hier_block2
except ImportError, e: #print error and exit
print '\nMissing critical component: "%s"\nExiting!'%(e,)
exit(-1)
Modified: grc/branches/jblum_work/src/ExecFlowGraph.py
===================================================================
--- grc/branches/jblum_work/src/ExecFlowGraph.py 2007-06-26 21:56:12 UTC
(rev 5849)
+++ grc/branches/jblum_work/src/ExecFlowGraph.py 2007-06-27 00:32:02 UTC
(rev 5850)
@@ -32,15 +32,21 @@
##############################################################################################
# Flow Graph Builder
##############################################################################################
-class FlowGraphBuilder(gr.flow_graph):
+class FlowGraphBuilder(gr.top_block):
""" Parse the input file to build the gnuradio flow graph.
Register the variables, handle signal block callbacks. """
- def __init__(self, file_path):
- nested_data = ParseXML.from_xml(ParseXML.from_file(file_path))
- gr.flow_graph.__init__(self)
+ def __init__(self, file_path):
+ gr.top_block.__init__(self, file_path)
+ #internal data structures
self.callbacks = list()
- self.var_keys = list()
- self._parse_nested_data(nested_data)
+ self.var_keys = list()
+ #access methods to runtime
+ runtime = gr.runtime(self)
+ self.start = lambda: runtime.start()
+ self.stop = lambda: runtime.stop()
+ self.restart = lambda: runtime.restart()
+ #build the flow graph
+
self._parse_nested_data(ParseXML.from_xml(ParseXML.from_file(file_path)))
def add_window(self, window, type='', title=''):
''' Empty method for adding a window in the GUI flow graph.
'''
@@ -92,15 +98,7 @@
output_signal_block_id = find_data(connection,
'output_signal_block_id')
output_socket_index = int(find_data(connection,
'output_socket_index'))
input_signal_block =
signal_blocks_dict[input_signal_block_id]
- output_signal_block =
signal_blocks_dict[output_signal_block_id]
- #start handle meta blocks
- if hasattr(input_signal_block, 'meta_block'):
- input_signal_block,input_socket_index = \
-
input_signal_block.get_input_block(input_socket_index)
- if hasattr(output_signal_block, 'meta_block'):
- output_signal_block,output_socket_index = \
-
output_signal_block.get_output_block(output_socket_index)
- #end handle meta blocks
+ output_signal_block =
signal_blocks_dict[output_signal_block_id]
self.connect(# use this flow graph's connect method
#
(output_signal_block, output_socket_index),
(input_signal_block, input_socket_index))
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Filters.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Filters.py 2007-06-26
21:56:12 UTC (rev 5849)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Filters.py 2007-06-27
00:32:02 UTC (rev 5850)
@@ -22,7 +22,7 @@
from DataTypes import *
from gnuradio import gr,gru,blks
-from SignalBlockConstants import default_samp_rate,all_choices
+from SignalBlockConstants import default_samp_rate,all_choices,HierHelper
###########################################################################
# Generic filters with taps parameters
@@ -148,7 +148,10 @@
sb.add_param('Taps', ComplexVector('1.0,0.0'))
sb.set_docs('''Simulate channel distortion.''')
def make(fg, noise_voltage, frequency_offset, epsilon, taps):
- return fcn(fg, noise_voltage.parse(), frequency_offset.parse(),
epsilon.parse(), taps.parse())
+ return HierHelper(
+ fcn(fg, noise_voltage.parse(),
frequency_offset.parse(), epsilon.parse(), taps.parse()),
+ Complex().get_num_bytes(), Complex().get_num_bytes(),
+ )
return sb, make
###########################################################################
@@ -460,7 +463,10 @@
out_rate = outrate.parse()
interp = int(lcm(in_rate, out_rate)/in_rate)
decim = int(lcm(in_rate, out_rate)/out_rate)
- return filter_type.parse()[0](fg, interp, decim, taps=None,
fractional_bw=fractional_bw.parse())
+ return HierHelper(
+ filter_type.parse()[0](fg, interp, decim, taps=None,
fractional_bw=fractional_bw.parse()),
+ filter_type.parse()[1].get_num_bytes(),
filter_type.parse()[1].get_num_bytes(),
+ )
return sb, make
def FractionalInterpolator(sb):
Modified: grc/branches/jblum_work/src/SignalBlockDefs/GraphicalSinks.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/GraphicalSinks.py
2007-06-26 21:56:12 UTC (rev 5849)
+++ grc/branches/jblum_work/src/SignalBlockDefs/GraphicalSinks.py
2007-06-27 00:32:02 UTC (rev 5850)
@@ -22,7 +22,7 @@
from DataTypes import *
from gnuradio import gr
-from SignalBlockConstants import default_samp_rate,ThrottleHelper
+from SignalBlockConstants import default_samp_rate,ThrottleHelper,HierHelper
number_display_pritority = 0
fft_display_priority = 1
@@ -58,7 +58,7 @@
fg.add_window(block.win, fft_display_priority, title.parse())
fg.add_callback(block.set_ref_level, ref_lvl)
fg.add_callback(block.set_y_per_div, y_per_div)
- return ThrottleHelper(fg, type.parse()[1].get_num_bytes(),
samp_rate.parse(), block, True)
+ return ThrottleHelper(type.parse()[1].get_num_bytes(),
samp_rate.parse(), HierHelper(block, type.parse()[1].get_num_bytes()), True)
return sb, make
def WaterfallSink(sb):
@@ -87,7 +87,7 @@
block.set_average(average) #set the
average option outside the contructor
fg.add_window(block.win, waterfall_display_priority,
title.parse())
fg.add_callback(block.set_baseband_freq, baseband_freq)
- return ThrottleHelper(fg, type.parse()[1].get_num_bytes(),
samp_rate.parse(), block, True)
+ return ThrottleHelper(type.parse()[1].get_num_bytes(),
samp_rate.parse(), HierHelper(block, type.parse()[1].get_num_bytes()), True)
return sb, make
def ScopeSink(sb):
@@ -114,7 +114,7 @@
sample_rate=samp_rate.parse(),
frame_decim=frame_decim.parse(),
v_scale=v_scale, t_scale=t_scale.parse())
fg.add_window(block.win, scope_display_priority, title.parse())
- return ThrottleHelper(fg, type.parse()[1].get_num_bytes(),
samp_rate.parse(), block, True)
+ return ThrottleHelper(type.parse()[1].get_num_bytes(),
samp_rate.parse(), HierHelper(block, type.parse()[1].get_num_bytes()), True)
return sb, make
def ConstellationSink(sb):
@@ -136,7 +136,7 @@
elif marker == 1: block.win.set_format_dot()
elif marker == 2: block.win.set_format_line()
fg.add_window(block.win, constellation_display_pritority,
title.parse())
- return ThrottleHelper(fg, Complex().get_num_bytes(),
samp_rate.parse(), block, True)
+ return ThrottleHelper(Complex().get_num_bytes(),
samp_rate.parse(), HierHelper(block, Complex().get_num_bytes()), True)
return sb, make
def NumericalSink(sb):
@@ -176,7 +176,7 @@
fg.add_callback(block.set_base_value, base)
fg.add_callback(block.set_ref_level, ref_lvl)
fg.add_callback(block.set_decimal_places, decimals)
- return ThrottleHelper(fg, type.parse()[1].get_num_bytes(),
samp_rate.parse(), block, True)
+ return ThrottleHelper(type.parse()[1].get_num_bytes(),
samp_rate.parse(), HierHelper(block, type.parse()[1].get_num_bytes()), True)
return sb, make
\ No newline at end of file
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Misc.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Misc.py 2007-06-26 21:56:12 UTC
(rev 5849)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Misc.py 2007-06-27 00:32:02 UTC
(rev 5850)
@@ -20,7 +20,6 @@
#These blocks were not categorized. Try to keep the number of misc blocks
small.
address@hidden Josh Blum
-import time
import gnuradio.gr.gr_threading as threading
from DataTypes import *
from gnuradio import gr,blks
@@ -87,80 +86,94 @@
return sb, lambda *args: None
#######################################################################################
-## Selector Def, and Helper Thread
+## Selector Def, and Helper Block
#######################################################################################
-class SelectorThread(threading.Thread):
- """Thread to forward data between the input message queue and the
output message queue."""
- ##special attr to tell builder that this is not a gr block
- meta_block = True
- def __init__(self, item_size, input_index, output_index):
+class SelectorHelper(gr.hier_block2):
+ """A hier2 block with N inputs and M outputs, where data is only
forwarded through input n to output m."""
+ def __init__(self, fg, item_size, num_inputs, num_outputs, input_index,
output_index):
"""!
- SelectorThread contructor.
+ SelectorHelper constructor.
+ @param fg the gr flow graph
@param item_size the size of the gr data stream in bytes
- @param input_index the input index to read messages
- @param output_index the output index to write messages
- """
- ##dict to map input indexes to output queues
- self.queues_out = dict()
- ##dict to map output indexes to input queues
- self.queues_in = dict()
- self.set_input_index(input_index)
- self.set_output_index(output_index)
- self.item_size = item_size
- threading.Thread.__init__(self)
- self.setDaemon(1)
- self.keep_running = True
- self.start()
- print 'Created selector thread.'
+ @param num_inputs the number of inputs (integer)
+ @param num_outputs the number of outputs (integer)
+ @param input_index the index for the source data
+ @param output_index the index for the destination data
+ """
+ gr.hier_block2.__init__(
+ self, 'selector',
+ gr.io_signature(num_inputs, num_inputs, item_size),
+ gr.io_signature(num_outputs, num_outputs, item_size)
+ )
+ #terminator blocks for unused inputs and outputs
+ self.input_terminators = [gr.null_sink(item_size) for i in
range(num_inputs)]
+ self.output_terminators = [gr.head(item_size, 0) for i in
range(num_outputs)]
+ self.copy = gr.skiphead(item_size, 0)
+ #connections
+ for i in range(num_inputs): self.connect((self, i),
self.input_terminators[i])
+ for i in range(num_outputs):
self.connect(gr.null_source(item_size), self.output_terminators[i], (self, i))
+ self.input_index = input_index
+ self.output_index = output_index
+ self.num_inputs = num_inputs
+ self.num_outputs = num_outputs
+ self.fg = fg
+ self._connect_current()
- def set_input_index(self, input_index):
+ def _indexes_valid(self):
"""!
- Set the input index.
- @param input_index the new input index (int)
+ Are the input and output indexes within range of the number of
inputs and outputs?
+ @return true if input index and output index are in range
"""
- self.input_index = input_index
+ return self.input_index in range(self.num_inputs) and
self.output_index in range(self.num_outputs)
- def set_output_index(self, output_index):
+ def _connect_current(self):
+ """If the input and output indexes are valid:
+ disconnect the blocks at the input and output index from their
terminators,
+ and connect them to one another. Then connect the terminators
to one another."""
+ if self._indexes_valid():
+ self.disconnect((self, self.input_index),
self.input_terminators[self.input_index])
+
self.disconnect(self.output_terminators[self.output_index], (self,
self.output_index))
+ self.connect((self, self.input_index), self.copy)
+ self.connect(self.copy, (self, self.output_index))
+
self.connect(self.output_terminators[self.output_index],
self.input_terminators[self.input_index])
+
+ def _disconnect_current(self):
+ """If the input and output indexes are valid:
+ disconnect the blocks at the input and output index from one
another,
+ and the terminators at the input and output index from one
another.
+ Reconnect the blocks to the terminators."""
+ if self._indexes_valid():
+ self.disconnect((self, self.input_index), self.copy)
+ self.disconnect(self.copy, (self, self.output_index))
+
self.disconnect(self.output_terminators[self.output_index],
self.input_terminators[self.input_index])
+ self.connect((self, self.input_index),
self.input_terminators[self.input_index])
+
self.connect(self.output_terminators[self.output_index], (self,
self.output_index))
+
+ def set_input_index(self, input_index):
"""!
- Set the output index.
- @param output_index the new output index (int)
+ Change the block to the new input index if the index changed.
+ @param input_index the new input index
"""
- self.output_index = output_index
-
- def get_input_block(self, input_index):
- """!
- Create a new message sink and add its queue to the queues out
dict.
- @param input_index the input index for the message sink
- @return a gr message sink,connection index
- """
- msgq = gr.msg_queue(DEFAULT_QUEUE_LIMIT)
- msg_sink = gr.message_sink(self.item_size, msgq, False)
- self.queues_out[input_index] = msgq
- return msg_sink,0
+ if self.input_index != input_index:
+ self._disconnect_current()
+ self.input_index = input_index
+ self._connect_current()
+ print "***\n\nabout to call restart in set input\n\n***"
+ self.fg.restart()
- def get_output_block(self, output_index):
+ def set_output_index(self, output_index):
"""!
- Create a new message source and add its queue to the queues in
dict.
- @param output_index the output index for the message source
- @return a gr message source,connection index
+ Change the block to the new output index if the index changed.
+ @param output_index the new output index
"""
- msg_source = gr.message_source(self.item_size,
DEFAULT_QUEUE_LIMIT)
- self.queues_in[output_index] = msg_source.msgq()
- return msg_source,0
-
- def run(self):
- """In an endless while loop: read the msgq_out and write to the
msgq_in."""
- while self.keep_running:
- input_index = self.input_index
- output_index = self.output_index
- if self.queues_out.has_key(input_index):
- msg =
self.queues_out[input_index].delete_head() #blocking read of message
queue
- if self.queues_in.has_key(output_index):
-
self.queues_in[output_index].insert_tail(msg) #forward message
- else: del msg #delete the message
- else: time.sleep(.001) #sleep 1 ms
-
+ if self.output_index != output_index:
+ self._disconnect_current()
+ self.output_index = output_index
+ self._connect_current()
+ print "***\n\nabout to call restart in set
output\n\n***"
+ self.fg.restart()
+
def Selector(sb):
type = Enum(all_choices, 1)
vlen = Int(1, min=1)
@@ -177,7 +190,14 @@
sb.set_docs('''Forward data from the input index to the output
index.''')
def make(fg, type, input_index, output_index, num_inputs, num_outputs,
vlen):
item_size = type.parse().get_num_bytes()*vlen.parse()
- block = SelectorThread(item_size, input_index.parse(),
output_index.parse())
+ block = SelectorHelper(
+ fg,
+ item_size,
+ num_inputs.parse(),
+ num_outputs.parse(),
+ input_index.parse(),
+ output_index.parse(),
+ )
fg.add_callback(block.set_input_index, input_index)
fg.add_callback(block.set_output_index, output_index)
return block
@@ -194,7 +214,7 @@
sb.set_docs('''When open is 0, the valve will forward data.''')
def make(fg, type, open, vlen):
item_size = type.parse().get_num_bytes()*vlen.parse()
- block = SelectorThread(item_size, 0, open.parse())
+ block = SelectorHelper(fg, item_size, 1, 1, 0, open.parse())
fg.add_callback(block.set_output_index, open)
return block
return sb, make
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Modulators.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Modulators.py 2007-06-26
21:56:12 UTC (rev 5849)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Modulators.py 2007-06-27
00:32:02 UTC (rev 5850)
@@ -22,6 +22,7 @@
from DataTypes import *
from gnuradio import gr
+from SignalBlockConstants import HierHelper
def FrequencyMod(sb):
fcn = gr.frequency_modulator_fc
@@ -58,7 +59,8 @@
sb.set_docs('''\
Wide Band FM Receiver.
The audio rate is the quad rate/audio decimation.''')
- return sb, lambda fg, quad_rate, audio_dec: fcn(fg, quad_rate.parse(),
audio_dec.parse())
+ return sb, lambda fg, quad_rate, audio_dec: \
+ HierHelper(fcn(fg, quad_rate.parse(), audio_dec.parse()),
Complex().get_num_bytes(), Float().get_num_bytes())
def WFMTransmit(sb):
from gnuradio import blks
@@ -78,7 +80,7 @@
# make sure that the quad rate is an integer multiple of
the audio rate #
audio_rate = quad_rate/audio_decimation
quad_rate = audio_decimation * (quad_rate/audio_decimation)
- return fcn(fg, audio_rate, quad_rate, tau.parse(),
max_dev.parse())
+ return HierHelper(fcn(fg, audio_rate, quad_rate, tau.parse(),
max_dev.parse()), Float().get_num_bytes(), Complex().get_num_bytes())
return sb, make
def NBFMReceive(sb):
@@ -99,7 +101,7 @@
# make sure that the quad rate is an integer multiple of
the audio rate #
audio_rate = quad_rate/audio_decimation
quad_rate = audio_decimation * (quad_rate/audio_decimation)
- return fcn(fg, audio_rate, quad_rate, tau.parse(),
max_dev.parse())
+ return HierHelper(fcn(fg, audio_rate, quad_rate, tau.parse(),
max_dev.parse()), Complex().get_num_bytes(), Float().get_num_bytes())
return sb, make
def NBFMTransmit(sb):
@@ -120,7 +122,7 @@
# make sure that the quad rate is an integer multiple of
the audio rate #
audio_rate = quad_rate/audio_decimation
quad_rate = audio_decimation * (quad_rate/audio_decimation)
- return fcn(fg, audio_rate, quad_rate, tau.parse(),
max_dev.parse())
+ return HierHelper(fcn(fg, audio_rate, quad_rate, tau.parse(),
max_dev.parse()), Float().get_num_bytes(), Complex().get_num_bytes())
return sb, make
###########################################################################
@@ -136,7 +138,8 @@
sb.add_param('Audio Decimation', Int(1, min=1))
sb.add_param('Audio Passband (Hz)', Float(5e3))
sb.add_param('Audio Stopband (Hz)', Float(5.5e3))
- return sb, lambda fg, *args: fcn(fg, *map(lambda a: a.parse(), args))
+ return sb, lambda fg, *args: \
+ HierHelper(fcn(fg, *map(lambda a: a.parse(), args)),
Complex().get_num_bytes(), Float().get_num_bytes())
def FMDemod(sb):
from gnuradio import blks
@@ -150,7 +153,8 @@
sb.add_param('Audio Stopband (Hz)', Float(4e3))
sb.add_param('Gain', Float(1))
sb.add_param('Tau', Float(75e-6))
- return sb, lambda fg, *args: fcn(fg, *map(lambda a: a.parse(), args))
+ return sb, lambda fg, *args: \
+ HierHelper(fcn(fg, *map(lambda a: a.parse(), args)),
Complex().get_num_bytes(), Float().get_num_bytes())
###########################################################################
# Phase shift keying
@@ -168,7 +172,8 @@
sb.add_param('Samples/Symbol', Int(2, min=2))
sb.add_param('Excess BW', Float(0.35))
sb.add_param('Use Gray Code', Bool(true='Yes', false='No',
default=True))
- return sb, lambda fg, type, *args: type.parse()(fg, *map(lambda a:
a.parse(), args))
+ return sb, lambda fg, type, *args: \
+ HierHelper(type.parse()(fg, *map(lambda a: a.parse(), args)),
Byte().get_num_bytes(), Complex().get_num_bytes())
def PSKDemod(sb):
from gnuradio import blks
@@ -186,7 +191,8 @@
sb.add_param('Mu', Float(0.005))
sb.add_param('Omega Relative Limit', Float(0.05))
sb.add_param('Use Gray Code', Bool(true='Yes', false='No',
default=True))
- return sb, lambda fg, type, *args: type.parse()(fg, *map(lambda a:
a.parse(), args))
+ return sb, lambda fg, type, *args: \
+ HierHelper(type.parse()(fg, *map(lambda a: a.parse(), args)),
Complex().get_num_bytes(), Byte().get_num_bytes())
###########################################################################
# Gaussian minimum shift keying
@@ -199,7 +205,8 @@
sb.add_output_socket('out', Complex())
sb.add_param('Samples/Symbol', Int(2, min=2))
sb.add_param('Filter BW', Float(0.35))
- return sb, lambda fg, *args: fcn(fg, *map(lambda a: a.parse(), args))
+ return sb, lambda fg, *args: \
+ HierHelper(fcn(fg, *map(lambda a: a.parse(), args)),
Byte().get_num_bytes(), Complex().get_num_bytes())
def GMSKDemod(sb):
from gnuradio import blks
@@ -212,7 +219,8 @@
sb.add_param('Omega Relative Limit', Float(0.005))
sb.add_param('Frequency Error', Float(0))
sb.set_docs('''Mu is the fractional delay between 0 and 1''')
- return sb, lambda fg, *args: fcn(fg, *map(lambda a: a.parse(), args))
+ return sb, lambda fg, *args: \
+ HierHelper(fcn(fg, *map(lambda a: a.parse(), args)),
Complex().get_num_bytes(), Byte().get_num_bytes())
###########################################################################
# Quadrature amplitude modulation
@@ -230,7 +238,8 @@
sb.add_param('Samples/Symbol', Int(2, min=2))
sb.add_param('Excess BW', Float(0.35))
sb.add_param('Use Gray Code', Bool(true='Yes', false='No',
default=True))
- return sb, lambda fg, type, *args: type.parse()(fg, *map(lambda a:
a.parse(), args))
+ return sb, lambda fg, type, *args: \
+ HierHelper(type.parse()(fg, *map(lambda a: a.parse(), args)),
Byte().get_num_bytes(), Complex().get_num_bytes())
def QAMDemod(sb):
from gnuradio import blks
@@ -248,7 +257,8 @@
sb.add_param('Mu', Float(0.005))
sb.add_param('Omega Relative Limit', Float(0.05))
sb.add_param('Use Gray Code', Bool(true='Yes', false='No',
default=True))
- return sb, lambda fg, type, *args: type.parse()(fg, *map(lambda a:
a.parse(), args))
+ return sb, lambda fg, type, *args: \
+ HierHelper(type.parse()(fg, *map(lambda a: a.parse(), args)),
Complex().get_num_bytes(), Byte().get_num_bytes())
###########################################################################
# Phase Locked Loops
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Packet.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Packet.py 2007-06-26
21:56:12 UTC (rev 5849)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Packet.py 2007-06-27
00:32:02 UTC (rev 5850)
@@ -20,6 +20,8 @@
#Support for the gr packet framework.
address@hidden Josh Blum
+import struct
+import os
import gnuradio.gr.gr_threading as threading
from DataTypes import *
from gnuradio import gr,blks,packet_utils
@@ -67,7 +69,7 @@
#print len(s), len(r), msg.type(), msg.arg1(),
msg.arg2()
for i in range(num_packets):
self.send_packet(s[i*self.packet_length:(i+1)*self.packet_length])
-class PacketModHelper(gr.hier_block):
+class PacketModHelper(gr.hier_block2):
"""Forward data from the gr data stream to the mod packet."""
def __init__(self, fg, item_size, packet_length, samples_per_symbol,
bits_per_symbol, access_code, pad_for_usrp, use_whitener_offset):
"""!
@@ -77,6 +79,12 @@
@param packet_length the length in bytes of the packets
@param *args the arguments for blks.mod_pkts
"""
+ #create hier block
+ gr.hier_block2.__init__(
+ self, 'packet_mod',
+ gr.io_signature(1, 1, item_size),
+ gr.io_signature(1, 1, Byte().get_num_bytes())
+ )
#dummy modulator with access functions
modulator = gr.skiphead(Byte().get_num_bytes(), 0)
modulator.samples_per_symbol = lambda: samples_per_symbol
@@ -92,13 +100,14 @@
)
#the message sink (handles the input data stream)
msgq = gr.msg_queue(DEFAULT_QUEUE_LIMIT)
- msg_sink = gr.message_sink(item_size, msgq, False)
- #create hier block
- gr.hier_block.__init__(self, fg, msg_sink, packet_mod)
+ msg_sink = gr.message_sink(item_size, msgq, False)
+ #connections
+ self.connect(packet_mod.tail, self)
+ self.connect(self, msg_sink)
#create/start the thread
PacketModThread(msgq, packet_mod.send_pkt, packet_length)
-class PacketDemodHelper(gr.hier_block):
+class PacketDemodHelper(gr.hier_block2):
"""Forward data from demod packet to the gr data stream."""
def __init__(self, fg, item_size, access_code, threshold):
"""!
@@ -108,6 +117,12 @@
@param *args the arguments for blks.demod_pkts
@param msgq_limit the queue limit for the message source
"""
+ #create hier block
+ gr.hier_block2.__init__(
+ self, 'packet_demod',
+ gr.io_signature(1, 1, Byte().get_num_bytes()),
+ gr.io_signature(1, 1, item_size)
+ )
#the message source (handles the output data stream)
msg_source = gr.message_source(item_size, DEFAULT_QUEUE_LIMIT)
msgq = msg_source.msgq()
@@ -123,8 +138,9 @@
callback=callback,
threshold=threshold,
)
- #create hier block
- gr.hier_block.__init__(self, fg, packet_demod, msg_source)
+ #connections
+ self.connect(msg_source, self)
+ self.connect(self, packet_demod.head)
#######################################################################################
## Packet Modulator and Demodulator Defs
@@ -211,3 +227,90 @@
) #build packet demodulator
return sb, make
+#######################################################################################
+## TUN/TAP Access Threads
+#######################################################################################
+
+IFF_TUN = 0x0001 # tunnel IP packets
+IFF_TAP = 0x0002 # tunnel ethernet frames
+IFF_NO_PI = 0x1000 # don't pass extra packet info
+IFF_ONE_QUEUE = 0x2000 # beats me ;)
+DEFAULT_TUN_DEVICE = '/dev/net/tun'
+DEFAULT_VIRTUAL_DEVICE = 'tun%d'
+DEFAULT_IP_ADDR = '10.0.0.1'
+
+def open_tun_interface(tun_device_filename=DEFAULT_TUN_DEVICE,
virtual_device_filename=DEFAULT_VIRTUAL_DEVICE):
+ """!
+ Open a virtual ethernet interface via the Tun/Tap framework.
+ An alternative function can be found: "from eunuchs.tuntap import
opentuntap"
+ @param tun_device_filename the path to the tun device
+ @param virtual_device_filename the name of the virtual device (to be
created)
+ @return a file descriptor to rw the device, name of the virtual device
(created)
+ """
+ from fcntl import ioctl
+ mode = IFF_TAP | IFF_NO_PI
+ TUNSETIFF = 0x400454ca
+ tun_fd = os.open(tun_device_filename, os.O_RDWR)
+ ifs = ioctl(tun_fd, TUNSETIFF, struct.pack("16sH",
virtual_device_filename, mode))
+ ifname = ifs[:16].strip("\x00")
+ return tun_fd, ifname
+
+class TunSinkThread(threading.Thread):
+ """
+ Thread to forward data from the message queue and to the virtual device.
+ """
+ def __init__(self, msgq, tun_fd, ifname):
+ """!
+ TunSinkThread contructor.
+ @param msgq the message queue with incoming data
+ @param tun_fd the file descriptor for the virtual device
+ @param ifname the name of virtual interface
+ """
+ self.msgq = msgq
+ self.tun_fd = tun_fd
+ threading.Thread.__init__(self)
+ self.setDaemon(1)
+ self.keep_running = True
+ self.start()
+ print 'Created tun sink thread for device "%s".'%ifname
+
+ def run(self):
+ """In an endless while loop: read the msgq and write to tun."""
+ while self.keep_running:
+ msg = self.msgq.delete_head() # blocking read of
message queue
+ os.write(self.tun_fd, msg.to_string())
+
+#######################################################################################
+## TUN/TAP Block Defs
+#######################################################################################
+
+def TunSink(sb):
+ gr.message_sink #uses
+ type = Enum(all_choices, 1)
+ sb.add_input_socket('in', Variable(type))
+ sb.add_param('Type', type, False, type=True)
+ sb.add_param('Tun Device', String(DEFAULT_TUN_DEVICE))
+ sb.add_param('Virtual Device', String(DEFAULT_VIRTUAL_DEVICE))
+ sb.add_param('IP Address', String(DEFAULT_IP_ADDR))
+ sb.set_docs('''\
+Write data from a gnuradio data stream into a virtual ethernet interface.
+---
+Tun Device: File path to the tun device.
+
+Virtual Device: Desired name for the virtual ethernet device. \
+"%d" will give the device a number starting at zero.
+
+IP Address: IP address for the virtual device, leave blank and device will not
be configured.
+''')
+ def make(fg, type, tun, virt, ip_addr):
+ item_size = type.parse().get_num_bytes()
+ msgq = gr.msg_queue(DEFAULT_QUEUE_LIMIT)
+ tun_fd, ifname = open_tun_interface(tun.parse(), virt.parse())
+ #try to set the ip address
+ ip_addr = ip_addr.parse()
+ if ip_addr: os.system('ifconfig %s %s'%(ifname, ip_addr))
+ TunSinkThread(msgq, tun_fd, ifname)
+ return gr.message_sink(item_size, msgq, False)
+ return sb, make
+
+
\ No newline at end of file
Modified: grc/branches/jblum_work/src/SignalBlockDefs/SignalBlockConstants.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/SignalBlockConstants.py
2007-06-26 21:56:12 UTC (rev 5849)
+++ grc/branches/jblum_work/src/SignalBlockDefs/SignalBlockConstants.py
2007-06-27 00:32:02 UTC (rev 5850)
@@ -23,26 +23,50 @@
from DataTypes import *
from gnuradio import gr
-class ThrottleHelper(gr.hier_block):
+class ThrottleHelper(gr.hier_block2):
"""A block with a throttle on the input or output."""
- def __init__(self, fg, item_size, samp_rate, block, position):
+ def __init__(self, item_size, samp_rate, block, position):
"""!
ThrottleHelper contructor.
Create a throttle and append it to the block.
- @param fg the gr flow graph
@param item_size the size of the gr data stream in bytes
@param block the gr block
@param position if true connect a throttle to the input of
block, otherwise the output
- """
+ """
+ gr.hier_block2.__init__(
+ self, "throttle_helper",
+ gr.io_signature(1, 1, item_size),
+ gr.io_signature(1, 1, item_size)
+ )
input = output = block
throttle = gr.throttle(item_size, samp_rate)
if position:
input = throttle
- fg.connect(throttle, block)
+ self.connect(self, throttle, block, self)
else:
output = throttle
- fg.connect(block, throttle)
- gr.hier_block.__init__(self, fg, input, output)
+ self.connect(self, block, throttle, self)
+
+class HierHelper(gr.hier_block2):
+ """Wrap a hier2 block around a hier block."""
+ def __init__(self, hier_block, item_size_in=0, item_size_out=0):
+ """!
+ HierHelper constructor.
+ An item size of zero means that there is no connection.
+ @param hier_block a regular hier block
+ @param item_size_in the size of the input data stream in bytes
+ @param item_size_out the size of the output data stream in
bytes
+ """
+ #io signatures
+ if item_size_in > 0: io_sig_in = gr.io_signature(1, 1,
item_size_in)
+ else: io_sig_in = gr.io_signature(0, 0, 0)
+ if item_size_out > 0: io_sig_out = gr.io_signature(1, 1,
item_size_out)
+ else: io_sig_out = gr.io_signature(0, 0, 0)
+ #initialize
+ gr.hier_block2.__init__(self, "hier_helper", io_sig_in,
io_sig_out)
+ #connect
+ if item_size_in > 0: self.connect(self, hier_block.head)
+ if item_size_out > 0: self.connect(hier_block.tail, self)
##max number of sockets to draw on one side of a signal block.
MAX_NUM_SOCKETS = 20
Modified: grc/branches/jblum_work/src/SignalBlockDefs/SignalBlockTree.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/SignalBlockTree.py
2007-06-26 21:56:12 UTC (rev 5849)
+++ grc/branches/jblum_work/src/SignalBlockDefs/SignalBlockTree.py
2007-06-27 00:32:02 UTC (rev 5850)
@@ -56,6 +56,7 @@
('Audio Sink', Sinks.AudioSink),
('USRP Sink', USRP.USRPSink),
('USRP Dual Sink', USRP.USRPDualSink),
+ ('Tun Sink', Packet.TunSink),
]),
('Graphical Sinks', [
('Numerical Sink',
GraphicalSinks.NumericalSink),
Modified: grc/branches/jblum_work/src/SignalBlockDefs/Sinks.py
===================================================================
--- grc/branches/jblum_work/src/SignalBlockDefs/Sinks.py 2007-06-26
21:56:12 UTC (rev 5849)
+++ grc/branches/jblum_work/src/SignalBlockDefs/Sinks.py 2007-06-27
00:32:02 UTC (rev 5850)
@@ -149,7 +149,7 @@
item_size = type.parse().get_num_bytes()
block = gr.message_sink(item_size, msgq, True)
var_sink_thread = VariableSinkThread(fg, var_key.parse(), msgq)
- return ThrottleHelper(fg, item_size, samp_rate.parse(), block,
True)
+ return ThrottleHelper(item_size, samp_rate.parse(), block, True)
return sb, make
\ No newline at end of file
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r5850 - in grc/branches/jblum_work: examples notes src src/SignalBlockDefs,
jblum <=