summaryrefslogtreecommitdiff
path: root/gnuradio-runtime/lib
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-runtime/lib')
-rw-r--r--gnuradio-runtime/lib/block.cc12
-rw-r--r--gnuradio-runtime/lib/controlport/CMakeLists.txt70
-rw-r--r--gnuradio-runtime/lib/controlport/rpcmanager.cc14
-rw-r--r--gnuradio-runtime/lib/controlport/rpcserver_booter_aggregator.cc3
-rw-r--r--gnuradio-runtime/lib/controlport/rpcserver_selector.cc15
-rw-r--r--gnuradio-runtime/lib/controlport/thrift/gnuradio.thrift108
-rw-r--r--gnuradio-runtime/lib/controlport/thrift/rpcpmtconverters_thrift.cc303
-rw-r--r--gnuradio-runtime/lib/controlport/thrift/rpcserver_booter_thrift.cc137
-rw-r--r--gnuradio-runtime/lib/controlport/thrift/rpcserver_thrift.cc194
-rw-r--r--gnuradio-runtime/lib/controlport/thrift/thrift.conf.example4
-rw-r--r--gnuradio-runtime/lib/controlport/thrift/thrift_application_base.cc23
-rw-r--r--gnuradio-runtime/lib/prefs.cc28
12 files changed, 880 insertions, 31 deletions
diff --git a/gnuradio-runtime/lib/block.cc b/gnuradio-runtime/lib/block.cc
index f26d6bb933..6edb73966d 100644
--- a/gnuradio-runtime/lib/block.cc
+++ b/gnuradio-runtime/lib/block.cc
@@ -842,42 +842,42 @@ namespace gr {
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
alias(), "input \% full", &block::pc_input_buffers_full,
- pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ pmt::make_f32vector(0,0), pmt::make_f32vector(0,1), pmt::make_f32vector(0,0),
"", "how full input buffers are", RPC_PRIVLVL_MIN,
DISPTIME | DISPOPTSTRIP)));
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
alias(), "avg input \% full", &block::pc_input_buffers_full_avg,
- pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ pmt::make_f32vector(0,0), pmt::make_f32vector(0,1), pmt::make_f32vector(0,0),
"", "Average of how full input buffers are", RPC_PRIVLVL_MIN,
DISPTIME | DISPOPTSTRIP)));
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
alias(), "var input \% full", &block::pc_input_buffers_full_var,
- pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ pmt::make_f32vector(0,0), pmt::make_f32vector(0,1), pmt::make_f32vector(0,0),
"", "Var. of how full input buffers are", RPC_PRIVLVL_MIN,
DISPTIME | DISPOPTSTRIP)));
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
alias(), "output \% full", &block::pc_output_buffers_full,
- pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ pmt::make_f32vector(0,0), pmt::make_f32vector(0,1), pmt::make_f32vector(0,0),
"", "how full output buffers are", RPC_PRIVLVL_MIN,
DISPTIME | DISPOPTSTRIP)));
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
alias(), "avg output \% full", &block::pc_output_buffers_full_avg,
- pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ pmt::make_f32vector(0,0), pmt::make_f32vector(0,1), pmt::make_f32vector(0,0),
"", "Average of how full output buffers are", RPC_PRIVLVL_MIN,
DISPTIME | DISPOPTSTRIP)));
d_rpc_vars.push_back(
rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
alias(), "var output \% full", &block::pc_output_buffers_full_var,
- pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ pmt::make_f32vector(0,0), pmt::make_f32vector(0,1), pmt::make_f32vector(0,0),
"", "Var. of how full output buffers are", RPC_PRIVLVL_MIN,
DISPTIME | DISPOPTSTRIP)));
#endif /* defined(GR_CTRLPORT) && defined(GR_PERFORMANCE_COUNTERS) */
diff --git a/gnuradio-runtime/lib/controlport/CMakeLists.txt b/gnuradio-runtime/lib/controlport/CMakeLists.txt
index 262c5adb8b..f0d2618c01 100644
--- a/gnuradio-runtime/lib/controlport/CMakeLists.txt
+++ b/gnuradio-runtime/lib/controlport/CMakeLists.txt
@@ -19,8 +19,13 @@
if(ENABLE_GR_CTRLPORT)
+# Keep track of the number of backends ControlPort supports
+SET(CTRLPORT_BACKENDS 0)
+
# Add definition so we can compile in ControlPort to the blocks.
-ADD_DEFINITIONS(-DGR_CTRLPORT)
+add_definitions(-DGR_CTRLPORT)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
list(APPEND gnuradio_ctrlport_sources
${CMAKE_CURRENT_SOURCE_DIR}/rpcmanager.cc
@@ -29,14 +34,71 @@ list(APPEND gnuradio_ctrlport_sources
${CMAKE_CURRENT_SOURCE_DIR}/rpcserver_selector.cc
)
+
+OPTION(ENABLE_CTRLPORT_THRIFT "Enable ControlPort Thrift support" ON)
+
+if(ENABLE_CTRLPORT_THRIFT)
+
+# Look if Thrift is installed and use it as a ControlPort backend.
+FIND_PACKAGE(Thrift)
+
+if(THRIFT_FOUND)
+
+MATH(EXPR CTRLPORT_BACKENDS "${CTRLPORT_BACKENDS} + 1")
+
+# Indicate thrift as an installed backend in the cmake summary.
+message(STATUS "Found and enabling Thrift backend to ControlPort")
+GR_APPEND_SUBCOMPONENT("thrift")
+
+# Run Thrrift To compile C++ and Python files
+message(STATUS "Running thrift to build C++ bindings")
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/thrift/)
+EXECUTE_PROCESS(
+ COMMAND ${THRIFT_BIN} --gen cpp -out ${CMAKE_CURRENT_BINARY_DIR}/thrift/ ${CMAKE_CURRENT_SOURCE_DIR}/thrift/gnuradio.thrift
+ OUTPUT_VARIABLE THRIFT_CPP_OUTPUT
+ ERROR_VARIABLE THRIFT_CPP_ERROR
+ )
+
+list(APPEND gnuradio_ctrlport_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/thrift/rpcserver_thrift.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/thrift/rpcpmtconverters_thrift.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/thrift/rpcserver_booter_thrift.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/thrift/thrift_application_base.cc
+)
+
+# add files built by compiling gnuradio.thrift
+list(APPEND gnuradio_ctrlport_sources
+ ${CMAKE_CURRENT_BINARY_DIR}/thrift/gnuradio_types.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/thrift/gnuradio_constants.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/thrift/ControlPort.cpp
+)
+
+# Add required libraries here
+list(APPEND gnuradio_runtime_libs
+ ${THRIFT_LIBRARIES}
+)
+
+# Add install rule to move example Thrift configuration file into
+# $prefix/etc/gnuradio
+install(
+ FILES ${CMAKE_CURRENT_SOURCE_DIR}/thrift/thrift.conf.example
+ DESTINATION ${SYSCONFDIR}/${CMAKE_PROJECT_NAME}
+ COMPONENT "runtime_runtime"
+)
+
+endif(THRIFT_FOUND)
+endif(ENABLE_CTRLPORT_THRIFT)
+
########################################################################
# Add controlport stuff to gnuradio-runtime
########################################################################
include_directories(${CMAKE_CURRENT_BINARY_DIR})
-# Add any required libraries here
-#list(APPEND gnuradio_runtime_libs
-#)
+# Save the number of backends for testing against later
+set(
+ CTRLPORT_BACKENDS ${CTRLPORT_BACKENDS}
+ CACHE INTERNAL "Number of ControlPort backends available"
+)
endif(ENABLE_GR_CTRLPORT)
diff --git a/gnuradio-runtime/lib/controlport/rpcmanager.cc b/gnuradio-runtime/lib/controlport/rpcmanager.cc
index 0c7bc135be..a67febe386 100644
--- a/gnuradio-runtime/lib/controlport/rpcmanager.cc
+++ b/gnuradio-runtime/lib/controlport/rpcmanager.cc
@@ -26,16 +26,12 @@
bool rpcmanager::booter_registered(false);
bool rpcmanager::aggregator_registered(false);
-rpcserver_booter_base* rpcmanager::boot(0);
+std::auto_ptr<rpcserver_booter_base> rpcmanager::boot(0);
std::auto_ptr<rpcserver_booter_aggregator> rpcmanager::aggregator(0);
rpcmanager::rpcmanager() {;}
-rpcmanager::~rpcmanager()
-{
- if(boot)
- delete boot;
-}
+rpcmanager::~rpcmanager() {;}
rpcserver_booter_base*
rpcmanager::get()
@@ -44,10 +40,10 @@ rpcmanager::get()
return aggregator.get();
}
else if(booter_registered) {
- return boot;
+ return boot.get();
}
assert(booter_registered || aggregator_registered);
- return boot;
+ return boot.get();
}
void
@@ -63,7 +59,7 @@ rpcmanager::register_booter(rpcserver_booter_base* booter)
aggregator->agg()->registerServer(bootreg);
}
else if(!booter_registered) {
- boot = booter;
+ boot.reset(booter);
booter_registered = true;
}
else {
diff --git a/gnuradio-runtime/lib/controlport/rpcserver_booter_aggregator.cc b/gnuradio-runtime/lib/controlport/rpcserver_booter_aggregator.cc
index 201dfb3929..a1983b4ac5 100644
--- a/gnuradio-runtime/lib/controlport/rpcserver_booter_aggregator.cc
+++ b/gnuradio-runtime/lib/controlport/rpcserver_booter_aggregator.cc
@@ -23,7 +23,8 @@
#include <gnuradio/rpcserver_booter_aggregator.h>
rpcserver_booter_aggregator::rpcserver_booter_aggregator() :
- d_type(std::string("aggregator")), server(new rpcserver_aggregator())
+ d_type(std::string("aggregator")),
+ server(new rpcserver_aggregator())
{;}
rpcserver_booter_aggregator::~rpcserver_booter_aggregator()
diff --git a/gnuradio-runtime/lib/controlport/rpcserver_selector.cc b/gnuradio-runtime/lib/controlport/rpcserver_selector.cc
index 692f151958..8f3b4557c2 100644
--- a/gnuradio-runtime/lib/controlport/rpcserver_selector.cc
+++ b/gnuradio-runtime/lib/controlport/rpcserver_selector.cc
@@ -26,14 +26,23 @@
bool rpcmanager::make_aggregator(false);
-#ifdef RPCSERVER_ICE
+#ifdef GR_RPCSERVER_ENABLED
+rpcmanager manager_instance;
+#endif
+
+#ifdef GR_RPCSERVER_ICE
#error TODO ICE
#endif
-#ifdef RPCSERVER_ERLANG
+#ifdef GR_RPCSERVER_THRIFT
+#include <gnuradio/rpcserver_booter_thrift.h>
+rpcmanager::rpcserver_booter_register_helper<rpcserver_booter_thrift> boot_thrift;
+#endif
+
+#ifdef GR_RPCSERVER_ERLANG
#error TODO ERLANG
#endif
-#ifdef RPCSERVER_XMLRPC
+#ifdef GR_RPCSERVER_XMLRPC
#error TODO XMLRPC
#endif
diff --git a/gnuradio-runtime/lib/controlport/thrift/gnuradio.thrift b/gnuradio-runtime/lib/controlport/thrift/gnuradio.thrift
new file mode 100644
index 0000000000..ae7f839a2f
--- /dev/null
+++ b/gnuradio-runtime/lib/controlport/thrift/gnuradio.thrift
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2014,2015 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.
+ */
+
+namespace cpp GNURadio
+namespace py GNURadio
+
+struct complex {
+ 1: double re;
+ 2: double im;
+}
+
+typedef list<bool> VectorB
+typedef binary VectorC
+typedef list<i16> VectorT
+typedef list<i32> VectorI
+typedef list<i64> VectorL
+typedef list<double> VectorF
+typedef list<double> VectorD
+typedef list<string> VectorS
+typedef list<complex> VectorZ
+
+enum BaseTypes { BOOL, BYTE, SHORT, INT, LONG, DOUBLE, STRING, COMPLEX,
+ F32VECTOR, F64VECTOR, S64VECTOR, S32VECTOR, S16VECTOR,
+ S8VECTOR, C32VECTOR }
+
+union KnobBase {
+ 1: bool a_bool;
+ 2: byte a_byte;
+ 3: i16 a_short;
+ 4: i32 a_int;
+ 5: i64 a_long;
+ 6: double a_double;
+ 7: string a_string;
+ 8: complex a_complex;
+ 9: VectorF a_f32vector;
+ 10: VectorD a_f64vector;
+ 11: VectorL a_s64vector;
+ 12: VectorI a_s32vector;
+ 13: VectorT a_s16vector;
+ 14: VectorC a_s8vector;
+ 15: VectorZ a_c32vector;
+}
+
+struct Knob {
+ 1: BaseTypes type;
+ 2: KnobBase value;
+}
+
+enum KnobType { KNOBBOOL, KNOBCHAR, KNOBINT, KNOBDOUBLE, KNOBSTRING,
+ KNOBLONG, KNOBVECBOOL, KNOBVECCHAR, KNOBVECINT,
+ KNOBVECDOUBLE, KNOBVECSTRING, KNOBVECLONG, KNOBSHORT}
+
+const i32 DISPNULL = 0x0000
+const i32 DISPTIME = 0x0001
+const i32 DISPXY = 0x0002
+const i32 DISPPSD = 0x0004
+const i32 DISPSPEC = 0x0008
+const i32 DISPRAST = 0x0010
+const i32 DISPOPTCPLX = 0x0100
+const i32 DISPOPTLOG = 0x0200
+const i32 DISPOPTSTEM = 0x0400
+const i32 DISPOPTSTRIP = 0x0800
+const i32 DISPOPTSCATTER = 0x1000
+
+struct KnobProp {
+ 1: KnobType type,
+ 2: string units,
+ 3: string description,
+ 4: i32 display,
+ 5: Knob min,
+ 6: Knob max,
+ 7: Knob defaultvalue
+}
+
+typedef list<string> KnobIDList
+typedef map<string, Knob> KnobMap
+typedef map<string, KnobProp> KnobPropMap
+typedef map<string, string> WaveformArgMap
+
+service StreamReceiver {
+ void push(1:VectorC data);
+}
+
+service ControlPort {
+ void setKnobs(1:KnobMap knobs);
+ KnobMap getKnobs(1:KnobIDList knobs);
+ KnobMap getRe(1:KnobIDList knobs);
+ KnobPropMap properties(1:KnobIDList knobs);
+ void shutdown();
+}
diff --git a/gnuradio-runtime/lib/controlport/thrift/rpcpmtconverters_thrift.cc b/gnuradio-runtime/lib/controlport/thrift/rpcpmtconverters_thrift.cc
new file mode 100644
index 0000000000..19da05f787
--- /dev/null
+++ b/gnuradio-runtime/lib/controlport/thrift/rpcpmtconverters_thrift.cc
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2014,2015 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 <boost/assign/ptr_map_inserter.hpp>
+#include <gnuradio/rpcpmtconverters_thrift.h>
+#include <gnuradio/gr_complex.h>
+#include "thrift/gnuradio_types.h"
+#include <iostream>
+
+GNURadio::Knob
+rpcpmtconverter::from_pmt(const pmt::pmt_t& knob)
+{
+ if(pmt::is_real(knob)) {
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::DOUBLE;
+ result.value.__set_a_double(pmt::to_double(knob));
+ return result;
+ }
+ else if(pmt::is_symbol(knob)) {
+ std::string value = pmt::symbol_to_string(knob);
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::STRING;
+ result.value.__set_a_string(value);
+ return result;
+ }
+ else if(pmt::is_integer(knob)) {
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::LONG;
+ result.value.__set_a_long(pmt::to_long(knob));
+ return result;
+ }
+ else if(pmt::is_bool(knob)) {
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::BOOL;
+ result.value.__set_a_bool(pmt::to_bool(knob));
+ return result;
+ }
+ else if(pmt::is_uint64(knob)) {
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::LONG;
+ result.value.__set_a_long(pmt::to_uint64(knob));
+ return result;
+ }
+ else if(pmt::is_complex(knob)) {
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::COMPLEX;
+ std::complex<double> tmp = pmt::to_complex(knob);
+ GNURadio::complex cpx;
+ cpx.re = tmp.real();
+ cpx.im = tmp.imag();
+ result.value.__set_a_complex(cpx);
+ return result;
+ }
+ else if(pmt::is_f32vector(knob)) {
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::F32VECTOR;
+ size_t size(pmt::length(knob));
+ const float* start((const float*)pmt::f32vector_elements(knob,size));
+ result.value.__set_a_f32vector(std::vector<double>(start,start+size));
+ return result;
+ }
+ else if(pmt::is_f64vector(knob)) {
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::F64VECTOR;
+ size_t size(pmt::length(knob));
+ const double* start((const double*)pmt::f64vector_elements(knob,size));
+ result.value.__set_a_f64vector(std::vector<double>(start,start+size));
+ return result;
+ }
+ else if(pmt::is_s64vector(knob)) {
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::S64VECTOR;
+ size_t size(pmt::length(knob));
+ const int64_t* start((const int64_t*)pmt::s64vector_elements(knob,size));
+ result.value.__set_a_s64vector(std::vector<int64_t>(start,start+size));
+ return result;
+ }
+ else if(pmt::is_s32vector(knob)) {
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::S32VECTOR;
+ size_t size(pmt::length(knob));
+ const int32_t* start((const int32_t*)pmt::s32vector_elements(knob,size));
+ result.value.__set_a_s32vector(std::vector<int32_t>(start,start+size));
+ return result;
+ }
+ else if(pmt::is_s16vector(knob)) {
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::S16VECTOR;
+ size_t size(pmt::length(knob));
+ const int16_t* start((const int16_t*)pmt::s16vector_elements(knob,size));
+ result.value.__set_a_s16vector(std::vector<int16_t>(start,start+size));
+ return result;
+ }
+ else if(pmt::is_s8vector(knob)) {
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::S8VECTOR;
+ size_t size(pmt::length(knob));
+ const int8_t* start((const int8_t*)pmt::s8vector_elements(knob,size));
+ result.value.__set_a_s8vector(std::basic_string<char>(start,start+size));
+ return result;
+ }
+ else if(pmt::is_c32vector(knob)) {
+ std::vector< GNURadio::complex > z;
+
+ GNURadio::Knob result;
+ result.type = GNURadio::BaseTypes::C32VECTOR;
+ size_t size(pmt::length(knob));
+ const gr_complex* start((const gr_complex*)pmt::c32vector_elements(knob,size));
+ for(size_t s = 0; s < size; s++) {
+ GNURadio::complex z0;
+ gr_complex z1 = gr_complex(*(start+s));
+ z0.__set_re(z1.real());
+ z0.__set_im(z1.imag());
+ z.push_back(z0);
+ }
+ result.value.__set_a_c32vector(z);
+ return result;
+ }
+ else {
+ std::cerr << "Error: Don't know how to handle Knob Type (from): " << knob << std::endl;
+ assert(0);
+ }
+ return GNURadio::Knob();
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_byte_f::operator()(const GNURadio::Knob& knob)
+{
+ return pmt::mp(knob.value.a_byte);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_short_f::operator()(const GNURadio::Knob& knob)
+{
+ return pmt::mp(knob.value.a_short);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_int_f::operator()(const GNURadio::Knob& knob)
+{
+ return pmt::mp(knob.value.a_int);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_long_f::operator()(const GNURadio::Knob& knob)
+{
+ return pmt::mp(knob.value.a_long);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_double_f::operator()(const GNURadio::Knob& knob)
+{
+ return pmt::mp(knob.value.a_double);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_string_f::operator()(const GNURadio::Knob& knob)
+{
+ return pmt::string_to_symbol(knob.value.a_string);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_bool_f::operator()(const GNURadio::Knob& knob)
+{
+ if(knob.value.a_bool)
+ return pmt::PMT_T;
+ else
+ return pmt::PMT_F;
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_complex_f::operator()(const GNURadio::Knob& knob)
+{
+ gr_complexd cpx(knob.value.a_complex.re, knob.value.a_complex.im);
+ return pmt::from_complex(cpx);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_f32vect_f::operator()(const GNURadio::Knob& knob)
+{
+ std::vector<double> v_double = knob.value.a_f32vector;
+ std::vector<float> v(v_double.begin(), v_double.end());
+ return pmt::init_f32vector(v.size(), v);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_f64vect_f::operator()(const GNURadio::Knob& knob)
+{
+ std::vector<double> v = knob.value.a_f64vector;
+ return pmt::init_f64vector(v.size(), v);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_s64vect_f::operator()(const GNURadio::Knob& knob)
+{
+ std::vector<int64_t> v = knob.value.a_s64vector;
+ return pmt::init_s64vector(v.size(), v);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_s32vect_f::operator()(const GNURadio::Knob& knob)
+{
+ std::vector<int32_t> v = knob.value.a_s32vector;
+ return pmt::init_s32vector(v.size(), v);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_s16vect_f::operator()(const GNURadio::Knob& knob)
+{
+ std::vector<int16_t> v = knob.value.a_s16vector;
+ return pmt::init_s16vector(v.size(), v);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_s8vect_f::operator()(const GNURadio::Knob& knob)
+{
+ std::basic_string<char> v = knob.value.a_s8vector;
+ return pmt::init_s8vector(v.size(), reinterpret_cast<const int8_t*>(v.data()));
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_c32vect_f::operator()(const GNURadio::Knob& knob)
+{
+ std::vector<GNURadio::complex> v0 = knob.value.a_c32vector;
+ std::vector<GNURadio::complex>::iterator vitr;
+ std::vector<gr_complex> v;
+ for(vitr = v0.begin(); vitr != v0.end(); vitr++) {
+ v.push_back(gr_complex(vitr->re, vitr->im));
+ }
+ return pmt::init_c32vector(v.size(), v);
+}
+
+rpcpmtconverter::To_PMT rpcpmtconverter::To_PMT::instance;
+
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_bool_f> reg_bool(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::BOOL);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_byte_f> reg_byte(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::BYTE);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_short_f> reg_short(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::SHORT);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_int_f> reg_int(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::INT);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_long_f> reg_long(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::LONG);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_double_f> reg_double(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::DOUBLE);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_string_f> reg_string(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::STRING);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_complex_f> reg_complex(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::COMPLEX);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_f32vect_f> reg_f32v(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::F32VECTOR);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_f64vect_f> reg_f64v(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::F64VECTOR);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_s64vect_f> reg_s64v(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::S64VECTOR);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_s32vect_f> reg_s32v(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::S32VECTOR);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_s16vect_f> reg_s16v(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::S16VECTOR);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_s8vect_f> reg_s8v(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::S8VECTOR);
+rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_c32vect_f> reg_c32v(rpcpmtconverter::To_PMT::instance,
+ GNURadio::BaseTypes::C32VECTOR);
+
+template<typename TO_PMT_F>
+rpcpmtconverter::to_pmt_reg<TO_PMT_F>::to_pmt_reg(To_PMT& instance,
+ const GNURadio::BaseTypes::type type)
+{
+ boost::assign::ptr_map_insert<TO_PMT_F>(instance.to_pmt_map)(type);
+}
+
+pmt::pmt_t
+rpcpmtconverter::to_pmt_f::operator()(const GNURadio::Knob& knob)
+{
+ std::cerr << "Error: Don't know how to handle Knob Type: " << knob.type << std::endl;
+ assert(0);
+ return pmt::pmt_t();
+}
+
+pmt::pmt_t
+rpcpmtconverter::To_PMT::operator()(const GNURadio::Knob& knob)
+{
+ return to_pmt_map[knob.type](knob);
+}
diff --git a/gnuradio-runtime/lib/controlport/thrift/rpcserver_booter_thrift.cc b/gnuradio-runtime/lib/controlport/thrift/rpcserver_booter_thrift.cc
new file mode 100644
index 0000000000..40cfe1a48a
--- /dev/null
+++ b/gnuradio-runtime/lib/controlport/thrift/rpcserver_booter_thrift.cc
@@ -0,0 +1,137 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 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 <gnuradio/rpcserver_thrift.h>
+#include <gnuradio/rpcserver_booter_thrift.h>
+
+#include <boost/asio/ip/host_name.hpp>
+
+namespace {
+ static const char* const CONTROL_PORT_CLASS("thrift");
+ static const unsigned int ETHERNET_HEADER_SIZE(14);
+ static const unsigned int IP_HEADER_SIZE(20);
+ static const unsigned int TCP_HEADER_SIZE(32);
+ static const unsigned int ETHERNET_TYPICAL_MTU(1500);
+ static const unsigned int ALRIGHT_DEFAULT_BUFFER_SIZE(
+ ETHERNET_TYPICAL_MTU - ETHERNET_HEADER_SIZE - IP_HEADER_SIZE - TCP_HEADER_SIZE);
+};
+
+/*!
+ * \brief A booter implementation for a Thrift application class.
+ */
+
+rpcserver_booter_thrift::rpcserver_booter_thrift() :
+ thrift_server_template<rpcserver_base,
+ rpcserver_thrift,
+ rpcserver_booter_thrift,
+ boost::shared_ptr<GNURadio::ControlPortIf> >(this),
+ d_type(std::string(CONTROL_PORT_CLASS))
+{;}
+
+rpcserver_booter_thrift::~rpcserver_booter_thrift()
+{;}
+
+rpcserver_base*
+rpcserver_booter_thrift::i()
+{
+ return thrift_server_template<rpcserver_base, rpcserver_thrift,
+ rpcserver_booter_thrift,
+ GNURadio::ControlPortIf>::i();
+}
+
+/*!
+ * \brief Returns the endpoint string for the application
+ */
+
+const std::vector<std::string>
+rpcserver_booter_thrift::endpoints()
+{
+ return thrift_server_template<rpcserver_base, rpcserver_thrift,
+ rpcserver_booter_thrift,
+ GNURadio::ControlPortIf>::endpoints();
+}
+
+// Specialized thrift_application_base attributes and functions
+// for this rpcserver_booter instance.
+
+template<class rpcserver_base, class rpcserver_booter_thrift>
+const unsigned int thrift_application_base<rpcserver_base, rpcserver_booter_thrift>::d_default_max_init_attempts(100U);
+
+template<class rpcserver_base, class rpcserver_booter_thrift>
+const unsigned int thrift_application_base<rpcserver_base, rpcserver_booter_thrift>::d_default_thrift_port(0U);
+
+template<class rpcserver_base, class rpcserver_booter_thrift>
+const unsigned int thrift_application_base<rpcserver_base, rpcserver_booter_thrift>::d_default_num_thrift_threads(10U);
+
+template<class rpcserver_base, class rpcserver_booter_thrift>
+const unsigned int thrift_application_base<rpcserver_base, rpcserver_booter_thrift>::d_default_thrift_buffer_size(
+ ALRIGHT_DEFAULT_BUFFER_SIZE);
+
+template<class rpcserver_base, class rpcserver_booter_thrift>
+std::auto_ptr<thrift_application_base_impl>
+ thrift_application_base<rpcserver_base, rpcserver_booter_thrift>::p_impl(
+ new thrift_application_base_impl());
+
+template<class rpcserver_base, class rpcserver_booter_thrift>
+thrift_application_base<rpcserver_base, rpcserver_booter_thrift>::~thrift_application_base()
+{
+ GR_LOG_DEBUG(d_debug_logger, "thrift_application_base: shutdown");
+ if(d_thirft_is_running) {
+ d_thriftserver->stop();
+ d_thirft_is_running = false;
+ }
+}
+
+template<class rpcserver_base, class rpcserver_booter_thrift>
+void thrift_application_base<rpcserver_base, rpcserver_booter_thrift>::start_thrift()
+{
+ d_thriftserver->serve();
+}
+
+template<class rpcserver_base, typename rpcserver_booter_thrift>
+bool thrift_application_base<rpcserver_base, rpcserver_booter_thrift>::application_started()
+{
+ if (d_thirft_is_running) return true;
+
+ bool result(false);
+ // Define the endpoint.
+ apache::thrift::transport::TServerTransport *thetransport =
+ d_thriftserver->getServerTransport().get();
+
+ // Determine the specified endpoint port number, or the port number selected by bind() if
+ int used_port = ((apache::thrift::transport::TServerSocket*)thetransport)->getPort();
+
+ if (used_port > 0) {
+ // Determine the hostname of this host
+ const std::string boost_hostname(boost::asio::ip::host_name());
+
+ std::string endpoint = boost::str(boost::format("-h %1% -p %2%") % boost_hostname % used_port);
+ //std::cout << "Thrift endpoint: " << endpoint << " boost hostname: " << boost_hostname << std::endl;
+ set_endpoint(endpoint);
+
+ GR_LOG_INFO(d_logger, "Apache Thrift: " + endpoint);
+ d_thirft_is_running = true;
+ result = true;
+ }
+
+ return result;
+}
diff --git a/gnuradio-runtime/lib/controlport/thrift/rpcserver_thrift.cc b/gnuradio-runtime/lib/controlport/thrift/rpcserver_thrift.cc
new file mode 100644
index 0000000000..c4655d366e
--- /dev/null
+++ b/gnuradio-runtime/lib/controlport/thrift/rpcserver_thrift.cc
@@ -0,0 +1,194 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2014,2015 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 <gnuradio/rpcserver_thrift.h>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <pmt/pmt.h>
+#include <thrift/protocol/TBinaryProtocol.h>
+#include <thrift/transport/TSocket.h>
+#include <thrift/transport/TTransportUtils.h>
+#include <boost/xpressive/xpressive.hpp>
+#include "thrift/ControlPort.h"
+
+#define DEBUG 0
+
+using namespace rpcpmtconverter;
+
+rpcserver_thrift::rpcserver_thrift()
+{
+ //std::cerr << "rpcserver_thrift::ctor" << std::endl;
+}
+
+rpcserver_thrift::~rpcserver_thrift()
+{
+ //std::cerr << "rpcserver_thrift::dtor" << std::endl;
+}
+
+void
+rpcserver_thrift::registerConfigureCallback(const std::string &id,
+ const configureCallback_t callback)
+{
+ {
+ ConfigureCallbackMap_t::const_iterator iter(d_setcallbackmap.find(id));
+ if(iter != d_setcallbackmap.end()) {
+ std::stringstream s;
+ s << "rpcserver_thrift:: rpcserver_thrift ERROR registering set, already registered: "
+ << id << std::endl;
+ throw std::runtime_error(s.str().c_str());
+ }
+ }
+
+ if(DEBUG) {
+ std::cerr << "rpcserver_thrift registering set: " << id << std::endl;
+ }
+ d_setcallbackmap.insert(ConfigureCallbackMap_t::value_type(id, callback));
+}
+
+void
+rpcserver_thrift::unregisterConfigureCallback(const std::string &id)
+{
+ ConfigureCallbackMap_t::iterator iter(d_setcallbackmap.find(id));
+ if(iter == d_setcallbackmap.end()) {
+ std::stringstream s;
+ s << "rpcserver_thrift:: rpcserver_thrift ERROR unregistering set, not registered: "
+ << id << std::endl;
+ throw std::runtime_error(s.str().c_str());
+ }
+
+ if(DEBUG)
+ std::cerr << "rpcserver_thrift unregistering set: " << id << std::endl;
+
+ d_setcallbackmap.erase(iter);
+}
+
+void
+rpcserver_thrift::registerQueryCallback(const std::string &id,
+ const queryCallback_t callback)
+{
+ {
+ QueryCallbackMap_t::const_iterator iter(d_getcallbackmap.find(id));
+ if(iter != d_getcallbackmap.end()) {
+ std::stringstream s;
+ s << "rpcserver_thrift:: rpcserver_thrift ERROR registering get, already registered: "
+ << id << std::endl;
+ throw std::runtime_error(s.str().c_str());
+ }
+ }
+
+ if(DEBUG) {
+ std::cerr << "rpcserver_thrift registering get: " << id << std::endl;
+ }
+ d_getcallbackmap.insert(QueryCallbackMap_t::value_type(id, callback));
+}
+
+void
+rpcserver_thrift::unregisterQueryCallback(const std::string &id)
+{
+ QueryCallbackMap_t::iterator iter(d_getcallbackmap.find(id));
+ if(iter == d_getcallbackmap.end()) {
+ std::stringstream s;
+ s << "rpcserver_thrift:: rpcserver_thrift ERROR unregistering get, registered: "
+ << id << std::endl;
+ throw std::runtime_error(s.str().c_str());
+ }
+
+ if(DEBUG) {
+ std::cerr << "rpcserver_thrift unregistering get: " << id << std::endl;
+ }
+
+ d_getcallbackmap.erase(iter);
+}
+
+void
+rpcserver_thrift::setKnobs(const GNURadio::KnobMap& knobs)
+{
+ std::for_each(knobs.begin(), knobs.end(),
+ set_f<GNURadio::KnobMap::value_type,ConfigureCallbackMap_t>
+ (d_setcallbackmap, cur_priv));
+}
+
+
+void
+rpcserver_thrift::getKnobs(GNURadio::KnobMap& _return,
+ const GNURadio::KnobIDList& knobs)
+{
+ if(knobs.size() == 0) {
+ std::for_each(d_getcallbackmap.begin(), d_getcallbackmap.end(),
+ get_all_f<QueryCallbackMap_t::value_type, QueryCallbackMap_t, GNURadio::KnobMap>
+ (d_getcallbackmap, cur_priv, _return));
+ }
+ else {
+ std::for_each(knobs.begin(), knobs.end(),
+ get_f<GNURadio::KnobIDList::value_type, QueryCallbackMap_t>
+ (d_getcallbackmap, cur_priv, _return));
+ }
+}
+
+void
+rpcserver_thrift::getRe(GNURadio::KnobMap& _return, const GNURadio::KnobIDList& knobs)
+{
+ if(knobs.size() == 0) {
+ std::for_each(d_getcallbackmap.begin(), d_getcallbackmap.end(),
+ get_all_f<QueryCallbackMap_t::value_type, QueryCallbackMap_t, GNURadio::KnobMap>
+ (d_getcallbackmap, cur_priv, _return));
+ }
+ else {
+ QueryCallbackMap_t::iterator it;
+ for(it = d_getcallbackmap.begin(); it != d_getcallbackmap.end(); it++){
+ for(size_t j=0; j<knobs.size(); j++) {
+ const boost::xpressive::sregex re(boost::xpressive::sregex::compile(knobs[j]));
+ if(boost::xpressive::regex_match(it->first, re)) {
+ get_f<GNURadio::KnobIDList::value_type, QueryCallbackMap_t>
+ (d_getcallbackmap, cur_priv, _return)(it->first);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void
+rpcserver_thrift::properties(GNURadio::KnobPropMap& _return,
+ const GNURadio::KnobIDList& knobs)
+{
+ if(knobs.size() == 0) {
+ std::for_each(d_getcallbackmap.begin(), d_getcallbackmap.end(),
+ properties_all_f<QueryCallbackMap_t::value_type,
+ QueryCallbackMap_t, GNURadio::KnobPropMap>(d_getcallbackmap,
+ cur_priv, _return));
+ }
+ else {
+ std::for_each(knobs.begin(), knobs.end(),
+ properties_f<GNURadio::KnobIDList::value_type,
+ QueryCallbackMap_t, GNURadio::KnobPropMap>(d_getcallbackmap,
+ cur_priv, _return));
+ }
+}
+
+void
+rpcserver_thrift::shutdown() {
+ if (DEBUG) {
+ std::cerr << "Shutting down..." << std::endl;
+ }
+}
diff --git a/gnuradio-runtime/lib/controlport/thrift/thrift.conf.example b/gnuradio-runtime/lib/controlport/thrift/thrift.conf.example
new file mode 100644
index 0000000000..71cc506249
--- /dev/null
+++ b/gnuradio-runtime/lib/controlport/thrift/thrift.conf.example
@@ -0,0 +1,4 @@
+[thrift]
+port = 9090
+nthreads = 2
+buffersize = 1434
diff --git a/gnuradio-runtime/lib/controlport/thrift/thrift_application_base.cc b/gnuradio-runtime/lib/controlport/thrift/thrift_application_base.cc
new file mode 100644
index 0000000000..282ed9fc63
--- /dev/null
+++ b/gnuradio-runtime/lib/controlport/thrift/thrift_application_base.cc
@@ -0,0 +1,23 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 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 <gnuradio/thrift_application_base.h>
diff --git a/gnuradio-runtime/lib/prefs.cc b/gnuradio-runtime/lib/prefs.cc
index b7fcaada9d..b303ffdaf9 100644
--- a/gnuradio-runtime/lib/prefs.cc
+++ b/gnuradio-runtime/lib/prefs.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006,2013 Free Software Foundation, Inc.
+ * Copyright 2006,2013,2015 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -46,7 +46,10 @@ namespace gr {
prefs::prefs()
{
- _read_files();
+ std::string config = _read_files(_sys_prefs_filenames());
+
+ // Convert the string into a map
+ _convert_to_map(config);
}
prefs::~prefs()
@@ -83,13 +86,12 @@ namespace gr {
return fnames;
}
- void
- prefs::_read_files()
+ std::string
+ prefs::_read_files(const std::vector<std::string> &filenames)
{
std::string config;
- std::vector<std::string> filenames = _sys_prefs_filenames();
- std::vector<std::string>::iterator sitr;
+ std::vector<std::string>::const_iterator sitr;
char tmp[1024];
for(sitr = filenames.begin(); sitr != filenames.end(); sitr++) {
fs::ifstream fin(*sitr);
@@ -142,8 +144,7 @@ namespace gr {
fin.close();
}
- // Convert the string into a map
- _convert_to_map(config);
+ return config;
}
void
@@ -188,6 +189,17 @@ namespace gr {
}
}
+ void
+ prefs::add_config_file(const std::string &configfile)
+ {
+ std::vector<std::string> filenames;
+ filenames.push_back(configfile);
+
+ std::string config = _read_files(filenames);
+ _convert_to_map(config);
+ }
+
+
std::string
prefs::to_string()
{