GNU Radio Manual and C++ API Reference 3.10.5.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
28class rpcserver_thrift : public virtual rpcserver_base, public GNURadio::ControlPortIf
29{
30public:
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
79private:
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,
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;
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;
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:268
GR_RUNTIME_API const pmt::pmt_t msg()
boost::mutex mutex
Definition: thread.h:37
std::shared_ptr< logger > logger_ptr
Definition: logger.h:225
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