diff options
Diffstat (limited to 'gnuradio-runtime/lib')
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() { |