GNU Radio Manual and C++ API Reference  3.10.1.0
The Free & Open Software Radio Ecosystem
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  * SPDX-License-Identifier: GPL-3.0-or-later
8  *
9  */
10 
11 #ifndef RPCSERVER_THRIFT_H
12 #define RPCSERVER_THRIFT_H
13 
14 #include "thrift/ControlPort.h"
15 #include "thrift/gnuradio_types.h"
16 #include <gnuradio/logger.h>
19 #include <boost/format.hpp>
20 #include <boost/thread/mutex.hpp>
21 #include <map>
22 #include <sstream>
23 #include <string>
24 
25 #define S(x) #x
26 #define S_(x) S(x)
27 #define S__LINE__ S_(__LINE__)
28 
29 class rpcserver_thrift : public virtual rpcserver_base, public GNURadio::ControlPortIf
30 {
31 public:
33  virtual ~rpcserver_thrift();
34 
35  void registerConfigureCallback(const std::string& id,
36  const configureCallback_t callback);
37  void unregisterConfigureCallback(const std::string& id);
38 
39  void registerQueryCallback(const std::string& id, const queryCallback_t callback);
40  void unregisterQueryCallback(const std::string& id);
41 
42  void registerHandlerCallback(const std::string& id, const handlerCallback_t callback);
43  void unregisterHandlerCallback(const std::string& id);
44 
45  void setKnobs(const GNURadio::KnobMap&);
46  void getKnobs(GNURadio::KnobMap&, const GNURadio::KnobIDList&);
47  void getRe(GNURadio::KnobMap&, const GNURadio::KnobIDList&);
48  void properties(GNURadio::KnobPropMap&, const GNURadio::KnobIDList& knobs);
49 
50  /*!
51  * \brief Call this to post a message to the \p port for the block
52  * identified by \p alias.
53  *
54  * The message, \p msg, is passed as a serialized PMT that is then
55  * passed to the message handler function identified by \p port to
56  * the block identified by \p alias. The \p alias and \p port
57  * values are passed as serialized PMT symbols (see
58  * pmt::intern). The message is whatever PMT format is appropriate
59  * for the message handler function.
60  *
61  * To use this function, the message handler function must have
62  * been registered (most likely in setup_rpc) in the block during
63  * construction using rpcbasic_register_handler.
64  *
65  * \param alias The alias of the block, which is used to map to the
66  * real block through the global_block_registry. Passed in
67  * as a serialized PMT symbol.
68  * \param port The name of the message port. Passed in as a
69  * serialized PMT symbol.
70  * \param msg The actual message to pass to \p port. This is a
71  * serialized PMT where the PMT is whatever form appropriate
72  * for the message handler function.
73  */
74  void postMessage(const std::string& alias,
75  const std::string& port,
76  const std::string& msg);
77 
78  virtual void shutdown();
79 
80 private:
81  static gr::logger_ptr d_logger;
82  static gr::logger_ptr d_debug_logger;
83 
84  boost::mutex d_callback_map_lock;
85 
86  typedef std::map<std::string, configureCallback_t> ConfigureCallbackMap_t;
87  ConfigureCallbackMap_t d_setcallbackmap;
88 
89  typedef std::map<std::string, queryCallback_t> QueryCallbackMap_t;
90  QueryCallbackMap_t d_getcallbackmap;
91 
92  typedef std::map<std::string, handlerCallback_t> HandlerCallbackMap_t;
93  HandlerCallbackMap_t d_handlercallbackmap;
94 
95  /*!
96  * \brief Manages calling the callback function for a message handler posting.
97  */
98  void set_h(const handlerCallback_t& _handlerCallback,
99  const priv_lvl_t& _cur_priv,
100  pmt::pmt_t port,
101  pmt::pmt_t msg)
102  {
103  if (cur_priv <= _handlerCallback.priv) {
104  _handlerCallback.callback->post(port, msg);
105  } else {
106  std::ostringstream msg;
107  msg << _handlerCallback.description
108  << " requires PRIVLVL <= " << _handlerCallback.priv
109  << " to set, currently at: " << cur_priv;
110  GR_LOG_ERROR(d_logger, msg.str());
111  }
112  }
113 
114 
115  template <typename T, typename TMap>
116  struct set_f : public std::unary_function<T, void> {
117  set_f(TMap& _setcallbackmap, const priv_lvl_t& _cur_priv)
118  : d_setcallbackmap(_setcallbackmap), cur_priv(_cur_priv)
119  {
120  ;
121  }
122 
123  void operator()(const T& p)
124  {
125  ConfigureCallbackMap_t::const_iterator iter(d_setcallbackmap.find(p.first));
126  if (iter != d_setcallbackmap.end()) {
127  if (cur_priv <= iter->second.priv) {
128  (*iter->second.callback)
130  } else {
131  std::ostringstream msg;
132  msg << "Key " << p.first
133  << " requires PRIVLVL <= " << iter->second.priv
134  << " to set, currently at: " << cur_priv;
135  GR_LOG_ERROR(d_logger, msg.str());
136  }
137  } else {
138  throw apache::thrift::TApplicationException(__FILE__ " " S__LINE__);
139  }
140  }
141 
142  TMap& d_setcallbackmap;
143  const priv_lvl_t& cur_priv;
144  };
145 
146  template <typename T, typename TMap>
147  struct get_f : public std::unary_function<T, void> {
148  get_f(TMap& _getcallbackmap,
149  const priv_lvl_t& _cur_priv,
150  GNURadio::KnobMap& _outknobs)
151  : d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs)
152  {
153  }
154 
155  void operator()(const T& p)
156  {
157  QueryCallbackMap_t::const_iterator iter(d_getcallbackmap.find(p));
158  if (iter != d_getcallbackmap.end()) {
159  if (cur_priv <= iter->second.priv) {
160  outknobs[p] =
161  rpcpmtconverter::from_pmt((*iter->second.callback).retrieve());
162  } else {
163  std::ostringstream msg;
164  msg << "Key " << iter->first
165  << " requires PRIVLVL: <= " << iter->second.priv
166  << " to get, currently at: " << cur_priv;
167  GR_LOG_ERROR(d_logger, msg.str());
168  }
169  } else {
170  std::ostringstream smsgs;
171  smsgs << "Ctrlport Key called with unregistered key (" << p << ")\n";
172  GR_LOG_ERROR(d_logger, smsgs.str());
173  throw apache::thrift::TApplicationException(__FILE__ " " S__LINE__);
174  }
175  }
176 
177  TMap& d_getcallbackmap;
178  const priv_lvl_t& cur_priv;
179  GNURadio::KnobMap& outknobs;
180  };
181 
182  template <typename T, typename TMap, typename TKnobMap>
183  struct get_all_f : public std::unary_function<T, void> {
184  get_all_f(TMap& _getcallbackmap, const priv_lvl_t& _cur_priv, TKnobMap& _outknobs)
185  : d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs)
186  {
187  ;
188  }
189 
190  void operator()(const T& p)
191  {
192  if (cur_priv <= p.second.priv) {
193  outknobs[p.first] =
194  rpcpmtconverter::from_pmt(p.second.callback->retrieve());
195  } else {
196  std::ostringstream msg;
197  msg << "Key " << p.first << " requires PRIVLVL: <= " << p.second.priv
198  << " to get, currently at: " << cur_priv;
199  GR_LOG_ERROR(d_logger, msg.str());
200  }
201  }
202 
203  TMap& d_getcallbackmap;
204  const priv_lvl_t& cur_priv;
205  TKnobMap& outknobs;
206  };
207 
208  template <typename T, typename TMap, typename TKnobMap>
209  struct properties_all_f : public std::unary_function<T, void> {
210  properties_all_f(QueryCallbackMap_t& _getcallbackmap,
211  const priv_lvl_t& _cur_priv,
212  GNURadio::KnobPropMap& _outknobs)
213  : d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs)
214  {
215  ;
216  }
217 
218  void operator()(const T& p)
219  {
220  if (cur_priv <= p.second.priv) {
221  GNURadio::KnobProp prop;
222  prop.type = GNURadio::KnobType::KNOBDOUBLE;
223  prop.units = p.second.units;
224  prop.description = p.second.description;
225  prop.min = rpcpmtconverter::from_pmt(p.second.min);
226  prop.max = rpcpmtconverter::from_pmt(p.second.max);
227  prop.display = static_cast<uint32_t>(p.second.display);
228  outknobs[p.first] = prop;
229  } else {
230  std::ostringstream msg;
231  msg << "Key " << p.first << " requires PRIVLVL: <= " << p.second.priv
232  << " to get, currently at: " << cur_priv;
233  GR_LOG_ERROR(d_logger, msg.str());
234  }
235  }
236 
237  TMap& d_getcallbackmap;
238  const priv_lvl_t& cur_priv;
239  TKnobMap& outknobs;
240  };
241 
242  template <class T, typename TMap, typename TKnobMap>
243  struct properties_f : public std::unary_function<T, void> {
244  properties_f(TMap& _getcallbackmap,
245  const priv_lvl_t& _cur_priv,
246  TKnobMap& _outknobs)
247  : d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs)
248  {
249  ;
250  }
251 
252  void operator()(const T& p)
253  {
254  typename TMap::const_iterator iter(d_getcallbackmap.find(p));
255  if (iter != d_getcallbackmap.end()) {
256  if (cur_priv <= iter->second.priv) {
257  GNURadio::KnobProp prop;
258  prop.type = GNURadio::KnobType::KNOBDOUBLE;
259  prop.units = iter->second.units;
260  prop.description = iter->second.description;
261  prop.min = rpcpmtconverter::from_pmt(iter->second.min);
262  prop.max = rpcpmtconverter::from_pmt(iter->second.max);
263  prop.display = static_cast<uint32_t>(iter->second.display);
264  outknobs[p] = prop;
265  } else {
266  std::ostringstream msg;
267  msg << "Key " << iter->first
268  << " requires PRIVLVL: <= " << iter->second.priv
269  << " to get, currently at: " << cur_priv;
270  GR_LOG_ERROR(d_logger, msg.str());
271  }
272  } else {
273  throw apache::thrift::TApplicationException(__FILE__ " " S__LINE__);
274  }
275  }
276 
277  TMap& d_getcallbackmap;
278  const priv_lvl_t& cur_priv;
279  TKnobMap& outknobs;
280  };
281 };
282 
283 #endif /* RPCSERVER_THRIFT_H */
Definition: rpccallbackregister_base.h:83
Tsptr callback
Definition: rpccallbackregister_base.h:105
static To_PMT instance
Definition: rpcpmtconverters_thrift.h:77
Definition: rpcserver_base.h:17
priv_lvl_t cur_priv
Definition: rpcserver_base.h:39
Definition: rpcserver_thrift.h:30
void unregisterQueryCallback(const std::string &id)
void registerConfigureCallback(const std::string &id, const configureCallback_t callback)
virtual ~rpcserver_thrift()
void getRe(GNURadio::KnobMap &, const GNURadio::KnobIDList &)
void setKnobs(const GNURadio::KnobMap &)
void properties(GNURadio::KnobPropMap &, const GNURadio::KnobIDList &knobs)
void getKnobs(GNURadio::KnobMap &, const GNURadio::KnobIDList &)
void registerQueryCallback(const std::string &id, const queryCallback_t callback)
virtual void shutdown()
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 unregisterHandlerCallback(const std::string &id)
void registerHandlerCallback(const std::string &id, const handlerCallback_t callback)
void unregisterConfigureCallback(const std::string &id)
#define GR_LOG_ERROR(log, msg)
Definition: logger.h:250
GR_RUNTIME_API const pmt::pmt_t msg()
boost::mutex mutex
Definition: thread.h:37
std::shared_ptr< logger > logger_ptr
Definition: logger.h:207
std::shared_ptr< pmt_base > pmt_t
typedef for shared pointer (transparent reference counting).
Definition: pmt.h:84
GNURadio::Knob from_pmt(const pmt::pmt_t &knob)
#define PMT_NIL
Definition: pmt.h:122
priv_lvl_t
Definition: rpccallbackregister_base.h:34
@ KNOBDOUBLE
Definition: rpccallbackregister_base.h:41
#define S__LINE__
Definition: rpcserver_thrift.h:27
std::string description
Definition: rpccallbackregister_base.h:76
priv_lvl_t priv
Definition: rpccallbackregister_base.h:75