GNU Radio Manual and C++ API Reference  3.7.9.2
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
rpcserver_thrift.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2014,2015 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef RPCSERVER_THRIFT_H
24 #define RPCSERVER_THRIFT_H
25 
28 #include <string>
29 #include <iostream>
30 #include <sstream>
31 #include <map>
32 #include "thrift/ControlPort.h"
33 #include "thrift/gnuradio_types.h"
34 #include <boost/format.hpp>
35 #include <boost/thread/mutex.hpp>
36 
37 #define S(x) #x
38 #define S_(x) S(x)
39 #define S__LINE__ S_(__LINE__)
40 
42  : public virtual rpcserver_base,
43  public GNURadio::ControlPortIf
44 {
45 public:
47  virtual ~rpcserver_thrift();
48 
49  void registerConfigureCallback(const std::string &id,
50  const configureCallback_t callback);
51  void unregisterConfigureCallback(const std::string &id);
52 
53  void registerQueryCallback(const std::string &id,
54  const queryCallback_t callback);
55  void unregisterQueryCallback(const std::string &id);
56 
57  void registerHandlerCallback(const std::string &id,
58  const handlerCallback_t callback);
59  void unregisterHandlerCallback(const std::string &id);
60 
61  void setKnobs(const GNURadio::KnobMap&);
62  void getKnobs(GNURadio::KnobMap&,
63  const GNURadio::KnobIDList&);
64  void getRe(GNURadio::KnobMap&,
65  const GNURadio::KnobIDList&);
66  void properties(GNURadio::KnobPropMap&,
67  const GNURadio::KnobIDList& knobs);
68 
69  /*!
70  * \brief Call this to post a message to the \p port for the block
71  * identified by \p alias.
72  *
73  * The message, \p msg, is passed as a serialized PMT that is then
74  * passed to the message handler function identified by \p port to
75  * the block identified by \p alias. The \p alias and \p port
76  * values are passed as serialized PMT symbols (see
77  * pmt::intern). The message is whatever PMT format is appropriate
78  * for the message handler function.
79  *
80  * To use this function, the message handler function must have
81  * been registered (most likely in setup_rpc) in the block during
82  * construction using rpcbasic_register_handler.
83  *
84  * \param alias The alias of the block, which is used to map to the
85  * real block through the global_block_registry. Passed in
86  * as a serialized PMT symbol.
87  * \param port The name of the message port. Passed in as a
88  * serialized PMT symbol.
89  * \param msg The actual message to pass to \p port. This is a
90  * serialized PMT where the PMT is whatever form appropriate
91  * for the message handler function.
92  */
93  void postMessage(const std::string& alias,
94  const std::string& port,
95  const std::string& msg);
96 
97  virtual void shutdown();
98 
99  private:
100  boost::mutex d_callback_map_lock;
101 
102  typedef std::map<std::string, configureCallback_t> ConfigureCallbackMap_t;
103  ConfigureCallbackMap_t d_setcallbackmap;
104 
105  typedef std::map<std::string, queryCallback_t> QueryCallbackMap_t;
106  QueryCallbackMap_t d_getcallbackmap;
107 
108  typedef std::map<std::string, handlerCallback_t> HandlerCallbackMap_t;
109  HandlerCallbackMap_t d_handlercallbackmap;
110 
111  /*!
112  * \brief Manages calling the callback function for a message handler posting.
113  */
114  void
115  set_h(const handlerCallback_t &_handlerCallback,
116  const priv_lvl_t &_cur_priv,
117  pmt::pmt_t port, pmt::pmt_t msg)
118  {
119  if(cur_priv <= _handlerCallback.priv) {
120  _handlerCallback.callback->post(port, msg);
121  }
122  else {
123  std::cerr << "Message " << _handlerCallback.description << " requires PRIVLVL <= "
124  << _handlerCallback.priv << " to set, currently at: "
125  << cur_priv << std::endl;
126  }
127  }
128 
129 
130  template<typename T, typename TMap> struct set_f
131  : public std::unary_function<T,void>
132  {
133  set_f(TMap &_setcallbackmap, const priv_lvl_t &_cur_priv)
134  : d_setcallbackmap(_setcallbackmap), cur_priv(_cur_priv)
135  {
136  ;
137  }
138 
139  void operator()(const T& p)
140  {
141  ConfigureCallbackMap_t::const_iterator iter(d_setcallbackmap.find(p.first));
142  if(iter != d_setcallbackmap.end()) {
143  if(cur_priv <= iter->second.priv) {
144  (*iter->second.callback).post(pmt::PMT_NIL, rpcpmtconverter::To_PMT::instance(p.second));
145  }
146  else {
147  std::cerr << "Key " << p.first << " requires PRIVLVL <= "
148  << iter->second.priv << " to set, currently at: "
149  << cur_priv << std::endl;
150  }
151  }
152  else {
153  throw apache::thrift::TApplicationException(__FILE__ " " S__LINE__);
154  }
155  }
156 
157  TMap& d_setcallbackmap;
158  const priv_lvl_t& cur_priv;
159  };
160 
161  template<typename T, typename TMap>
162  struct get_f : public std::unary_function<T,void>
163  {
164  get_f(TMap &_getcallbackmap, const priv_lvl_t &_cur_priv, GNURadio::KnobMap &_outknobs) :
165  d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs)
166  {}
167 
168  void operator()(const T& p)
169  {
170  QueryCallbackMap_t::const_iterator iter(d_getcallbackmap.find(p));
171  if(iter != d_getcallbackmap.end()) {
172  if(cur_priv <= iter->second.priv) {
173  outknobs[p] = rpcpmtconverter::from_pmt((*iter->second.callback).retrieve());
174  }
175  else {
176  std::cerr << "Key " << iter->first << " requires PRIVLVL: <= "
177  << iter->second.priv << " to get, currently at: "
178  << cur_priv << std::endl;
179  }
180  }
181  else {
182  std::stringstream ss;
183  ss << "Ctrlport Key called with unregistered key (" << p << ")\n";
184  std::cerr << ss.str();
185  throw apache::thrift::TApplicationException(__FILE__ " " S__LINE__);
186  }
187  }
188 
189  TMap& d_getcallbackmap;
190  const priv_lvl_t& cur_priv;
191  GNURadio::KnobMap& outknobs;
192  };
193 
194  template<typename T, typename TMap, typename TKnobMap>
195  struct get_all_f : public std::unary_function<T,void>
196  {
197  get_all_f(TMap &_getcallbackmap, const priv_lvl_t &_cur_priv, TKnobMap &_outknobs) :
198  d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs)
199  {;}
200 
201  void operator()(const T& p)
202  {
203  if(cur_priv <= p.second.priv) {
204  outknobs[p.first] = rpcpmtconverter::from_pmt(p.second.callback->retrieve());
205  }
206  else {
207  std::cerr << "Key " << p.first << " requires PRIVLVL <= "
208  << p.second.priv << " to get, currently at: "
209  << cur_priv << std::endl;
210  }
211  }
212 
213  TMap& d_getcallbackmap;
214  const priv_lvl_t& cur_priv;
215  TKnobMap& outknobs;
216  };
217 
218  template<typename T, typename TMap, typename TKnobMap>
219  struct properties_all_f : public std::unary_function<T,void>
220  {
221  properties_all_f(QueryCallbackMap_t &_getcallbackmap,
222  const priv_lvl_t &_cur_priv,
223  GNURadio::KnobPropMap &_outknobs)
224  : d_getcallbackmap(_getcallbackmap),
225  cur_priv(_cur_priv),
226  outknobs(_outknobs)
227  {;}
228 
229  void operator()(const T& p)
230  {
231  if(cur_priv <= p.second.priv) {
232  GNURadio::KnobProp prop;
233  prop.type = GNURadio::KnobType::KNOBDOUBLE;
234  prop.units = p.second.units;
235  prop.description = p.second.description;
236  prop.min = rpcpmtconverter::from_pmt(p.second.min);
237  prop.max = rpcpmtconverter::from_pmt(p.second.max);
238  prop.display = static_cast<uint32_t>(p.second.display);
239  outknobs[p.first] = prop;
240  }
241  else {
242  std::cerr << "Key " << p.first << " requires PRIVLVL <= "
243  << p.second.priv << " to get, currently at: "
244  << cur_priv << std::endl;
245  }
246  }
247 
248  TMap& d_getcallbackmap;
249  const priv_lvl_t& cur_priv;
250  TKnobMap& outknobs;
251  };
252 
253  template<class T, typename TMap, typename TKnobMap>
254  struct properties_f : public std::unary_function<T,void>
255  {
256  properties_f(TMap &_getcallbackmap, const priv_lvl_t &_cur_priv, TKnobMap &_outknobs) :
257  d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs)
258  {;}
259 
260  void operator()(const T& p)
261  {
262  typename TMap::const_iterator iter(d_getcallbackmap.find(p));
263  if(iter != d_getcallbackmap.end()) {
264  if(cur_priv <= iter->second.priv) {
265  GNURadio::KnobProp prop;
266  prop.type = GNURadio::KnobType::KNOBDOUBLE;
267  prop.units = iter->second.units;
268  prop.description = iter->second.description;
269  prop.min = rpcpmtconverter::from_pmt(iter->second.min);
270  prop.max = rpcpmtconverter::from_pmt(iter->second.max);
271  prop.display = static_cast<uint32_t>(iter->second.display);
272  outknobs[p] = prop;
273  }
274  else {
275  std::cerr << "Key " << iter->first << " requires PRIVLVL: <= "
276  << iter->second.priv << " to get, currently at: " << cur_priv << std::endl;
277  }
278  }
279  else {
280  throw apache::thrift::TApplicationException(__FILE__ " " S__LINE__);
281  }
282  }
283 
284  TMap& d_getcallbackmap;
285  const priv_lvl_t& cur_priv;
286  TKnobMap& outknobs;
287  };
288 };
289 
290 #endif /* RPCSERVER_THRIFT_H */
Definition: rpccallbackregister_base.h:80
void registerHandlerCallback(const std::string &id, const handlerCallback_t callback)
void unregisterHandlerCallback(const std::string &id)
void registerQueryCallback(const std::string &id, const queryCallback_t callback)
void properties(GNURadio::KnobPropMap &, const GNURadio::KnobIDList &knobs)
priv_lvl_t
Definition: rpccallbackregister_base.h:46
void registerConfigureCallback(const std::string &id, const configureCallback_t callback)
void getKnobs(GNURadio::KnobMap &, const GNURadio::KnobIDList &)
Definition: rpccallbackregister_base.h:54
callback_t< gr::messages::msg_accepter, gr::messages::msg_accepter_sptr > configureCallback_t
Definition: rpccallbackregister_base.h:100
void postMessage(const std::string &alias, const std::string &port, const std::string &msg)
Call this to post a message to the port for the block identified by alias.
void getRe(GNURadio::KnobMap &, const GNURadio::KnobIDList &)
void unregisterConfigureCallback(const std::string &id)
#define PMT_NIL
Definition: pmt.h:103
Definition: rpcserver_base.h:28
#define S__LINE__
Definition: rpcserver_thrift.h:39
static To_PMT instance
Definition: rpcpmtconverters_thrift.h:59
callback_t< gr::messages::msg_producer, gr::messages::msg_producer_sptr > queryCallback_t
Definition: rpccallbackregister_base.h:101
priv_lvl_t priv
Definition: rpccallbackregister_base.h:73
void unregisterQueryCallback(const std::string &id)
boost::mutex mutex
Definition: thread.h:46
Definition: rpcserver_thrift.h:41
std::string description
Definition: rpccallbackregister_base.h:74
boost::intrusive_ptr< pmt_base > pmt_t
typedef for shared pointer (transparent reference counting). See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
Definition: pmt.h:56
void setKnobs(const GNURadio::KnobMap &)
GNURadio::Knob from_pmt(const pmt::pmt_t &knob)
priv_lvl_t cur_priv
Definition: rpcserver_base.h:47
virtual void shutdown()
virtual ~rpcserver_thrift()
Tsptr callback
Definition: rpccallbackregister_base.h:97