1 /* -*- c++ -*- */ 2 /* 3 * Copyright 2012,2014 Free Software Foundation, Inc. 4 * 5 * This file is part of GNU Radio 6 * 7 * GNU Radio is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 3, or (at your option) 10 * any later version. 11 * 12 * GNU Radio is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with GNU Radio; see the file COPYING. If not, write to 19 * the Free Software Foundation, Inc., 51 Franklin Street, 20 * Boston, MA 02110-1301, USA. 21 */ 22 23 #ifndef RPCREGISTERHELPERS_H 24 #define RPCREGISTERHELPERS_H 25 26 #include <gnuradio/rpcmanager.h> 27 #include <gnuradio/rpcserver_base.h> 28 #include <gnuradio/rpcserver_booter_base.h> 29 #include <gnuradio/rpcserver_selector.h> 30 #include <stdio.h> 31 #include <iostream> 32 #include <sstream> 33 34 // Fixes circular dependency issue before including block_registry.h 35 class rpcbasic_base; 36 typedef boost::shared_ptr<rpcbasic_base> rpcbasic_sptr; 37 38 #include <gnuradio/block_registry.h> 39 40 41 /********************************************************************* 42 * RPC Extractor Base Classes 43 ********************************************************************/ 44 45 /*! 46 *\brief Base class for registering a ControlPort Extractor. Acts as 47 * a message acceptor. 48 */ 49 template <typename T, typename Tto> 50 class rpcextractor_base : public virtual gr::messages::msg_accepter 51 { 52 public: rpcextractor_base(T * source,void (T::* func)(Tto))53 rpcextractor_base(T* source, void (T::*func)(Tto)) : _source(source), _func(func) 54 { 55 ; 56 } ~rpcextractor_base()57 ~rpcextractor_base() { ; } 58 post(pmt::pmt_t which_port,pmt::pmt_t msg)59 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 60 { 61 (void)which_port; 62 (void)msg; 63 throw std::runtime_error( 64 "rpcextractor_base: no post defined for this data type.\n"); 65 } 66 67 protected: 68 T* _source; 69 void (T::*_func)(Tto); 70 }; 71 72 template <typename T> 73 class rpcextractor_base<T, void> : public virtual gr::messages::msg_accepter 74 { 75 public: rpcextractor_base(T * source,void (T::* func)())76 rpcextractor_base(T* source, void (T::*func)()) : _source(source), _func(func) { ; } ~rpcextractor_base()77 ~rpcextractor_base() { ; } 78 post(pmt::pmt_t which_port,pmt::pmt_t msg)79 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 80 { 81 (void)which_port; 82 (void)msg; 83 throw std::runtime_error( 84 "rpcextractor_base: no post defined for this data type.\n"); 85 } 86 87 protected: 88 T* _source; 89 void (T::*_func)(); 90 }; 91 92 /*! 93 * \brief Templated parent class for registering a ControlPort Extractor. 94 */ 95 template <typename T, typename Tto> 96 class rpcbasic_extractor : public virtual rpcextractor_base<T, Tto> 97 { 98 public: rpcbasic_extractor(T * source,void (T::* func)(Tto))99 rpcbasic_extractor(T* source, void (T::*func)(Tto)) 100 : rpcextractor_base<T, Tto>(source, func) 101 { 102 ; 103 } 104 }; 105 106 107 /********************************************************************* 108 * RPC Inserter Base Classes 109 ********************************************************************/ 110 111 /*! 112 * \brief Base class for registering a ControlPort Inserter. Produces a 113 * message. 114 */ 115 template <typename T, typename Tfrom> 116 class rpcinserter_base : public virtual gr::messages::msg_producer 117 { 118 public: rpcinserter_base(T * source,Tfrom (T::* func)())119 rpcinserter_base(T* source, Tfrom (T::*func)()) : _source(source), _func(func) { ; } rpcinserter_base()120 rpcinserter_base() { ; } 121 retrieve()122 pmt::pmt_t retrieve() 123 { 124 assert(0); 125 return pmt::pmt_t(); 126 } 127 128 protected: 129 T* _source; 130 Tfrom (T::*_func)(); 131 }; 132 133 134 /*! 135 * \brief Templated parent class for registering a ControlPort 136 * Inserter. 137 */ 138 template <typename T, typename Tfrom> 139 class rpcbasic_inserter : public virtual rpcinserter_base<T, Tfrom> 140 { 141 public: rpcbasic_inserter(T * source,Tfrom (T::* func)()const)142 rpcbasic_inserter(T* source, Tfrom (T::*func)() const) 143 : rpcinserter_base<T, Tfrom>(source, func) 144 { 145 ; 146 } 147 rpcbasic_inserter(T * source,Tfrom (T::* func)())148 rpcbasic_inserter(T* source, Tfrom (T::*func)()) 149 : rpcinserter_base<T, Tfrom>(source, func) 150 { 151 ; 152 } 153 retrieve()154 pmt::pmt_t retrieve() 155 { 156 return pmt::mp( 157 (rpcinserter_base<T, Tfrom>::_source->*rpcinserter_base<T, Tfrom>::_func)()); 158 } 159 }; 160 161 162 /********************************************************************* 163 * RPC Handler Base Classes 164 ********************************************************************/ 165 166 /*! 167 *\brief Base class for registering a ControlPort Handler. Acts as 168 * a message acceptor. 169 */ 170 template <typename T> 171 class rpchandler_base : public virtual gr::messages::msg_accepter 172 { 173 public: rpchandler_base(T * source,const char * handler)174 rpchandler_base(T* source, const char* handler) : _source(source), _handler(handler) 175 { 176 ; 177 } ~rpchandler_base()178 ~rpchandler_base() { ; } 179 post(pmt::pmt_t which_port,pmt::pmt_t msg)180 void post(pmt::pmt_t which_port, pmt::pmt_t msg) { _source->post(which_port, msg); } 181 182 protected: 183 T* _source; 184 const char* _handler; 185 }; 186 187 188 /*! 189 * \brief Templated parent class for registering a ControlPort Extractor. 190 */ 191 template <typename T> 192 class rpcbasic_handler : public virtual rpchandler_base<T> 193 { 194 public: rpcbasic_handler(T * source,const char * handler)195 rpcbasic_handler(T* source, const char* handler) : rpchandler_base<T>(source, handler) 196 { 197 ; 198 } 199 }; 200 201 202 /********************************************************************* 203 * RPC Specialized Extractors 204 ********************************************************************/ 205 206 /*! 207 * \brief Specialized extractor class to make calls to functions that 208 * do not take data (enable, reset, start, etc.). 209 */ 210 template <typename T> 211 class rpcbasic_extractor<T, void> : public virtual rpcextractor_base<T, void> 212 { 213 public: rpcbasic_extractor(T * source,void (T::* func)())214 rpcbasic_extractor(T* source, void (T::*func)()) 215 : rpcextractor_base<T, void>(source, func) 216 { 217 ; 218 } 219 post(pmt::pmt_t which_port,pmt::pmt_t msg)220 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 221 { 222 (void)which_port; 223 (void)msg; 224 (rpcextractor_base<T, void>::_source->*rpcextractor_base<T, void>::_func)(); 225 } 226 }; 227 228 /*! 229 * \brief Specialized extractor class for char data. 230 */ 231 template <typename T> 232 class rpcbasic_extractor<T, char> : public virtual rpcextractor_base<T, char> 233 { 234 public: rpcbasic_extractor(T * source,void (T::* func)(char))235 rpcbasic_extractor(T* source, void (T::*func)(char)) 236 : rpcextractor_base<T, char>(source, func) 237 { 238 ; 239 } 240 post(pmt::pmt_t which_port,pmt::pmt_t msg)241 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 242 { 243 (void)which_port; 244 (rpcextractor_base<T, char>::_source->*rpcextractor_base<T, char>::_func)( 245 static_cast<char>(pmt::to_long(msg))); 246 } 247 }; 248 249 /*! 250 * \brief Specialized extractor class for short data. 251 */ 252 template <typename T> 253 class rpcbasic_extractor<T, short> : public virtual rpcextractor_base<T, short> 254 { 255 public: rpcbasic_extractor(T * source,void (T::* func)(short))256 rpcbasic_extractor(T* source, void (T::*func)(short)) 257 : rpcextractor_base<T, short>(source, func) 258 { 259 ; 260 } 261 post(pmt::pmt_t which_port,pmt::pmt_t msg)262 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 263 { 264 (void)which_port; 265 (rpcextractor_base<T, short>::_source->*rpcextractor_base<T, short>::_func)( 266 static_cast<short>(pmt::to_long(msg))); 267 } 268 }; 269 270 /*! 271 * \brief Specialized extractor class for double data. 272 */ 273 template <typename T> 274 class rpcbasic_extractor<T, double> : public virtual rpcextractor_base<T, double> 275 { 276 public: rpcbasic_extractor(T * source,void (T::* func)(double))277 rpcbasic_extractor(T* source, void (T::*func)(double)) 278 : rpcextractor_base<T, double>(source, func) 279 { 280 ; 281 } 282 post(pmt::pmt_t which_port,pmt::pmt_t msg)283 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 284 { 285 (void)which_port; 286 (rpcextractor_base<T, double>::_source->*rpcextractor_base<T, double>::_func)( 287 pmt::to_double(msg)); 288 } 289 }; 290 291 /*! 292 * \brief Specialized extractor class for float data. 293 */ 294 template <typename T> 295 class rpcbasic_extractor<T, float> : public virtual rpcextractor_base<T, float> 296 { 297 public: rpcbasic_extractor(T * source,void (T::* func)(float))298 rpcbasic_extractor(T* source, void (T::*func)(float)) 299 : rpcextractor_base<T, float>(source, func) 300 { 301 ; 302 } 303 post(pmt::pmt_t which_port,pmt::pmt_t msg)304 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 305 { 306 (void)which_port; 307 (rpcextractor_base<T, float>::_source->*rpcextractor_base<T, float>::_func)( 308 pmt::to_double(msg)); 309 } 310 }; 311 312 /*! 313 * \brief Specialized extractor class for long data. 314 */ 315 template <typename T> 316 class rpcbasic_extractor<T, long> : public virtual rpcextractor_base<T, long> 317 { 318 public: rpcbasic_extractor(T * source,void (T::* func)(long))319 rpcbasic_extractor(T* source, void (T::*func)(long)) 320 : rpcextractor_base<T, long>(source, func) 321 { 322 ; 323 } 324 post(pmt::pmt_t which_port,pmt::pmt_t msg)325 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 326 { 327 (void)which_port; 328 (rpcextractor_base<T, long>::_source->*rpcextractor_base<T, long>::_func)( 329 pmt::to_long(msg)); 330 } 331 }; 332 333 /*! 334 * \brief Specialized extractor class for int data. 335 */ 336 template <typename T> 337 class rpcbasic_extractor<T, int> : public virtual rpcextractor_base<T, int> 338 { 339 public: rpcbasic_extractor(T * source,void (T::* func)(int))340 rpcbasic_extractor(T* source, void (T::*func)(int)) 341 : rpcextractor_base<T, int>(source, func) 342 { 343 ; 344 } 345 post(pmt::pmt_t which_port,pmt::pmt_t msg)346 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 347 { 348 (void)which_port; 349 (rpcextractor_base<T, int>::_source->*rpcextractor_base<T, int>::_func)( 350 pmt::to_long(msg)); 351 } 352 }; 353 354 /*! 355 * \brief Specialized extractor class for bool data. 356 */ 357 template <typename T> 358 class rpcbasic_extractor<T, bool> : public virtual rpcextractor_base<T, bool> 359 { 360 public: rpcbasic_extractor(T * source,void (T::* func)(bool))361 rpcbasic_extractor(T* source, void (T::*func)(bool)) 362 : rpcextractor_base<T, bool>(source, func) 363 { 364 ; 365 } 366 post(pmt::pmt_t which_port,pmt::pmt_t msg)367 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 368 { 369 (void)which_port; 370 (rpcextractor_base<T, bool>::_source->*rpcextractor_base<T, bool>::_func)( 371 pmt::to_bool(msg)); 372 } 373 }; 374 375 /*! 376 * \brief Specialized extractor class for complex (float) data. 377 */ 378 template <typename T> 379 class rpcbasic_extractor<T, std::complex<float>> 380 : public virtual rpcextractor_base<T, std::complex<float>> 381 { 382 public: rpcbasic_extractor(T * source,void (T::* func)(std::complex<float>))383 rpcbasic_extractor(T* source, void (T::*func)(std::complex<float>)) 384 : rpcextractor_base<T, std::complex<float>>(source, func) 385 { 386 ; 387 } 388 post(pmt::pmt_t which_port,pmt::pmt_t msg)389 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 390 { 391 (void)which_port; 392 std::complex<float> k = static_cast<std::complex<float>>(pmt::to_complex(msg)); 393 (rpcextractor_base<T, std::complex<float>>::_source 394 ->*rpcextractor_base<T, std::complex<float>>::_func)(k); 395 } 396 }; 397 398 /*! 399 * \brief Specialized extractor class for complex (double) data. 400 */ 401 template <typename T> 402 class rpcbasic_extractor<T, std::complex<double>> 403 : public virtual rpcextractor_base<T, std::complex<double>> 404 { 405 public: rpcbasic_extractor(T * source,void (T::* func)(std::complex<double>))406 rpcbasic_extractor(T* source, void (T::*func)(std::complex<double>)) 407 : rpcextractor_base<T, std::complex<double>>(source, func) 408 { 409 ; 410 } 411 post(pmt::pmt_t which_port,pmt::pmt_t msg)412 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 413 { 414 (void)which_port; 415 (rpcextractor_base<T, std::complex<double>>::_source 416 ->*rpcextractor_base<T, std::complex<double>>::_func)(pmt::to_complex(msg)); 417 } 418 }; 419 420 /*! 421 * \brief Specialized extractor class for string data. 422 */ 423 template <typename T> 424 class rpcbasic_extractor<T, std::string> 425 : public virtual rpcextractor_base<T, std::string> 426 { 427 public: rpcbasic_extractor(T * source,void (T::* func)(std::string))428 rpcbasic_extractor(T* source, void (T::*func)(std::string)) 429 : rpcextractor_base<T, std::string>(source, func) 430 { 431 ; 432 } 433 post(pmt::pmt_t which_port,pmt::pmt_t msg)434 void post(pmt::pmt_t which_port, pmt::pmt_t msg) 435 { 436 (void)which_port; 437 (rpcextractor_base<T, std::string>::_source 438 ->*rpcextractor_base<T, std::string>::_func)(pmt::symbol_to_string(msg)); 439 } 440 }; 441 442 443 /********************************************************************* 444 * RPC Specialized Inserters 445 ********************************************************************/ 446 447 /*! 448 * \brief Specialized inserter class for uint64_t data. 449 */ 450 template <typename T> 451 class rpcbasic_inserter<T, uint64_t> : public virtual rpcinserter_base<T, uint64_t> 452 { 453 public: rpcbasic_inserter(T * source,uint64_t (T::* func)()const)454 rpcbasic_inserter(T* source, uint64_t (T::*func)() const) 455 : rpcinserter_base<T, uint64_t>(source, func) 456 { 457 ; 458 } 459 rpcbasic_inserter(T * source,uint64_t (T::* func)())460 rpcbasic_inserter(T* source, uint64_t (T::*func)()) 461 : rpcinserter_base<T, uint64_t>(source, func) 462 { 463 ; 464 } 465 retrieve()466 pmt::pmt_t retrieve() 467 { 468 return pmt::from_uint64((rpcinserter_base<T, uint64_t>::_source 469 ->*rpcinserter_base<T, uint64_t>::_func)()); 470 } 471 }; 472 473 /*! 474 * \brief Specialized inserter class for vectors of signed char data. 475 */ 476 template <typename T> 477 class rpcbasic_inserter<T, std::vector<signed char>> 478 : public virtual rpcinserter_base<T, std::vector<signed char>> 479 { 480 public: rpcbasic_inserter(T * source,std::vector<signed char> (T::* func)()const)481 rpcbasic_inserter(T* source, std::vector<signed char> (T::*func)() const) 482 : rpcinserter_base<T, std::vector<signed char>>(source, func) 483 { 484 ; 485 } 486 rpcbasic_inserter(T * source,std::vector<signed char> (T::* func)())487 rpcbasic_inserter(T* source, std::vector<signed char> (T::*func)()) 488 : rpcinserter_base<T, std::vector<signed char>>(source, func) 489 { 490 ; 491 } 492 retrieve()493 pmt::pmt_t retrieve() 494 { 495 std::vector<signed char> vec( 496 (rpcinserter_base<T, std::vector<signed char>>::_source 497 ->*rpcinserter_base<T, std::vector<signed char>>::_func)()); 498 return pmt::init_s8vector(vec.size(), &vec[0]); 499 } 500 }; 501 502 /*! 503 * \brief Specialized inserter class for vectors of short data. 504 */ 505 template <typename T> 506 class rpcbasic_inserter<T, std::vector<short>> 507 : public virtual rpcinserter_base<T, std::vector<short>> 508 { 509 public: rpcbasic_inserter(T * source,std::vector<short> (T::* func)()const)510 rpcbasic_inserter(T* source, std::vector<short> (T::*func)() const) 511 : rpcinserter_base<T, std::vector<short>>(source, func) 512 { 513 ; 514 } 515 rpcbasic_inserter(T * source,std::vector<short> (T::* func)())516 rpcbasic_inserter(T* source, std::vector<short> (T::*func)()) 517 : rpcinserter_base<T, std::vector<short>>(source, func) 518 { 519 ; 520 } 521 retrieve()522 pmt::pmt_t retrieve() 523 { 524 std::vector<short> vec((rpcinserter_base<T, std::vector<short>>::_source 525 ->*rpcinserter_base<T, std::vector<short>>::_func)()); 526 return pmt::init_s16vector(vec.size(), &vec[0]); 527 } 528 }; 529 530 /*! 531 * \brief Specialized inserter class for vectors of int data. 532 */ 533 template <typename T> 534 class rpcbasic_inserter<T, std::vector<int>> 535 : public virtual rpcinserter_base<T, std::vector<int>> 536 { 537 public: rpcbasic_inserter(T * source,std::vector<int> (T::* func)()const)538 rpcbasic_inserter(T* source, std::vector<int> (T::*func)() const) 539 : rpcinserter_base<T, std::vector<int>>(source, func) 540 { 541 ; 542 } 543 rpcbasic_inserter(T * source,std::vector<int> (T::* func)())544 rpcbasic_inserter(T* source, std::vector<int> (T::*func)()) 545 : rpcinserter_base<T, std::vector<int>>(source, func) 546 { 547 ; 548 } 549 retrieve()550 pmt::pmt_t retrieve() 551 { 552 std::vector<int> vec((rpcinserter_base<T, std::vector<int>>::_source 553 ->*rpcinserter_base<T, std::vector<int>>::_func)()); 554 return pmt::init_s32vector(vec.size(), &vec[0]); 555 } 556 }; 557 558 /*! 559 * \brief Specialized inserter class for vectors of int64_t data. 560 */ 561 template <typename T> 562 class rpcbasic_inserter<T, std::vector<int64_t>> 563 : public virtual rpcinserter_base<T, std::vector<int64_t>> 564 { 565 public: rpcbasic_inserter(T * source,std::vector<int64_t> (T::* func)()const)566 rpcbasic_inserter(T* source, std::vector<int64_t> (T::*func)() const) 567 : rpcinserter_base<T, std::vector<int64_t>>(source, func) 568 { 569 ; 570 } 571 rpcbasic_inserter(T * source,std::vector<int64_t> (T::* func)())572 rpcbasic_inserter(T* source, std::vector<int64_t> (T::*func)()) 573 : rpcinserter_base<T, std::vector<int64_t>>(source, func) 574 { 575 ; 576 } 577 retrieve()578 pmt::pmt_t retrieve() 579 { 580 std::vector<int64_t> vec( 581 (rpcinserter_base<T, std::vector<int64_t>>::_source 582 ->*rpcinserter_base<T, std::vector<int64_t>>::_func)()); 583 return pmt::init_s64vector(vec.size(), &vec[0]); 584 } 585 }; 586 587 /*! 588 * \brief Specialized inserter class for vectors of complex (float) data. 589 */ 590 template <typename T> 591 class rpcbasic_inserter<T, std::vector<std::complex<float>>> 592 : public virtual rpcinserter_base<T, std::vector<std::complex<float>>> 593 { 594 public: rpcbasic_inserter(T * source,std::vector<std::complex<float>> (T::* func)()const)595 rpcbasic_inserter(T* source, std::vector<std::complex<float>> (T::*func)() const) 596 : rpcinserter_base<T, std::vector<std::complex<float>>>(source, func) 597 { 598 ; 599 } 600 rpcbasic_inserter(T * source,std::vector<std::complex<float>> (T::* func)())601 rpcbasic_inserter(T* source, std::vector<std::complex<float>> (T::*func)()) 602 : rpcinserter_base<T, std::vector<std::complex<float>>>(source, func) 603 { 604 ; 605 } 606 retrieve()607 pmt::pmt_t retrieve() 608 { 609 std::vector<std::complex<float>> vec( 610 (rpcinserter_base<T, std::vector<std::complex<float>>>::_source 611 ->*rpcinserter_base<T, std::vector<std::complex<float>>>::_func)()); 612 return pmt::init_c32vector(vec.size(), &vec[0]); 613 } 614 }; 615 616 /*! 617 * \brief Specialized inserter class for vectors of float data. 618 */ 619 template <typename T> 620 class rpcbasic_inserter<T, std::vector<float>> 621 : public virtual rpcinserter_base<T, std::vector<float>> 622 { 623 public: rpcbasic_inserter(T * source,std::vector<float> (T::* func)()const)624 rpcbasic_inserter(T* source, std::vector<float> (T::*func)() const) 625 : rpcinserter_base<T, std::vector<float>>(source, func) 626 { 627 ; 628 } 629 rpcbasic_inserter(T * source,std::vector<float> (T::* func)())630 rpcbasic_inserter(T* source, std::vector<float> (T::*func)()) 631 : rpcinserter_base<T, std::vector<float>>(source, func) 632 { 633 ; 634 } 635 retrieve()636 pmt::pmt_t retrieve() 637 { 638 std::vector<float> vec((rpcinserter_base<T, std::vector<float>>::_source 639 ->*rpcinserter_base<T, std::vector<float>>::_func)()); 640 return pmt::init_f32vector(vec.size(), &vec[0]); 641 } 642 }; 643 644 /*! 645 * \brief Specialized inserter class for vectors of uint8_t data. 646 */ 647 template <typename T> 648 class rpcbasic_inserter<T, std::vector<uint8_t>> 649 : public virtual rpcinserter_base<T, std::vector<uint8_t>> 650 { 651 public: rpcbasic_inserter(T * source,std::vector<uint8_t> (T::* func)()const)652 rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)() const) 653 : rpcinserter_base<T, std::vector<uint8_t>>(source, func) 654 { 655 ; 656 } 657 rpcbasic_inserter(T * source,std::vector<uint8_t> (T::* func)())658 rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)()) 659 : rpcinserter_base<T, std::vector<uint8_t>>(source, func) 660 { 661 ; 662 } 663 retrieve()664 pmt::pmt_t retrieve() 665 { 666 std::vector<uint8_t> vec( 667 (rpcinserter_base<T, std::vector<uint8_t>>::_source 668 ->*rpcinserter_base<T, std::vector<uint8_t>>::_func)()); 669 return pmt::init_u8vector(vec.size(), &vec[0]); 670 } 671 }; 672 673 /*! 674 * \brief Specialized inserter class for complex (float) data. 675 */ 676 template <typename T> 677 class rpcbasic_inserter<T, std::complex<float>> 678 : public virtual rpcinserter_base<T, std::complex<float>> 679 { 680 public: rpcbasic_inserter(T * source,std::complex<float> (T::* func)()const)681 rpcbasic_inserter(T* source, std::complex<float> (T::*func)() const) 682 : rpcinserter_base<T, std::complex<float>>(source, func) 683 { 684 ; 685 } 686 rpcbasic_inserter(T * source,std::complex<float> (T::* func)())687 rpcbasic_inserter(T* source, std::complex<float> (T::*func)()) 688 : rpcinserter_base<T, std::complex<float>>(source, func) 689 { 690 ; 691 } 692 retrieve()693 pmt::pmt_t retrieve() 694 { 695 std::complex<float> k((rpcinserter_base<T, std::complex<float>>::_source 696 ->*rpcinserter_base<T, std::complex<float>>::_func)()); 697 return pmt::from_complex(k); 698 } 699 }; 700 701 /*! 702 * \brief Specialized inserter class for complex (double) data. 703 */ 704 template <typename T> 705 class rpcbasic_inserter<T, std::complex<double>> 706 : public virtual rpcinserter_base<T, std::complex<double>> 707 { 708 public: rpcbasic_inserter(T * source,std::complex<double> (T::* func)()const)709 rpcbasic_inserter(T* source, std::complex<double> (T::*func)() const) 710 : rpcinserter_base<T, std::complex<double>>(source, func) 711 { 712 ; 713 } 714 rpcbasic_inserter(T * source,std::complex<double> (T::* func)())715 rpcbasic_inserter(T* source, std::complex<double> (T::*func)()) 716 : rpcinserter_base<T, std::complex<double>>(source, func) 717 { 718 ; 719 } 720 retrieve()721 pmt::pmt_t retrieve() 722 { 723 std::complex<double> k( 724 (rpcinserter_base<T, std::complex<double>>::_source 725 ->*rpcinserter_base<T, std::complex<double>>::_func)()); 726 return pmt::from_complex(k); 727 } 728 }; 729 730 /*! 731 * \brief Base class for registering a ControlPort function. 732 */ 733 template <typename T> 734 struct rpc_register_base { rpc_register_baserpc_register_base735 rpc_register_base() { count++; } 736 737 protected: 738 static int count; 739 }; 740 741 /*! 742 * Base class to inherit from and create universal shared pointers. 743 */ 744 class rpcbasic_base 745 { 746 public: rpcbasic_base()747 rpcbasic_base() {} ~rpcbasic_base()748 virtual ~rpcbasic_base(){}; 749 }; 750 751 752 /********************************************************************* 753 * RPC Register Set Classes 754 ********************************************************************/ 755 756 /*! 757 * \brief Registers a 'set' function to set a parameter over 758 * ControlPort. 759 * 760 * \details 761 * 762 * This class allows us to remotely set a value or parameter of the 763 * block over ControlPort. The set occurs by calling a setter accessor 764 * function of the class, usually set_[variable](), which is passed in 765 * as \p function. 766 * 767 * We can set the (expected) minimum (\p min), maximum (\p max), and 768 * default (\p def) of the variables being set. These values are not 769 * enforced, however, but can be useful for setting up graphs and 770 * other ways of bounding the data. 771 * 772 * This class also allows us to provide information to the user about 773 * the variable being set, such as an appropriate unit (\p units_) as 774 * well as a description (\p desc_) about what the variable does. 775 * 776 * The privilege (\p minpriv_) level is the minimum privilege level a 777 * remote must identify with to be able to call this function. 778 * 779 * We also provide display hints (\p display_), which can be used by 780 * the ControlPort client application to know how to best display or 781 * even print the data. This is a mask of options for variables set in 782 * rpccallbackregister_base.h. The mask is defined by one of the 783 * "DisplayType Plotting Types" and or'd with any of the "DisplayType 784 * Options" features. See "Display Options" in \ref page_ctrlport for 785 * details. 786 */ 787 template <typename T, typename Tto> 788 struct rpcbasic_register_set : public rpcbasic_base { 789 /*! 790 * \brief Adds the ability to set the variable over ControlPort. 791 * 792 * \details 793 * 794 * This constructor is specifically for gr::block's to use to add 795 * settable variables to ControlPort. Generally meant to be used 796 * in gr::block::setup_rpc. 797 * 798 * Uses the block's alias to create the ControlPort interface. This 799 * alias is cross-referenced by the global_block_registry (static 800 * variable of type gr::block_registry) to get the pointer to the 801 * block. 802 * 803 * \param block_alias Block's alias; use alias() to get it from the block. 804 * \param functionbase The name of the function that we'll access over ControlPort 805 * \param function A function pointer to the real function accessed when called 806 * something like: &[block class]\::set_[variable]() 807 * \param min Expected minimum value the parameter can hold 808 * \param max Expected maximum value the parameter can hold 809 * \param def Expected default value the parameter can hold 810 * \param units_ A string to describe what units to represent the variable with 811 * \param desc_ A string to describing the variable. 812 * \param minpriv_ The required minimum privilege level 813 * \param display_ The display mask 814 */ 815 rpcbasic_register_set(const std::string& block_alias, 816 const char* functionbase, 817 void (T::*function)(Tto), 818 const pmt::pmt_t& min, 819 const pmt::pmt_t& max, 820 const pmt::pmt_t& def, 821 const char* units_ = "", 822 const char* desc_ = "", 823 priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, 824 DisplayType display_ = DISPNULL) 825 { 826 d_min = min; 827 d_max = max; 828 d_def = def; 829 d_units = units_; 830 d_desc = desc_; 831 d_minpriv = minpriv_; 832 d_display = display_; 833 d_object = dynamic_cast<T*>( 834 global_block_registry.block_lookup(pmt::intern(block_alias)).get()); 835 #ifdef GR_RPCSERVER_ENABLED 836 callbackregister_base::configureCallback_t extractor( 837 new rpcbasic_extractor<T, Tto>(d_object, function), 838 minpriv_, 839 std::string(units_), 840 display_, 841 std::string(desc_), 842 min, 843 max, 844 def); 845 std::ostringstream oss(std::ostringstream::out); 846 oss << block_alias << "::" << functionbase; 847 d_id = oss.str(); 848 // std::cerr << "REGISTERING SET: " << d_id << " " << desc_ << std::endl; 849 rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor); 850 #endif 851 } 852 853 /*! 854 * \brief Adds the ability to set the variable over ControlPort. 855 * 856 * \details 857 * 858 * Allows us to add non gr::block related objects to 859 * ControlPort. Instead of using the block's alias, we give it a \p 860 * name and the actual pointer to the object as \p obj. We just need 861 * to make sure that the pointer to this object is always valid. 862 * 863 * \param name Name of the object being set up for ControlPort access 864 * \param functionbase The name of the function that we'll access over ControlPort 865 * \param obj A pointer to the object itself 866 * \param function A function pointer to the real function accessed when called 867 * something like: &[block class]\::set_[variable]() 868 * \param min Expected minimum value the parameter can hold 869 * \param max Expected maximum value the parameter can hold 870 * \param def Expected default value the parameter can hold 871 * \param units_ A string to describe what units to represent the variable with 872 * \param desc_ A string to describing the variable. 873 * \param minpriv_ The required minimum privilege level 874 * \param display_ The display mask 875 */ 876 rpcbasic_register_set(const std::string& name, 877 const char* functionbase, 878 T* obj, 879 void (T::*function)(Tto), 880 const pmt::pmt_t& min, 881 const pmt::pmt_t& max, 882 const pmt::pmt_t& def, 883 const char* units_ = "", 884 const char* desc_ = "", 885 priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, 886 DisplayType display_ = DISPNULL) 887 { 888 d_min = min; 889 d_max = max; 890 d_def = def; 891 d_units = units_; 892 d_desc = desc_; 893 d_minpriv = minpriv_; 894 d_display = display_; 895 d_object = obj; 896 #ifdef GR_RPCSERVER_ENABLED 897 callbackregister_base::configureCallback_t extractor( 898 new rpcbasic_extractor<T, Tto>(d_object, function), 899 minpriv_, 900 std::string(units_), 901 display_, 902 std::string(desc_), 903 min, 904 max, 905 def); 906 std::ostringstream oss(std::ostringstream::out); 907 oss << name << "::" << functionbase; 908 d_id = oss.str(); 909 // std::cerr << "REGISTERING SET: " << d_id << " " << desc_ << std::endl; 910 rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor); 911 #endif 912 } 913 ~rpcbasic_register_setrpcbasic_register_set914 ~rpcbasic_register_set() 915 { 916 #ifdef GR_RPCSERVER_ENABLED 917 rpcmanager::get()->i()->unregisterConfigureCallback(d_id); 918 #endif 919 } 920 921 minrpcbasic_register_set922 pmt::pmt_t min() const { return d_min; } maxrpcbasic_register_set923 pmt::pmt_t max() const { return d_max; } defrpcbasic_register_set924 pmt::pmt_t def() const { return d_def; } unitsrpcbasic_register_set925 std::string units() const { return d_units; } descriptionrpcbasic_register_set926 std::string description() const { return d_desc; } privilege_levelrpcbasic_register_set927 priv_lvl_t privilege_level() const { return d_minpriv; } default_displayrpcbasic_register_set928 DisplayType default_display() const { return d_display; } 929 set_minrpcbasic_register_set930 void set_min(pmt::pmt_t p) { d_min = p; } set_maxrpcbasic_register_set931 void set_max(pmt::pmt_t p) { d_max = p; } set_defrpcbasic_register_set932 void set_def(pmt::pmt_t p) { d_def = p; } unitsrpcbasic_register_set933 void units(std::string u) { d_units = u; } descriptionrpcbasic_register_set934 void description(std::string d) { d_desc = d; } privilege_levelrpcbasic_register_set935 void privilege_level(priv_lvl_t p) { d_minpriv = p; } default_displayrpcbasic_register_set936 void default_display(DisplayType d) { d_display = d; } 937 938 private: 939 std::string d_id; 940 pmt::pmt_t d_min, d_max, d_def; 941 std::string d_units, d_desc; 942 priv_lvl_t d_minpriv; 943 DisplayType d_display; 944 T* d_object; 945 }; 946 947 948 /********************************************************************* 949 * RPC Register Trigger Classes 950 ********************************************************************/ 951 952 /*! 953 * \brief Registers a 'trigger' function to trigger an action over 954 * ControlPort. 955 * 956 * \details 957 * 958 * This class allows us to set up triggered events or function calls 959 * over ControlPort. When used from a ControlPort client, the \p 960 * function established here will be activated. Generally, this is 961 * meant to enable some kind of trigger or action that a block or 962 * object will perform, such as a reset, start, stop, etc. 963 * 964 * Simpler than the rpcbasic_register_set class, the constructor here 965 * only takes a few parameters, mostly because there is not actual 966 * variable associated with these function calls. It takes in the 967 * information to set up the pointer to the object that has the \p 968 * function, a ControlPort name (\p functionbase) for the triggered 969 * action, a description (\p desc_), and a privilege level (\p 970 * minpriv_). 971 */ 972 template <typename T> 973 struct rpcbasic_register_trigger : public rpcbasic_base { 974 /*! 975 * \brief Adds the ability to trigger a function over ControlPort. 976 * 977 * \details 978 * 979 * This constructor is specifically for gr::block's to use to add 980 * trigger functions to ControlPort. Generally meant to be used 981 * in gr::block::setup_rpc. 982 * 983 * Uses the block's alias to create the ControlPort interface. This 984 * alias is cross-referenced by the global_block_registry (static 985 * variable of type gr::block_registry) to get the pointer to the 986 * block. 987 * 988 * \param block_alias Block's alias; use alias() to get it from the block. 989 * \param functionbase The name of the function that we'll access over ControlPort 990 * \param function A function pointer to the real function accessed when called 991 * something like: &[block class]\::set_[variable] 992 * \param desc_ A string to describing the variable. 993 * \param minpriv_ The required minimum privilege level 994 */ 995 rpcbasic_register_trigger(const std::string& block_alias, 996 const char* functionbase, 997 void (T::*function)(), 998 const char* desc_ = "", 999 priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN) 1000 { 1001 d_desc = desc_; 1002 d_minpriv = minpriv_; 1003 d_object = dynamic_cast<T*>( 1004 global_block_registry.block_lookup(pmt::intern(block_alias)).get()); 1005 #ifdef GR_RPCSERVER_ENABLED 1006 callbackregister_base::configureCallback_t extractor( 1007 new rpcbasic_extractor<T, void>(d_object, function), 1008 minpriv_, 1009 std::string(desc_)); 1010 std::ostringstream oss(std::ostringstream::out); 1011 oss << block_alias << "::" << functionbase; 1012 d_id = oss.str(); 1013 // std::cerr << "REGISTERING TRIGGER: " << d_id << " " << desc_ << std::endl; 1014 rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor); 1015 #endif 1016 } 1017 1018 /*! 1019 * \brief Adds the ability to trigger a function over ControlPort. 1020 * 1021 * \details 1022 * 1023 * Allows us to add non gr::block related objects to 1024 * ControlPort. Instead of using the block's alias, we give it a \p 1025 * name and the actual pointer to the object as \p obj. We just need 1026 * to make sure that the pointer to this object is always valid. 1027 * 1028 * \param name Name of the object being set up for ControlPort access 1029 * \param functionbase The name of the function that we'll access over ControlPort 1030 * \param obj A pointer to the object itself 1031 * \param function A function pointer to the real function accessed when called 1032 * something like: &[block class]\::set_[variable] 1033 * \param desc_ A string to describing the variable. 1034 * \param minpriv_ The required minimum privilege level 1035 */ 1036 rpcbasic_register_trigger(const std::string& name, 1037 const char* functionbase, 1038 T* obj, 1039 void (T::*function)(), 1040 const char* desc_ = "", 1041 priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN) 1042 { 1043 d_desc = desc_; 1044 d_minpriv = minpriv_; 1045 d_object = obj; 1046 #ifdef GR_RPCSERVER_ENABLED 1047 callbackregister_base::configureCallback_t extractor( 1048 new rpcbasic_extractor<T, void>(d_object, function), 1049 minpriv_, 1050 std::string(desc_)); 1051 std::ostringstream oss(std::ostringstream::out); 1052 oss << name << "::" << functionbase; 1053 d_id = oss.str(); 1054 // std::cerr << "REGISTERING TRIGGER: " << d_id << " " << desc_ << std::endl; 1055 rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor); 1056 #endif 1057 } 1058 ~rpcbasic_register_triggerrpcbasic_register_trigger1059 ~rpcbasic_register_trigger() 1060 { 1061 #ifdef GR_RPCSERVER_ENABLED 1062 rpcmanager::get()->i()->unregisterConfigureCallback(d_id); 1063 #endif 1064 } 1065 1066 descriptionrpcbasic_register_trigger1067 std::string description() const { return d_desc; } privilege_levelrpcbasic_register_trigger1068 priv_lvl_t privilege_level() const { return d_minpriv; } 1069 descriptionrpcbasic_register_trigger1070 void description(std::string d) { d_desc = d; } privilege_levelrpcbasic_register_trigger1071 void privilege_level(priv_lvl_t p) { d_minpriv = p; } 1072 1073 private: 1074 std::string d_id; 1075 std::string d_desc; 1076 priv_lvl_t d_minpriv; 1077 T* d_object; 1078 }; 1079 1080 1081 /********************************************************************* 1082 * RPC Register Get Classes 1083 ********************************************************************/ 1084 1085 /*! 1086 * \brief Registers a 'get' function to get a parameter over 1087 * ControlPort. 1088 * 1089 * \details 1090 * 1091 * This class allows us to remotely get a value or parameter of the 1092 * block over ControlPort. The get occurs by calling a getter accessor 1093 * function of the class, usually [variable](), which is passed in 1094 * as \p function. 1095 * 1096 * We can set the (expected) minimum (\p min), maximum (\p max), and 1097 * default (\p def) of the variables we will get. These values are not 1098 * enforced, however, but can be useful for setting up graphs and 1099 * other ways of bounding the data. 1100 * 1101 * This class also allows us to provide information to the user about 1102 * the variable, such as an appropriate unit (\p units_) as well as a 1103 * description (\p desc_) about what the variable does. 1104 * 1105 * The privilege (\p minpriv_) level is the minimum privilege level a 1106 * remote must identify with to be able to call this function. 1107 * 1108 * We also provide display hints (\p display_), which can be used by 1109 * the ControlPort client application to know how to best display or 1110 * even print the data. This is a mask of options for variables set in 1111 * rpccallbackregister_base.h. The mask is defined by one of the 1112 * "DisplayType Plotting Types" and or'd with any of the "DisplayType 1113 * Options" features. See "Display Options" in \ref page_ctrlport for 1114 * details. 1115 */ 1116 template <typename T, typename Tfrom> 1117 class rpcbasic_register_get : public rpcbasic_base 1118 { 1119 public: 1120 /*! 1121 * \brief Adds the ability to get the variable over ControlPort. 1122 * 1123 * \details 1124 * 1125 * This constructor is specifically for gr::block's to use to add 1126 * gettable variables to ControlPort. Generally meant to be used 1127 * in gr::block::setup_rpc. 1128 * 1129 * Uses the block's alias to create the ControlPort interface. This 1130 * alias is cross-referenced by the global_block_registry (static 1131 * variable of type gr::block_registry) to get the pointer to the 1132 * block. 1133 * 1134 * \param block_alias Block's alias; use alias() to get it from the block. 1135 * \param functionbase The name of the function that we'll access over ControlPort 1136 * \param function A function pointer to the real function accessed when called 1137 * something like: &[block class]\::[variable]() 1138 * \param min Expected minimum value the parameter can hold 1139 * \param max Expected maximum value the parameter can hold 1140 * \param def Expected default value the parameter can hold 1141 * \param units_ A string to describe what units to represent the variable with 1142 * \param desc_ A string to describing the variable. 1143 * \param minpriv_ The required minimum privilege level 1144 * \param display_ The display mask 1145 */ 1146 rpcbasic_register_get(const std::string& block_alias, 1147 const char* functionbase, 1148 Tfrom (T::*function)(), 1149 const pmt::pmt_t& min, 1150 const pmt::pmt_t& max, 1151 const pmt::pmt_t& def, 1152 const char* units_ = "", 1153 const char* desc_ = "", 1154 priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, 1155 DisplayType display_ = DISPNULL) 1156 { 1157 d_min = min; 1158 d_max = max; 1159 d_def = def; 1160 d_units = units_; 1161 d_desc = desc_; 1162 d_minpriv = minpriv_; 1163 d_display = display_; 1164 d_object = dynamic_cast<T*>( 1165 global_block_registry.block_lookup(pmt::intern(block_alias)).get()); 1166 #ifdef GR_RPCSERVER_ENABLED 1167 callbackregister_base::queryCallback_t inserter( 1168 new rpcbasic_inserter<T, Tfrom>(d_object, function), 1169 minpriv_, 1170 std::string(units_), 1171 display_, 1172 std::string(desc_), 1173 min, 1174 max, 1175 def); 1176 std::ostringstream oss(std::ostringstream::out); 1177 oss << block_alias << "::" << functionbase; 1178 d_id = oss.str(); 1179 // std::cerr << "REGISTERING GET: " << d_id << " " << desc_ << std::endl; 1180 rpcmanager::get()->i()->registerQueryCallback(d_id, inserter); 1181 #endif 1182 } 1183 1184 1185 /*! 1186 * \brief Same as rpcbasic_register_get::rpcbasic_register_get that allows using 1187 * '[variable]() const' getter functions. 1188 */ 1189 rpcbasic_register_get(const std::string& block_alias, 1190 const char* functionbase, 1191 Tfrom (T::*function)() const, 1192 const pmt::pmt_t& min, 1193 const pmt::pmt_t& max, 1194 const pmt::pmt_t& def, 1195 const char* units_ = "", 1196 const char* desc_ = "", 1197 priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, 1198 DisplayType display_ = DISPNULL) 1199 { 1200 d_min = min; 1201 d_max = max; 1202 d_def = def; 1203 d_units = units_; 1204 d_desc = desc_; 1205 d_minpriv = minpriv_; 1206 d_display = display_; 1207 d_object = dynamic_cast<T*>( 1208 global_block_registry.block_lookup(pmt::intern(block_alias)).get()); 1209 #ifdef GR_RPCSERVER_ENABLED 1210 callbackregister_base::queryCallback_t inserter( 1211 new rpcbasic_inserter<T, Tfrom>(d_object, (Tfrom(T::*)())function), 1212 minpriv_, 1213 std::string(units_), 1214 display_, 1215 std::string(desc_), 1216 min, 1217 max, 1218 def); 1219 std::ostringstream oss(std::ostringstream::out); 1220 oss << block_alias << "::" << functionbase; 1221 d_id = oss.str(); 1222 // std::cerr << "REGISTERING GET CONST: " << d_id << " " << desc_ << " " << 1223 // display_ << std::endl; 1224 rpcmanager::get()->i()->registerQueryCallback(d_id, inserter); 1225 #endif 1226 } 1227 1228 1229 /*! 1230 * \brief Adds the ability to get the variable over ControlPort. 1231 * 1232 * \details 1233 * 1234 * Allows us to add non gr::block related objects to 1235 * ControlPort. Instead of using the block's alias, we give it a \p 1236 * name and the actual pointer to the object as \p obj. We just need 1237 * to make sure that the pointer to this object is always valid. 1238 * 1239 * \param name Name of the object being set up for ControlPort access 1240 * \param functionbase The name of the function that we'll access over ControlPort 1241 * \param obj A pointer to the object itself 1242 * \param function A function pointer to the real function accessed when called 1243 * something like: &[block class]\::set_[variable]() 1244 * \param min Expected minimum value the parameter can hold 1245 * \param max Expected maximum value the parameter can hold 1246 * \param def Expected default value the parameter can hold 1247 * \param units_ A string to describe what units to represent the variable with 1248 * \param desc_ A string to describing the variable. 1249 * \param minpriv_ The required minimum privilege level 1250 * \param display_ The display mask 1251 */ 1252 rpcbasic_register_get(const std::string& name, 1253 const char* functionbase, 1254 T* obj, 1255 Tfrom (T::*function)(), 1256 const pmt::pmt_t& min, 1257 const pmt::pmt_t& max, 1258 const pmt::pmt_t& def, 1259 const char* units_ = "", 1260 const char* desc_ = "", 1261 priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, 1262 DisplayType display_ = DISPNULL) 1263 { 1264 d_min = min; 1265 d_max = max; 1266 d_def = def; 1267 d_units = units_; 1268 d_desc = desc_; 1269 d_minpriv = minpriv_; 1270 d_display = display_; 1271 d_object = obj; 1272 #ifdef GR_RPCSERVER_ENABLED 1273 callbackregister_base::queryCallback_t inserter( 1274 new rpcbasic_inserter<T, Tfrom>(d_object, function), 1275 minpriv_, 1276 std::string(units_), 1277 display_, 1278 std::string(desc_), 1279 min, 1280 max, 1281 def); 1282 std::ostringstream oss(std::ostringstream::out); 1283 oss << name << "::" << functionbase; 1284 d_id = oss.str(); 1285 // std::cerr << "REGISTERING GET: " << d_id << " " << desc_ << std::endl; 1286 rpcmanager::get()->i()->registerQueryCallback(d_id, inserter); 1287 #endif 1288 } 1289 1290 1291 /*! 1292 * \brief Same as above that allows using '[variable]() const' 1293 * getter functions. 1294 */ 1295 rpcbasic_register_get(const std::string& name, 1296 const char* functionbase, 1297 T* obj, 1298 Tfrom (T::*function)() const, 1299 const pmt::pmt_t& min, 1300 const pmt::pmt_t& max, 1301 const pmt::pmt_t& def, 1302 const char* units_ = "", 1303 const char* desc_ = "", 1304 priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, 1305 DisplayType display_ = DISPNULL) 1306 { 1307 d_min = min; 1308 d_max = max; 1309 d_def = def; 1310 d_units = units_; 1311 d_desc = desc_; 1312 d_minpriv = minpriv_; 1313 d_display = display_; 1314 d_object = obj; 1315 #ifdef GR_RPCSERVER_ENABLED 1316 callbackregister_base::queryCallback_t inserter( 1317 new rpcbasic_inserter<T, Tfrom>(d_object, (Tfrom(T::*)())function), 1318 minpriv_, 1319 std::string(units_), 1320 display_, 1321 std::string(desc_), 1322 min, 1323 max, 1324 def); 1325 std::ostringstream oss(std::ostringstream::out); 1326 oss << name << "::" << functionbase; 1327 d_id = oss.str(); 1328 // std::cerr << "REGISTERING GET CONST: " << d_id << " " << desc_ << " " << 1329 // display_ << std::endl; 1330 rpcmanager::get()->i()->registerQueryCallback(d_id, inserter); 1331 #endif 1332 } 1333 ~rpcbasic_register_get()1334 ~rpcbasic_register_get() 1335 { 1336 #ifdef GR_RPCSERVER_ENABLED 1337 rpcmanager::get()->i()->unregisterQueryCallback(d_id); 1338 #endif 1339 } 1340 min()1341 pmt::pmt_t min() const { return d_min; } max()1342 pmt::pmt_t max() const { return d_max; } def()1343 pmt::pmt_t def() const { return d_def; } units()1344 std::string units() const { return d_units; } description()1345 std::string description() const { return d_desc; } privilege_level()1346 priv_lvl_t privilege_level() const { return d_minpriv; } default_display()1347 DisplayType default_display() const { return d_display; } 1348 set_min(pmt::pmt_t p)1349 void set_min(pmt::pmt_t p) { d_min = p; } set_max(pmt::pmt_t p)1350 void set_max(pmt::pmt_t p) { d_max = p; } set_def(pmt::pmt_t p)1351 void set_def(pmt::pmt_t p) { d_def = p; } units(std::string u)1352 void units(std::string u) { d_units = u; } description(std::string d)1353 void description(std::string d) { d_desc = d; } privilege_level(priv_lvl_t p)1354 void privilege_level(priv_lvl_t p) { d_minpriv = p; } default_display(DisplayType d)1355 void default_display(DisplayType d) { d_display = d; } 1356 1357 private: 1358 std::string d_id; 1359 pmt::pmt_t d_min, d_max, d_def; 1360 std::string d_units, d_desc; 1361 priv_lvl_t d_minpriv; 1362 DisplayType d_display; 1363 T* d_object; 1364 }; 1365 1366 1367 /********************************************************************* 1368 * RPC Register Variable Classes 1369 ********************************************************************/ 1370 1371 /*! 1372 * \brief Registers a read-only function to get a parameter over ControlPort. 1373 * 1374 * \details 1375 * 1376 * This class allows us to remotely get a value or parameter of the 1377 * block over ControlPort. Unlike the rpcbasic_register_get class, 1378 * this version is passed the variable directly and establishes a 1379 * getter for us, so there is no need to have a getter function 1380 * already in the object. 1381 * 1382 * This version is for read-only get access. 1383 * 1384 * We can set the (expected) minimum (\p min), maximum (\p max), and 1385 * default (\p def) of the variables we will get. These values are not 1386 * enforced, however, but can be useful for setting up graphs and 1387 * other ways of bounding the data. 1388 * 1389 * This class also allows us to provide information to the user about 1390 * the variable, such as an appropriate unit (\p units_) as well as a 1391 * description (\p desc_) about what the variable does. 1392 * 1393 * The privilege (\p minpriv_) level is the minimum privilege level a 1394 * remote must identify with to be able to call this function. 1395 * 1396 * We also provide display hints (\p display_), which can be used by 1397 * the ControlPort client application to know how to best display or 1398 * even print the data. This is a mask of options for variables set in 1399 * rpccallbackregister_base.h. The mask is defined by one of the 1400 * "DisplayType Plotting Types" and or'd with any of the "DisplayType 1401 * Options" features. See "Display Options" in \ref page_ctrlport for 1402 * details. 1403 */ 1404 template <typename Tfrom> 1405 class rpcbasic_register_variable : public rpcbasic_base 1406 { 1407 protected: 1408 rpcbasic_register_get<rpcbasic_register_variable<Tfrom>, Tfrom> d_rpc_reg; 1409 Tfrom* d_variable; get()1410 Tfrom get() { return *d_variable; } 1411 1412 public: setptr(Tfrom * _variable)1413 void setptr(Tfrom* _variable) 1414 { 1415 rpcbasic_register_variable<Tfrom>::d_variable = _variable; 1416 } 1417 1418 /*! Empty constructor which should never be called but needs to 1419 * exist for ues in varous STL data structures 1420 */ rpcbasic_register_variable()1421 rpcbasic_register_variable() 1422 : d_rpc_reg("FAIL", 1423 "FAIL", 1424 this, 1425 &rpcbasic_register_variable::get, 1426 pmt::PMT_NIL, 1427 pmt::PMT_NIL, 1428 pmt::PMT_NIL, 1429 DISPNULL, 1430 "FAIL", 1431 "FAIL", 1432 RPC_PRIVLVL_MIN), 1433 d_variable(NULL) 1434 { 1435 throw std::runtime_error( 1436 "ERROR: rpcbasic_register_variable called with no args. If this happens, " 1437 "someone has tried to use rpcbasic_register_variable incorrectly."); 1438 }; 1439 1440 /*! 1441 * \brief Adds the ability to get the variable over ControlPort. 1442 * 1443 * \details 1444 * 1445 * Creates a new getter accessor function to read \p variable. 1446 * 1447 * \param namebase Name of the object being set up for ControlPort access 1448 * \param functionbase The name of the function that we'll access over ControlPort 1449 * \param variable A pointer to the variable, possibly as a member of a class 1450 * \param min Expected minimum value the parameter can hold 1451 * \param max Expected maximum value the parameter can hold 1452 * \param def Expected default value the parameter can hold 1453 * \param units_ A string to describe what units to represent the variable with 1454 * \param desc_ A string to describing the variable. 1455 * \param minpriv_ The required minimum privilege level 1456 * \param display_ The display mask 1457 */ 1458 rpcbasic_register_variable(const std::string& namebase, 1459 const char* functionbase, 1460 Tfrom* variable, 1461 const pmt::pmt_t& min, 1462 const pmt::pmt_t& max, 1463 const pmt::pmt_t& def, 1464 const char* units_ = "", 1465 const char* desc_ = "", 1466 priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, 1467 DisplayType display_ = DISPNULL) 1468 : d_rpc_reg(namebase, 1469 functionbase, 1470 this, 1471 &rpcbasic_register_variable::get, 1472 min, 1473 max, 1474 def, 1475 units_, 1476 desc_, 1477 minpriv_, 1478 display_), 1479 d_variable(variable) 1480 { 1481 // std::cerr << "REGISTERING VAR: " << " " << desc_ << std::endl; 1482 } 1483 }; 1484 1485 1486 /*! 1487 * \brief Registers a read/write function to get and set a parameter 1488 * over ControlPort. 1489 * 1490 * \details 1491 * 1492 * This class allows us to remotely get and/or set a value or 1493 * parameter of the block over ControlPort. Unlike the 1494 * rpcbasic_register_get class, this version is passed the variable 1495 * directly and establishes a getter for us, so there is no need to 1496 * have a getter function already in the object. 1497 * 1498 * This version establishes both get and set functions and so provides 1499 * read/write access to the variable. 1500 * 1501 * We can set the (expected) minimum (\p min), maximum (\p max), and 1502 * default (\p def) of the variables we will get. These values are not 1503 * enforced, however, but can be useful for setting up graphs and 1504 * other ways of bounding the data. 1505 * 1506 * This class also allows us to provide information to the user about 1507 * the variable, such as an appropriate unit (\p units_) as well as a 1508 * description (\p desc_) about what the variable does. 1509 * 1510 * The privilege (\p minpriv_) level is the minimum privilege level a 1511 * remote must identify with to be able to call this function. 1512 * 1513 * We also provide display hints (\p display_), which can be used by 1514 * the ControlPort client application to know how to best display or 1515 * even print the data. This is a mask of options for variables set in 1516 * rpccallbackregister_base.h. The mask is defined by one of the 1517 * "DisplayType Plotting Types" and or'd with any of the "DisplayType 1518 * Options" features. See "Display Options" in \ref page_ctrlport for 1519 * details. 1520 */ 1521 template <typename Tfrom> 1522 class rpcbasic_register_variable_rw : public rpcbasic_register_variable<Tfrom> 1523 { 1524 private: 1525 rpcbasic_register_set<rpcbasic_register_variable_rw<Tfrom>, Tfrom> d_rpc_regset; 1526 1527 public: 1528 /*! Empty constructor which should never be called but needs to 1529 * exist for ues in varous STL data structures. 1530 */ rpcbasic_register_variable_rw()1531 rpcbasic_register_variable_rw() 1532 : d_rpc_regset("FAIL", 1533 "FAIL", 1534 this, 1535 &rpcbasic_register_variable<Tfrom>::get, 1536 pmt::PMT_NIL, 1537 pmt::PMT_NIL, 1538 pmt::PMT_NIL, 1539 DISPNULL, 1540 "FAIL", 1541 "FAIL", 1542 RPC_PRIVLVL_MIN) 1543 { 1544 throw std::runtime_error( 1545 "ERROR: rpcbasic_register_variable_rw called with no args. if this happens " 1546 "someone used rpcbasic_register_variable_rw incorrectly.\n"); 1547 }; 1548 set(Tfrom _variable)1549 void set(Tfrom _variable) 1550 { 1551 *(rpcbasic_register_variable<Tfrom>::d_variable) = _variable; 1552 } 1553 1554 /*! 1555 * \brief Adds the ability to set and get the variable over ControlPort. 1556 * 1557 * \details 1558 * 1559 * Creates new getter and setter accessor functions to read and write \p variable. 1560 * 1561 * \param namebase Name of the object being set up for ControlPort access 1562 * \param functionbase The name of the function that we'll access over ControlPort 1563 * \param variable A pointer to the variable, possibly as a member of a class 1564 * \param min Expected minimum value the parameter can hold 1565 * \param max Expected maximum value the parameter can hold 1566 * \param def Expected default value the parameter can hold 1567 * \param units_ A string to describe what units to represent the variable with 1568 * \param desc_ A string to describing the variable. 1569 * \param minpriv The required minimum privilege level 1570 * \param display_ The display mask 1571 */ 1572 rpcbasic_register_variable_rw(const std::string& namebase, 1573 const char* functionbase, 1574 Tfrom* variable, 1575 const pmt::pmt_t& min, 1576 const pmt::pmt_t& max, 1577 const pmt::pmt_t& def, 1578 const char* units_ = "", 1579 const char* desc_ = "", 1580 priv_lvl_t minpriv = RPC_PRIVLVL_MIN, 1581 DisplayType display_ = DISPNULL) 1582 : rpcbasic_register_variable<Tfrom>( 1583 namebase, functionbase, variable, min, max, def, units_, desc_), 1584 d_rpc_regset(namebase, 1585 functionbase, 1586 this, 1587 &rpcbasic_register_variable_rw::set, 1588 min, 1589 max, 1590 def, 1591 units_, 1592 desc_, 1593 minpriv, 1594 display_) 1595 { 1596 // no action 1597 } 1598 }; 1599 1600 1601 /*! 1602 * \brief Registers a message handler function to post a message to a 1603 * block's handler. 1604 */ 1605 template <typename T> 1606 class rpcbasic_register_handler : public rpcbasic_base 1607 { 1608 public: 1609 /*! 1610 * \brief Adds the ability to pass a message over ControlPort. 1611 * 1612 * \details 1613 * This makes any message handler function available over 1614 * ControlPort. Since message handlers always take in a single PMT 1615 * message input, this interface provides a very generic way of 1616 * setting values in a block in a flowgraph. 1617 * 1618 * \param block_alias Alias of the block 1619 * \param handler The name of the message port in the block 1620 * \param units_ A string to describe what units to represent the variable with 1621 * \param desc_ A string to describing the variable. 1622 * \param minpriv_ The required minimum privilege level 1623 * \param display_ The display mask 1624 */ 1625 rpcbasic_register_handler(const std::string& block_alias, 1626 const char* handler, 1627 const char* units_ = "", 1628 const char* desc_ = "", 1629 priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, 1630 DisplayType display_ = DISPNULL) 1631 { 1632 d_units = units_; 1633 d_desc = desc_; 1634 d_minpriv = minpriv_; 1635 d_display = display_; 1636 d_object = dynamic_cast<T*>( 1637 global_block_registry.block_lookup(pmt::intern(block_alias)).get()); 1638 #ifdef GR_RPCSERVER_ENABLED 1639 callbackregister_base::handlerCallback_t inserter( 1640 new rpcbasic_handler<T>(d_object, handler), 1641 minpriv_, 1642 std::string(units_), 1643 display_, 1644 std::string(desc_), 1645 0, 1646 0, 1647 0); 1648 std::ostringstream oss(std::ostringstream::out); 1649 oss << block_alias << "::" << handler; 1650 d_id = oss.str(); 1651 // std::cerr << "REGISTERING GET: " << d_id << " " << desc_ << std::endl; 1652 rpcmanager::get()->i()->registerHandlerCallback(d_id, inserter); 1653 #endif 1654 } 1655 ~rpcbasic_register_handler()1656 ~rpcbasic_register_handler() 1657 { 1658 #ifdef GR_RPCSERVER_ENABLED 1659 rpcmanager::get()->i()->unregisterHandlerCallback(d_id); 1660 #endif 1661 } 1662 units()1663 std::string units() const { return d_units; } description()1664 std::string description() const { return d_desc; } privilege_level()1665 priv_lvl_t privilege_level() const { return d_minpriv; } default_display()1666 DisplayType default_display() const { return d_display; } 1667 units(std::string u)1668 void units(std::string u) { d_units = u; } description(std::string d)1669 void description(std::string d) { d_desc = d; } privilege_level(priv_lvl_t p)1670 void privilege_level(priv_lvl_t p) { d_minpriv = p; } default_display(DisplayType d)1671 void default_display(DisplayType d) { d_display = d; } 1672 1673 private: 1674 std::string d_id; 1675 std::string d_units, d_desc; 1676 priv_lvl_t d_minpriv; 1677 DisplayType d_display; 1678 T* d_object; 1679 }; 1680 1681 1682 #endif 1683