commit-gnuradio
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]