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