diff options
63 files changed, 4784 insertions, 26 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 9803104d12..404ce04347 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -327,6 +327,7 @@ add_subdirectory(gr-vocoder) add_subdirectory(gr-fcd) add_subdirectory(gr-wavelet) add_subdirectory(gr-wxgui) +add_subdirectory(gr-zeromq) # Defining GR_CTRLPORT for gnuradio/config.h if(ENABLE_GR_CTRLPORT) diff --git a/cmake/Modules/FindPortaudio.cmake b/cmake/Modules/FindPortaudio.cmake index 61e4ae23a1..20145ea8df 100644 --- a/cmake/Modules/FindPortaudio.cmake +++ b/cmake/Modules/FindPortaudio.cmake @@ -6,7 +6,7 @@ # PORTAUDIO_LIBRARIES - Link these to use Portaudio include(FindPkgConfig) -pkg_check_modules(PC_PORTAUDIO portaudio) +pkg_check_modules(PC_PORTAUDIO portaudio-2.0) find_path(PORTAUDIO_INCLUDE_DIRS NAMES @@ -15,7 +15,7 @@ find_path(PORTAUDIO_INCLUDE_DIRS /usr/local/include /usr/include HINTS - ${PC_PORTAUDIO_INCLUDE_DIR} + ${PC_PORTAUDIO_INCLUDEDIR} ) find_library(PORTAUDIO_LIBRARIES @@ -31,5 +31,22 @@ find_library(PORTAUDIO_LIBRARIES mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES) -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(PORTAUDIO DEFAULT_MSG PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES) +# Found PORTAUDIO, but it may be version 18 which is not acceptable. +if(EXISTS ${PORTAUDIO_INCLUDE_DIRS}/portaudio.h) + include(CheckCXXSourceCompiles) + include(CMakePushCheckState) + cmake_push_check_state() + set(CMAKE_REQUIRED_INCLUDES ${PORTAUDIO_INCLUDE_DIRS}) + CHECK_CXX_SOURCE_COMPILES( + "#include <portaudio.h>\nPaDeviceIndex pa_find_device_by_name(const char *name); int main () {return 0;}" + PORTAUDIO2_FOUND) + cmake_pop_check_state() + if(PORTAUDIO2_FOUND) + INCLUDE(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(PORTAUDIO DEFAULT_MSG PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES) + else(PORTAUDIO2_FOUND) + message(STATUS + " portaudio.h not compatible (requires API 2.0)") + set(PORTAUDIO_FOUND FALSE) + endif(PORTAUDIO2_FOUND) +endif() diff --git a/cmake/Modules/FindZeroMQ.cmake b/cmake/Modules/FindZeroMQ.cmake new file mode 100644 index 0000000000..c1155c4cc5 --- /dev/null +++ b/cmake/Modules/FindZeroMQ.cmake @@ -0,0 +1,26 @@ +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(PC_ZEROMQ "libzmq") + +FIND_PATH(ZEROMQ_INCLUDE_DIRS + NAMES zmq.h + HINTS ${PC_ZEROMQ_INCLUDE_DIR} + ${CMAKE_INSTALL_PREFIX}/include + PATHS + /usr/local/include + /usr/include +) + +FIND_LIBRARY(ZEROMQ_LIBRARIES + NAMES zmq libzmq + HINTS ${PC_ZEROMQ_LIBDIR} + ${CMAKE_INSTALL_PREFIX}/lib + ${CMAKE_INSTALL_PREFIX}/lib64 + PATHS + ${ZEROMQ_INCLUDE_DIRS}/../lib + /usr/local/lib + /usr/lib +) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZEROMQ DEFAULT_MSG ZEROMQ_LIBRARIES ZEROMQ_INCLUDE_DIRS) +MARK_AS_ADVANCED(ZEROMQ_LIBRARIES ZEROMQ_INCLUDE_DIRS) diff --git a/gnuradio-runtime/python/gnuradio/__init__.py b/gnuradio-runtime/python/gnuradio/__init__.py index 1e2966bd08..39886272de 100644 --- a/gnuradio-runtime/python/gnuradio/__init__.py +++ b/gnuradio-runtime/python/gnuradio/__init__.py @@ -48,3 +48,4 @@ if path.endswith(path_ending): __path__.append(os.path.join(build_path, 'gr-fec', 'python')) __path__.append(os.path.join(build_path, 'gr-utils', 'python')) __path__.append(os.path.join(build_path, 'gr-uhd', 'python')) + __path__.append(os.path.join(build_path, 'gr-zeromq', 'python')) diff --git a/gr-blocks/grc/blocks_pdu_filter.xml b/gr-blocks/grc/blocks_pdu_filter.xml index a9565c9b9c..1fb7209500 100644 --- a/gr-blocks/grc/blocks_pdu_filter.xml +++ b/gr-blocks/grc/blocks_pdu_filter.xml @@ -9,7 +9,7 @@ <key>blocks_pdu_filter</key> <import>from gnuradio import blocks</import> <import>import pmt</import> - <make>blocks.pdu_filter($k, $v)</make> + <make>blocks.pdu_filter($k, $v, $invert)</make> <param> <name>Key</name> <key>k</key> @@ -22,6 +22,20 @@ <value>pmt.intern("value")</value> <type>raw</type> </param> + <param> + <name>Invert Filter</name> + <key>invert</key> + <value>False</value> + <type>enum</type> + <option> + <name>No</name> + <key>False</key> + </option> + <option> + <name>Yes</name> + <key>True</key> + </option> + </param> <sink> <name>pdus</name> <type>message</type> diff --git a/gr-blocks/include/gnuradio/blocks/pdu_filter.h b/gr-blocks/include/gnuradio/blocks/pdu_filter.h index 5d0d2ed69a..1483731042 100644 --- a/gr-blocks/include/gnuradio/blocks/pdu_filter.h +++ b/gr-blocks/include/gnuradio/blocks/pdu_filter.h @@ -43,7 +43,7 @@ namespace gr { /*! * \brief Construct a PDU filter */ - static sptr make(pmt::pmt_t k, pmt::pmt_t v); + static sptr make(pmt::pmt_t k, pmt::pmt_t v, bool invert = false); }; } /* namespace blocks */ diff --git a/gr-blocks/lib/pdu_filter_impl.cc b/gr-blocks/lib/pdu_filter_impl.cc index 455c6c8ad9..5db8915b31 100644 --- a/gr-blocks/lib/pdu_filter_impl.cc +++ b/gr-blocks/lib/pdu_filter_impl.cc @@ -32,16 +32,16 @@ namespace gr { namespace blocks { pdu_filter::sptr - pdu_filter::make(pmt::pmt_t k, pmt::pmt_t v) + pdu_filter::make(pmt::pmt_t k, pmt::pmt_t v, bool invert) { - return gnuradio::get_initial_sptr(new pdu_filter_impl(k,v)); + return gnuradio::get_initial_sptr(new pdu_filter_impl(k,v,invert)); } - pdu_filter_impl::pdu_filter_impl(pmt::pmt_t k, pmt::pmt_t v) + pdu_filter_impl::pdu_filter_impl(pmt::pmt_t k, pmt::pmt_t v, bool invert) : block("pdu_filter", io_signature::make (0, 0, 0), io_signature::make (0, 0, 0)), - d_k(k), d_v(v) + d_k(k), d_v(v), d_invert(invert) { message_port_register_out(pmt::mp("pdus")); message_port_register_in(pmt::mp("pdus")); @@ -52,21 +52,19 @@ namespace gr { pdu_filter_impl::handle_msg(pmt::pmt_t pdu) { pmt::pmt_t meta = pmt::car(pdu); + bool output = d_invert; - // discard if meta is not a dict - if(!pmt::is_dict(meta)) - return; - - // make sure the dict has the target key - if(!dict_has_key(meta, d_k)) - return; - - // validate the value matches - if(!pmt::eqv(pmt::dict_ref(meta,d_k,pmt::PMT_NIL), d_v)) - return; + // check base type + // key exists + // value matches + if(pmt::is_dict(meta) && dict_has_key(meta, d_k) && pmt::eqv(pmt::dict_ref(meta,d_k,pmt::PMT_NIL), d_v)){ + output = !d_invert; + } // if all tests pass, propagate the pdu - message_port_pub(pmt::mp("pdus"), pdu); + if(output){ + message_port_pub(pmt::mp("pdus"), pdu); + } } } /* namespace blocks */ diff --git a/gr-blocks/lib/pdu_filter_impl.h b/gr-blocks/lib/pdu_filter_impl.h index 86fa648f00..66440ee421 100644 --- a/gr-blocks/lib/pdu_filter_impl.h +++ b/gr-blocks/lib/pdu_filter_impl.h @@ -33,9 +33,10 @@ namespace gr { private: pmt::pmt_t d_k; pmt::pmt_t d_v; + bool d_invert; public: - pdu_filter_impl(pmt::pmt_t k, pmt::pmt_t v); + pdu_filter_impl(pmt::pmt_t k, pmt::pmt_t v, bool invert); void handle_msg(pmt::pmt_t msg); }; diff --git a/gr-digital/lib/hdlc_deframer_bp_impl.cc b/gr-digital/lib/hdlc_deframer_bp_impl.cc index 12d7ec66bc..0723ad473e 100644 --- a/gr-digital/lib/hdlc_deframer_bp_impl.cc +++ b/gr-digital/lib/hdlc_deframer_bp_impl.cc @@ -64,6 +64,7 @@ namespace gr { */ hdlc_deframer_bp_impl::~hdlc_deframer_bp_impl() { + delete[] d_pktbuf; } unsigned int @@ -94,12 +95,13 @@ namespace gr { if(bit) { //six ones is a frame delimiter if(d_bytectr >= d_length_min) { //check CRC, publish frame + int len = d_bytectr - 2; //make Coverity happy unsigned short crc = d_pktbuf[d_bytectr-1] << 8 | d_pktbuf[d_bytectr-2]; - unsigned short calc_crc = crc_ccitt(d_pktbuf, d_bytectr-2); + unsigned short calc_crc = crc_ccitt(d_pktbuf, len); if (crc==calc_crc) { pmt::pmt_t pdu(pmt::cons(pmt::PMT_NIL, - pmt::make_blob(&d_pktbuf[0], d_bytectr-2))); + pmt::make_blob(d_pktbuf, len))); message_port_pub(pmt::mp("out"), pdu); } else { diff --git a/gr-utils/python/modtool/gr-newmod/python/__init__.py b/gr-utils/python/modtool/gr-newmod/python/__init__.py index 575cbfc222..d852fda545 100644 --- a/gr-utils/python/modtool/gr-newmod/python/__init__.py +++ b/gr-utils/python/modtool/gr-newmod/python/__init__.py @@ -42,7 +42,11 @@ if _RTLD_GLOBAL != 0: # import swig generated symbols into the howto namespace -from howto_swig import * +try: + # this might fail if the module is python-only + from howto_swig import * +except ImportError: + pass # import any pure python here # diff --git a/gr-zeromq/CMakeLists.txt b/gr-zeromq/CMakeLists.txt new file mode 100644 index 0000000000..ffb9a0fc67 --- /dev/null +++ b/gr-zeromq/CMakeLists.txt @@ -0,0 +1,111 @@ +# Copyright 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. + + +######################################################################## +# Setup dependencies +######################################################################## +include(GrBoost) +find_package(ZeroMQ) + +######################################################################## +# Register component +######################################################################## +include(GrComponent) + +GR_REGISTER_COMPONENT("gr-zeromq" ENABLE_GR_ZEROMQ + Boost_FOUND + ENABLE_GNURADIO_RUNTIME + ZEROMQ_FOUND +) + +GR_SET_GLOBAL(GR_ZEROMQ_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/lib + ${CMAKE_CURRENT_SOURCE_DIR}/include +) + +SET(GR_PKG_ZEROMQ_EXAMPLES_DIR ${GR_PKG_DATA_DIR}/examples/zeromq) + +######################################################################## +# Begin conditional configuration +######################################################################## +if(ENABLE_GR_ZEROMQ) + + +######################################################################## +# Setup CPack components +######################################################################## +include(GrPackage) +CPACK_SET(CPACK_COMPONENT_GROUP_ZEROMQ_DESCRIPTION "GNU Radio ZeromMQ Interface Blocks") + +CPACK_COMPONENT("zeromq_runtime" + GROUP "ZeroMQ Blocks" + DISPLAY_NAME "Runtime" + DESCRIPTION "Runtime" + DEPENDS "runtime_runtime" +) + +CPACK_COMPONENT("zeromq_devel" + GROUP "ZeroMQ Blocks" + DISPLAY_NAME "Development" + DESCRIPTION "C++ headers, package config, import libraries" + DEPENDS "runtime_devel" +) + +CPACK_COMPONENT("zeromq_python" + GROUP "ZeroMQ Blocks" + DISPLAY_NAME "Python" + DESCRIPTION "Python modules for runtime; GRC xml files" + DEPENDS "runtime_python;zeromq_runtime" +) + +CPACK_COMPONENT("zeromq_swig" + GROUP "ZeroMQ Blocks" + DISPLAY_NAME "SWIG" + DESCRIPTION "SWIG development .i files" + DEPENDS "runtime_swig;zeromq_python;zeromq_devel" +) + +######################################################################## +# Add subdirectories +######################################################################## +add_subdirectory(include/gnuradio/zeromq) +add_subdirectory(lib) +if(ENABLE_PYTHON) + add_subdirectory(swig) + add_subdirectory(python/zeromq) + add_subdirectory(grc) + add_subdirectory(examples) +endif(ENABLE_PYTHON) + +######################################################################## +# Create Pkg Config File +######################################################################## +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-zeromq.pc.in + ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-zeromq.pc +@ONLY) + +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-zeromq.pc + DESTINATION ${GR_LIBRARY_DIR}/pkgconfig + COMPONENT "zeromq_devel" +) + +endif(ENABLE_GR_ZEROMQ) diff --git a/gr-zeromq/docs/CMakeLists.txt b/gr-zeromq/docs/CMakeLists.txt new file mode 100644 index 0000000000..611193e967 --- /dev/null +++ b/gr-zeromq/docs/CMakeLists.txt @@ -0,0 +1,23 @@ +# 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. + +install( + FILES README.zeromq + DESTINATION ${GR_PKG_DOC_DIR} +) diff --git a/gr-zeromq/docs/README.zeromq b/gr-zeromq/docs/README.zeromq new file mode 100644 index 0000000000..f1d1f33e99 --- /dev/null +++ b/gr-zeromq/docs/README.zeromq @@ -0,0 +1,12 @@ +This is the gr-zeromq package. It contains all of the zeromq blocks, +utilities, and examples. To use the zeromq blocks, the Python +namespace is in gnuradio.zeromq, which would be normally imported as: + + from gnuradio import zeromq + +See the Doxygen documentation for details about the blocks available +in this package. A quick listing of the details can be found in Python +after importing by using: + + help(zeromq) + diff --git a/gr-zeromq/examples/CMakeLists.txt b/gr-zeromq/examples/CMakeLists.txt new file mode 100644 index 0000000000..f6730ce4d3 --- /dev/null +++ b/gr-zeromq/examples/CMakeLists.txt @@ -0,0 +1,29 @@ +# 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. + +include(GrPython) + +# Base stuff +INSTALL(FILES + zeromq_pubsub.grc + zeromq_pushpull.grc + zeromq_reqrep.grc + DESTINATION ${GR_PKG_ZEROMQ_EXAMPLES_DIR} + COMPONENT "zeromq_python" +) diff --git a/gr-zeromq/examples/python/README b/gr-zeromq/examples/python/README new file mode 100644 index 0000000000..2bc2dc8a52 --- /dev/null +++ b/gr-zeromq/examples/python/README @@ -0,0 +1,71 @@ +THIS IS EXPERIMENTAL SOFTWARE AND API IS SUBJECT TO CHANGE + +How to run the example +---------------------- + +Assuming that the module has been compiled but not installed, in the +gr-zeromq folder do + + cd examples + ./run_app.sh server + +on another terminal or machine + + ./run_app.sh client -s hostname + +You can also run a (remote) GUI on any of the two or a third machine for monitoring and control. + + ./run_app.sh gui.py -s servername -c hostname + +in doing so the order of starting the scripts is arbitrary. When installing the +module, the run\_app.sh script is of course not needed. + + +How to use the API +------------------ + +### PROBE API +Connect a zmq pubsub sink to the block you want to monitor + + self.zmq_probe = zeromq.sink_pubsub(gr.sizeof_float, "tcp://*:5556") + +add a probe manager to your Python GUI + + # ZeroMQ + probe_manager = zeromq.probe_manager() + probe_manager.add_socket("tcp://localhost:5556", + 'float32', self.plot_data) + + def plot_data(self,samples): + [...] + +basically creates a watcher thread that calls the call back functions and +unpacks sample data. Now you can use a timer to update the plot, e.g. in PyQt + + update_timer = Qt.QTimer() + self.connect(update_timer, + QtCore.SIGNAL("timeout()"), + probe_manager.watcher) + update_timer.start(30) + +### RPC API +Add an rpc manager to your Python app to receive RPCs + + rpc_manager = zeromq.rpc_manager() + rpc_manager.set_reply_socket("tcp://*:6666") + rpc_manager.add_interface("start_fg",self.start) + rpc_manager.start_watcher() + +to be able to send requests also add one on the other side + + rpc_manager = zeromq.rpc_manager() + rpc_manager.set_request_socket("tcp://localhost:6666") + +send a request + + rpc_mganager.request("start_fg") + rpc_mgr_server.request("set_k",gain) + +RPCs use GNU Radio pmt's to serialize arguments, the watcher thread will +regularly poll for incoming RPC requests, deserializes arguments and call the +interface callback function accordingly. diff --git a/gr-zeromq/examples/python/client.py b/gr-zeromq/examples/python/client.py new file mode 100755 index 0000000000..7663f9a056 --- /dev/null +++ b/gr-zeromq/examples/python/client.py @@ -0,0 +1,117 @@ +# +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio. +# +# This 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. +# +# This software 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 this software; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +############################################################################### +# Imports +############################################################################### +from gnuradio import zeromq +#import zeromq +from gnuradio import gr +from gnuradio import blocks +from gnuradio import analog +from gnuradio import eng_notation +from gnuradio.eng_option import eng_option +from optparse import OptionParser +import numpy +import sys +from threading import Thread +import time + +############################################################################### +# GNU Radio top_block +############################################################################### +class top_block(gr.top_block): + def __init__(self, options): + gr.top_block.__init__(self) + + self.options = options + + # socket addresses + rpc_adr = "tcp://*:6667" + probe_adr = "tcp://*:5557" + source_adr = "tcp://"+self.options.servername+":5555" + + # blocks + #self.zmq_source = zeromq.req_source(gr.sizeof_float, 1, source_adr) + #self.zmq_source = zeromq.pull_source(gr.sizeof_float, 1, source_adr) + self.zmq_source = zeromq.sub_source(gr.sizeof_float, 1, source_adr) + #self.zmq_probe = zeromq.push_sink(gr.sizeof_float,probe_adr) + self.zmq_probe = zeromq.pub_sink(gr.sizeof_float,probe_adr) + + # connects + self.connect(self.zmq_source, self.zmq_probe) + + # ZeroMQ + self.rpc_manager = zeromq.rpc_manager() + self.rpc_manager.set_reply_socket(rpc_adr) + self.rpc_manager.add_interface("start_fg",self.start_fg) + self.rpc_manager.add_interface("stop_fg",self.stop_fg) + self.rpc_manager.start_watcher() + + def start_fg(self): + print "Start Flowgraph" + try: + self.start() + except RuntimeError: + print "Can't start, flowgraph already running!" + + def stop_fg(self): + print "Stop Flowgraph" + self.stop() + self.wait() + +############################################################################### +# Options Parser +############################################################################### +def parse_options(): + """ Options parser. """ + parser = OptionParser(option_class=eng_option, usage="%prog: [options]") + parser.add_option("-s", "--servername", type="string", default="localhost", + help="Server hostname") + (options, args) = parser.parse_args() + return options + +############################################################################### +# Waiter Thread +############################################################################### +class waiter(Thread): + """ To keep the program alive when flowgraph is stopped. """ + def run(self): + while keep_running: + time.sleep(1) + +############################################################################### +# Main +############################################################################### +if __name__ == "__main__": + options = parse_options() + tb = top_block(options) + try: + # keep the program running when flowgraph is stopped + while True: + time.sleep(1) + except KeyboardInterrupt: + pass + print "Shutting down flowgraph." + tb.rpc_manager.stop_watcher() + tb.stop() + tb.wait() + tb = None diff --git a/gr-zeromq/examples/python/fixui4py.sh b/gr-zeromq/examples/python/fixui4py.sh new file mode 100755 index 0000000000..d2978000bf --- /dev/null +++ b/gr-zeromq/examples/python/fixui4py.sh @@ -0,0 +1,2 @@ +#!/bin/bash +sed -i 's/qwt_plot.h/PyQt4.Qwt5.Qwt/' $1 diff --git a/gr-zeromq/examples/python/gui.py b/gr-zeromq/examples/python/gui.py new file mode 100755 index 0000000000..91223dd734 --- /dev/null +++ b/gr-zeromq/examples/python/gui.py @@ -0,0 +1,164 @@ +# +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio. +# +# This 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. +# +# This software 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 this software; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +############################################################################### +# Imports +############################################################################### +from optparse import OptionParser +from gnuradio.eng_option import eng_option +import gui +import sys +import os +from PyQt4 import Qt, QtGui, QtCore, uic +import PyQt4.Qwt5 as Qwt +from gnuradio import zeromq +import signal + +class gui(QtGui.QMainWindow): + def __init__(self, window_name, options, parent=None): + QtGui.QMainWindow.__init__(self, parent) + + # give Ctrl+C back to system + signal.signal(signal.SIGINT, signal.SIG_DFL) + + self.gui = uic.loadUi(os.path.join(os.path.dirname(__file__),'main_window.ui'), self) + + self.update_timer = Qt.QTimer() + + # socket addresses + rpc_adr_server = "tcp://"+options.servername+":6666" + rpc_adr_client = "tcp://"+options.clientname+":6667" + probe_adr_server = "tcp://"+options.servername+":5556" + probe_adr_client = "tcp://"+options.clientname+":5557" + + # ZeroMQ + self.probe_manager = zeromq.probe_manager() + self.probe_manager.add_socket(probe_adr_server, 'float32', self.plot_data_server) + self.probe_manager.add_socket(probe_adr_client, 'float32', self.plot_data_client) + + self.rpc_mgr_server = zeromq.rpc_manager() + self.rpc_mgr_server.set_request_socket(rpc_adr_server) + self.rpc_mgr_client = zeromq.rpc_manager() + self.rpc_mgr_client.set_request_socket(rpc_adr_client) + + self.gui.setWindowTitle(window_name) + self.gui.qwtPlotServer.setTitle("Signal Scope") + self.gui.qwtPlotServer.setAxisTitle(Qwt.QwtPlot.xBottom, "Samples") + self.gui.qwtPlotServer.setAxisTitle(Qwt.QwtPlot.yLeft, "Amplitude") + self.gui.qwtPlotServer.setAxisScale(Qwt.QwtPlot.xBottom, 0, 100) + self.gui.qwtPlotServer.setAxisScale(Qwt.QwtPlot.yLeft, -2, 2) + self.gui.qwtPlotClient.setTitle("Signal Scope") + self.gui.qwtPlotClient.setAxisTitle(Qwt.QwtPlot.xBottom, "Samples") + self.gui.qwtPlotClient.setAxisTitle(Qwt.QwtPlot.yLeft, "Amplitude") + self.gui.qwtPlotClient.setAxisScale(Qwt.QwtPlot.xBottom, 0, 100) + self.gui.qwtPlotClient.setAxisScale(Qwt.QwtPlot.yLeft, -2, 2) + + # Grid + pen = Qt.QPen(Qt.Qt.DotLine) + pen.setColor(Qt.Qt.black) + pen.setWidth(0) + grid_server = Qwt.QwtPlotGrid() + grid_client = Qwt.QwtPlotGrid() + grid_server.setPen(pen) + grid_client.setPen(pen) + grid_server.attach(self.gui.qwtPlotServer) + grid_client.attach(self.gui.qwtPlotClient) + + #Signals + self.connect(self.update_timer, QtCore.SIGNAL("timeout()"), self.probe_manager.watcher) + self.connect(self.gui.pushButtonRunServer, QtCore.SIGNAL("clicked()"), self.start_fg_server) + self.connect(self.gui.pushButtonStopServer, QtCore.SIGNAL("clicked()"), self.stop_fg_server) + self.connect(self.gui.pushButtonRunClient, QtCore.SIGNAL("clicked()"), self.start_fg_client) + self.connect(self.gui.pushButtonStopClient, QtCore.SIGNAL("clicked()"), self.stop_fg_client) + self.connect(self.gui.comboBox, QtCore.SIGNAL("currentIndexChanged(QString)"), self.set_waveform) + self.connect(self.gui.spinBox, QtCore.SIGNAL("valueChanged(int)"), self.set_gain) + self.shortcut_start = QtGui.QShortcut(Qt.QKeySequence("Ctrl+S"), self.gui) + self.shortcut_stop = QtGui.QShortcut(Qt.QKeySequence("Ctrl+C"), self.gui) + self.shortcut_exit = QtGui.QShortcut(Qt.QKeySequence("Ctrl+D"), self.gui) + self.connect(self.shortcut_exit, QtCore.SIGNAL("activated()"), self.gui.close) + + # start update timer + self.update_timer.start(30) + + def start_fg_server(self): + self.rpc_mgr_server.request("start_fg") + + def stop_fg_server(self): + self.rpc_mgr_server.request("stop_fg") + + def start_fg_client(self): + self.rpc_mgr_client.request("start_fg") + + def stop_fg_client(self): + self.rpc_mgr_client.request("stop_fg") + + # plot the data from the queues + def plot_data(self, plot, samples): + self.x = range(0,len(samples),1) + self.y = samples + # clear the previous points from the plot + plot.clear() + # draw curve with new points and plot + curve = Qwt.QwtPlotCurve() + curve.setPen(Qt.QPen(Qt.Qt.blue, 2)) + curve.attach(plot) + curve.setData(self.x, self.y) + plot.replot() + + def plot_data_server(self, samples): + self.plot_data(self.gui.qwtPlotServer, samples) + + def plot_data_client(self, samples): + self.plot_data(self.gui.qwtPlotClient, samples) + + def set_waveform(self, waveform_str): + self.rpc_mgr_server.request("set_waveform",str(waveform_str)) + + def set_gain(self, gain): + self.rpc_set_gain(gain) + + def rpc_set_gain(self, gain): + self.rpc_mgr_server.request("set_k",gain) + +############################################################################### +# Options Parser +############################################################################### +def parse_options(): + """ Options parser. """ + parser = OptionParser(option_class=eng_option, usage="%prog: [options]") + parser.add_option("-s", "--servername", type="string", default="localhost", + help="Server hostname") + parser.add_option("-c", "--clientname", type="string", default="localhost", + help="Server hostname") + (options, args) = parser.parse_args() + return options + + +############################################################################### +# Main +############################################################################### +if __name__ == "__main__": + options = parse_options() + qapp = Qt.QApplication(sys.argv) + qapp.main_window = gui("Remote GNU Radio GUI",options) + qapp.main_window.show() + qapp.exec_() + diff --git a/gr-zeromq/examples/python/main_window.ui b/gr-zeromq/examples/python/main_window.ui new file mode 100644 index 0000000000..14f810e67d --- /dev/null +++ b/gr-zeromq/examples/python/main_window.ui @@ -0,0 +1,199 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ControlPort_Example</class> + <widget class="QMainWindow" name="ControlPort_Example"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1000</width> + <height>600</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="windowTitle"> + <string>ControlPort Example</string> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="2"> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Client</string> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="1" column="0"> + <widget class="QPushButton" name="pushButtonRunClient"> + <property name="text"> + <string>Run</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QwtPlot" name="qwtPlotClient"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="pushButtonStopClient"> + <property name="text"> + <string>Stop</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="0" column="1" rowspan="4"> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item row="2" column="0"> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Waveform:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="comboBox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="currentIndex"> + <number>1</number> + </property> + <item> + <property name="text"> + <string>Constant</string> + </property> + </item> + <item> + <property name="text"> + <string>Sine</string> + </property> + </item> + <item> + <property name="text"> + <string>Cosine</string> + </property> + </item> + <item> + <property name="text"> + <string>Square</string> + </property> + </item> + <item> + <property name="text"> + <string>Triangle</string> + </property> + </item> + <item> + <property name="text"> + <string>Saw Tooth</string> + </property> + </item> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Gain:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QSpinBox" name="spinBox"> + <property name="value"> + <number>1</number> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="0"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Server</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="1" column="0"> + <widget class="QPushButton" name="pushButtonRunServer"> + <property name="text"> + <string>Run</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="pushButtonStopServer"> + <property name="text"> + <string>Stop</string> + </property> + </widget> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QwtPlot" name="qwtPlotServer"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="1" column="0"> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="Line" name="line_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1000</width> + <height>25</height> + </rect> + </property> + </widget> + <widget class="QStatusBar" name="statusbar"/> + </widget> + <customwidgets> + <customwidget> + <class>QwtPlot</class> + <extends>QFrame</extends> + <header>PyQt4.Qwt5.Qwt</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/gr-zeromq/examples/python/run_app.sh b/gr-zeromq/examples/python/run_app.sh new file mode 100755 index 0000000000..4af936ca82 --- /dev/null +++ b/gr-zeromq/examples/python/run_app.sh @@ -0,0 +1,4 @@ +#!/bin/sh +export LD_LIBRARY_PATH="$PWD/../../build/gr-zeromq/lib" +export PYTHONPATH="$PWD/../../build/gr-zeromq/swig:$PWD/../../python" +/usr/bin/python $1 $2 $3 $4 $5 $6 $7 $8 $9 diff --git a/gr-zeromq/examples/python/server.py b/gr-zeromq/examples/python/server.py new file mode 100755 index 0000000000..358b66c568 --- /dev/null +++ b/gr-zeromq/examples/python/server.py @@ -0,0 +1,126 @@ +# +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio. +# +# This 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. +# +# This software 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 this software; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +############################################################################### +# Imports +############################################################################### +from gnuradio import zeromq +from gnuradio import gr +from gnuradio import blocks +from gnuradio import analog +from gnuradio import eng_notation +from gnuradio.eng_option import eng_option +from optparse import OptionParser +import numpy +import sys +from threading import Thread +import time + + +############################################################################### +# GNU Radio top_block +############################################################################### +class top_block(gr.top_block): + def __init__(self, options): + gr.top_block.__init__(self) + + self.options = options + + # socket addresses + rpc_adr = "tcp://*:6666" + probe_adr = "tcp://*:5556" + sink_adr = "tcp://*:5555" + + # the strange sampling rate gives a nice movement in the plot :P + self.samp_rate = samp_rate = 48200 + + # blocks + self.gr_sig_source = analog.sig_source_f(samp_rate, analog.GR_SIN_WAVE , 1000, 1, 0) + self.throttle = blocks.throttle(gr.sizeof_float, samp_rate) + self.mult = blocks.multiply_const_ff(1) + #self.zmq_sink = zeromq.rep_sink(gr.sizeof_float, 1, sink_adr) + self.zmq_sink = zeromq.pub_sink(gr.sizeof_float, 1, sink_adr) + #self.zmq_sink = zeromq.push_sink(gr.sizeof_float, 1, sink_adr) + #self.zmq_probe = zeromq.push_sink(gr.sizeof_float, probe_adr) + self.zmq_probe = zeromq.pub_sink(gr.sizeof_float, probe_adr) + #self.null_sink = blocks.null_sink(gr.sizeof_float) + + # connects + self.connect(self.gr_sig_source, self.mult, self.throttle, self.zmq_sink) + self.connect(self.throttle, self.zmq_probe) + + # ZeroMQ + self.rpc_manager = zeromq.rpc_manager() + self.rpc_manager.set_reply_socket(rpc_adr) + self.rpc_manager.add_interface("start_fg",self.start_fg) + self.rpc_manager.add_interface("stop_fg",self.stop_fg) + self.rpc_manager.add_interface("set_waveform",self.set_waveform) + self.rpc_manager.add_interface("set_k",self.mult.set_k) + self.rpc_manager.add_interface("get_sample_rate",self.throttle.sample_rate) + self.rpc_manager.start_watcher() + + def start_fg(self): + print "Start Flowgraph" + try: + self.start() + except RuntimeError: + print "Can't start, flowgraph already running!" + + def stop_fg(self): + print "Stop Flowgraph" + self.stop() + self.wait() + + def set_waveform(self, waveform_str): + waveform = {'Constant' : analog.GR_CONST_WAVE, + 'Sine' : analog.GR_SIN_WAVE, + 'Cosine' : analog.GR_COS_WAVE, + 'Square' : analog.GR_SQR_WAVE, + 'Triangle' : analog.GR_TRI_WAVE, + 'Saw Tooth' : analog.GR_SAW_WAVE}[waveform_str] + self.gr_sig_source.set_waveform(waveform) + +############################################################################### +# Options Parser +############################################################################### +def parse_options(): + """ Options parser. """ + parser = OptionParser(option_class=eng_option, usage="%prog: [options]") + (options, args) = parser.parse_args() + return options + +############################################################################### +# Main +############################################################################### +if __name__ == "__main__": + options = parse_options() + tb = top_block(options) + try: + # keep the program running when flowgraph is stopped + while True: + time.sleep(1) + except KeyboardInterrupt: + pass + print "Shutting down flowgraph." + tb.rpc_manager.stop_watcher() + tb.stop() + tb.wait() + tb = None diff --git a/gr-zeromq/examples/zeromq_pubsub.grc b/gr-zeromq/examples/zeromq_pubsub.grc new file mode 100644 index 0000000000..2b50b9f617 --- /dev/null +++ b/gr-zeromq/examples/zeromq_pubsub.grc @@ -0,0 +1,477 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Tue May 13 13:09:21 2014</timestamp> + <block> + <key>analog_sig_source_x</key> + <param> + <key>id</key> + <value>analog_sig_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>analog.GR_TRI_WAVE</value> + </param> + <param> + <key>freq</key> + <value>2000</value> + </param> + <param> + <key>amp</key> + <value>1</value> + </param> + <param> + <key>offset</key> + <value>0</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(170, 78)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>32000</value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 170)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_add_xx</key> + <param> + <key>id</key> + <value>blocks_add_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(417, 156)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_throttle</key> + <param> + <key>id</key> + <value>blocks_throttle_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samples_per_second</key> + <value>samp_rate</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>ignoretag</key> + <value>True</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(536, 169)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>zeromq_pub_sink</key> + <param> + <key>id</key> + <value>zeromq_pub_sink_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>address</key> + <value>tcp://127.0.0.1:5555</value> + </param> + <param> + <key>timeout</key> + <value>100</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(723, 153)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>analog_fastnoise_source_x</key> + <param> + <key>id</key> + <value>analog_fastnoise_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>noise_type</key> + <value>analog.GR_GAUSSIAN</value> + </param> + <param> + <key>amp</key> + <value>0.1</value> + </param> + <param> + <key>seed</key> + <value>0</value> + </param> + <param> + <key>samples</key> + <value>8192</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(169, 196)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>zeromq_sub_source</key> + <param> + <key>id</key> + <value>zeromq_sub_source_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>address</key> + <value>tcp://127.0.0.1:5555</value> + </param> + <param> + <key>timeout</key> + <value>100</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(185, 327)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_scopesink2</key> + <param> + <key>id</key> + <value>wxgui_scopesink2_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>title</key> + <value>Scope Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>v_scale</key> + <value>0</value> + </param> + <param> + <key>v_offset</key> + <value>0</value> + </param> + <param> + <key>t_scale</key> + <value>0</value> + </param> + <param> + <key>ac_couple</key> + <value>False</value> + </param> + <param> + <key>xy_mode</key> + <value>False</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>trig_mode</key> + <value>wxgui.TRIG_MODE_AUTO</value> + </param> + <param> + <key>y_axis_label</key> + <value>Counts</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(444, 319)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>options</key> + <param> + <key>id</key> + <value>zeromq_pubsub</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value></value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>analog_sig_source_x_0</source_block_id> + <sink_block_id>blocks_add_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>analog_fastnoise_source_x_0</source_block_id> + <sink_block_id>blocks_add_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>blocks_add_xx_0</source_block_id> + <sink_block_id>blocks_throttle_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_throttle_0</source_block_id> + <sink_block_id>zeromq_pub_sink_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>zeromq_sub_source_0</source_block_id> + <sink_block_id>wxgui_scopesink2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gr-zeromq/examples/zeromq_pushpull.grc b/gr-zeromq/examples/zeromq_pushpull.grc new file mode 100644 index 0000000000..b087a513d3 --- /dev/null +++ b/gr-zeromq/examples/zeromq_pushpull.grc @@ -0,0 +1,477 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Tue May 13 13:11:44 2014</timestamp> + <block> + <key>analog_sig_source_x</key> + <param> + <key>id</key> + <value>analog_sig_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>analog.GR_TRI_WAVE</value> + </param> + <param> + <key>freq</key> + <value>2000</value> + </param> + <param> + <key>amp</key> + <value>1</value> + </param> + <param> + <key>offset</key> + <value>0</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(170, 78)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>32000</value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 170)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_add_xx</key> + <param> + <key>id</key> + <value>blocks_add_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(409, 144)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_throttle</key> + <param> + <key>id</key> + <value>blocks_throttle_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samples_per_second</key> + <value>samp_rate</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>ignoretag</key> + <value>True</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(529, 157)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>options</key> + <param> + <key>id</key> + <value>zeromq_pushpull</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value></value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>zeromq_push_sink</key> + <param> + <key>id</key> + <value>zeromq_push_sink_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>address</key> + <value>tcp://127.0.0.1:5555</value> + </param> + <param> + <key>timeout</key> + <value>100</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(722, 141)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>zeromq_pull_source</key> + <param> + <key>id</key> + <value>zeromq_pull_source_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>address</key> + <value>tcp://127.0.0.1:5555</value> + </param> + <param> + <key>timeout</key> + <value>100</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(167, 308)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_scopesink2</key> + <param> + <key>id</key> + <value>wxgui_scopesink2_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>title</key> + <value>Scope Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>v_scale</key> + <value>0</value> + </param> + <param> + <key>v_offset</key> + <value>0</value> + </param> + <param> + <key>t_scale</key> + <value>0</value> + </param> + <param> + <key>ac_couple</key> + <value>False</value> + </param> + <param> + <key>xy_mode</key> + <value>False</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>trig_mode</key> + <value>wxgui.TRIG_MODE_AUTO</value> + </param> + <param> + <key>y_axis_label</key> + <value>Counts</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(422, 300)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>analog_fastnoise_source_x</key> + <param> + <key>id</key> + <value>analog_fastnoise_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>noise_type</key> + <value>analog.GR_GAUSSIAN</value> + </param> + <param> + <key>amp</key> + <value>0.1</value> + </param> + <param> + <key>seed</key> + <value>0</value> + </param> + <param> + <key>samples</key> + <value>8192</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(169, 196)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>blocks_throttle_0</source_block_id> + <sink_block_id>zeromq_push_sink_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>zeromq_pull_source_0</source_block_id> + <sink_block_id>wxgui_scopesink2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>analog_sig_source_x_0</source_block_id> + <sink_block_id>blocks_add_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>analog_fastnoise_source_x_0</source_block_id> + <sink_block_id>blocks_add_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>blocks_add_xx_0</source_block_id> + <sink_block_id>blocks_throttle_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gr-zeromq/examples/zeromq_reqrep.grc b/gr-zeromq/examples/zeromq_reqrep.grc new file mode 100644 index 0000000000..ede0e1b08a --- /dev/null +++ b/gr-zeromq/examples/zeromq_reqrep.grc @@ -0,0 +1,477 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Tue May 13 13:12:52 2014</timestamp> + <block> + <key>analog_sig_source_x</key> + <param> + <key>id</key> + <value>analog_sig_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>waveform</key> + <value>analog.GR_TRI_WAVE</value> + </param> + <param> + <key>freq</key> + <value>2000</value> + </param> + <param> + <key>amp</key> + <value>1</value> + </param> + <param> + <key>offset</key> + <value>0</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(170, 78)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>32000</value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 170)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>zeromq_req_source</key> + <param> + <key>id</key> + <value>zeromq_req_source_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>address</key> + <value>tcp://127.0.0.1:5555</value> + </param> + <param> + <key>timeout</key> + <value>100</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(171, 306)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_scopesink2</key> + <param> + <key>id</key> + <value>wxgui_scopesink2_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>title</key> + <value>Scope Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + <param> + <key>v_scale</key> + <value>0</value> + </param> + <param> + <key>v_offset</key> + <value>0</value> + </param> + <param> + <key>t_scale</key> + <value>0</value> + </param> + <param> + <key>ac_couple</key> + <value>False</value> + </param> + <param> + <key>xy_mode</key> + <value>False</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>trig_mode</key> + <value>wxgui.TRIG_MODE_AUTO</value> + </param> + <param> + <key>y_axis_label</key> + <value>Counts</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(450, 298)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_add_xx</key> + <param> + <key>id</key> + <value>blocks_add_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(411, 151)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>options</key> + <param> + <key>id</key> + <value>zeromq_reqrep</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value></value> + </param> + <param> + <key>author</key> + <value></value> + </param> + <param> + <key>description</key> + <value></value> + </param> + <param> + <key>window_size</key> + <value>1280, 1024</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>blocks_throttle</key> + <param> + <key>id</key> + <value>blocks_throttle_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>samples_per_second</key> + <value>samp_rate</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>ignoretag</key> + <value>True</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(534, 164)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>zeromq_rep_sink</key> + <param> + <key>id</key> + <value>zeromq_rep_sink_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>address</key> + <value>tcp://127.0.0.1:5555</value> + </param> + <param> + <key>timeout</key> + <value>100</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(722, 148)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>analog_fastnoise_source_x</key> + <param> + <key>id</key> + <value>analog_fastnoise_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>noise_type</key> + <value>analog.GR_GAUSSIAN</value> + </param> + <param> + <key>amp</key> + <value>0.1</value> + </param> + <param> + <key>seed</key> + <value>0</value> + </param> + <param> + <key>samples</key> + <value>8192</value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(169, 196)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>analog_sig_source_x_0</source_block_id> + <sink_block_id>blocks_add_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>analog_fastnoise_source_x_0</source_block_id> + <sink_block_id>blocks_add_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>blocks_add_xx_0</source_block_id> + <sink_block_id>blocks_throttle_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_throttle_0</source_block_id> + <sink_block_id>zeromq_rep_sink_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>zeromq_req_source_0</source_block_id> + <sink_block_id>wxgui_scopesink2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gr-zeromq/gnuradio-zeromq.pc.in b/gr-zeromq/gnuradio-zeromq.pc.in new file mode 100644 index 0000000000..e13143ee98 --- /dev/null +++ b/gr-zeromq/gnuradio-zeromq.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: gnuradio-zeromq +Description: GNU Radio blocks to interface with ZeroMQ +Requires: gnuradio-runtime +Version: @LIBVER@ +Libs: -L${libdir} -lgnuradio-zeromq +Cflags: -I${includedir} diff --git a/gr-zeromq/grc/CMakeLists.txt b/gr-zeromq/grc/CMakeLists.txt new file mode 100644 index 0000000000..548c2f28ed --- /dev/null +++ b/gr-zeromq/grc/CMakeLists.txt @@ -0,0 +1,31 @@ +# 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. + +install(FILES + zeromq_pub_sink.xml + zeromq_sub_source.xml + zeromq_push_sink.xml + zeromq_pull_source.xml + zeromq_rep_sink.xml + zeromq_req_source.xml + + DESTINATION share/gnuradio/grc/blocks +) + + diff --git a/gr-zeromq/grc/zeromq_pub_sink.xml b/gr-zeromq/grc/zeromq_pub_sink.xml new file mode 100644 index 0000000000..e78cd58b14 --- /dev/null +++ b/gr-zeromq/grc/zeromq_pub_sink.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<block> + <name>ZMQ PUB Sink</name> + <key>zeromq_pub_sink</key> + <category>ZeroMQ Interfaces</category> + <import>from gnuradio import zeromq</import> + <make>zeromq.pub_sink($type.itemsize, $vlen, $address, $timeout)</make> + + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>itemsize:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>itemsize:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>itemsize:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>itemsize:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>itemsize:gr.sizeof_char</opt> + </option> + </param> + + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + + <param> + <name>Address</name> + <key>address</key> + <type>string</type> + </param> + + <param> + <name>Timeout (msec)</name> + <key>timeout</key> + <value>100</value> + <type>float</type> + </param> + + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + +</block> diff --git a/gr-zeromq/grc/zeromq_pull_source.xml b/gr-zeromq/grc/zeromq_pull_source.xml new file mode 100644 index 0000000000..3833cd7341 --- /dev/null +++ b/gr-zeromq/grc/zeromq_pull_source.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<block> + <name>ZMQ PULL Source</name> + <key>zeromq_pull_source</key> + <category>ZeroMQ Interfaces</category> + <import>from gnuradio import zeromq</import> + <make>zeromq.pull_source($type.itemsize, $vlen, $address, $timeout)</make> + + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>itemsize:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>itemsize:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>itemsize:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>itemsize:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>itemsize:gr.sizeof_char</opt> + </option> + </param> + + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + + <param> + <name>Address</name> + <key>address</key> + <type>string</type> + </param> + + <param> + <name>Timeout (msec)</name> + <key>timeout</key> + <value>100</value> + <type>float</type> + </param> + + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> + +</block> diff --git a/gr-zeromq/grc/zeromq_push_sink.xml b/gr-zeromq/grc/zeromq_push_sink.xml new file mode 100644 index 0000000000..54bb8d0d98 --- /dev/null +++ b/gr-zeromq/grc/zeromq_push_sink.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<block> + <name>ZMQ PUSH Sink</name> + <key>zeromq_push_sink</key> + <category>ZeroMQ Interfaces</category> + <import>from gnuradio import zeromq</import> + <make>zeromq.push_sink($type.itemsize, $vlen, $address, $timeout)</make> + + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>itemsize:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>itemsize:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>itemsize:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>itemsize:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>itemsize:gr.sizeof_char</opt> + </option> + </param> + + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + + <param> + <name>Address</name> + <key>address</key> + <type>string</type> + </param> + + <param> + <name>Timeout (msec)</name> + <key>timeout</key> + <value>100</value> + <type>float</type> + </param> + + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + +</block> diff --git a/gr-zeromq/grc/zeromq_rep_sink.xml b/gr-zeromq/grc/zeromq_rep_sink.xml new file mode 100644 index 0000000000..1320bfef82 --- /dev/null +++ b/gr-zeromq/grc/zeromq_rep_sink.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<block> + <name>ZMQ REP Sink</name> + <key>zeromq_rep_sink</key> + <category>ZeroMQ Interfaces</category> + <import>from gnuradio import zeromq</import> + <make>zeromq.rep_sink($type.itemsize, $vlen, $address, $timeout)</make> + + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>itemsize:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>itemsize:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>itemsize:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>itemsize:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>itemsize:gr.sizeof_char</opt> + </option> + </param> + + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + + <param> + <name>Address</name> + <key>address</key> + <type>string</type> + </param> + + <param> + <name>Timeout (msec)</name> + <key>timeout</key> + <value>100</value> + <type>float</type> + </param> + + <sink> + <name>in</name> + <type>$type</type> + <vlen>$vlen</vlen> + </sink> + +</block> diff --git a/gr-zeromq/grc/zeromq_req_source.xml b/gr-zeromq/grc/zeromq_req_source.xml new file mode 100644 index 0000000000..d2951d2256 --- /dev/null +++ b/gr-zeromq/grc/zeromq_req_source.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<block> + <name>ZMQ REQ Source</name> + <key>zeromq_req_source</key> + <category>ZeroMQ Interfaces</category> + <import>from gnuradio import zeromq</import> + <make>zeromq.req_source($type.itemsize, $vlen, $address, $timeout)</make> + + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>itemsize:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>itemsize:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>itemsize:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>itemsize:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>itemsize:gr.sizeof_char</opt> + </option> + </param> + + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + + <param> + <name>Address</name> + <key>address</key> + <type>string</type> + </param> + + <param> + <name>Timeout (msec)</name> + <key>timeout</key> + <value>100</value> + <type>float</type> + </param> + + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> + +</block> diff --git a/gr-zeromq/grc/zeromq_sub_source.xml b/gr-zeromq/grc/zeromq_sub_source.xml new file mode 100644 index 0000000000..2ec8cfa887 --- /dev/null +++ b/gr-zeromq/grc/zeromq_sub_source.xml @@ -0,0 +1,66 @@ +<?xml version="1.0"?> +<block> + <name>ZMQ SUB Source</name> + <key>zeromq_sub_source</key> + <category>ZeroMQ Interfaces</category> + <import>from gnuradio import zeromq</import> + <make>zeromq.sub_source($type.itemsize, $vlen, $address, $timeout)</make> + + <param> + <name>IO Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>itemsize:gr.sizeof_gr_complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>itemsize:gr.sizeof_float</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>itemsize:gr.sizeof_int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>itemsize:gr.sizeof_short</opt> + </option> + <option> + <name>Byte</name> + <key>byte</key> + <opt>itemsize:gr.sizeof_char</opt> + </option> + </param> + + <param> + <name>Vec Length</name> + <key>vlen</key> + <value>1</value> + <type>int</type> + </param> + + <param> + <name>Address</name> + <key>address</key> + <type>string</type> + </param> + + <param> + <name>Timeout (msec)</name> + <key>timeout</key> + <value>100</value> + <type>float</type> + </param> + + <source> + <name>out</name> + <type>$type</type> + <vlen>$vlen</vlen> + </source> + +</block> diff --git a/gr-zeromq/include/gnuradio/zeromq/CMakeLists.txt b/gr-zeromq/include/gnuradio/zeromq/CMakeLists.txt new file mode 100644 index 0000000000..970cf1ce9a --- /dev/null +++ b/gr-zeromq/include/gnuradio/zeromq/CMakeLists.txt @@ -0,0 +1,34 @@ +# Copyright 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. + +######################################################################## +# Install header files +######################################################################## +install(FILES + api.h + pub_sink.h + sub_source.h + pull_source.h + push_sink.h + rep_sink.h + req_source.h + + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/zeromq + COMPONENT "zeromq_devel" +) diff --git a/gr-zeromq/include/gnuradio/zeromq/api.h b/gr-zeromq/include/gnuradio/zeromq/api.h new file mode 100644 index 0000000000..82d022f2b0 --- /dev/null +++ b/gr-zeromq/include/gnuradio/zeromq/api.h @@ -0,0 +1,33 @@ +/* + * Copyright 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. + */ + +#ifndef INCLUDED_ZEROMQ_API_H +#define INCLUDED_ZEROMQ_API_H + +#include <gnuradio/attributes.h> + +#ifdef gnuradio_zeromq_EXPORTS +# define ZEROMQ_API __GR_ATTR_EXPORT +#else +# define ZEROMQ_API __GR_ATTR_IMPORT +#endif + +#endif /* INCLUDED_ZEROMQ_API_H */ diff --git a/gr-zeromq/include/gnuradio/zeromq/pub_sink.h b/gr-zeromq/include/gnuradio/zeromq/pub_sink.h new file mode 100644 index 0000000000..a60fb15c88 --- /dev/null +++ b/gr-zeromq/include/gnuradio/zeromq/pub_sink.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ZEROMQ_PUB_SINK_H +#define INCLUDED_ZEROMQ_PUB_SINK_H + +#include <gnuradio/zeromq/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace zeromq { + + /*! + * \brief Sink the contents of a stream to a ZMQ PUB socket + * \ingroup zeromq + * + * \details + * This block acts a a streaming sink for a GNU Radio flowgraph + * and writes its contents to a ZMQ PUB socket. A PUB socket may + * have subscribers and will pass all incoming stream data to each + * subscriber. Subscribers can be either another gr-zeromq source + * block or a non-GNU Radio ZMQ socket. + */ + class ZEROMQ_API pub_sink : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr<pub_sink> sptr; + + /*! + * \brief Return a shared_ptr to a new instance of zeromq::pub_sink. + * + * \param itemsize Size of a stream item in bytes + * \param vlen Vector length of the input items. Note that one vector is one item. + * \param address ZMQ socket address specifier + * \param timeout Receive timeout in seconds, default is 100ms, 1us increments + */ + static sptr make(size_t itemsize, size_t vlen, char *address, int timeout=100); + }; + + } // namespace zeromq +} // namespace gr + +#endif /* INCLUDED_ZEROMQ_PUB_SINK_H */ diff --git a/gr-zeromq/include/gnuradio/zeromq/pull_source.h b/gr-zeromq/include/gnuradio/zeromq/pull_source.h new file mode 100644 index 0000000000..5c1d37d353 --- /dev/null +++ b/gr-zeromq/include/gnuradio/zeromq/pull_source.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ZEROMQ_PULL_SOURCE_H +#define INCLUDED_ZEROMQ_PULL_SOURCE_H + +#include <gnuradio/zeromq/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace zeromq { + + /*! + * \brief Receive messages on ZMQ PULL socket and source stream + * \ingroup zeromq + * + * \details + * This block will connect to a ZMQ PUSH socket, then produce all + * incoming messages as streaming output. + */ + class ZEROMQ_API pull_source : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr<pull_source> sptr; + + /*! + * \brief Return a shared_ptr to a new instance of gr::zeromq::pull_source. + * + * \param itemsize Size of a stream item in bytes + * \param vlen Vector length of the input items. Note that one vector is one item. + * \param address ZMQ socket address specifier + * \param timeout Receive timeout in seconds, default is 100ms, 1us increments + * + */ + static sptr make(size_t itemsize, size_t vlen, char *address, int timeout=100); + }; + + } // namespace zeromq +} // namespace gr + +#endif /* INCLUDED_ZEROMQ_PULL_SOURCE_H */ diff --git a/gr-zeromq/include/gnuradio/zeromq/push_sink.h b/gr-zeromq/include/gnuradio/zeromq/push_sink.h new file mode 100644 index 0000000000..b54a1e40d8 --- /dev/null +++ b/gr-zeromq/include/gnuradio/zeromq/push_sink.h @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ZEROMQ_PUSH_SINK_H +#define INCLUDED_ZEROMQ_PUSH_SINK_H + +#include <gnuradio/zeromq/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace zeromq { + + /*! + * \brief Sink the contents of a stream to a ZMQ PUSH socket + * \ingroup zeromq + * + * \details + * This block acts a a streaming sink for a GNU Radio flowgraph + * and writes its contents to a ZMQ PUSH socket. A PUSH socket + * will round-robin send its messages to each connected ZMQ PULL + * socket, either another gr-zeromq source block or a regular, + * non-GNU Radio ZMQ socket. + * + */ + class ZEROMQ_API push_sink : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr<push_sink> sptr; + + /*! + * \brief Return a shared_ptr to a new instance of gr::zeromq::push_sink + * + * \param itemsize Size of a stream item in bytes + * \param vlen Vector length of the input items. Note that one vector is one item. + * \param address ZMQ socket address specifier + * \param timeout Receive timeout in seconds, default is 100ms, 1us increments + * + */ + static sptr make(size_t itemsize, size_t vlen, char *address, int timeout=100); + }; + + } // namespace zeromq +} // namespace gr + +#endif /* INCLUDED_ZEROMQ_PUSH_SINK_H */ diff --git a/gr-zeromq/include/gnuradio/zeromq/rep_sink.h b/gr-zeromq/include/gnuradio/zeromq/rep_sink.h new file mode 100644 index 0000000000..1da325257f --- /dev/null +++ b/gr-zeromq/include/gnuradio/zeromq/rep_sink.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ZEROMQ_REP_SINK_H +#define INCLUDED_ZEROMQ_REP_SINK_H + +#include <gnuradio/zeromq/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace zeromq { + + /*! + * \brief Sink the contents of a stream to a ZMQ REP socket + * \ingroup zeromq + * + * \details + * This block acts a a streaming sink for a GNU Radio flowgraph + * and writes its contents to a ZMQ REP socket. A REP socket will + * only send its contents to an attached REQ socket when it + * requests items. + */ + class ZEROMQ_API rep_sink : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr<rep_sink> sptr; + + /*! + * \brief Return a shared_ptr to a new instance of zeromq::rep_sink. + * + * \param itemsize Size of a stream item in bytes + * \param vlen Vector length of the input items. Note that one vector is one item. + * \param address ZMQ socket address specifier + * \param timeout Receive timeout in seconds, default is 100ms, 1us increments + * + */ + static sptr make(size_t itemsize, size_t vlen, char *address, int timeout=100); + }; + + } // namespace zeromq +} // namespace gr + +#endif /* INCLUDED_ZEROMQ_REP_SINK_H */ diff --git a/gr-zeromq/include/gnuradio/zeromq/req_source.h b/gr-zeromq/include/gnuradio/zeromq/req_source.h new file mode 100644 index 0000000000..c272c28510 --- /dev/null +++ b/gr-zeromq/include/gnuradio/zeromq/req_source.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ZEROMQ_REQ_SOURCE_H +#define INCLUDED_ZEROMQ_REQ_SOURCE_H + +#include <gnuradio/zeromq/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace zeromq { + + /*! + * \brief Receive messages on ZMQ REQ socket and source stream + * \ingroup zeromq + * + * \details + * This block will connect to a ZMQ REP socket, then produce all + * incoming messages as streaming output. + */ + class ZEROMQ_API req_source : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr<req_source> sptr; + + /*! + * \brief Return a shared_ptr to a new instance of zeromq::req_source. + * + * + * \param itemsize Size of a stream item in bytes + * \param vlen Vector length of the input items. Note that one vector is one item. + * \param address ZMQ socket address specifier + * \param timeout Receive timeout in seconds, default is 100ms, 1us increments + * + */ + static sptr make(size_t itemsize, size_t vlen, char *address, int timeout=100); + }; + + } // namespace zeromq +} // namespace gr + +#endif /* INCLUDED_ZEROMQ_SOURCE_REQREP_H */ diff --git a/gr-zeromq/include/gnuradio/zeromq/sub_source.h b/gr-zeromq/include/gnuradio/zeromq/sub_source.h new file mode 100644 index 0000000000..9deaa7f3ff --- /dev/null +++ b/gr-zeromq/include/gnuradio/zeromq/sub_source.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ZEROMQ_SUB_SOURCE_H +#define INCLUDED_ZEROMQ_SUB_SOURCE_H + +#include <gnuradio/zeromq/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace zeromq { + + /*! + * \brief Receive messages on ZMQ SUB socket and source stream + * \ingroup zeromq + * + * \details + * This block will connect to a ZMQ PUB socket, then produce all + * incoming messages as streaming output. + */ + class ZEROMQ_API sub_source : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr<sub_source> sptr; + + /*! + * \brief Return a shared_ptr to a new instance of gr::zeromq::sub_source. + * + * \param itemsize Size of a stream item in bytes + * \param vlen Vector length of the input items. Note that one vector is one item. + * \param address ZMQ socket address specifier + * \param timeout Receive timeout in seconds, default is 100ms, 1us increments + * + */ + static sptr make(size_t itemsize, size_t vlen, char *address, int timeout=100); + }; + + } // namespace zeromq +} // namespace gr + +#endif /* INCLUDED_ZEROMQ_SUB_SOURCE_H */ diff --git a/gr-zeromq/lib/CMakeLists.txt b/gr-zeromq/lib/CMakeLists.txt new file mode 100644 index 0000000000..cc62c79f35 --- /dev/null +++ b/gr-zeromq/lib/CMakeLists.txt @@ -0,0 +1,71 @@ +# Copyright 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. + +######################################################################## +# Setup the include and linker paths +######################################################################## +include_directories( + ${GR_ZEROMQ_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${ZEROMQ_INCLUDE_DIRS} +) + +link_directories(${Boost_LIBRARY_DIRS}) + +if(ENABLE_GR_CTRLPORT) + ADD_DEFINITIONS(-DGR_CTRLPORT) + include_directories(${ICE_INCLUDE_DIR}) +endif(ENABLE_GR_CTRLPORT) + +######################################################################## +# Setup library +######################################################################## +list(APPEND zeromq_sources + pub_sink_impl.cc + sub_source_impl.cc + pull_source_impl.cc + push_sink_impl.cc + rep_sink_impl.cc + req_source_impl.cc +) + +#Add Windows DLL resource file if using MSVC +if(MSVC) + include(${CMAKE_SOURCE_DIR}/cmake/Modules/GrVersion.cmake) + + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-zeromq.rc.in + ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-zeromq.rc + @ONLY) + + list(APPEND gr_zeromq_sources + ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-zeromq.rc + ) +endif(MSVC) + +list(APPEND zeromq_libs + gnuradio-runtime + ${Boost_LIBRARIES} + ${ZEROMQ_LIBRARIES} +) + +add_library(gnuradio-zeromq SHARED ${zeromq_sources}) +target_link_libraries(gnuradio-zeromq ${zeromq_libs}) +GR_LIBRARY_FOO(gnuradio-zeromq RUNTIME_COMPONENT "zeromq_runtime" DEVEL_COMPONENT "zeromq_devel") diff --git a/gr-zeromq/lib/gnuradio-zeromq.rc.in b/gr-zeromq/lib/gnuradio-zeromq.rc.in new file mode 100644 index 0000000000..41a5e65e91 --- /dev/null +++ b/gr-zeromq/lib/gnuradio-zeromq.rc.in @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 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. + */ + +#include <afxres.h> + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @MAJOR_VERSION@,@API_COMPAT@,@RC_MINOR_VERSION@,@RC_MAINT_VERSION@ + PRODUCTVERSION @MAJOR_VERSION@,@API_COMPAT@,@RC_MINOR_VERSION@,@RC_MAINT_VERSION@ + FILEFLAGSMASK 0x3fL +#ifndef NDEBUG + FILEFLAGS 0x0L +#else + FILEFLAGS 0x1L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_DRV_INSTALLABLE + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "gnuradio-zeromq" + VALUE "FileVersion", "@VERSION@" + VALUE "InternalName", "gnuradio-zeromq.dll" + VALUE "LegalCopyright", "Licensed under GPLv3 or any later version" + VALUE "OriginalFilename", "gnuradio-zeromq.dll" + VALUE "ProductName", "gnuradio-zeromq" + VALUE "ProductVersion", "@VERSION@" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END + END diff --git a/gr-zeromq/lib/pub_sink_impl.cc b/gr-zeromq/lib/pub_sink_impl.cc new file mode 100644 index 0000000000..13f86045d7 --- /dev/null +++ b/gr-zeromq/lib/pub_sink_impl.cc @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; 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 <gnuradio/io_signature.h> +#include "pub_sink_impl.h" + +namespace gr { + namespace zeromq { + + pub_sink::sptr + pub_sink::make(size_t itemsize, size_t vlen, char *address, int timeout) + { + return gnuradio::get_initial_sptr + (new pub_sink_impl(itemsize, vlen, address, timeout)); + } + + pub_sink_impl::pub_sink_impl(size_t itemsize, size_t vlen, char *address, int timeout) + : gr::sync_block("pub_sink", + gr::io_signature::make(1, 1, itemsize * vlen), + gr::io_signature::make(0, 0, 0)), + d_itemsize(itemsize), d_vlen(vlen), d_timeout(timeout) + { + int major, minor, patch; + zmq::version (&major, &minor, &patch); + if (major < 3) { + d_timeout = timeout*1000; + } + d_context = new zmq::context_t(1); + d_socket = new zmq::socket_t(*d_context, ZMQ_PUB); + int time = 0; + d_socket->setsockopt(ZMQ_LINGER, &time, sizeof(time)); + d_socket->bind(address); + } + + pub_sink_impl::~pub_sink_impl() + { + d_socket->close(); + delete d_socket; + delete d_context; + } + + int + pub_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]; + + // create message copy and send + zmq::message_t msg(d_itemsize*d_vlen*noutput_items); + memcpy((void *)msg.data(), in, d_itemsize*d_vlen*noutput_items); + d_socket->send(msg); + + return noutput_items; + } + + } /* namespace zeromq */ +} /* namespace gr */ diff --git a/gr-zeromq/lib/pub_sink_impl.h b/gr-zeromq/lib/pub_sink_impl.h new file mode 100644 index 0000000000..9c956ef2fa --- /dev/null +++ b/gr-zeromq/lib/pub_sink_impl.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ZEROMQ_PUB_SINK_IMPL_H +#define INCLUDED_ZEROMQ_PUB_SINK_IMPL_H + +#include <gnuradio/zeromq/pub_sink.h> +#include <zmq.hpp> + +namespace gr { + namespace zeromq { + + class pub_sink_impl : public pub_sink + { + private: + size_t d_itemsize; + size_t d_vlen; + float d_timeout; + zmq::context_t *d_context; + zmq::socket_t *d_socket; + + public: + pub_sink_impl(size_t itemsize, size_t vlen, char *address, int timeout); + ~pub_sink_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace zeromq +} // namespace gr + +#endif /* INCLUDED_ZEROMQ_PUB_SINK_IMPL_H */ diff --git a/gr-zeromq/lib/pull_source_impl.cc b/gr-zeromq/lib/pull_source_impl.cc new file mode 100644 index 0000000000..479b15bb32 --- /dev/null +++ b/gr-zeromq/lib/pull_source_impl.cc @@ -0,0 +1,102 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; 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 <gnuradio/io_signature.h> +#include "pull_source_impl.h" + +namespace gr { + namespace zeromq { + + pull_source::sptr + pull_source::make(size_t itemsize, size_t vlen, char *address, int timeout) + { + return gnuradio::get_initial_sptr + (new pull_source_impl(itemsize, vlen, address, timeout)); + } + + pull_source_impl::pull_source_impl(size_t itemsize, size_t vlen, char *address, int timeout) + : gr::sync_block("pull_source", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(1, 1, itemsize * vlen)), + d_itemsize(itemsize), d_vlen(vlen), d_timeout(timeout) + { + int major, minor, patch; + zmq::version (&major, &minor, &patch); + if (major < 3) { + d_timeout = timeout*1000; + } + d_context = new zmq::context_t(1); + d_socket = new zmq::socket_t(*d_context, ZMQ_PULL); + int time = 0; + d_socket->setsockopt(ZMQ_LINGER, &time, sizeof(time)); + d_socket->connect (address); + } + + /* + * Our virtual destructor. + */ + pull_source_impl::~pull_source_impl() + { + d_socket->close(); + delete d_socket; + delete d_context; + } + + int + pull_source_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + char *out = (char*)output_items[0]; + + zmq::pollitem_t items[] = { { *d_socket, 0, ZMQ_POLLIN, 0 } }; + zmq::poll (&items[0], 1, d_timeout); + + // If we got a reply, process + if (items[0].revents & ZMQ_POLLIN) { + + // Receive data + zmq::message_t msg; + d_socket->recv(&msg); + // Copy to ouput buffer and return + if (msg.size() >= d_itemsize*d_vlen*noutput_items) { + memcpy(out, (void *)msg.data(), d_itemsize*d_vlen*noutput_items); + + return noutput_items; + } + else { + memcpy(out, (void *)msg.data(), msg.size()); + + return msg.size()/(d_itemsize*d_vlen); + } + } + else { + return 0; // FIXME: someday when the scheduler does all the poll/selects + } + } + + } /* namespace zeromq */ +} /* namespace gr */ diff --git a/gr-zeromq/lib/pull_source_impl.h b/gr-zeromq/lib/pull_source_impl.h new file mode 100644 index 0000000000..e69de81dcd --- /dev/null +++ b/gr-zeromq/lib/pull_source_impl.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ZEROMQ_PULL_SOURCE_IMPL_H +#define INCLUDED_ZEROMQ_PULL_SOURCE_IMPL_H + +#include <gnuradio/zeromq/pull_source.h> +#include <zmq.hpp> + +namespace gr { + namespace zeromq { + + class pull_source_impl : public pull_source + { + private: + size_t d_itemsize; + size_t d_vlen; + int d_timeout; // microseconds, -1 is blocking + zmq::context_t *d_context; + zmq::socket_t *d_socket; + + public: + pull_source_impl(size_t itemsize, size_t vlen, char *address, int timeout); + ~pull_source_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace zeromq +} // namespace gr + +#endif /* INCLUDED_ZEROMQ_PULL_SOURCE_IMPL_H */ diff --git a/gr-zeromq/lib/push_sink_impl.cc b/gr-zeromq/lib/push_sink_impl.cc new file mode 100644 index 0000000000..d949a7f95f --- /dev/null +++ b/gr-zeromq/lib/push_sink_impl.cc @@ -0,0 +1,90 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; 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 <gnuradio/io_signature.h> +#include "push_sink_impl.h" + +namespace gr { + namespace zeromq { + + push_sink::sptr + push_sink::make(size_t itemsize, size_t vlen, char *address, int timeout) + { + return gnuradio::get_initial_sptr + (new push_sink_impl(itemsize, vlen, address, timeout)); + } + + push_sink_impl::push_sink_impl(size_t itemsize, size_t vlen, char *address, int timeout) + : gr::sync_block("push_sink", + gr::io_signature::make(1, 1, itemsize * vlen), + gr::io_signature::make(0, 0, 0)), + d_itemsize(itemsize), d_vlen(vlen), d_timeout(timeout) + { + int major, minor, patch; + zmq::version (&major, &minor, &patch); + if (major < 3) { + d_timeout = timeout*1000; + } + d_context = new zmq::context_t(1); + d_socket = new zmq::socket_t(*d_context, ZMQ_PUSH); + int time = 0; + d_socket->setsockopt(ZMQ_LINGER, &time, sizeof(time)); + d_socket->bind (address); + } + + push_sink_impl::~push_sink_impl() + { + d_socket->close(); + delete d_socket; + delete d_context; + } + + int + push_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]; + + zmq::pollitem_t itemsout[] = { { *d_socket, 0, ZMQ_POLLOUT, 0 } }; + zmq::poll (&itemsout[0], 1, d_timeout); + + // If we got a reply, process + if (itemsout[0].revents & ZMQ_POLLOUT) { + // create message copy and send + zmq::message_t msg(d_itemsize*d_vlen*noutput_items); + memcpy((void *)msg.data(), in, d_itemsize*d_vlen*noutput_items); + d_socket->send(msg); + + return noutput_items; + } + else { + return 0; + } + } + + } /* namespace zeromq */ +} /* namespace gr */ diff --git a/gr-zeromq/lib/push_sink_impl.h b/gr-zeromq/lib/push_sink_impl.h new file mode 100644 index 0000000000..9a10065eba --- /dev/null +++ b/gr-zeromq/lib/push_sink_impl.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ZEROMQ_PUSH_SINK_IMPL_H +#define INCLUDED_ZEROMQ_PUSH_SINK_IMPL_H + +#include <gnuradio/zeromq/push_sink.h> +#include <zmq.hpp> + +namespace gr { + namespace zeromq { + + class push_sink_impl : public push_sink + { + private: + size_t d_itemsize; + size_t d_vlen; + float d_timeout; + zmq::context_t *d_context; + zmq::socket_t *d_socket; + + public: + push_sink_impl(size_t itemsize, size_t vlen, char *address, int timeout); + ~push_sink_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace zeromq +} // namespace gr + +#endif /* INCLUDED_ZEROMQ_ZMQ_PUSH_SINK_IMPL_H */ diff --git a/gr-zeromq/lib/rep_sink_impl.cc b/gr-zeromq/lib/rep_sink_impl.cc new file mode 100644 index 0000000000..a8fd5881e5 --- /dev/null +++ b/gr-zeromq/lib/rep_sink_impl.cc @@ -0,0 +1,102 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; 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 <gnuradio/io_signature.h> +#include "rep_sink_impl.h" + +namespace gr { + namespace zeromq { + + rep_sink::sptr + rep_sink::make(size_t itemsize, size_t vlen, char *address, int timeout) + { + return gnuradio::get_initial_sptr + (new rep_sink_impl(itemsize, vlen, address, timeout)); + } + + rep_sink_impl::rep_sink_impl(size_t itemsize, size_t vlen, char *address, int timeout) + : gr::sync_block("rep_sink", + gr::io_signature::make(1, 1, itemsize * vlen), + gr::io_signature::make(0, 0, 0)), + d_itemsize(itemsize), d_vlen(vlen), d_timeout(timeout) + { + int major, minor, patch; + zmq::version (&major, &minor, &patch); + if (major < 3) { + d_timeout = timeout*1000; + } + d_context = new zmq::context_t(1); + d_socket = new zmq::socket_t(*d_context, ZMQ_REP); + int time = 0; + d_socket->setsockopt(ZMQ_LINGER, &time, sizeof(time)); + d_socket->bind (address); + } + + rep_sink_impl::~rep_sink_impl() + { + d_socket->close(); + delete d_socket; + delete d_context; + } + + int + rep_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]; + + zmq::pollitem_t items[] = { { *d_socket, 0, ZMQ_POLLIN, 0 } }; + zmq::poll (&items[0], 1, d_timeout); + + // If we got a reply, process + if (items[0].revents & ZMQ_POLLIN) { + // receive data request + zmq::message_t request; + d_socket->recv(&request); + int req_output_items = *(static_cast<int*>(request.data())); + + // create message copy and send + if (noutput_items < req_output_items) { + zmq::message_t msg(d_itemsize*d_vlen*noutput_items); + memcpy((void *)msg.data(), in, d_itemsize*d_vlen*noutput_items); + d_socket->send(msg); + + return noutput_items; + } + else { + zmq::message_t msg(d_itemsize*d_vlen*req_output_items); + memcpy((void *)msg.data(), in, d_itemsize*d_vlen*req_output_items); + d_socket->send(msg); + + return req_output_items; + } + } + + return 0; + } + } /* namespace zeromq */ +} /* namespace gr */ diff --git a/gr-zeromq/lib/rep_sink_impl.h b/gr-zeromq/lib/rep_sink_impl.h new file mode 100644 index 0000000000..ff69735757 --- /dev/null +++ b/gr-zeromq/lib/rep_sink_impl.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,204 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ZEROMQ_REP_SINK_IMPL_H +#define INCLUDED_ZEROMQ_REP_SINK_IMPL_H + +#include <gnuradio/zeromq/rep_sink.h> +#include <zmq.hpp> + +namespace gr { + namespace zeromq { + + class rep_sink_impl : public rep_sink + { + private: + size_t d_itemsize; + size_t d_vlen; + int d_timeout; + zmq::context_t *d_context; + zmq::socket_t *d_socket; + + public: + rep_sink_impl(size_t itemsize, size_t vlen, char *address, int timeout); + ~rep_sink_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace zeromq +} // namespace gr + +#endif /* INCLUDED_ZEROMQ_REP_SINK_IMPL_H */ diff --git a/gr-zeromq/lib/req_source_impl.cc b/gr-zeromq/lib/req_source_impl.cc new file mode 100644 index 0000000000..54cd659972 --- /dev/null +++ b/gr-zeromq/lib/req_source_impl.cc @@ -0,0 +1,101 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; 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 <gnuradio/io_signature.h> +#include "req_source_impl.h" + +namespace gr { + namespace zeromq { + + req_source::sptr + req_source::make(size_t itemsize, size_t vlen, char *address, int timeout) + { + return gnuradio::get_initial_sptr + (new req_source_impl(itemsize, vlen, address, timeout)); + } + + req_source_impl::req_source_impl(size_t itemsize, size_t vlen, char *address, int timeout) + : gr::sync_block("req_source", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(1, 1, itemsize * vlen)), + d_itemsize(itemsize), d_vlen(vlen), d_timeout(timeout) + { + int major, minor, patch; + zmq::version (&major, &minor, &patch); + if (major < 3) { + d_timeout = timeout*1000; + } + d_context = new zmq::context_t(1); + d_socket = new zmq::socket_t(*d_context, ZMQ_REQ); + int time = 0; + d_socket->setsockopt(ZMQ_LINGER, &time, sizeof(time)); + d_socket->connect (address); + } + + req_source_impl::~req_source_impl() + { + d_socket->close(); + delete d_socket; + delete d_context; + } + + int + req_source_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + char *out = (char*)output_items[0]; + + zmq::pollitem_t itemsout[] = { { *d_socket, 0, ZMQ_POLLOUT, 0 } }; + zmq::poll (&itemsout[0], 1, d_timeout); + + // If we got a reply, process + if (itemsout[0].revents & ZMQ_POLLOUT) { + // Request data, FIXME non portable? + zmq::message_t request(sizeof(int)); + memcpy ((void *) request.data (), &noutput_items, sizeof(int)); + d_socket->send(request); + } + + zmq::pollitem_t itemsin[] = { { *d_socket, 0, ZMQ_POLLIN, 0 } }; + zmq::poll (&itemsin[0], 1, d_timeout); + + // If we got a reply, process + if (itemsin[0].revents & ZMQ_POLLIN) { + // Receive data + zmq::message_t reply; + d_socket->recv(&reply); + + // Copy to ouput buffer and return + memcpy(out, (void *)reply.data(), reply.size()); + return reply.size()/(d_itemsize*d_vlen); + } + + return 0; + } + + } /* namespace zeromq */ +} /* namespace gr */ diff --git a/gr-zeromq/lib/req_source_impl.h b/gr-zeromq/lib/req_source_impl.h new file mode 100644 index 0000000000..f61b1d1ce4 --- /dev/null +++ b/gr-zeromq/lib/req_source_impl.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ZEROMQ_REQ_SOURCE_IMPL_H +#define INCLUDED_ZEROMQ_REQ_SOURCE_IMPL_H + +#include <gnuradio/zeromq/req_source.h> +#include <zmq.hpp> + +namespace gr { + namespace zeromq { + + class req_source_impl : public req_source + { + private: + size_t d_itemsize; + size_t d_vlen; + int d_timeout; + zmq::context_t *d_context; + zmq::socket_t *d_socket; + + public: + req_source_impl(size_t itemsize, size_t vlen, char *address, int timeout); + ~req_source_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace zeromq +} // namespace gr + +#endif /* INCLUDED_ZEROMQ_REQ_SOURCE_IMPL_H */ diff --git a/gr-zeromq/lib/sub_source_impl.cc b/gr-zeromq/lib/sub_source_impl.cc new file mode 100644 index 0000000000..38ddc78e59 --- /dev/null +++ b/gr-zeromq/lib/sub_source_impl.cc @@ -0,0 +1,102 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; 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 <gnuradio/io_signature.h> +#include "sub_source_impl.h" + +namespace gr { + namespace zeromq { + + sub_source::sptr + sub_source::make(size_t itemsize, size_t vlen, char *address, int timeout) + { + return gnuradio::get_initial_sptr + (new sub_source_impl(itemsize, vlen, address, timeout)); + } + + sub_source_impl::sub_source_impl(size_t itemsize, size_t vlen, char *address, int timeout) + : gr::sync_block("sub_source", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(1, 1, itemsize * vlen)), + d_itemsize(itemsize), d_vlen(vlen), d_timeout(timeout) + { + int major, minor, patch; + zmq::version (&major, &minor, &patch); + if (major < 3) { + d_timeout = timeout*1000; + } + d_context = new zmq::context_t(1); + d_socket = new zmq::socket_t(*d_context, ZMQ_SUB); + //int time = 0; + d_socket->setsockopt(ZMQ_SUBSCRIBE, "", 0); + d_socket->connect (address); + } + + /* + * Our virtual destructor. + */ + sub_source_impl::~sub_source_impl() + { + d_socket->close(); + delete d_socket; + delete d_context; + } + + int + sub_source_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + char *out = (char*)output_items[0]; + + zmq::pollitem_t items[] = { { *d_socket, 0, ZMQ_POLLIN, 0 } }; + zmq::poll (&items[0], 1, d_timeout); + + // If we got a reply, process + if (items[0].revents & ZMQ_POLLIN) { + + // Receive data + zmq::message_t msg; + d_socket->recv(&msg); + // Copy to ouput buffer and return + if (msg.size() >= d_itemsize*d_vlen*noutput_items) { + memcpy(out, (void *)msg.data(), d_itemsize*d_vlen*noutput_items); + + return noutput_items; + } + else { + memcpy(out, (void *)msg.data(), msg.size()); + + return msg.size()/(d_itemsize*d_vlen); + } + } + else { + return 0; // FIXME: someday when the scheduler does all the poll/selects + } + } + + } /* namespace zeromq */ +} /* namespace gr */ diff --git a/gr-zeromq/lib/sub_source_impl.h b/gr-zeromq/lib/sub_source_impl.h new file mode 100644 index 0000000000..44647527b1 --- /dev/null +++ b/gr-zeromq/lib/sub_source_impl.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio. + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_ZEROMQ_SUB_SOURCE_IMPL_H +#define INCLUDED_ZEROMQ_SUB_SOURCE_IMPL_H + +#include <gnuradio/zeromq/sub_source.h> +#include "zmq.hpp" + +namespace gr { + namespace zeromq { + + class sub_source_impl : public sub_source + { + private: + size_t d_itemsize; + size_t d_vlen; + int d_timeout; // microseconds, -1 is blocking + zmq::context_t *d_context; + zmq::socket_t *d_socket; + + public: + sub_source_impl(size_t itemsize, size_t vlen, char *address, int timeout); + ~sub_source_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace zeromq +} // namespace gr + +#endif /* INCLUDED_ZEROMQ_SUB_SOURCE_IMPL_H */ + diff --git a/gr-zeromq/python/zeromq/CMakeLists.txt b/gr-zeromq/python/zeromq/CMakeLists.txt new file mode 100644 index 0000000000..66fc65a4b5 --- /dev/null +++ b/gr-zeromq/python/zeromq/CMakeLists.txt @@ -0,0 +1,56 @@ +# 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 python install macros +######################################################################## +include(GrPython) +if(NOT PYTHONINTERP_FOUND) + return() +endif() + +######################################################################## +# Install python sources +######################################################################## +GR_PYTHON_INSTALL( + FILES + __init__.py + rpc_manager.py + probe_manager.py + DESTINATION ${GR_PYTHON_DIR}/gnuradio/zeromq +) + +######################################################################## +# Handle the unit tests +######################################################################## +if(ENABLE_TESTING) + + set(GR_TEST_TARGET_DEPS "") + set(GR_TEST_LIBRARY_DIRS "") + set(GR_TEST_PYTHON_DIRS + ${CMAKE_BINARY_DIR}/gnuradio-runtime/python + ) + + include(GrTest) + file(GLOB py_qa_test_files "qa_*.py") + foreach(py_qa_test_file ${py_qa_test_files}) + get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE) + GR_ADD_TEST(${py_qa_test_name} ${QA_PYTHON_EXECUTABLE} ${PYTHON_DASH_B} ${py_qa_test_file}) + endforeach(py_qa_test_file) +endif(ENABLE_TESTING) diff --git a/gr-zeromq/python/zeromq/__init__.py b/gr-zeromq/python/zeromq/__init__.py new file mode 100644 index 0000000000..cab4b67640 --- /dev/null +++ b/gr-zeromq/python/zeromq/__init__.py @@ -0,0 +1,36 @@ +# +# Copyright 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. +# + +''' +Blocks for interfacing with ZeroMQ endpoints. +''' + +import os + +try: + from zeromq_swig import * +except ImportError: + dirname, filename = os.path.split(os.path.abspath(__file__)) + __path__.append(os.path.join(dirname, "..", "..", "swig")) + from zeromq_swig import * + +from probe_manager import probe_manager +from rpc_manager import rpc_manager diff --git a/gr-zeromq/python/zeromq/probe_manager.py b/gr-zeromq/python/zeromq/probe_manager.py new file mode 100644 index 0000000000..c30e6eaaba --- /dev/null +++ b/gr-zeromq/python/zeromq/probe_manager.py @@ -0,0 +1,50 @@ +# +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio. +# +# This 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. +# +# This software 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 this software; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import zmq +import threading +import numpy + +class probe_manager(): + def __init__(self): + self.zmq_context = zmq.Context() + self.poller = zmq.Poller() + self.interfaces = [] + + def add_socket(self, address, data_type, callback_func): + socket = self.zmq_context.socket(zmq.SUB) + socket.setsockopt(zmq.SUBSCRIBE, "") + socket.connect(address) + # use a tuple to store interface elements + self.interfaces.append((socket, data_type, callback_func)) + self.poller.register(socket, zmq.POLLIN) + + def watcher(self): + poll = dict(self.poller.poll(0)) + for i in self.interfaces: + # i = (socket, data_type, callback_func) + if poll.get(i[0]) == zmq.POLLIN: + # receive data + msg_packed = i[0].recv() + # use numpy to unpack the data + msg_unpacked = numpy.fromstring(msg_packed, numpy.dtype(i[1])) + # invoke callback function + i[2](msg_unpacked) diff --git a/gr-zeromq/python/zeromq/qa_zeromq_pub.py b/gr-zeromq/python/zeromq/qa_zeromq_pub.py new file mode 100755 index 0000000000..6f08aa544f --- /dev/null +++ b/gr-zeromq/python/zeromq/qa_zeromq_pub.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# 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 +from gnuradio import blocks, zeromq +from gnuradio import eng_notation + +class qa_zeromq_pub (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001 (self): + vlen = 10 + self.rx_data = None + src_data = range(vlen)*100 + src = blocks.vector_source_f(src_data, False, vlen) + zeromq_pub_sink = zeromq.pub_sink(gr.sizeof_float, vlen, "tcp://127.0.0.1:5555") + self.tb.connect(src, zeromq_pub_sink) + self.probe_manager = zeromq.probe_manager() + self.probe_manager.add_socket("tcp://127.0.0.1:5555", 'float32', self.recv_data) + self.tb.run() + self.probe_manager.watcher() + self.assertFloatTuplesAlmostEqual(self.rx_data, src_data) + + def recv_data (self, data): + self.rx_data = data + + +if __name__ == '__main__': + gr_unittest.run(qa_zeromq_pub) diff --git a/gr-zeromq/python/zeromq/qa_zeromq_pushpull.py b/gr-zeromq/python/zeromq/qa_zeromq_pushpull.py new file mode 100755 index 0000000000..0b732c9723 --- /dev/null +++ b/gr-zeromq/python/zeromq/qa_zeromq_pushpull.py @@ -0,0 +1,50 @@ +#!/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, zeromq +import time + +class qa_zeromq_pushpull (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001 (self): + vlen = 10 + src_data = range(vlen)*100 + src = blocks.vector_source_f(src_data, False, vlen) + zeromq_push_sink = zeromq.push_sink(gr.sizeof_float, vlen, "tcp://127.0.0.1:5555") + zeromq_pull_source = zeromq.pull_source(gr.sizeof_float, vlen, "tcp://127.0.0.1:5555", 0) + sink = blocks.vector_sink_f(vlen) + self.tb.connect(src, zeromq_push_sink) + self.tb.connect(zeromq_pull_source, sink) + self.tb.start() + time.sleep(0.25) + self.tb.stop() + self.tb.wait() + self.assertFloatTuplesAlmostEqual(sink.data(), src_data) + +if __name__ == '__main__': + gr_unittest.run(qa_zeromq_pushpull) diff --git a/gr-zeromq/python/zeromq/qa_zeromq_reqrep.py b/gr-zeromq/python/zeromq/qa_zeromq_reqrep.py new file mode 100755 index 0000000000..3329add1be --- /dev/null +++ b/gr-zeromq/python/zeromq/qa_zeromq_reqrep.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# 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 +from gnuradio import blocks, zeromq +from gnuradio import eng_notation +import time + +class qa_zeromq_reqrep (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001 (self): + vlen = 10 + src_data = range(vlen)*100 + src = blocks.vector_source_f(src_data, False, vlen) + zeromq_rep_sink = zeromq.rep_sink(gr.sizeof_float, vlen, "tcp://127.0.0.1:5555", 0) + zeromq_req_source = zeromq.req_source(gr.sizeof_float, vlen, "tcp://127.0.0.1:5555", 0) + sink = blocks.vector_sink_f(vlen) + self.tb.connect(src, zeromq_rep_sink) + self.tb.connect(zeromq_req_source, sink) + self.tb.start() + time.sleep(0.25) + self.tb.stop() + self.tb.wait() + self.assertFloatTuplesAlmostEqual(sink.data(), src_data) + +if __name__ == '__main__': + gr_unittest.run(qa_zeromq_reqrep) diff --git a/gr-zeromq/python/zeromq/rpc_manager.py b/gr-zeromq/python/zeromq/rpc_manager.py new file mode 100644 index 0000000000..ac8ebfa7cf --- /dev/null +++ b/gr-zeromq/python/zeromq/rpc_manager.py @@ -0,0 +1,101 @@ +# +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio. +# +# This 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. +# +# This software 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 this software; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import zmq +import pmt +import threading + + +class rpc_manager(): + def __init__(self): + self.zmq_context = zmq.Context() + self.poller_rep = zmq.Poller() + self.poller_req_out = zmq.Poller() + self.poller_req_in = zmq.Poller() + self.interfaces = dict() + + def __del__(self): + self.stop_watcher() + self.watcher_thread.join() + + def set_reply_socket(self, address): + self.rep_socket = self.zmq_context.socket(zmq.REP) + self.rep_socket.bind(address) + print "[RPC] reply socket bound to: ", address + self.poller_rep.register(self.rep_socket, zmq.POLLIN) + + def set_request_socket(self, address): + self.req_socket = self.zmq_context.socket(zmq.REQ) + self.req_socket.connect(address) + print "[RPC] request socket connected to: ", address + self.poller_req_out.register(self.req_socket, zmq.POLLOUT) + self.poller_req_in.register(self.req_socket, zmq.POLLIN) + + def add_interface(self, id_str, callback_func): + if not self.interfaces.has_key(id_str): + self.interfaces[id_str] = callback_func + print "[RPC] added reply interface:", id_str + else: + print "ERROR: duplicate id_str" + + def watcher(self): + self.keep_running = True + while self.keep_running: + # poll for calls + socks = dict(self.poller_rep.poll(10)) + if socks.get(self.rep_socket) == zmq.POLLIN: + # receive call + msg = self.rep_socket.recv() + (id_str, args) = pmt.to_python(pmt.deserialize_str(msg)) + print "[RPC] request:", id_str, ", args:", args + reply = self.callback(id_str, args) + self.rep_socket.send(pmt.serialize_str(pmt.to_pmt(reply))) + + def start_watcher(self): + self.watcher_thread = threading.Thread(target=self.watcher,args=()) + self.watcher_thread.daemon = True + self.watcher_thread.start() + + def stop_watcher(self): + self.keep_running = False + self.watcher_thread.join() + + def request(self, id_str, args=None): + socks = dict(self.poller_req_out.poll(10)) + if socks.get(self.req_socket) == zmq.POLLOUT: + self.req_socket.send(pmt.serialize_str(pmt.to_pmt((id_str,args)))) + socks = dict(self.poller_req_in.poll(10)) + if socks.get(self.req_socket) == zmq.POLLIN: + reply = pmt.to_python(pmt.deserialize_str(self.req_socket.recv())) + print "[RPC] reply:", reply + return reply + + def callback(self, id_str, args): + if self.interfaces.has_key(id_str): + callback_func = self.interfaces.get(id_str) + if not args == None: + # use unpacking or splat operator * to unpack argument list + return(callback_func(*args)) + else: + return(callback_func()) + else: + print "[RPC] ERROR: id_str not found" + return None diff --git a/gr-zeromq/swig/CMakeLists.txt b/gr-zeromq/swig/CMakeLists.txt new file mode 100644 index 0000000000..529cb0deaf --- /dev/null +++ b/gr-zeromq/swig/CMakeLists.txt @@ -0,0 +1,57 @@ +# Copyright 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. + +######################################################################## +# Setup swig generation +######################################################################## +include(GrPython) +include(GrSwig) + +set(GR_SWIG_INCLUDE_DIRS + ${GR_ZEROMQ_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_SWIG_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} + ${ZEROMQ_INCLUDE_DIRS} +) + +if(ENABLE_GR_CTRLPORT) + list(APPEND GR_SWIG_FLAGS "-DGR_CTRLPORT") + list(APPEND GR_SWIG_INCLUDE_DIRS ${ICE_INCLUDE_DIR}) +endif(ENABLE_GR_CTRLPORT) + +set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/zeromq_swig_doc.i) +set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include/gnuradio/zeromq) +set(GR_SWIG_DOCS_TARGET_DEPS runtime_swig_swig_doc) +set(GR_SWIG_LIBRARIES gnuradio-zeromq) + +GR_SWIG_MAKE(zeromq_swig zeromq_swig.i) + +GR_SWIG_INSTALL( + TARGETS zeromq_swig + DESTINATION ${GR_PYTHON_DIR}/gnuradio/zeromq + COMPONENT "zeromq_python" +) + +install( + FILES + zeromq_swig.i + ${CMAKE_CURRENT_BINARY_DIR}/zeromq_swig_doc.i + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig + COMPONENT "zeromq_swig" +) diff --git a/gr-zeromq/swig/zeromq_swig.i b/gr-zeromq/swig/zeromq_swig.i new file mode 100644 index 0000000000..bcd90550d4 --- /dev/null +++ b/gr-zeromq/swig/zeromq_swig.i @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 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. + */ + +#define ZEROMQ_API + +%include "gnuradio.i" + +//load generated python docstrings +%include "zeromq_swig_doc.i" + +%{ +#include "gnuradio/zeromq/pub_sink.h" +#include "gnuradio/zeromq/push_sink.h" +#include "gnuradio/zeromq/rep_sink.h" +#include "gnuradio/zeromq/sub_source.h" +#include "gnuradio/zeromq/pull_source.h" +#include "gnuradio/zeromq/req_source.h" +%} + +%include "gnuradio/zeromq/pub_sink.h" +%include "gnuradio/zeromq/push_sink.h" +%include "gnuradio/zeromq/rep_sink.h" +%include "gnuradio/zeromq/sub_source.h" +%include "gnuradio/zeromq/pull_source.h" +%include "gnuradio/zeromq/req_source.h" + +GR_SWIG_BLOCK_MAGIC2(zeromq, pub_sink); +GR_SWIG_BLOCK_MAGIC2(zeromq, push_sink); +GR_SWIG_BLOCK_MAGIC2(zeromq, rep_sink); +GR_SWIG_BLOCK_MAGIC2(zeromq, sub_source); +GR_SWIG_BLOCK_MAGIC2(zeromq, pull_source); +GR_SWIG_BLOCK_MAGIC2(zeromq, req_source); |