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