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
27class rpcserver_thrift : public virtual rpcserver_base, public GNURadio::ControlPortIf
28{
29public:
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
78private:
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;
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;
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