summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--cmake/Modules/GrVersion.cmake21
-rw-r--r--docs/sphinx/source/blocks_blocks.rst1
-rw-r--r--docs/sphinx/source/index.rst1
-rw-r--r--gnuradio-runtime/lib/prefs.cc3
-rw-r--r--gr-blocks/grc/blocks_block_tree.xml1
-rw-r--r--gr-blocks/grc/blocks_tcp_server_sink.xml77
-rw-r--r--gr-blocks/include/gnuradio/blocks/CMakeLists.txt1
-rw-r--r--gr-blocks/include/gnuradio/blocks/tcp_server_sink.h66
-rw-r--r--gr-blocks/lib/CMakeLists.txt1
-rw-r--r--gr-blocks/lib/tcp_server_sink_impl.cc161
-rw-r--r--gr-blocks/lib/tcp_server_sink_impl.h73
-rw-r--r--gr-blocks/python/blocks/qa_tcp_server_sink.py87
-rw-r--r--gr-blocks/swig/blocks_swig5.i3
-rw-r--r--gr-dtv/lib/dvbt/dvbt_bit_inner_interleaver_impl.cc5
-rw-r--r--gr-uhd/apps/uhd_app.py35
-rwxr-xr-xgr-uhd/apps/uhd_fft58
-rw-r--r--gr-uhd/apps/uhd_siggen_base.py94
-rwxr-xr-xgr-uhd/apps/uhd_siggen_gui33
-rw-r--r--gr-uhd/lib/usrp_source_impl.cc1
20 files changed, 643 insertions, 83 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 29e5e00778..e2d997d77a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -72,9 +72,9 @@ ELSE()
ENDIF()
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11")
ELSE()
diff --git a/cmake/Modules/GrVersion.cmake b/cmake/Modules/GrVersion.cmake
index dceac67bab..414c34d64f 100644
--- a/cmake/Modules/GrVersion.cmake
+++ b/cmake/Modules/GrVersion.cmake
@@ -33,6 +33,16 @@ set(MAINT_VERSION ${VERSION_INFO_MAINT_VERSION})
########################################################################
find_package(Git)
+MACRO(create_manual_git_describe)
+ if(NOT GR_GIT_COUNT)
+ set(GR_GIT_COUNT "compat-xxx")
+ endif()
+ if(NOT GR_GIT_HASH)
+ set(GR_GIT_HASH "xunknown")
+ endif()
+ set(GIT_DESCRIBE "v${MAJOR_VERSION}.${API_COMPAT}-${GR_GIT_COUNT}-${GR_GIT_HASH}")
+ENDMACRO()
+
if(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git)
message(STATUS "Extracting version information from git describe...")
execute_process(
@@ -40,14 +50,11 @@ if(GIT_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/.git)
OUTPUT_VARIABLE GIT_DESCRIBE OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
-else()
- if(NOT GR_GIT_COUNT)
- set(GR_GIT_COUNT "compat-xxx")
- endif()
- if(NOT GR_GIT_HASH)
- set(GR_GIT_HASH "xunknown")
+ if(GIT_DESCRIBE STREQUAL "")
+ create_manual_git_describe()
endif()
- set(GIT_DESCRIBE "v${MAJOR_VERSION}.${API_COMPAT}-${GR_GIT_COUNT}-${GR_GIT_HASH}")
+else()
+ create_manual_git_describe()
endif()
########################################################################
diff --git a/docs/sphinx/source/blocks_blocks.rst b/docs/sphinx/source/blocks_blocks.rst
index 056e9efe9a..f214e01c47 100644
--- a/docs/sphinx/source/blocks_blocks.rst
+++ b/docs/sphinx/source/blocks_blocks.rst
@@ -185,6 +185,7 @@ gnuradio.blocks
.. autoblock:: gnuradio.blocks.tagged_stream_mux
.. autoblock:: gnuradio.blocks.tagged_stream_to_pdu
.. autoblock:: gnuradio.blocks.tags_strobe
+.. autoblock:: gnuradio.blocks.tcp_server_sink
.. autoblock:: gnuradio.blocks.threshold_ff
.. autoblock:: gnuradio.blocks.throttle
.. autoblock:: gnuradio.blocks.transcendental
diff --git a/docs/sphinx/source/index.rst b/docs/sphinx/source/index.rst
index 7bba2f8e32..5c14d22cce 100644
--- a/docs/sphinx/source/index.rst
+++ b/docs/sphinx/source/index.rst
@@ -854,6 +854,7 @@ Networking Tools Blocks
:nosignatures:
gnuradio.blocks.socket_pdu
+ gnuradio.blocks.tcp_server_sink
gnuradio.blocks.udp_sink
gnuradio.blocks.udp_source
diff --git a/gnuradio-runtime/lib/prefs.cc b/gnuradio-runtime/lib/prefs.cc
index 341028eba8..18acae0124 100644
--- a/gnuradio-runtime/lib/prefs.cc
+++ b/gnuradio-runtime/lib/prefs.cc
@@ -30,6 +30,7 @@
#include <algorithm>
#include <fstream>
+#include <iostream>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
@@ -113,7 +114,7 @@ namespace gr {
std::string value = o.value[0];
d_config_map[section][key] = value;
}
- } catch(const boost::program_options::invalid_config_file_syntax & e) {
+ } catch(std::exception e) {
std::cerr << "WARNING: Config file '" << fname << "' failed to parse:" << std::endl;
std::cerr << e.what() << std::endl;
std::cerr << "Skipping it" << std::endl;
diff --git a/gr-blocks/grc/blocks_block_tree.xml b/gr-blocks/grc/blocks_block_tree.xml
index c4857f3b3a..644773f686 100644
--- a/gr-blocks/grc/blocks_block_tree.xml
+++ b/gr-blocks/grc/blocks_block_tree.xml
@@ -158,6 +158,7 @@
<name>Networking Tools</name>
<block>blocks_tuntap_pdu</block>
<block>blocks_socket_pdu</block>
+ <block>blocks_tcp_server_sink</block>
<block>blocks_udp_source</block>
<block>blocks_udp_sink</block>
</cat>
diff --git a/gr-blocks/grc/blocks_tcp_server_sink.xml b/gr-blocks/grc/blocks_tcp_server_sink.xml
new file mode 100644
index 0000000000..644027da65
--- /dev/null
+++ b/gr-blocks/grc/blocks_tcp_server_sink.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##TCP Server Sink
+###################################################
+ -->
+<block>
+ <name>TCP Server Sink</name>
+ <key>blocks_tcp_server_sink</key>
+ <import>from gnuradio import blocks</import>
+ <make>blocks.tcp_server_sink($type.size*$vlen, $ipaddr, $port, $noblock)</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>Destination IP Address</name>
+ <key>ipaddr</key>
+ <type>string</type>
+ </param>
+ <param>
+ <name>Destination Port</name>
+ <key>port</key>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Nonblocking Mode</name>
+ <key>noblock</key>
+ <type>enum</type>
+ <option>
+ <name>On</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>Off</name>
+ <key>False</key>
+ </option>
+ </param>
+ <param>
+ <name>Vec Length</name>
+ <key>vlen</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <check>$vlen &gt; 0</check>
+ <sink>
+ <name>in</name>
+ <type>$type</type>
+ <vlen>$vlen</vlen>
+ </sink>
+</block>
diff --git a/gr-blocks/include/gnuradio/blocks/CMakeLists.txt b/gr-blocks/include/gnuradio/blocks/CMakeLists.txt
index 38c79d60f3..6b3eca69d3 100644
--- a/gr-blocks/include/gnuradio/blocks/CMakeLists.txt
+++ b/gr-blocks/include/gnuradio/blocks/CMakeLists.txt
@@ -174,6 +174,7 @@ install(FILES
tagged_stream_multiply_length.h
tagged_stream_to_pdu.h
tags_strobe.h
+ tcp_server_sink.h
test_tag_variable_rate_ff.h
threshold_ff.h
throttle.h
diff --git a/gr-blocks/include/gnuradio/blocks/tcp_server_sink.h b/gr-blocks/include/gnuradio/blocks/tcp_server_sink.h
new file mode 100644
index 0000000000..6d951a8e67
--- /dev/null
+++ b/gr-blocks/include/gnuradio/blocks/tcp_server_sink.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef INCLUDED_BLOCKS_TCP_SERVER_SINK_H
+#define INCLUDED_BLOCKS_TCP_SERVER_SINK_H
+
+#include <gnuradio/blocks/api.h>
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+ namespace blocks {
+
+ /*!
+ * \brief Send stream trought an TCP socket.
+ * \ingroup networking_tools_blk
+ *
+ * \details
+ * Listen for incomming TCP connection(s). Duplicate data for each
+ * opened connection. Optionaly can wait until first client connects
+ * before streaming starts.
+ */
+ class BLOCKS_API tcp_server_sink : virtual public gr::sync_block
+ {
+ public:
+ // gr::blocks::tcp_server_sink::sptr
+ typedef boost::shared_ptr<tcp_server_sink> sptr;
+
+ /*!
+ * \brief TCP Server Sink Constructor
+ *
+ * \param itemsize The size (in bytes) of the item datatype
+ * \param host The name or IP address of interface to bind to.
+ * \param port Port where to listen.
+ * \param noblock If false, wait until first client connects before
+ * streaming starts. In non blocking mode
+ * (noblock=true), drop data onto floor if no client
+ * is connected.
+ */
+ static sptr make(size_t itemsize,
+ const std::string &host, int port,
+ bool noblock = false);
+ };
+
+ } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_BLOCKS_TCP_SERVER_SINK_H */
diff --git a/gr-blocks/lib/CMakeLists.txt b/gr-blocks/lib/CMakeLists.txt
index 643190c2ee..1d69f27a1d 100644
--- a/gr-blocks/lib/CMakeLists.txt
+++ b/gr-blocks/lib/CMakeLists.txt
@@ -199,6 +199,7 @@ list(APPEND gr_blocks_sources
throttle_impl.cc
transcendental_impl.cc
tcp_connection.cc
+ tcp_server_sink_impl.cc
tuntap_pdu_impl.cc
tag_gate_impl.cc
tagged_stream_align_impl.cc
diff --git a/gr-blocks/lib/tcp_server_sink_impl.cc b/gr-blocks/lib/tcp_server_sink_impl.cc
new file mode 100644
index 0000000000..329e798ca8
--- /dev/null
+++ b/gr-blocks/lib/tcp_server_sink_impl.cc
@@ -0,0 +1,161 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007-2010,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tcp_server_sink_impl.h"
+#include <gnuradio/io_signature.h>
+#include <algorithm>
+#include <boost/array.hpp>
+#include <boost/asio.hpp>
+#include <boost/format.hpp>
+#include <gnuradio/thread/thread.h>
+#include <stdexcept>
+#include <stdio.h>
+#include <string.h>
+
+namespace gr {
+ namespace blocks {
+
+ tcp_server_sink::sptr
+ tcp_server_sink::make(size_t itemsize,
+ const std::string &host, int port,
+ bool noblock)
+ {
+ return gnuradio::get_initial_sptr
+ (new tcp_server_sink_impl(itemsize, host, port, noblock));
+ }
+
+ tcp_server_sink_impl::tcp_server_sink_impl(size_t itemsize,
+ const std::string &host, int port,
+ bool noblock)
+ : sync_block("tcp_server_sink",
+ io_signature::make(1, 1, itemsize),
+ io_signature::make(0, 0, 0)),
+ d_itemsize(itemsize),
+ d_acceptor(d_io_service),
+ d_buf(new uint8_t[BUF_SIZE]),
+ d_writing(0)
+ {
+ std::string s_port = (boost::format("%d") % port).str();
+ std::string s_host = host.empty() ? std::string("localhost") : host;
+ boost::asio::ip::tcp::resolver resolver(d_io_service);
+ boost::asio::ip::tcp::resolver::query query(s_host, s_port,
+ boost::asio::ip::resolver_query_base::passive);
+ d_endpoint = *resolver.resolve(query);
+
+ d_acceptor.open(d_endpoint.protocol());
+ d_acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
+ d_acceptor.bind(d_endpoint);
+ d_acceptor.listen();
+
+ if (!noblock) {
+ d_socket.reset(new boost::asio::ip::tcp::socket(d_io_service));
+ d_acceptor.accept(*d_socket, d_endpoint);
+ d_sockets.insert(d_socket.release());
+ }
+
+ d_socket.reset(new boost::asio::ip::tcp::socket(d_io_service));
+ d_acceptor.async_accept(*d_socket, boost::bind(&tcp_server_sink_impl::do_accept,
+ this, boost::asio::placeholders::error));
+ d_io_serv_thread = boost::thread(
+ boost::bind(&boost::asio::io_service::run, &d_io_service));
+ }
+
+ void
+ tcp_server_sink_impl::do_accept(const boost::system::error_code& error)
+ {
+ if (!error) {
+ gr::thread::scoped_lock guard(d_writing_mut);
+ d_sockets.insert(d_socket.release());
+ d_socket.reset(new boost::asio::ip::tcp::socket(d_io_service));
+ d_acceptor.async_accept(*d_socket, boost::bind(&tcp_server_sink_impl::do_accept,
+ this, boost::asio::placeholders::error));
+ }
+ }
+
+ void
+ tcp_server_sink_impl::do_write(const boost::system::error_code& error,
+ size_t len, std::set<boost::asio::ip::tcp::socket *>::iterator i)
+ {
+ {
+ gr::thread::scoped_lock guard(d_writing_mut);
+ --d_writing;
+ if (error) {
+ delete *i;
+ d_sockets.erase(i);
+ }
+ }
+ d_writing_cond.notify_one();
+ }
+
+ tcp_server_sink_impl::~tcp_server_sink_impl()
+ {
+ gr::thread::scoped_lock guard(d_writing_mut);
+ while (d_writing) {
+ d_writing_cond.wait(guard);
+ }
+
+ for (std::set<boost::asio::ip::tcp::socket *>::iterator i = d_sockets.begin();
+ i != d_sockets.end(); ++i ) {
+ delete *i;
+ }
+ d_sockets.clear();
+
+ d_io_service.reset();
+ d_io_service.stop();
+ d_io_serv_thread.join();
+ }
+
+ int
+ tcp_server_sink_impl::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const char *in = (const char *) input_items[0];
+
+ gr::thread::scoped_lock guard(d_writing_mut);
+ while (d_writing) {
+ d_writing_cond.wait(guard);
+ }
+
+ size_t data_len = std::min(size_t(BUF_SIZE), noutput_items * d_itemsize);
+ data_len -= data_len % d_itemsize;
+ memcpy(d_buf.get(), in, data_len);
+ for (std::set<boost::asio::ip::tcp::socket *>::iterator i = d_sockets.begin();
+ i != d_sockets.end(); ++i ) {
+ boost::asio::async_write(**i, boost::asio::buffer(d_buf.get(), data_len),
+ boost::bind(&tcp_server_sink_impl::do_write, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ i));
+ }
+ d_writing = d_sockets.size();
+
+ return data_len / d_itemsize;
+ }
+
+ } /* namespace blocks */
+} /* namespace gr */
+
diff --git a/gr-blocks/lib/tcp_server_sink_impl.h b/gr-blocks/lib/tcp_server_sink_impl.h
new file mode 100644
index 0000000000..d10f3b95b8
--- /dev/null
+++ b/gr-blocks/lib/tcp_server_sink_impl.h
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014 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.
+ */
+
+#ifndef INCLUDED_GR_TCP_SERVER_SINK_IMPL_H
+#define INCLUDED_GR_TCP_SERVER_SINK_IMPL_H
+
+#include <gnuradio/blocks/tcp_server_sink.h>
+#include <boost/asio.hpp>
+#include <set>
+#include <boost/ptr_container/ptr_vector.hpp>
+
+namespace gr {
+ namespace blocks {
+
+ class tcp_server_sink_impl : public tcp_server_sink
+ {
+ private:
+ size_t d_itemsize;
+
+ boost::asio::io_service d_io_service;
+ gr::thread::thread d_io_serv_thread;
+ boost::asio::ip::tcp::endpoint d_endpoint;
+ std::auto_ptr<boost::asio::ip::tcp::socket> d_socket;
+ std::set<boost::asio::ip::tcp::socket *> d_sockets;
+ boost::asio::ip::tcp::acceptor d_acceptor;
+
+ boost::shared_ptr<uint8_t> d_buf;
+ enum {
+ BUF_SIZE = 256 * 1024,
+ };
+
+ int d_writing;
+ boost::condition_variable d_writing_cond;
+ boost::mutex d_writing_mut;
+
+ void do_accept(const boost::system::error_code& error);
+ void do_write(const boost::system::error_code& error, std::size_t len,
+ std::set<boost::asio::ip::tcp::socket *>::iterator);
+
+ public:
+ tcp_server_sink_impl(size_t itemsize,
+ const std::string &host, int port,
+ bool noblock);
+ ~tcp_server_sink_impl();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace blocks */
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_TCP_SERVER_SINK_IMPL_H */
diff --git a/gr-blocks/python/blocks/qa_tcp_server_sink.py b/gr-blocks/python/blocks/qa_tcp_server_sink.py
new file mode 100644
index 0000000000..f7d3a0af92
--- /dev/null
+++ b/gr-blocks/python/blocks/qa_tcp_server_sink.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+#
+# Copyright 2014 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, gr_unittest, blocks
+import os
+import socket
+from time import sleep
+
+from threading import Timer
+from multiprocessing import Process
+
+class test_tcp_sink(gr_unittest.TestCase):
+
+ def setUp(self):
+ os.environ['GR_CONF_CONTROLPORT_ON'] = 'False'
+ self.tb_snd = gr.top_block()
+ self.tb_rcv = gr.top_block()
+
+ def tearDown(self):
+ self.tb_rcv = None
+ self.tb_snd = None
+
+ def _tcp_client(self):
+ dst = blocks.vector_sink_s()
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ for t in (0, 0.2):
+# wait until server listens
+ sleep(t)
+ try:
+ sock.connect((self.addr, self.port))
+ except socket.error as e:
+ if e.errno != 111:
+ raise
+ continue
+ break
+ fd = os.dup(sock.fileno())
+ self.tb_rcv.connect(blocks.file_descriptor_source(self.itemsize, fd), dst)
+ self.tb_rcv.run()
+ self.assertEqual(self.data, dst.data())
+
+ def test_001(self):
+ self.addr = '127.0.0.1'
+ self.port = 65510
+ self.itemsize = gr.sizeof_short
+ n_data = 16
+ self.data = tuple([x for x in range(n_data)])
+
+# tcp_server_sink blocks until client does not connect, start client process first
+ p = Process(target=self._tcp_client)
+ p.start()
+
+ src = blocks.vector_source_s(self.data, False)
+ tcp_snd = blocks.tcp_server_sink(self.itemsize, self.addr, self.port, False)
+ self.tb_snd.connect(src, tcp_snd)
+
+ self.tb_snd.run()
+ del tcp_snd
+ self.tb_snd = None
+ p.join()
+
+ def stop_rcv(self):
+ self.timeout = True
+ self.tb_rcv.stop()
+ #print "tb_rcv stopped by Timer"
+
+if __name__ == '__main__':
+ gr_unittest.run(test_tcp_sink, "test_tcp_server_sink.xml")
+
diff --git a/gr-blocks/swig/blocks_swig5.i b/gr-blocks/swig/blocks_swig5.i
index 51601a8c30..761b0a855a 100644
--- a/gr-blocks/swig/blocks_swig5.i
+++ b/gr-blocks/swig/blocks_swig5.i
@@ -56,6 +56,7 @@
#include "gnuradio/blocks/tagged_stream_multiply_length.h"
#include "gnuradio/blocks/tagged_stream_to_pdu.h"
#include "gnuradio/blocks/tags_strobe.h"
+#include "gnuradio/blocks/tcp_server_sink.h"
#include "gnuradio/blocks/test_tag_variable_rate_ff.h"
#include "gnuradio/blocks/threshold_ff.h"
#include "gnuradio/blocks/transcendental.h"
@@ -100,6 +101,7 @@
%include "gnuradio/blocks/tagged_stream_multiply_length.h"
%include "gnuradio/blocks/tagged_stream_to_pdu.h"
%include "gnuradio/blocks/tags_strobe.h"
+%include "gnuradio/blocks/tcp_server_sink.h"
%include "gnuradio/blocks/test_tag_variable_rate_ff.h"
%include "gnuradio/blocks/threshold_ff.h"
%include "gnuradio/blocks/transcendental.h"
@@ -143,6 +145,7 @@ GR_SWIG_BLOCK_MAGIC2(blocks, tagged_stream_mux);
GR_SWIG_BLOCK_MAGIC2(blocks, tagged_stream_multiply_length);
GR_SWIG_BLOCK_MAGIC2(blocks, tagged_stream_to_pdu);
GR_SWIG_BLOCK_MAGIC2(blocks, tags_strobe);
+GR_SWIG_BLOCK_MAGIC2(blocks, tcp_server_sink);
GR_SWIG_BLOCK_MAGIC2(blocks, test_tag_variable_rate_ff);
GR_SWIG_BLOCK_MAGIC2(blocks, threshold_ff);
GR_SWIG_BLOCK_MAGIC2(blocks, transcendental);
diff --git a/gr-dtv/lib/dvbt/dvbt_bit_inner_interleaver_impl.cc b/gr-dtv/lib/dvbt/dvbt_bit_inner_interleaver_impl.cc
index d2bfb3d9d2..a5a9847812 100644
--- a/gr-dtv/lib/dvbt/dvbt_bit_inner_interleaver_impl.cc
+++ b/gr-dtv/lib/dvbt/dvbt_bit_inner_interleaver_impl.cc
@@ -118,8 +118,9 @@ namespace gr {
void
dvbt_bit_inner_interleaver_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required)
{
- ninput_items_required[0] = noutput_items;
- ninput_items_required[1] = noutput_items;
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = noutput_items;
}
int
diff --git a/gr-uhd/apps/uhd_app.py b/gr-uhd/apps/uhd_app.py
index ff4412a140..652a9fbab6 100644
--- a/gr-uhd/apps/uhd_app.py
+++ b/gr-uhd/apps/uhd_app.py
@@ -42,12 +42,25 @@ LONG_TPL = """{prefix} Motherboard: {mb_id} ({mb_serial})
"""
class UHDApp(object):
+ " Base class for simple UHD-based applications "
def __init__(self, prefix=None, args=None):
self.prefix = prefix
self.args = args
self.verbose = args.verbose or 0
if self.args.sync == 'auto' and len(self.args.channels) > 1:
self.args.sync = 'pps'
+ self.antenna = None
+ self.gain_range = None
+ self.samp_rate = None
+ self.has_lo_sensor = None
+ self.async_msgq = None
+ self.async_src = None
+ self.async_rcv = None
+ self.tr = None
+ self.gain = None
+ self.freq = None
+ self.channels = None
+ self.cpu_format = None
def vprint(self, *args):
"""
@@ -78,7 +91,7 @@ class UHDApp(object):
if info_pp['mb_serial'] == "":
info_pp['mb_serial'] = "no serial"
info_pp['db_subdev'] = usrp_info["{xx}_subdev_name".format(xx=tx_or_rx)]
- info_pp['db_serial'] = ", " + usrp_info["{xx}_serial".format(xx=tx_or_rx)]
+ info_pp['db_serial'] = ", " + usrp_info["{xx}_serial".format(xx=tx_or_rx)]
if info_pp['db_serial'] == "":
info_pp['db_serial'] = "no serial"
info_pp['subdev'] = self.usrp.get_subdev_spec(mboard)
@@ -112,12 +125,12 @@ class UHDApp(object):
"""
Call this when USRP async metadata needs printing.
"""
- md = self.async_src.msg_to_async_metadata_t(msg)
+ metadata = self.async_src.msg_to_async_metadata_t(msg)
print("[{prefix}] Channel: {chan} Time: {t} Event: {e}".format(
prefix=self.prefix,
- chan=md.channel,
- t=md.time_spec.get_real_secs(),
- e=md.event_code,
+ chan=metadata.channel,
+ t=metadata.time_spec.get_real_secs(),
+ e=metadata.event_code,
))
def setup_usrp(self, ctor, args, cpu_format='fc32'):
@@ -141,9 +154,13 @@ class UHDApp(object):
if args.spec:
for mb_idx in xrange(self.usrp.get_num_mboards()):
self.usrp.set_subdev_spec(args.spec, mb_idx)
- # Set the clock source:
+ # Set the clock and/or time source:
if args.clock_source is not None:
- self.usrp.set_clock_source(args.clock_source)
+ for mb_idx in xrange(self.usrp.get_num_mboards()):
+ self.usrp.set_clock_source(args.clock_source, mb_idx)
+ if args.time_source is not None:
+ for mb_idx in xrange(self.usrp.get_num_mboards()):
+ self.usrp.set_time_source(args.time_source, mb_idx)
# Sampling rate:
self.usrp.set_samp_rate(args.samp_rate)
self.samp_rate = self.usrp.get_samp_rate()
@@ -153,7 +170,7 @@ class UHDApp(object):
if self.antenna is not None:
for i, chan in enumerate(self.channels):
if not self.antenna[i] in self.usrp.get_antennas(chan):
- self.vprint("[ERROR] {} is not a valid antenna name for this USRP device!".format(ant))
+ self.vprint("[ERROR] {} is not a valid antenna name for this USRP device!".format(self.antenna[i]))
exit(1)
self.usrp.set_antenna(self.antenna[i], chan)
self.vprint("[{prefix}] Channel {chan}: Using antenna {ant}.".format(
@@ -310,5 +327,7 @@ class UHDApp(object):
default='auto', help="Set to 'pps' to sync devices to PPS")
group.add_argument("--clock-source",
help="Set the clock source; typically 'internal', 'external' or 'gpsdo'")
+ group.add_argument("--time-source",
+ help="Set the time source")
return parser
diff --git a/gr-uhd/apps/uhd_fft b/gr-uhd/apps/uhd_fft
index bb557e96f0..aa10cdf900 100755
--- a/gr-uhd/apps/uhd_fft
+++ b/gr-uhd/apps/uhd_fft
@@ -1,6 +1,6 @@
#!/usr/bin/env python2
#
-# Copyright 2015 Free Software Foundation, Inc.
+# Copyright 2015-2016 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -277,7 +277,37 @@ class uhd_fft(gr.top_block, Qt.QWidget, UHDApp):
_freeze_scope_thread = threading.Thread(target=lambda: _freeze_scaling(self.qtgui_time_sink_x_0, 2.0))
_freeze_scope_thread.daemon = True
_freeze_scope_thread.start()
-
+ if args.phase_relations and len(self.channels) > 1:
+ self.display_widget_phase = Qt.QWidget()
+ self.display_layout_phase = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.display_widget_phase)
+ self.display_grid_layout_phase = Qt.QGridLayout()
+ self.display_layout_phase.addLayout(self.display_grid_layout_phase)
+ self.display.addTab(self.display_widget_phase, "Rel. Phase")
+ self.qtgui_phase_plot = qtgui.time_sink_f(
+ 1024, #size
+ self.samp_rate, #samp_rate
+ "", #name
+ len(self.channels) - 1
+ )
+ self.qtgui_phase_plot.set_update_time(self.update_rate)
+ self.qtgui_phase_plot.set_y_axis(-3.5, 3.5)
+ self.qtgui_phase_plot.set_y_label("Relative Phase", "")
+ self.qtgui_phase_plot.enable_tags(-1, True)
+ self.qtgui_phase_plot.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "")
+ self.qtgui_phase_plot.enable_autoscale(False)
+ self.qtgui_phase_plot.enable_grid(True)
+ self.qtgui_phase_plot.enable_control_panel(True)
+ self.qtgui_phase_plot.disable_legend()
+ for i in xrange(len(self.channels) - 1):
+ self.qtgui_phase_plot.set_line_label(i, "Phase Delta Channels {0}/{1}".format(i, i+1))
+ self.qtgui_phase_plot.set_line_width(i, widths[i])
+ self.qtgui_phase_plot.set_line_color(i, colors[i])
+ self.qtgui_phase_plot.set_line_style(i, styles[i])
+ self.qtgui_phase_plot.set_line_marker(i, markers[i])
+ self.qtgui_phase_plot.set_line_alpha(i, alphas[i])
+ self._qtgui_phase_plot_win = sip.wrapinstance(self.qtgui_phase_plot.pyqwidget(), Qt.QWidget)
+ self.display_grid_layout_phase.addWidget(self._qtgui_phase_plot_win, 0,0,1,4)
+ ### Other widgets ###################################################
self._lo_locked_probe_tool_bar = Qt.QToolBar(self)
self._lo_locked_probe_formatter = lambda x: {True: 'Yes', False: 'No'}[x]
if self.has_lo_sensor:
@@ -317,10 +347,24 @@ class uhd_fft(gr.top_block, Qt.QWidget, UHDApp):
##################################################
self.msg_connect((self.qtgui_freq_sink_x_0, 'freq'), (self.qtgui_freq_sink_x_0, 'freq'))
self.msg_connect((self.qtgui_freq_sink_x_0, 'freq'), (self.usrp, 'command'))
- for c in self.channels:
- self.connect((self.usrp, c), (self.qtgui_freq_sink_x_0, c))
- self.connect((self.usrp, c), (self.qtgui_time_sink_x_0, c))
- self.connect((self.usrp, c), (self.qtgui_waterfall_sink_x_0, c))
+ for c, idx in enumerate(self.channels):
+ self.connect((self.usrp, c), (self.qtgui_freq_sink_x_0, idx))
+ self.connect((self.usrp, c), (self.qtgui_time_sink_x_0, idx))
+ self.connect((self.usrp, c), (self.qtgui_waterfall_sink_x_0, idx))
+ if args.phase_relations and len(self.channels) > 1:
+ for c, idx in enumerate(self.channels[:-1]):
+ self.connect_phase_plot(
+ (self.usrp, c),
+ (self.usrp, self.channels[idx+1]),
+ (self.qtgui_phase_plot, idx)
+ )
+
+ def connect_phase_plot(self, src_port1, src_port2, dst_port):
+ " Calculate relative phase between two src ports and send it dst_port "
+ from gnuradio import blocks
+ multiplier = blocks.multiply_cc()
+ self.connect(src_port1, (multiplier, 0), blocks.complex_to_arg(), dst_port)
+ self.connect(src_port2, blocks.conjugate_cc(), (multiplier, 1))
def closeEvent(self, event):
self.settings = Qt.QSettings("GNU Radio", "uhd_fft")
@@ -417,6 +461,8 @@ def setup_argparser():
help="Specify FFT average alpha (overrides --fft-average)")
group.add_argument("--update-rate", dest="update_rate", type=eng_arg.eng_float, default=eng_notation.num_to_str(.1),
help="Set GUI widget update rate")
+ group.add_argument("--phase-relations", action="store_true",
+ help="Plot relative phases between multiple channels")
return parser
diff --git a/gr-uhd/apps/uhd_siggen_base.py b/gr-uhd/apps/uhd_siggen_base.py
index 31415dac41..cc699dd145 100644
--- a/gr-uhd/apps/uhd_siggen_base.py
+++ b/gr-uhd/apps/uhd_siggen_base.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
#
# Copyright 2008,2009,2011,2012,2015 Free Software Foundation, Inc.
#
@@ -23,6 +23,17 @@
Provide a base flow graph for USRP signal generators.
"""
+from __future__ import print_function
+import math
+try:
+ from uhd_app import UHDApp
+except ImportError:
+ from gnuradio.uhd.uhd_app import UHDApp
+from gnuradio import gr, uhd, eng_notation, eng_arg
+from gnuradio import analog
+from gnuradio import blocks
+from gnuradio.gr.pubsub import pubsub
+
DESC_KEY = 'desc'
SAMP_RATE_KEY = 'samp_rate'
LINK_RATE_KEY = 'link_rate'
@@ -39,26 +50,9 @@ FREQ_RANGE_KEY = 'freq_range'
GAIN_RANGE_KEY = 'gain_range'
TYPE_KEY = 'type'
-# FIXME figure out if this can be deleted
-#def setter(ps, key, val): ps[key] = val
-
-import sys
-import math
-import argparse
-try:
- from uhd_app import UHDApp
-except ImportError:
- from gnuradio.uhd.uhd_app import UHDApp
-from gnuradio import gr, gru, uhd, eng_notation, eng_arg
-from gnuradio import analog
-from gnuradio import blocks
-from gnuradio.gr.pubsub import pubsub
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-
n2s = eng_notation.num_to_str
-waveforms = {
+WAVEFORMS = {
analog.GR_CONST_WAVE : "Constant",
analog.GR_SIN_WAVE : "Complex Sinusoid",
analog.GR_GAUSSIAN : "Gaussian Noise",
@@ -78,6 +72,11 @@ class USRPSiggen(gr.top_block, pubsub, UHDApp):
UHDApp.__init__(self, args=args, prefix="UHD-SIGGEN")
self.extra_sink = None
+ # Allocate some attributes
+ self._src1 = None
+ self._src2 = None
+ self._src = None
+
# Initialize device:
self.setup_usrp(
ctor=uhd.usrp_sink,
@@ -121,13 +120,13 @@ class USRPSiggen(gr.top_block, pubsub, UHDApp):
self[key] = self[key]
self[TYPE_KEY] = args.type #set type last
- def set_samp_rate(self, sr):
+ def set_samp_rate(self, samp_rate):
"""
When sampling rate is updated, also update the signal sources.
"""
- self.vprint("Setting sampling rate to: {rate} Msps".format(rate=sr/1e6))
- self.usrp.set_samp_rate(sr)
- sr = self.usrp.get_samp_rate()
+ self.vprint("Setting sampling rate to: {rate} Msps".format(rate=samp_rate/1e6))
+ self.usrp.set_samp_rate(samp_rate)
+ samp_rate = self.usrp.get_samp_rate()
if self[TYPE_KEY] in (analog.GR_SIN_WAVE, analog.GR_CONST_WAVE):
self._src.set_sampling_freq(self[SAMP_RATE_KEY])
elif self[TYPE_KEY] == "2tone":
@@ -138,10 +137,11 @@ class USRPSiggen(gr.top_block, pubsub, UHDApp):
self._src2.set_sampling_freq(self[WAVEFORM_FREQ_KEY]*2*math.pi/self[SAMP_RATE_KEY])
else:
return True # Waveform not yet set
- self.vprint("Set sample rate to: {rate} Msps".format(rate=sr/1e6))
+ self.vprint("Set sample rate to: {rate} Msps".format(rate=samp_rate/1e6))
return True
def set_waveform_freq(self, freq):
+ " Change the frequency 1 of the generated waveform "
if self[TYPE_KEY] == analog.GR_SIN_WAVE:
self._src.set_frequency(freq)
elif self[TYPE_KEY] == "2tone":
@@ -152,6 +152,10 @@ class USRPSiggen(gr.top_block, pubsub, UHDApp):
return True
def set_waveform2_freq(self, freq):
+ """
+ Change the frequency 2 of the generated waveform. This only
+ applies to 2-tone and sweep.
+ """
if freq is None:
self[WAVEFORM2_FREQ_KEY] = -self[WAVEFORM_FREQ_KEY]
return
@@ -161,19 +165,22 @@ class USRPSiggen(gr.top_block, pubsub, UHDApp):
self._src1.set_frequency(freq)
return True
- def set_waveform(self, type):
+ def set_waveform(self, waveform_type):
+ """
+ Select the generated waveform
+ """
self.vprint("Selecting waveform...")
self.lock()
self.disconnect_all()
- if type == analog.GR_SIN_WAVE or type == analog.GR_CONST_WAVE:
+ if waveform_type == analog.GR_SIN_WAVE or waveform_type == analog.GR_CONST_WAVE:
self._src = analog.sig_source_c(self[SAMP_RATE_KEY], # Sample rate
- type, # Waveform type
+ waveform_type, # Waveform waveform_type
self[WAVEFORM_FREQ_KEY], # Waveform frequency
self[AMPLITUDE_KEY], # Waveform amplitude
self[WAVEFORM_OFFSET_KEY]) # Waveform offset
- elif type == analog.GR_GAUSSIAN or type == analog.GR_UNIFORM:
- self._src = analog.noise_source_c(type, self[AMPLITUDE_KEY])
- elif type == "2tone":
+ elif waveform_type == analog.GR_GAUSSIAN or waveform_type == analog.GR_UNIFORM:
+ self._src = analog.noise_source_c(waveform_type, self[AMPLITUDE_KEY])
+ elif waveform_type == "2tone":
self._src1 = analog.sig_source_c(self[SAMP_RATE_KEY],
analog.GR_SIN_WAVE,
self[WAVEFORM_FREQ_KEY],
@@ -187,9 +194,9 @@ class USRPSiggen(gr.top_block, pubsub, UHDApp):
self[AMPLITUDE_KEY]/2.0,
0)
self._src = blocks.add_cc()
- self.connect(self._src1,(self._src,0))
- self.connect(self._src2,(self._src,1))
- elif type == "sweep":
+ self.connect(self._src1, (self._src, 0))
+ self.connect(self._src2, (self._src, 1))
+ elif waveform_type == "sweep":
# rf freq is center frequency
# waveform_freq is total swept width
# waveform2_freq is sweep rate
@@ -205,21 +212,21 @@ class USRPSiggen(gr.top_block, pubsub, UHDApp):
self._src = blocks.multiply_const_cc(self[AMPLITUDE_KEY])
self.connect(self._src1, self._src2, self._src)
else:
- raise RuntimeError("[UHD-SIGGEN] Unknown waveform type")
- for c in xrange(len(self.channels)):
- self.connect(self._src, (self.usrp, c))
+ raise RuntimeError("[UHD-SIGGEN] Unknown waveform waveform_type")
+ for chan in xrange(len(self.channels)):
+ self.connect(self._src, (self.usrp, chan))
if self.extra_sink is not None:
self.connect(self._src, self.extra_sink)
self.unlock()
- self.vprint("Set baseband modulation to:", waveforms[type])
- if type == analog.GR_SIN_WAVE:
+ self.vprint("Set baseband modulation to:", WAVEFORMS[waveform_type])
+ if waveform_type == analog.GR_SIN_WAVE:
self.vprint("Modulation frequency: %sHz" % (n2s(self[WAVEFORM_FREQ_KEY]),))
self.vprint("Initial phase:", self[WAVEFORM_OFFSET_KEY])
- elif type == "2tone":
+ elif waveform_type == "2tone":
self.vprint("Tone 1: %sHz" % (n2s(self[WAVEFORM_FREQ_KEY]),))
self.vprint("Tone 2: %sHz" % (n2s(self[WAVEFORM2_FREQ_KEY]),))
- elif type == "sweep":
- self.vprint("Sweeping across %sHz to %sHz" % (n2s(-self[WAVEFORM_FREQ_KEY]/2.0),n2s(self[WAVEFORM_FREQ_KEY]/2.0)))
+ elif waveform_type == "sweep":
+ self.vprint("Sweeping across %sHz to %sHz" % (n2s(-self[WAVEFORM_FREQ_KEY]/2.0), n2s(self[WAVEFORM_FREQ_KEY]/2.0)))
self.vprint("Sweep rate: %sHz" % (n2s(self[WAVEFORM2_FREQ_KEY]),))
self.vprint("TX amplitude:", self[AMPLITUDE_KEY])
@@ -274,6 +281,7 @@ def setup_argparser():
return parser
def main():
+ " Go, go, go! "
if gr.enable_realtime_scheduling() != gr.RT_OK:
print("Note: failed to enable realtime scheduling, continuing")
# Grab command line args and create top block
@@ -281,8 +289,8 @@ def main():
parser = setup_argparser()
args = parser.parse_args()
tb = USRPSiggen(args)
- except RuntimeError as e:
- print(e)
+ except RuntimeError as ex:
+ print(ex)
exit(1)
tb.start()
raw_input('[UHD-SIGGEN] Press Enter to quit:\n')
diff --git a/gr-uhd/apps/uhd_siggen_gui b/gr-uhd/apps/uhd_siggen_gui
index ab04ccc8e2..c5528f3777 100755
--- a/gr-uhd/apps/uhd_siggen_gui
+++ b/gr-uhd/apps/uhd_siggen_gui
@@ -1,6 +1,6 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python
#
-# Copyright 2015 Free Software Foundation, Inc.
+# Copyright 2015-2016 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -32,13 +32,14 @@ Signal Generator App
# Generated: Sun Jun 28 17:21:28 2015
##################################################
+from __future__ import print_function
import sip
import sys
import threading
import time
from distutils.version import StrictVersion
from PyQt4 import Qt
-from PyQt4.QtCore import QObject, pyqtSlot
+from PyQt4.QtCore import pyqtSlot
from gnuradio import analog
from gnuradio import eng_notation
from gnuradio import gr
@@ -69,9 +70,9 @@ class uhd_siggen_gui(Qt.QWidget):
Qt.QWidget.__init__(self)
self.setWindowTitle("UHD Signal Generator")
try:
- self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
+ self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
except:
- pass
+ pass
self.top_scroll_layout = Qt.QVBoxLayout()
self.setLayout(self.top_scroll_layout)
self.top_scroll = Qt.QScrollArea()
@@ -90,8 +91,8 @@ class uhd_siggen_gui(Qt.QWidget):
# Widgets + Controls
##################################################
### Waveform Selector
- self._waveform_options = uhd_siggen.waveforms.keys()
- self._waveform_labels = uhd_siggen.waveforms.values()
+ self._waveform_options = uhd_siggen.WAVEFORMS.keys()
+ self._waveform_labels = uhd_siggen.WAVEFORMS.values()
self._waveform_group_box = Qt.QGroupBox("Waveform")
self._waveform_box = Qt.QHBoxLayout()
class variable_chooser_button_group(Qt.QButtonGroup):
@@ -259,11 +260,12 @@ class uhd_siggen_gui(Qt.QWidget):
self._lo_locked_probe_0_tool_bar.addWidget(self._lo_locked_probe_0_label)
self.top_grid_layout.addWidget(self._lo_locked_probe_0_tool_bar, 8,0,1,1)
def _chan0_lo_locked_probe():
+ " Monitor lock status of LO on channel 0 "
while True:
- val = all([self.usrp.get_sensor('lo_locked', c).to_bool() for c in range(len(self._sg.channels))])
try:
+ val = all([self.usrp.get_sensor('lo_locked', c).to_bool() for c in range(len(self._sg.channels))])
self.set_chan0_lo_locked(val)
- except AttributeError:
+ except:
pass
time.sleep(.1)
_chan0_lo_locked_thread = threading.Thread(target=_chan0_lo_locked_probe)
@@ -366,8 +368,8 @@ class uhd_siggen_gui(Qt.QWidget):
self.freq_fine + self.freq_coarse,
self.lo_offset
)
- for idx, c in enumerate(self._sg.channels):
- tune_res = self.usrp.set_center_freq(tune_req, c)
+ for idx, chan in enumerate(self._sg.channels):
+ tune_res = self.usrp.set_center_freq(tune_req, chan)
if idx == 0:
self.set_label_dsp_freq(tune_res.actual_dsp_freq)
self.set_label_rf_freq(tune_res.actual_rf_freq)
@@ -446,7 +448,7 @@ def main():
""" Go, go, go! """
parser = setup_parser()
args = parser.parse_args()
- if(StrictVersion(Qt.qVersion()) >= StrictVersion("4.5.0")):
+ if StrictVersion(Qt.qVersion()) >= StrictVersion("4.5.0"):
Qt.QApplication.setGraphicsSystem(gr.prefs().get_string('qtgui', 'style', 'raster'))
qapp = Qt.QApplication(sys.argv)
siggen_gui = uhd_siggen_gui(args)
@@ -457,14 +459,17 @@ def main():
qapp.exec_()
siggen_gui = None #to clean up Qt widgets
-if __name__ == '__main__':
+def x11_init_threads():
+ " If on X11, init threads "
import ctypes
- import sys
if sys.platform.startswith('linux'):
try:
x11 = ctypes.cdll.LoadLibrary('libX11.so')
x11.XInitThreads()
except:
print("Warning: failed to XInitThreads()")
+
+if __name__ == '__main__':
+ x11_init_threads()
main()
diff --git a/gr-uhd/lib/usrp_source_impl.cc b/gr-uhd/lib/usrp_source_impl.cc
index f0450a604d..ebfdf4abb2 100644
--- a/gr-uhd/lib/usrp_source_impl.cc
+++ b/gr-uhd/lib/usrp_source_impl.cc
@@ -480,6 +480,7 @@ namespace gr {
{
_dev->issue_stream_cmd(cmd, _stream_args.channels[i]);
}
+ _tag_now = true;
}
bool