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