summaryrefslogtreecommitdiff
path: root/gnuradio-runtime/include/gnuradio
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-runtime/include/gnuradio')
-rw-r--r--gnuradio-runtime/include/gnuradio/CMakeLists.txt10
-rw-r--r--gnuradio-runtime/include/gnuradio/prefs.h32
-rw-r--r--gnuradio-runtime/include/gnuradio/rpcbufferedget.h65
-rw-r--r--gnuradio-runtime/include/gnuradio/rpcmanager.h2
-rw-r--r--gnuradio-runtime/include/gnuradio/rpcpmtconverters_thrift.h74
-rw-r--r--gnuradio-runtime/include/gnuradio/rpcregisterhelpers.h22
-rw-r--r--gnuradio-runtime/include/gnuradio/rpcserver_booter_thrift.h52
-rw-r--r--gnuradio-runtime/include/gnuradio/rpcserver_selector.h10
-rw-r--r--gnuradio-runtime/include/gnuradio/rpcserver_thrift.h230
-rw-r--r--gnuradio-runtime/include/gnuradio/thrift_application_base.h253
-rw-r--r--gnuradio-runtime/include/gnuradio/thrift_server_template.h160
11 files changed, 892 insertions, 18 deletions
diff --git a/gnuradio-runtime/include/gnuradio/CMakeLists.txt b/gnuradio-runtime/include/gnuradio/CMakeLists.txt
index 3fc2fe7bd8..472f91847b 100644
--- a/gnuradio-runtime/include/gnuradio/CMakeLists.txt
+++ b/gnuradio-runtime/include/gnuradio/CMakeLists.txt
@@ -86,6 +86,16 @@ install(FILES
COMPONENT "runtime_devel"
)
+if(THRIFT_FOUND)
+install(FILES
+ rpcserver_booter_thrift.h
+ thrift_application_base.h
+ thrift_server_template.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio
+ COMPONENT "runtime_devel"
+)
+endif(THRIFT_FOUND)
+
##########################################################################
# Configure logger
##########################################################################
diff --git a/gnuradio-runtime/include/gnuradio/prefs.h b/gnuradio-runtime/include/gnuradio/prefs.h
index a9a28586ab..4dc92b3631 100644
--- a/gnuradio-runtime/include/gnuradio/prefs.h
+++ b/gnuradio-runtime/include/gnuradio/prefs.h
@@ -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
*
@@ -47,10 +47,38 @@ namespace gr {
public:
static prefs *singleton();
+ /*!
+ * \brief Creates an object to read preference files.
+ *
+ * \details
+ *
+ * If no file name is given (empty arg list or ""), this opens up
+ * the standard GNU Radio configuration files in
+ * prefix/etc/gnuradio/conf.d as well as ~/.gnuradio/config.conf.
+ *
+ * Only access this through the singleton defined here:
+ * \code
+ * prefs *p = prefs::singleton();
+ * \endcode
+ */
prefs();
+
virtual ~prefs();
/*!
+ * If specifying a file name, this opens that specific
+ * configuration file of the standard form containing sections and
+ * key-value pairs:
+ *
+ * \code
+ * [SectionName]
+ * key0 = value0
+ * key1 = value1
+ * \endcode
+ */
+ void add_config_file(const std::string &configfile);
+
+ /*!
* \brief Returns the configuration options as a string.
*/
std::string to_string();
@@ -137,7 +165,7 @@ namespace gr {
protected:
virtual std::vector<std::string> _sys_prefs_filenames();
- virtual void _read_files();
+ virtual std::string _read_files(const std::vector<std::string> &filenames);
virtual void _convert_to_map(const std::string &conf);
virtual char * option_to_env(std::string section, std::string option);
diff --git a/gnuradio-runtime/include/gnuradio/rpcbufferedget.h b/gnuradio-runtime/include/gnuradio/rpcbufferedget.h
new file mode 100644
index 0000000000..ebd740b1f8
--- /dev/null
+++ b/gnuradio-runtime/include/gnuradio/rpcbufferedget.h
@@ -0,0 +1,65 @@
+/* -*- 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.
+ */
+
+#ifndef RPCBUFFEREDGET_H
+#define RPCBUFFEREDGET_H
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/mutex.hpp>
+#include <stdio.h>
+
+template<typename TdataType>
+class rpcbufferedget {
+public:
+ rpcbufferedget(const unsigned int init_buffer_size = 4096) :
+ d_data_needed(false), d_data_ready(), d_buffer_lock(), d_buffer(init_buffer_size) {;}
+
+ ~rpcbufferedget() {
+ d_data_ready.notify_all();
+ }
+
+ void offer_data(const TdataType& data) {
+ if (!d_data_needed)
+ return;
+ {
+ boost::mutex::scoped_lock lock(d_buffer_lock);
+ d_buffer = data;
+ d_data_needed = false;
+ }
+ d_data_ready.notify_one();
+ }
+
+ TdataType get() {
+ d_data_needed = true;
+ boost::mutex::scoped_lock lock(d_buffer_lock);
+ d_data_ready.wait(lock);
+ return d_buffer;
+ }
+
+private:
+ bool d_data_needed;
+ boost::condition_variable d_data_ready;
+ boost::mutex d_buffer_lock;
+ TdataType d_buffer;
+};
+
+#endif
diff --git a/gnuradio-runtime/include/gnuradio/rpcmanager.h b/gnuradio-runtime/include/gnuradio/rpcmanager.h
index 5635572a8b..e7ee4c4942 100644
--- a/gnuradio-runtime/include/gnuradio/rpcmanager.h
+++ b/gnuradio-runtime/include/gnuradio/rpcmanager.h
@@ -54,7 +54,7 @@ class GR_RUNTIME_API rpcmanager : public virtual rpcmanager_base
static bool booter_registered;
static bool aggregator_registered;
static void rpcserver_booter_base_sptr_dest(rpcserver_booter_base* b) {;}
- static rpcserver_booter_base* boot;
+ static std::auto_ptr<rpcserver_booter_base> boot;
static std::auto_ptr<rpcserver_booter_aggregator> aggregator;
};
diff --git a/gnuradio-runtime/include/gnuradio/rpcpmtconverters_thrift.h b/gnuradio-runtime/include/gnuradio/rpcpmtconverters_thrift.h
new file mode 100644
index 0000000000..6523165a11
--- /dev/null
+++ b/gnuradio-runtime/include/gnuradio/rpcpmtconverters_thrift.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#ifndef RPCPMTCONVERTERS_THRIFT_H
+#define RPCPMTCONVERTERS_THRIFT_H
+
+#include <pmt/pmt.h>
+#include <boost/noncopyable.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+#include "thrift/gnuradio_types.h"
+
+
+namespace rpcpmtconverter
+{
+ GNURadio::Knob from_pmt(const pmt::pmt_t& knob);
+
+ struct to_pmt_f {
+ to_pmt_f() {;}
+ virtual pmt::pmt_t operator()(const GNURadio::Knob& knob);
+ };
+
+ struct to_pmt_byte_f : public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_short_f : public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_int_f : public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_long_f : public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_double_f : public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_string_f : public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_bool_f : public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_complex_f: public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_f32vect_f: public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_f64vect_f: public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_s64vect_f: public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_s32vect_f: public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_s16vect_f: public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_s8vect_f : public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+ struct to_pmt_c32vect_f: public to_pmt_f { pmt::pmt_t operator()(const GNURadio::Knob& knob); };
+
+ class To_PMT : private boost::noncopyable {
+ public:
+ static To_PMT instance;
+ template<typename TO_PMT_F> friend struct to_pmt_reg;
+ pmt::pmt_t operator()(const GNURadio::Knob& knob);
+
+ protected:
+ boost::ptr_map<GNURadio::BaseTypes::type, to_pmt_f> to_pmt_map;
+
+ private:
+ To_PMT() {;}
+ };
+
+ template<typename TO_PMT_F> struct to_pmt_reg {
+ to_pmt_reg(To_PMT& instance, const GNURadio::BaseTypes::type type);
+ };
+}
+
+#endif /* RPCPMTCONVERTERS_THRIFT_H */
diff --git a/gnuradio-runtime/include/gnuradio/rpcregisterhelpers.h b/gnuradio-runtime/include/gnuradio/rpcregisterhelpers.h
index 0999dea747..f82f5ed0aa 100644
--- a/gnuradio-runtime/include/gnuradio/rpcregisterhelpers.h
+++ b/gnuradio-runtime/include/gnuradio/rpcregisterhelpers.h
@@ -672,7 +672,7 @@ struct rpcbasic_register_set : public rpcbasic_base
d_minpriv = minpriv_;
d_display = display_;
d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
-#ifdef RPCSERVER_ENABLED
+#ifdef GR_RPCSERVER_ENABLED
callbackregister_base::configureCallback_t
extractor(new rpcbasic_extractor<T,Tto>(d_object, function),
minpriv_, std::string(units_),
@@ -726,7 +726,7 @@ struct rpcbasic_register_set : public rpcbasic_base
d_minpriv = minpriv_;
d_display = display_;
d_object = obj;
-#ifdef RPCSERVER_ENABLED
+#ifdef GR_RPCSERVER_ENABLED
callbackregister_base::configureCallback_t
extractor(new rpcbasic_extractor<T,Tto>(d_object, function),
minpriv_, std::string(units_),
@@ -741,7 +741,7 @@ struct rpcbasic_register_set : public rpcbasic_base
~rpcbasic_register_set()
{
-#ifdef RPCSERVER_ENABLED
+#ifdef GR_RPCSERVER_ENABLED
rpcmanager::get()->i()->unregisterConfigureCallback(d_id);
#endif
}
@@ -830,7 +830,7 @@ struct rpcbasic_register_trigger : public rpcbasic_base
d_desc = desc_;
d_minpriv = minpriv_;
d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
-#ifdef RPCSERVER_ENABLED
+#ifdef GR_RPCSERVER_ENABLED
callbackregister_base::configureCallback_t
extractor(new rpcbasic_extractor<T,void>(d_object, function),
minpriv_, std::string(desc_));
@@ -870,7 +870,7 @@ struct rpcbasic_register_trigger : public rpcbasic_base
d_desc = desc_;
d_minpriv = minpriv_;
d_object = obj;
-#ifdef RPCSERVER_ENABLED
+#ifdef GR_RPCSERVER_ENABLED
callbackregister_base::configureCallback_t
extractor(new rpcbasic_extractor<T,void>(d_object, function),
minpriv_, std::string(desc_));
@@ -884,7 +884,7 @@ struct rpcbasic_register_trigger : public rpcbasic_base
~rpcbasic_register_trigger()
{
-#ifdef RPCSERVER_ENABLED
+#ifdef GR_RPCSERVER_ENABLED
rpcmanager::get()->i()->unregisterConfigureCallback(d_id);
#endif
}
@@ -988,7 +988,7 @@ public:
d_minpriv = minpriv_;
d_display = display_;
d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
-#ifdef RPCSERVER_ENABLED
+#ifdef GR_RPCSERVER_ENABLED
callbackregister_base::queryCallback_t
inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function),
minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
@@ -1022,7 +1022,7 @@ public:
d_minpriv = minpriv_;
d_display = display_;
d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get());
-#ifdef RPCSERVER_ENABLED
+#ifdef GR_RPCSERVER_ENABLED
callbackregister_base::queryCallback_t
inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function),
minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
@@ -1076,7 +1076,7 @@ public:
d_minpriv = minpriv_;
d_display = display_;
d_object = obj;
-#ifdef RPCSERVER_ENABLED
+#ifdef GR_RPCSERVER_ENABLED
callbackregister_base::queryCallback_t
inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function),
minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
@@ -1111,7 +1111,7 @@ public:
d_minpriv = minpriv_;
d_display = display_;
d_object = obj;
-#ifdef RPCSERVER_ENABLED
+#ifdef GR_RPCSERVER_ENABLED
callbackregister_base::queryCallback_t
inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function),
minpriv_, std::string(units_), display_, std::string(desc_), min, max, def);
@@ -1125,7 +1125,7 @@ public:
~rpcbasic_register_get()
{
-#ifdef RPCSERVER_ENABLED
+#ifdef GR_RPCSERVER_ENABLED
rpcmanager::get()->i()->unregisterQueryCallback(d_id);
#endif
}
diff --git a/gnuradio-runtime/include/gnuradio/rpcserver_booter_thrift.h b/gnuradio-runtime/include/gnuradio/rpcserver_booter_thrift.h
new file mode 100644
index 0000000000..28900a4670
--- /dev/null
+++ b/gnuradio-runtime/include/gnuradio/rpcserver_booter_thrift.h
@@ -0,0 +1,52 @@
+/* -*- 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.
+ */
+
+#ifndef RPCSERVER_BOOTER_THRIFT_H
+#define RPCSERVER_BOOTER_THRIFT_H
+
+#include <gnuradio/rpcserver_booter_base.h>
+#include <gnuradio/thrift_server_template.h>
+#include "thrift/ControlPort.h"
+
+class rpcserver_base;
+class rpcserver_thrift;
+
+class rpcserver_booter_thrift
+ : public virtual rpcserver_booter_base,
+ public virtual thrift_server_template<rpcserver_base,
+ rpcserver_thrift,
+ rpcserver_booter_thrift,
+ boost::shared_ptr<GNURadio::ControlPortIf> >
+{
+ public:
+ rpcserver_booter_thrift();
+ ~rpcserver_booter_thrift();
+
+ rpcserver_base* i();
+ const std::string & type() {return d_type;}
+ const std::vector<std::string> endpoints();
+
+ private:
+ std::string d_type;
+};
+
+#endif /* RPCSERVER_BOOTER_THRIFT_H */
diff --git a/gnuradio-runtime/include/gnuradio/rpcserver_selector.h b/gnuradio-runtime/include/gnuradio/rpcserver_selector.h
index 8a14f78d99..31ab6cea0b 100644
--- a/gnuradio-runtime/include/gnuradio/rpcserver_selector.h
+++ b/gnuradio-runtime/include/gnuradio/rpcserver_selector.h
@@ -23,10 +23,12 @@
#ifndef RPCSERVER_SELECTOR
#define RPCSERVER_SELECTOR
-//#define RPCSERVER_ENABLED
+#include <gnuradio/config.h>
-//#define RPCSERVER_ICE
-//#define RPCSERVER_ERLANG
-//#define RPCSERVER_XMLRPC
+//#define GR_RPCSERVER_ENABLED
+//#define GR_RPCSERVER_ICE
+//#define GR_RPCSERVER_THRIFT
+//#define GR_RPCSERVER_ERLANG
+//#define GR_RPCSERVER_XMLRPC
#endif
diff --git a/gnuradio-runtime/include/gnuradio/rpcserver_thrift.h b/gnuradio-runtime/include/gnuradio/rpcserver_thrift.h
new file mode 100644
index 0000000000..027a9ea75e
--- /dev/null
+++ b/gnuradio-runtime/include/gnuradio/rpcserver_thrift.h
@@ -0,0 +1,230 @@
+/* -*- 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.
+ */
+
+#ifndef RPCSERVER_THRIFT_H
+#define RPCSERVER_THRIFT_H
+
+#include <gnuradio/rpcserver_base.h>
+#include <gnuradio/rpcpmtconverters_thrift.h>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <map>
+#include "thrift/ControlPort.h"
+#include "thrift/gnuradio_types.h"
+#include <boost/format.hpp>
+
+#define S(x) #x
+#define S_(x) S(x)
+#define S__LINE__ S_(__LINE__)
+
+class rpcserver_thrift : public virtual rpcserver_base, public GNURadio::ControlPortIf
+{
+public:
+ rpcserver_thrift();
+ virtual ~rpcserver_thrift();
+
+ void registerConfigureCallback(const std::string &id,
+ const configureCallback_t callback);
+ void unregisterConfigureCallback(const std::string &id);
+
+ void registerQueryCallback(const std::string &id,
+ const queryCallback_t callback);
+ void unregisterQueryCallback(const std::string &id);
+
+ void setKnobs(const GNURadio::KnobMap&);
+ void getKnobs(GNURadio::KnobMap&,
+ const GNURadio::KnobIDList&);
+ void getRe(GNURadio::KnobMap&,
+ const GNURadio::KnobIDList&);
+ void properties(GNURadio::KnobPropMap&,
+ const GNURadio::KnobIDList& knobs);
+ virtual void shutdown();
+
+ private:
+ typedef std::map<std::string, configureCallback_t> ConfigureCallbackMap_t;
+ ConfigureCallbackMap_t d_setcallbackmap;
+
+ typedef std::map<std::string, queryCallback_t> QueryCallbackMap_t;
+ QueryCallbackMap_t d_getcallbackmap;
+
+ template<typename T, typename TMap> struct set_f
+ : public std::unary_function<T,void>
+ {
+ set_f(TMap &_setcallbackmap, const priv_lvl_t &_cur_priv)
+ : d_setcallbackmap(_setcallbackmap), cur_priv(_cur_priv)
+ {
+ ;
+ }
+
+ void operator()(const T& p)
+ {
+ ConfigureCallbackMap_t::const_iterator iter(d_setcallbackmap.find(p.first));
+ if(iter != d_setcallbackmap.end()) {
+ if(cur_priv <= iter->second.priv) {
+ (*iter->second.callback).post(pmt::PMT_NIL, rpcpmtconverter::To_PMT::instance(p.second));
+ }
+ else {
+ std::cout << "Key " << p.first << " requires PRIVLVL <= "
+ << iter->second.priv << " to set, currently at: "
+ << cur_priv << std::endl;
+ }
+ }
+ else {
+ throw apache::thrift::TApplicationException(__FILE__ " " S__LINE__);
+ }
+ }
+
+ TMap& d_setcallbackmap;
+ const priv_lvl_t& cur_priv;
+ };
+
+ template<typename T, typename TMap>
+ struct get_f : public std::unary_function<T,void>
+ {
+ get_f(TMap &_getcallbackmap, const priv_lvl_t &_cur_priv, GNURadio::KnobMap &_outknobs) :
+ d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs)
+ {}
+
+ void operator()(const T& p)
+ {
+ QueryCallbackMap_t::const_iterator iter(d_getcallbackmap.find(p));
+ if(iter != d_getcallbackmap.end()) {
+ if(cur_priv <= iter->second.priv) {
+ outknobs[p] = rpcpmtconverter::from_pmt((*iter->second.callback).retrieve());
+ }
+ else {
+ std::cout << "Key " << iter->first << " requires PRIVLVL: <= "
+ << iter->second.priv << " to get, currently at: "
+ << cur_priv << std::endl;
+ }
+ }
+ else {
+ std::stringstream ss;
+ ss << "Ctrlport Key called with unregistered key (" << p << ")\n";
+ std::cout << ss.str();
+ throw apache::thrift::TApplicationException(__FILE__ " " S__LINE__);
+ }
+ }
+
+ TMap& d_getcallbackmap;
+ const priv_lvl_t& cur_priv;
+ GNURadio::KnobMap& outknobs;
+ };
+
+ template<typename T, typename TMap, typename TKnobMap>
+ struct get_all_f : public std::unary_function<T,void>
+ {
+ get_all_f(TMap &_getcallbackmap, const priv_lvl_t &_cur_priv, TKnobMap &_outknobs) :
+ d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs)
+ {;}
+
+ void operator()(const T& p)
+ {
+ if(cur_priv <= p.second.priv) {
+ outknobs[p.first] = rpcpmtconverter::from_pmt(p.second.callback->retrieve());
+ }
+ else {
+ std::cout << "Key " << p.first << " requires PRIVLVL <= "
+ << p.second.priv << " to get, currently at: "
+ << cur_priv << std::endl;
+ }
+ }
+
+ TMap& d_getcallbackmap;
+ const priv_lvl_t& cur_priv;
+ TKnobMap& outknobs;
+ };
+
+ template<typename T, typename TMap, typename TKnobMap>
+ struct properties_all_f : public std::unary_function<T,void>
+ {
+ properties_all_f(QueryCallbackMap_t &_getcallbackmap,
+ const priv_lvl_t &_cur_priv,
+ GNURadio::KnobPropMap &_outknobs)
+ : d_getcallbackmap(_getcallbackmap),
+ cur_priv(_cur_priv),
+ outknobs(_outknobs)
+ {;}
+
+ void operator()(const T& p)
+ {
+ if(cur_priv <= p.second.priv) {
+ GNURadio::KnobProp prop;
+ prop.type = GNURadio::KnobType::KNOBDOUBLE;
+ prop.units = p.second.units;
+ prop.description = p.second.description;
+ prop.min = rpcpmtconverter::from_pmt(p.second.min);
+ prop.max = rpcpmtconverter::from_pmt(p.second.max);
+ prop.display = static_cast<uint32_t>(p.second.display);
+ outknobs[p.first] = prop;
+ }
+ else {
+ std::cout << "Key " << p.first << " requires PRIVLVL <= "
+ << p.second.priv << " to get, currently at: "
+ << cur_priv << std::endl;
+ }
+ }
+
+ TMap& d_getcallbackmap;
+ const priv_lvl_t& cur_priv;
+ TKnobMap& outknobs;
+ };
+
+ template<class T, typename TMap, typename TKnobMap>
+ struct properties_f : public std::unary_function<T,void>
+ {
+ properties_f(TMap &_getcallbackmap, const priv_lvl_t &_cur_priv, TKnobMap &_outknobs) :
+ d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs)
+ {;}
+
+ void operator()(const T& p)
+ {
+ typename TMap::const_iterator iter(d_getcallbackmap.find(p));
+ if(iter != d_getcallbackmap.end()) {
+ if(cur_priv <= iter->second.priv) {
+ GNURadio::KnobProp prop;
+ prop.type = GNURadio::KnobType::KNOBDOUBLE;
+ prop.units = iter->second.units;
+ prop.description = iter->second.description;
+ prop.min = rpcpmtconverter::from_pmt(iter->second.min);
+ prop.max = rpcpmtconverter::from_pmt(iter->second.max);
+ prop.display = static_cast<uint32_t>(iter->second.display);
+ outknobs[p] = prop;
+ }
+ else {
+ std::cout << "Key " << iter->first << " requires PRIVLVL: <= "
+ << iter->second.priv << " to get, currently at: " << cur_priv << std::endl;
+ }
+ }
+ else {
+ throw apache::thrift::TApplicationException(__FILE__ " " S__LINE__);
+ }
+ }
+
+ TMap& d_getcallbackmap;
+ const priv_lvl_t& cur_priv;
+ TKnobMap& outknobs;
+ };
+};
+
+#endif /* RPCSERVER_THRIFT_H */
diff --git a/gnuradio-runtime/include/gnuradio/thrift_application_base.h b/gnuradio-runtime/include/gnuradio/thrift_application_base.h
new file mode 100644
index 0000000000..aa50c55dc8
--- /dev/null
+++ b/gnuradio-runtime/include/gnuradio/thrift_application_base.h
@@ -0,0 +1,253 @@
+/* -*- 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.
+ */
+
+#ifndef THRIFT_APPLICATION_BASE_H
+#define THRIFT_APPLICATION_BASE_H
+
+#include <gnuradio/api.h>
+#include <gnuradio/logger.h>
+#include <gnuradio/prefs.h>
+#include <gnuradio/thread/thread.h>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+namespace {
+ // Time, in milliseconds, to wait between checks to the Thrift runtime to see if
+ // it has fully initialized.
+ static const unsigned int THRIFTAPPLICATION_ACTIVATION_TIMEOUT_MS(200);
+};
+
+namespace apache { namespace thrift { namespace server { class TServer; } } }
+
+/*!
+ * \brief Class to be statically initialized by thrift_application_base. Used
+ * to store state for thrift_application_base's singleton functions.
+ */
+
+class thrift_application_base_impl
+{
+public:
+ thrift_application_base_impl() :
+ d_application_initilized(false),
+ d_endpointStr(""),
+ d_start_thrift_thread() {;}
+
+ // Used to ensure the Thrift runtime is initialized on the first call to ::i().
+ bool d_application_initilized;
+ // Stores the generated endpoint string after the Thrift runtime has initialized.
+ std::string d_endpointStr;
+ // Thread to execute the Thrift runtime's blocking serve() function.
+ boost::shared_ptr<gr::thread::thread> d_start_thrift_thread;
+};
+
+/*!
+ * \brief Base class for a Thrift application with a singleton with
+ * instance function thrift_application_base::i(). Lazy initialization
+ * is used to start the Thrift runtime, therefore the Thrift runtime
+ * is not started unless thrift_application_base::i() is called at
+ * least once. This typically means that at least one rpc variable
+ * must be registered by a block before the runtime will start.
+ *
+ * \param TserverBase Template parameter naming the type of the server
+ * base, which is typically rpcserverbase.
+ * \param TserverClass Template parameter naming the eventual type of
+ * the fully derived application.
+ * \param _app Reference to the fully derived application instance to
+ * be returned by thrift_application_base::i().
+ */
+
+template<typename TserverBase, typename TserverClass>
+class thrift_application_base
+{
+public:
+ thrift_application_base(TserverClass* _app);
+
+ /*!
+ * Destructor for the application. Since shutdown and cleanup of the
+ * runtime is typically custom to a particular booter
+ * implementation, this must be implemented as a specalized function
+ * for a particular booter. Thus a template implementation is not
+ * provided here.
+ */
+ ~thrift_application_base();
+
+ /*!
+ * The application singleton instance function.
+ */
+ static TserverBase* i();
+
+ /*!
+ * Returns the endpoint string of this application.
+ */
+ static const std::vector<std::string> endpoints();
+
+protected:
+ /*!
+ * Allows this application's booter to set the endpoint string after
+ * the Thrift runtime has initialized.
+ *
+ * \param[in] endpoint The endpoint string reported by this class.
+ */
+ void set_endpoint(const std::string& endpoint);
+
+ virtual TserverBase* i_impl() = 0;
+
+ /*!
+ * Reference to the fully derived application instance.
+ */
+ static TserverClass* d_application;
+
+ /*!
+ * Reference to the Thrift runtime.
+ */
+ std::auto_ptr<apache::thrift::server::TServer> d_thriftserver;
+
+ /*!
+ * Max number of attempts when checking the Thrift runtime for
+ * Initialization before giving up. Set in the Thrift config file
+ * (see \ref ctrlport_thrift_prefs).
+ */
+ static const unsigned int d_default_max_init_attempts;
+
+ /*!
+ * Default port for the runtime to listen on, if a static port is
+ * not specified. Set in the Thrift config file (see \ref
+ * ctrlport_thrift_prefs).
+ */
+ static const unsigned int d_default_thrift_port;
+
+ /*!
+ * Maximum number of threads to create when serving multiple rpc
+ * clients. Set in the Thrift config file (see \ref
+ * ctrlport_thrift_prefs).
+ */
+ static const unsigned int d_default_num_thrift_threads;
+
+ /*!
+ * Default packet size for the IP payload of thrift packets. Set in
+ * the Thrift config file (see \ref ctrlport_thrift_prefs).
+ */
+ static const unsigned int d_default_thrift_buffer_size;
+
+ /*!
+ * \ref page_logger instances.
+ */
+ gr::logger_ptr d_logger, d_debug_logger;
+
+private:
+
+ // Function to be called in a separate thread to invoke the blocking
+ // ThriftServer::serve() function. Must be specialized for a particular
+ // booter implementation, therefore a template implementation is
+ // not provided here.
+ void start_thrift();
+
+ // Non-blocking function that returns true when the Thrift
+ // runtime has finished initialization. Must be implemented
+ // as a specialized template function for a particular booter
+ // implementation, therefore template implementation is not
+ // provided here.
+ bool application_started();
+
+ // Internal function to start the initialization of the runtime.
+ // Since this singleton uses lazy instantiation, this function
+ // will be called on the first call to the instance function ::i(),
+ // and since ::i() is static, this function must be static as well.
+ static void start_application();
+
+ // Pointer to the structure containing staticly allocated
+ // state information for the applicaiton_base singleton.
+ static std::auto_ptr<thrift_application_base_impl > p_impl;
+
+ // Mutex to protect the endpoint string.
+ gr::thread::mutex d_lock;
+
+ // Will be set to true by a the application_started() function,
+ // specialized for a particular booter implementation, once the
+ // thrift runtime has successfully initialized.
+ bool d_thirft_is_running;
+};
+
+template<typename TserverBase, typename TserverClass>
+TserverClass* thrift_application_base<TserverBase, TserverClass>::d_application(0);
+
+template<typename TserverBase, typename TserverClass>
+thrift_application_base<TserverBase, TserverClass>::thrift_application_base(TserverClass* _app)
+ : d_lock(),
+ d_thirft_is_running(false)
+{
+ gr::configure_default_loggers(d_logger, d_debug_logger, "controlport");
+ d_application = _app;
+ //GR_LOG_DEBUG(d_debug_logger, "thrift_application_base: ctor");
+}
+
+template<typename TserverBase, typename TserverClass>
+void thrift_application_base<TserverBase, TserverClass>::start_application()
+{
+ //std::cerr << "thrift_application_base: start_application" << std::endl;
+
+ unsigned int max_init_attempts = \
+ static_cast<unsigned int>(gr::prefs::singleton()->get_long("thrift", "init_attempts",
+ d_default_max_init_attempts));
+
+ if(!p_impl->d_application_initilized) {
+ p_impl->d_start_thrift_thread.reset(
+ (new gr::thread::thread(boost::bind(&thrift_application_base::start_thrift, d_application))));
+
+ bool app_started(false);
+ for(unsigned int attempts(0); (!app_started && attempts < max_init_attempts); ++attempts) {
+ boost::this_thread::sleep(boost::posix_time::milliseconds(THRIFTAPPLICATION_ACTIVATION_TIMEOUT_MS));
+ app_started = d_application->application_started();
+ }
+
+ if(!app_started) {
+ std::cerr << "thrift_application_base::start_application(), timeout waiting to port number might have failed?" << std::endl;
+ }
+
+ p_impl->d_application_initilized = true;
+ }
+}
+
+template<typename TserverBase, typename TserverClass>
+const std::vector<std::string> thrift_application_base<TserverBase, TserverClass>::endpoints()
+{
+ std::vector<std::string> ep;
+ ep.push_back(p_impl->d_endpointStr);
+ return ep;
+}
+
+template<typename TserverBase, typename TserverClass>
+void thrift_application_base<TserverBase, TserverClass>::set_endpoint(const std::string& endpoint)
+{
+ gr::thread::scoped_lock guard(d_lock);
+ p_impl->d_endpointStr = endpoint;
+}
+
+template<typename TserverBase, typename TserverClass>
+TserverBase* thrift_application_base<TserverBase, TserverClass>::i()
+{
+ if(!p_impl->d_application_initilized) {
+ start_application();
+ }
+ return d_application->i_impl();
+}
+
+#endif
diff --git a/gnuradio-runtime/include/gnuradio/thrift_server_template.h b/gnuradio-runtime/include/gnuradio/thrift_server_template.h
new file mode 100644
index 0000000000..1e9059d920
--- /dev/null
+++ b/gnuradio-runtime/include/gnuradio/thrift_server_template.h
@@ -0,0 +1,160 @@
+/* -*- 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.
+ */
+
+#ifndef THRIFT_SERVER_TEMPLATE_H
+#define THRIFT_SERVER_TEMPLATE_H
+
+#include <gnuradio/prefs.h>
+#include <gnuradio/logger.h>
+#include <gnuradio/rpcserver_thrift.h>
+#include <gnuradio/thrift_application_base.h>
+#include <iostream>
+
+#include <thrift/server/TSimpleServer.h>
+#include <thrift/server/TThreadPoolServer.h>
+#include <thrift/concurrency/ThreadManager.h>
+#include <thrift/concurrency/PlatformThreadFactory.h>
+#include <thrift/transport/TServerSocket.h>
+#include <thrift/transport/TBufferTransports.h>
+#include "thrift/ControlPort.h"
+
+using namespace apache;
+
+template<typename TserverBase, typename TserverClass, typename TImplClass, typename TThriftClass>
+class thrift_server_template : public thrift_application_base<TserverBase, TImplClass>
+{
+public:
+ thrift_server_template(TImplClass* _this);
+ ~thrift_server_template();
+
+protected:
+ TserverBase* i_impl();
+ friend class thrift_application_base<TserverBase, TImplClass>;
+
+ TserverBase* d_server;
+
+private:
+ /**
+ * Custom TransportFactory that allows you to override the default Thrift buffer size
+ * of 512 bytes.
+ *
+ */
+ class TBufferedTransportFactory : public thrift::transport::TTransportFactory
+ {
+ public:
+ TBufferedTransportFactory(const unsigned int _bufferSize) : bufferSize(_bufferSize) {;}
+
+ virtual ~TBufferedTransportFactory() {}
+
+ virtual boost::shared_ptr<thrift::transport::TTransport> getTransport(
+ boost::shared_ptr<thrift::transport::TTransport> trans)
+ {
+ return boost::shared_ptr<thrift::transport::TTransport>
+ (new thrift::transport::TBufferedTransport(trans, bufferSize));
+ }
+ private:
+ unsigned int bufferSize;
+ };
+};
+
+template<typename TserverBase, typename TserverClass, typename TImplClass, typename TThriftClass>
+thrift_server_template<TserverBase, TserverClass, TImplClass, TThriftClass>::thrift_server_template
+(TImplClass* _this) : thrift_application_base<TserverBase, TImplClass>(_this)
+{
+ gr::logger_ptr logger, debug_logger;
+ gr::configure_default_loggers(logger, debug_logger, "controlport");
+
+ unsigned int port, nthreads, buffersize;
+ std::string thrift_config_file = gr::prefs::singleton()->get_string("ControlPort", "config", "");
+
+ if(thrift_config_file.length() > 0) {
+ gr::prefs::singleton()->add_config_file(thrift_config_file);
+ }
+
+ // Collect configuration options from the Thrift config file;
+ // defaults if the config file doesn't exist or list the specific
+ // options.
+ port = static_cast<unsigned int>(gr::prefs::singleton()->get_long("thrift", "port",
+ thrift_application_base<TserverBase, TImplClass>::d_default_thrift_port));
+ nthreads = static_cast<unsigned int>(gr::prefs::singleton()->get_long("thrift", "nthreads",
+ thrift_application_base<TserverBase, TImplClass>::d_default_num_thrift_threads));
+ buffersize = static_cast<unsigned int>(gr::prefs::singleton()->get_long("thrift", "buffersize",
+ thrift_application_base<TserverBase, TImplClass>::d_default_thrift_buffer_size));
+
+ boost::shared_ptr<TserverClass> handler(new TserverClass());
+
+ boost::shared_ptr<thrift::TProcessor>
+ processor(new GNURadio::ControlPortProcessor(handler));
+
+ boost::shared_ptr<thrift::transport::TServerTransport>
+ serverTransport(new thrift::transport::TServerSocket(port));
+
+ boost::shared_ptr<thrift::transport::TTransportFactory>
+ transportFactory(new thrift_server_template::TBufferedTransportFactory(buffersize));
+
+ boost::shared_ptr<thrift::protocol::TProtocolFactory>
+ protocolFactory(new thrift::protocol::TBinaryProtocolFactory());
+
+
+ if(nthreads <= 1) {
+ // "Thrift: Single-threaded server"
+ //std::cout << "Thrift Single-threaded server" << std::endl;
+ thrift_application_base<TserverBase, TImplClass>::d_thriftserver.reset(
+ new thrift::server::TSimpleServer(processor, serverTransport,
+ transportFactory, protocolFactory));
+ }
+ else {
+ //std::cout << "Thrift Multi-threaded server : " << nthreads << std::endl;
+ boost::shared_ptr<thrift::concurrency::ThreadManager> threadManager
+ (thrift::concurrency::ThreadManager::newSimpleThreadManager(nthreads));
+
+ boost::shared_ptr<thrift::concurrency::PlatformThreadFactory> threadFactory
+ (boost::shared_ptr<thrift::concurrency::PlatformThreadFactory>
+ (new thrift::concurrency::PlatformThreadFactory()));
+
+ threadManager->threadFactory(threadFactory);
+
+ threadManager->start();
+
+ thrift_application_base<TserverBase, TImplClass>::d_thriftserver.reset(
+ new thrift::server::TThreadPoolServer(processor, serverTransport,
+ transportFactory, protocolFactory,
+ threadManager));
+ }
+
+ d_server = handler.get();
+}
+
+template<typename TserverBase, typename TserverClass, typename TImplClass, typename TThriftClass>
+thrift_server_template<TserverBase, TserverClass,TImplClass, TThriftClass>::~thrift_server_template()
+{
+}
+
+template<typename TserverBase, typename TserverClass, typename TImplClass, typename TThriftClass>
+TserverBase* thrift_server_template<TserverBase, TserverClass, TImplClass, TThriftClass>::i_impl()
+{
+ //std::cerr << "thrift_server_template: i_impl" << std::endl;
+
+ return d_server;
+}
+
+#endif /* THRIFT_SERVER_TEMPLATE_H */