diff options
Diffstat (limited to 'gr-blocks')
-rw-r--r-- | gr-blocks/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-blocks/grc/blks2_error_rate.xml | 69 | ||||
-rw-r--r-- | gr-blocks/grc/blks2_selector.xml | 97 | ||||
-rw-r--r-- | gr-blocks/grc/blks2_tcp_sink.xml | 90 | ||||
-rw-r--r-- | gr-blocks/grc/blks2_tcp_source.xml | 89 | ||||
-rw-r--r-- | gr-blocks/grc/blks2_valve.xml | 72 | ||||
-rw-r--r-- | gr-blocks/python/grc_gnuradio/CMakeLists.txt | 37 | ||||
-rw-r--r-- | gr-blocks/python/grc_gnuradio/README | 11 | ||||
-rw-r--r-- | gr-blocks/python/grc_gnuradio/__init__.py | 1 | ||||
-rw-r--r-- | gr-blocks/python/grc_gnuradio/blks2/__init__.py | 30 | ||||
-rw-r--r-- | gr-blocks/python/grc_gnuradio/blks2/error_rate.py | 140 | ||||
-rw-r--r-- | gr-blocks/python/grc_gnuradio/blks2/selector.py | 142 | ||||
-rw-r--r-- | gr-blocks/python/grc_gnuradio/blks2/tcp.py | 70 |
13 files changed, 849 insertions, 0 deletions
diff --git a/gr-blocks/CMakeLists.txt b/gr-blocks/CMakeLists.txt index 13b41a2e3c..685f5736fb 100644 --- a/gr-blocks/CMakeLists.txt +++ b/gr-blocks/CMakeLists.txt @@ -87,6 +87,7 @@ add_subdirectory(lib) #endif(ENABLE_TESTING) if(ENABLE_PYTHON) add_subdirectory(python/blocks) + add_subdirectory(python/grc_gnuradio) add_subdirectory(swig) add_subdirectory(grc) add_subdirectory(doc) diff --git a/gr-blocks/grc/blks2_error_rate.xml b/gr-blocks/grc/blks2_error_rate.xml new file mode 100644 index 0000000000..91a303206d --- /dev/null +++ b/gr-blocks/grc/blks2_error_rate.xml @@ -0,0 +1,69 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Error Rate: +## Custom blks2 block +################################################### + --> +<block> + <name>Error Rate</name> + <key>blks2_error_rate</key> + <import>from grc_gnuradio import blks2 as grc_blks2</import> + <make>grc_blks2.error_rate( + type=$type, + win_size=$win_size, + bits_per_symbol=$bits_per_symbol, +)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Bit Error Rate</name> + <key>'BER'</key> + <opt>hide_bps:</opt> + </option> + <option> + <name>Symbol Error Rate</name> + <key>'SER'</key> + <opt>hide_bps:all</opt> + </option> + </param> + <param> + <name>Window Size</name> + <key>win_size</key> + <value>1000</value> + <type>int</type> + </param> + <param> + <name>Bits per Symbol</name> + <key>bits_per_symbol</key> + <value>2</value> + <type>int</type> + <hide>$type.hide_bps</hide> + </param> + <sink> + <name>ref</name> + <type>byte</type> + </sink> + <sink> + <name>in</name> + <type>byte</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> + <doc> +Calculate the bit error rate (BER) or the symbol error rate (SER) over a number of samples given by the window size. \ +The actual window size will start at size one and grow to the full window size as new samples arrive. \ +Once the window has reached full size, old samples are shifted out of the window and new samples shfited in. + +The error block compares the input byte stream to the reference byte stream. \ +For example, the reference byte stream could be the input to a modulator, \ +and the input byte stream could be the output of a modulator. + +Each byte in the incoming stream represents one symbol. \ +The bits per symbol parameter is only useful for calculating the BER. + </doc> +</block> diff --git a/gr-blocks/grc/blks2_selector.xml b/gr-blocks/grc/blks2_selector.xml new file mode 100644 index 0000000000..2d89df1860 --- /dev/null +++ b/gr-blocks/grc/blks2_selector.xml @@ -0,0 +1,97 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Selector: +## Custom blks2 block +################################################### + --> +<block> + <name>Selector</name> + <key>blks2_selector</key> + <import>from grc_gnuradio import blks2 as grc_blks2</import> + <make>grc_blks2.selector( + item_size=$type.size*$vlen, + num_inputs=$num_inputs, + num_outputs=$num_outputs, + input_index=$input_index, + output_index=$output_index, +)</make> + <callback>set_input_index(int($input_index))</callback> + <callback>set_output_index(int($output_index))</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Num Inputs</name> + <key>num_inputs</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Num Outputs</name> + <key>num_outputs</key> + <value>2</value> + <type>int</type> + </param> + <param> + <name>Input Index</name> + <key>input_index</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Output Index</name> + <key>output_index</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_outputs</nports> + </source> + <doc> +Connect the sink at input index to the source at output index. Leave all other ports disconnected. + </doc> +</block> diff --git a/gr-blocks/grc/blks2_tcp_sink.xml b/gr-blocks/grc/blks2_tcp_sink.xml new file mode 100644 index 0000000000..46b10a7790 --- /dev/null +++ b/gr-blocks/grc/blks2_tcp_sink.xml @@ -0,0 +1,90 @@ +<?xml version="1.0"?> +<!-- +################################################### +##TCP Sink: Custom blks2 block +################################################### + --> +<block> + <name>TCP Sink</name> + <key>blks2_tcp_sink</key> + <category>Deprecated</category> + <import>from grc_gnuradio import blks2 as grc_blks2</import> + <make>grc_blks2.tcp_sink( + itemsize=$type.size*$vlen, + addr=$addr, + port=$port, + server=$server, +)</make> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Address</name> + <key>addr</key> + <value>127.0.0.1</value> + <type>string</type> + </param> + <param> + <name>Port</name> + <key>port</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Mode</name> + <key>server</key> + <value>False</value> + <type>enum</type> + <option> + <name>Server</name> + <key>True</key> + </option> + <option> + <name>Client</name> + <key>False</key> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + <doc> +In client mode, we attempt to connect to a server at the given address and port. \ +In server mode, we bind a socket to the given address and port and accept the first client. + </doc> +</block> diff --git a/gr-blocks/grc/blks2_tcp_source.xml b/gr-blocks/grc/blks2_tcp_source.xml new file mode 100644 index 0000000000..6bf742aa00 --- /dev/null +++ b/gr-blocks/grc/blks2_tcp_source.xml @@ -0,0 +1,89 @@ +<?xml version="1.0"?> +<!-- +################################################### +##TCP Source: Custom blks2 block +################################################### + --> +<block> + <name>TCP Source</name> + <key>blks2_tcp_source</key> + <import>from grc_gnuradio import blks2 as grc_blks2</import> + <make>grc_blks2.tcp_source( + itemsize=$type.size*$vlen, + addr=$addr, + port=$port, + server=$server, +)</make> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Address</name> + <key>addr</key> + <value>127.0.0.1</value> + <type>string</type> + </param> + <param> + <name>Port</name> + <key>port</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Mode</name> + <key>server</key> + <value>True</value> + <type>enum</type> + <option> + <name>Server</name> + <key>True</key> + </option> + <option> + <name>Client</name> + <key>False</key> + </option> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> + <doc> +In client mode, we attempt to connect to a server at the given address and port. \ +In server mode, we bind a socket to the given address and port and accept the first client. + </doc> +</block> diff --git a/gr-blocks/grc/blks2_valve.xml b/gr-blocks/grc/blks2_valve.xml new file mode 100644 index 0000000000..47c553523f --- /dev/null +++ b/gr-blocks/grc/blks2_valve.xml @@ -0,0 +1,72 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Valve: +## Custom blks2 block +################################################### + --> +<block> + <name>Valve</name> + <key>blks2_valve</key> + <import>from grc_gnuradio import blks2 as grc_blks2</import> + <make>grc_blks2.valve(item_size=$type.size*$vlen, open=bool($open))</make> + <callback>set_open(bool($open))</callback> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>size:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>size:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>size:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>size:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>size:gr.sizeof_char</opt> + </option> + </param> + <param> + <name>Open</name> + <key>open</key> + <value>0</value> + <type>raw</type> + </param> + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + <check>$vlen > 0</check> + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_inputs</nports> + </sink> + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + <nports>$num_outputs</nports> + </source> + <doc> +Connect output to input when valve is closed (not open). + </doc> +</block> diff --git a/gr-blocks/python/grc_gnuradio/CMakeLists.txt b/gr-blocks/python/grc_gnuradio/CMakeLists.txt new file mode 100644 index 0000000000..9ff1240997 --- /dev/null +++ b/gr-blocks/python/grc_gnuradio/CMakeLists.txt @@ -0,0 +1,37 @@ +# Copyright 2011 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## + +include(GrPython) + +GR_PYTHON_INSTALL( + FILES __init__.py + DESTINATION ${GR_PYTHON_DIR}/grc_gnuradio + COMPONENT "blocks_python" +) + +GR_PYTHON_INSTALL(FILES + blks2/__init__.py + blks2/error_rate.py + blks2/selector.py + blks2/tcp.py + DESTINATION ${GR_PYTHON_DIR}/grc_gnuradio/blks2 + COMPONENT "blocks_python" +) diff --git a/gr-blocks/python/grc_gnuradio/README b/gr-blocks/python/grc_gnuradio/README new file mode 100644 index 0000000000..897eed65ca --- /dev/null +++ b/gr-blocks/python/grc_gnuradio/README @@ -0,0 +1,11 @@ +This is the grc_gnuradio module. +It contains supplemental python modules that grc uses at runtime. +The supplemental modules are meant to mimic modules in gnuradio. +These will be phased-out as new functionaility is merged into gnuradio. + +The blk2s module wraps many blocks in blks2 and gives them streaming outputs. +Will be phased-out by new message passing implementations. +Other blks2 blocks will hopefully make their way into blks2impl. + +The wxgui module contains a top_block + wxgui frame. +Will be phased-out by gui.py in wxgui and a new top block template. diff --git a/gr-blocks/python/grc_gnuradio/__init__.py b/gr-blocks/python/grc_gnuradio/__init__.py new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/gr-blocks/python/grc_gnuradio/__init__.py @@ -0,0 +1 @@ + diff --git a/gr-blocks/python/grc_gnuradio/blks2/__init__.py b/gr-blocks/python/grc_gnuradio/blks2/__init__.py new file mode 100644 index 0000000000..d3c8210834 --- /dev/null +++ b/gr-blocks/python/grc_gnuradio/blks2/__init__.py @@ -0,0 +1,30 @@ +# Copyright 2008-2011 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from selector import selector, valve +from error_rate import error_rate +from tcp import tcp_source, tcp_sink + +try: + from packet import options, packet_encoder, packet_decoder, \ + packet_mod_b, packet_mod_s, packet_mod_i, packet_mod_f, packet_mod_c, \ + packet_demod_b, packet_demod_s, packet_demod_i, packet_demod_f, packet_demod_c +except ImportError: + pass # only available if gr-digital is install diff --git a/gr-blocks/python/grc_gnuradio/blks2/error_rate.py b/gr-blocks/python/grc_gnuradio/blks2/error_rate.py new file mode 100644 index 0000000000..9bf387030a --- /dev/null +++ b/gr-blocks/python/grc_gnuradio/blks2/error_rate.py @@ -0,0 +1,140 @@ +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +default_win_size = 1000 + +from gnuradio import gr +from gnuradio import blocks +import gnuradio.gr.gr_threading as _threading +import numpy + +#generate 1s counts array +_1s_counts = [sum([1&(i>>j) for j in range(8)]) for i in range(2**8)] + +class input_watcher(_threading.Thread): + """ + Read samples from the message queue and hand them to the callback. + """ + + def __init__(self, msgq, callback): + self._msgq = msgq + self._callback = callback + _threading.Thread.__init__(self) + self.setDaemon(1) + self.keep_running = True + self.start() + + def run(self): + r = '' + while True: + msg = self._msgq.delete_head() + itemsize = int(msg.arg1()) + nitems = int(msg.arg2()) + s = r + msg.to_string() + i = (nitems-nitems%2)*itemsize + r = s[i:] + s = s[:i] + samples = numpy.fromstring(s, numpy.int8) + self._callback(samples) + +class error_rate(gr.hier_block2): + """ + Sample the incoming data streams (byte) and calculate the bit or symbol error rate. + Write the running rate to the output data stream (float). + """ + + def __init__(self, type='BER', win_size=default_win_size, bits_per_symbol=2): + """ + Error rate constructor. + + Args: + type: a string 'BER' or 'SER' + win_size: the number of samples to calculate over + bits_per_symbol: the number of information bits per symbol (BER only) + """ + #init + gr.hier_block2.__init__( + self, 'error_rate', + gr.io_signature(2, 2, gr.sizeof_char), + gr.io_signature(1, 1, gr.sizeof_float), + ) + assert type in ('BER', 'SER') + self._max_samples = win_size + self._bits_per_symbol = bits_per_symbol + #setup message queue + msg_source = blocks.message_source(gr.sizeof_float, 1) + self._msgq_source = msg_source.msgq() + msgq_sink = gr.msg_queue(2) + msg_sink = blocks.message_sink(gr.sizeof_char, msgq_sink, False) #False -> blocking + inter = blocks.interleave(gr.sizeof_char) + #start thread + self._num_errs = 0 + self._err_index = 0 + self._num_samps = 0 + self._err_array = numpy.zeros(self._max_samples, numpy.int8) + if type == 'BER': + input_watcher(msgq_sink, self._handler_ber) + elif type == 'SER': + input_watcher(msgq_sink, self._handler_ser) + #connect + self.connect(msg_source, self) + self.connect((self, 0), (inter, 0)) + self.connect((self, 1), (inter, 1)) + self.connect(inter, msg_sink) + + def _handler_ber(self, samples): + num = len(samples)/2 + arr = numpy.zeros(num, numpy.float32) + for i in range(num): + old_err = self._err_array[self._err_index] + #record error + self._err_array[self._err_index] = _1s_counts[samples[i*2] ^ samples[i*2 + 1]] + self._num_errs = self._num_errs + self._err_array[self._err_index] - old_err + #increment index + self._err_index = (self._err_index + 1)%self._max_samples + self._num_samps = min(self._num_samps + 1, self._max_samples) + #write sample + arr[i] = float(self._num_errs)/float(self._num_samps*self._bits_per_symbol) + #write message + msg = gr.message_from_string(arr.tostring(), 0, gr.sizeof_float, num) + self._msgq_source.insert_tail(msg) + + def _handler_ser(self, samples): + num = len(samples)/2 + arr = numpy.zeros(num, numpy.float32) + for i in range(num): + old_err = self._err_array[self._err_index] + #record error + ref = samples[i*2] + res = samples[i*2 + 1] + if ref == res: + self._err_array[self._err_index] = 0 + else: + self._err_array[self._err_index] = 1 + #update number of errors + self._num_errs = self._num_errs + self._err_array[self._err_index] - old_err + #increment index + self._err_index = (self._err_index + 1)%self._max_samples + self._num_samps = min(self._num_samps + 1, self._max_samples) + #write sample + arr[i] = float(self._num_errs)/float(self._num_samps) + #write message + msg = gr.message_from_string(arr.tostring(), 0, gr.sizeof_float, num) + self._msgq_source.insert_tail(msg) diff --git a/gr-blocks/python/grc_gnuradio/blks2/selector.py b/gr-blocks/python/grc_gnuradio/blks2/selector.py new file mode 100644 index 0000000000..24e3844658 --- /dev/null +++ b/gr-blocks/python/grc_gnuradio/blks2/selector.py @@ -0,0 +1,142 @@ +# +# Copyright 2008,2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr +from gnuradio import blocks + +class selector(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, item_size, num_inputs, num_outputs, input_index, output_index): + """ + Selector constructor. + + Args: + item_size: the size of the gr data stream in bytes + num_inputs: the number of inputs (integer) + num_outputs: the number of outputs (integer) + input_index: the index for the source data + 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 = [blocks.null_sink(item_size) for i in range(num_inputs)] + self.output_terminators = [blocks.head(item_size, 0) for i in range(num_outputs)] + self.copy = blocks.copy(item_size) + #connections + for i in range(num_inputs): self.connect((self, i), self.input_terminators[i]) + for i in range(num_outputs): self.connect(blocks.null_source(item_size), + self.output_terminators[i], (self, i)) + self.item_size = item_size + self.input_index = input_index + self.output_index = output_index + self.num_inputs = num_inputs + self.num_outputs = num_outputs + self._connect_current() + + def _indexes_valid(self): + """ + Are the input and output indexes within range of the number of inputs and outputs? + + Returns: + true if input index and output index are in range + """ + return self.input_index in range(self.num_inputs) and self.output_index in range(self.num_outputs) + + 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): + """ + Change the block to the new input index if the index changed. + + Args: + input_index: the new input index + """ + if self.input_index != input_index: + self.lock() + self._disconnect_current() + self.input_index = input_index + self._connect_current() + self.unlock() + + def set_output_index(self, output_index): + """ + Change the block to the new output index if the index changed. + + Args: + output_index: the new output index + """ + if self.output_index != output_index: + self.lock() + self._disconnect_current() + self.output_index = output_index + self._connect_current() + self.unlock() + +class valve(selector): + """Wrapper for selector with 1 input and 1 output.""" + + def __init__(self, item_size, open): + """ + Constructor for valve. + + Args: + item_size: the size of the gr data stream in bytes + open: true if initial valve state is open + """ + if open: output_index = -1 + else: output_index = 0 + selector.__init__(self, item_size, 1, 1, 0, output_index) + + def set_open(self, open): + """ + Callback to set open state. + + Args: + open: true to set valve state to open + """ + if open: output_index = -1 + else: output_index = 0 + self.set_output_index(output_index) diff --git a/gr-blocks/python/grc_gnuradio/blks2/tcp.py b/gr-blocks/python/grc_gnuradio/blks2/tcp.py new file mode 100644 index 0000000000..aee90fad2c --- /dev/null +++ b/gr-blocks/python/grc_gnuradio/blks2/tcp.py @@ -0,0 +1,70 @@ +# +# Copyright 2009 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, blocks +import socket +import os + +def _get_sock_fd(addr, port, server): + """ + Get the file descriptor for the socket. + As a client, block on connect, dup the socket descriptor. + As a server, block on accept, dup the client descriptor. + + Args: + addr: the ip address string + port: the tcp port number + server: true for server mode, false for client mode + + Returns: + the file descriptor number + """ + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if server: + sock.bind((addr, port)) + sock.listen(1) + clientsock, address = sock.accept() + return os.dup(clientsock.fileno()) + else: + sock.connect((addr, port)) + return os.dup(sock.fileno()) + +class tcp_source(gr.hier_block2): + def __init__(self, itemsize, addr, port, server=True): + #init hier block + gr.hier_block2.__init__( + self, 'tcp_source', + gr.io_signature(0, 0, 0), + gr.io_signature(1, 1, itemsize), + ) + fd = _get_sock_fd(addr, port, server) + self.connect(blocks.file_descriptor_source(itemsize, fd), self) + +class tcp_sink(gr.hier_block2): + def __init__(self, itemsize, addr, port, server=False): + #init hier block + gr.hier_block2.__init__( + self, 'tcp_sink', + gr.io_signature(1, 1, itemsize), + gr.io_signature(0, 0, 0), + ) + fd = _get_sock_fd(addr, port, server) + self.connect(self, blocks.file_descriptor_sink(itemsize, fd)) |