diff options
Diffstat (limited to 'gnuradio-runtime/include/gnuradio')
79 files changed, 9706 insertions, 0 deletions
diff --git a/gnuradio-runtime/include/gnuradio/CMakeLists.txt b/gnuradio-runtime/include/gnuradio/CMakeLists.txt new file mode 100644 index 0000000000..aece490e45 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/CMakeLists.txt @@ -0,0 +1,105 @@ +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +add_subdirectory(messages) +add_subdirectory(thread) + +######################################################################## +# Install header files +######################################################################## +install(FILES + api.h + attributes.h + basic_block.h + block.h + block_detail.h + block_gateway.h + block_registry.h + buffer.h + constants.h + dispatcher.h + endianness.h + error_handler.h + expj.h + feval.h + flowgraph.h + fxpt.h + fxpt_nco.h + fxpt_vco.h + gr_complex.h + hier_block2.h + high_res_timer.h + io_signature.h + math.h + message.h + misc.h + msg_accepter.h + msg_handler.h + msg_queue.h + nco.h + prefs.h + py_feval.h + pycallback_object.h + random.h + realtime.h + realtime_impl.h + runtime_types.h + single_threaded_scheduler.h + tags.h + tagged_stream_block.h + top_block.h + tpb_detail.h + select_handler.h + sincos.h + sptr_magic.h + sync_block.h + sync_decimator.h + sync_interpolator.h + sys_paths.h + timer.h + types.h + sys_pri.h + unittests.h + ice_application_base.h + IcePy_Communicator.h + ice_server_template.h + rpccallbackregister_base.h + rpcmanager_base.h + rpcmanager.h + rpcpmtconverters_ice.h + rpcregisterhelpers.h + rpcserver_aggregator.h + rpcserver_base.h + rpcserver_booter_aggregator.h + rpcserver_booter_base.h + rpcserver_booter_ice.h + rpcserver_ice.h + rpcserver_selector.h + ${CMAKE_CURRENT_SOURCE_DIR}/logger.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio + COMPONENT "runtime_devel" +) + +########################################################################## +# Configure logger +########################################################################## +CONFIGURE_FILE( + ${CMAKE_CURRENT_SOURCE_DIR}/logger.h.in + ${CMAKE_CURRENT_BINARY_DIR}/logger.h +)
\ No newline at end of file diff --git a/gnuradio-runtime/include/gnuradio/IcePy_Communicator.h b/gnuradio-runtime/include/gnuradio/IcePy_Communicator.h new file mode 100644 index 0000000000..2dd0cc7bba --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/IcePy_Communicator.h @@ -0,0 +1,35 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_COMMUNICATOR_H +#define ICEPY_COMMUNICATOR_H + +#include <Ice/CommunicatorF.h> +#include <gnuradio/api.h> + +namespace IcePy +{ + +extern PyTypeObject CommunicatorType; + +GR_RUNTIME_API bool initCommunicator(PyObject*); + +GR_RUNTIME_API Ice::CommunicatorPtr getCommunicator(PyObject*); + +GR_RUNTIME_API PyObject* createCommunicator(const Ice::CommunicatorPtr&); +GR_RUNTIME_API PyObject* getCommunicatorWrapper(const Ice::CommunicatorPtr&); + +} + +extern "C" PyObject* IcePy_initialize(PyObject*, PyObject*); +extern "C" PyObject* IcePy_initializeWithProperties(PyObject*, PyObject*); +extern "C" PyObject* IcePy_initializeWithLogger(PyObject*, PyObject*); +extern "C" PyObject* IcePy_initializeWithPropertiesAndLogger(PyObject*, PyObject*); + +#endif diff --git a/gnuradio-runtime/include/gnuradio/api.h b/gnuradio-runtime/include/gnuradio/api.h new file mode 100644 index 0000000000..1c68b8c8b8 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/api.h @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_RUNTIME_API_H +#define INCLUDED_GR_RUNTIME_RUNTIME_API_H + +#include <gnuradio/attributes.h> + +#ifdef gnuradio_runtime_EXPORTS +# define GR_RUNTIME_API __GR_ATTR_EXPORT +#else +# define GR_RUNTIME_API __GR_ATTR_IMPORT +#endif + +#endif /* INCLUDED_GR_RUNTIME_RUNTIME_API_H */ diff --git a/gnuradio-runtime/include/gnuradio/attributes.h b/gnuradio-runtime/include/gnuradio/attributes.h new file mode 100644 index 0000000000..5baa52e7d3 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/attributes.h @@ -0,0 +1,74 @@ +/* + * Copyright 2010 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GNURADIO_ATTRIBUTES_H +#define INCLUDED_GNURADIO_ATTRIBUTES_H + +//////////////////////////////////////////////////////////////////////// +// Cross-platform attribute macros +//////////////////////////////////////////////////////////////////////// +#if defined __GNUC__ +# define __GR_ATTR_ALIGNED(x) __attribute__((aligned(x))) +# define __GR_ATTR_UNUSED __attribute__((unused)) +# define __GR_ATTR_INLINE __attribute__((always_inline)) +# define __GR_ATTR_DEPRECATED __attribute__((deprecated)) +# if __GNUC__ >= 4 +# define __GR_ATTR_EXPORT __attribute__((visibility("default"))) +# define __GR_ATTR_IMPORT __attribute__((visibility("default"))) +# else +# define __GR_ATTR_EXPORT +# define __GR_ATTR_IMPORT +# endif +#elif _MSC_VER +# define __GR_ATTR_ALIGNED(x) __declspec(align(x)) +# define __GR_ATTR_UNUSED +# define __GR_ATTR_INLINE __forceinline +# define __GR_ATTR_DEPRECATED __declspec(deprecated) +# define __GR_ATTR_EXPORT __declspec(dllexport) +# define __GR_ATTR_IMPORT __declspec(dllimport) +#else +# define __GR_ATTR_ALIGNED(x) +# define __GR_ATTR_UNUSED +# define __GR_ATTR_INLINE +# define __GR_ATTR_DEPRECATED +# define __GR_ATTR_EXPORT +# define __GR_ATTR_IMPORT +#endif + +//////////////////////////////////////////////////////////////////////// +// define inline when building C +//////////////////////////////////////////////////////////////////////// +#if defined(_MSC_VER) && !defined(__cplusplus) && !defined(inline) +# define inline __inline +#endif + +//////////////////////////////////////////////////////////////////////// +// suppress warnings +//////////////////////////////////////////////////////////////////////// +#ifdef _MSC_VER +# pragma warning(disable: 4251) // class 'A<T>' needs to have dll-interface to be used by clients of class 'B' +# pragma warning(disable: 4275) // non dll-interface class ... used as base for dll-interface class ... +# pragma warning(disable: 4244) // conversion from 'double' to 'float', possible loss of data +# pragma warning(disable: 4305) // 'initializing' : truncation from 'double' to 'float' +# pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + +#endif /* INCLUDED_GNURADIO_ATTRIBUTES_H */ diff --git a/gnuradio-runtime/include/gnuradio/basic_block.h b/gnuradio-runtime/include/gnuradio/basic_block.h new file mode 100644 index 0000000000..be385465d1 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/basic_block.h @@ -0,0 +1,354 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2008,2009,2011,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_BASIC_BLOCK_H +#define INCLUDED_GR_BASIC_BLOCK_H + +#include <gnuradio/api.h> +#include <gnuradio/sptr_magic.h> +#include <gnuradio/msg_accepter.h> +#include <gnuradio/runtime_types.h> +#include <gnuradio/io_signature.h> +#include <gnuradio/thread/thread.h> +#include <boost/enable_shared_from_this.hpp> +#include <boost/function.hpp> +#include <boost/foreach.hpp> +#include <boost/thread/condition_variable.hpp> +#include <iostream> +#include <string> +#include <deque> +#include <map> + +#ifdef GR_CTRLPORT +#include <gnuradio/rpcregisterhelpers.h> +#endif + +namespace gr { + + /*! + * \brief The abstract base class for all signal processing blocks. + * \ingroup internal + * + * Basic blocks are the bare abstraction of an entity that has a + * name, a set of inputs and outputs, and a message queue. These + * are never instantiated directly; rather, this is the abstract + * parent class of both gr_hier_block, which is a recursive + * container, and block, which implements actual signal + * processing functions. + */ + class GR_RUNTIME_API basic_block : public msg_accepter, + public boost::enable_shared_from_this<basic_block> + { + typedef boost::function<void(pmt::pmt_t)> msg_handler_t; + + private: + //msg_handler_t d_msg_handler; + typedef std::map<pmt::pmt_t , msg_handler_t, pmt::comperator> d_msg_handlers_t; + d_msg_handlers_t d_msg_handlers; + + typedef std::deque<pmt::pmt_t> msg_queue_t; + typedef std::map<pmt::pmt_t, msg_queue_t, pmt::comperator> msg_queue_map_t; + typedef std::map<pmt::pmt_t, msg_queue_t, pmt::comperator>::iterator msg_queue_map_itr; + std::map<pmt::pmt_t, boost::shared_ptr<boost::condition_variable>, pmt::comperator> msg_queue_ready; + + gr::thread::mutex mutex; //< protects all vars + + protected: + friend class flowgraph; + friend class flat_flowgraph; // TODO: will be redundant + friend class tpb_thread_body; + + enum vcolor { WHITE, GREY, BLACK }; + + std::string d_name; + gr::io_signature::sptr d_input_signature; + gr::io_signature::sptr d_output_signature; + long d_unique_id; + long d_symbolic_id; + std::string d_symbol_name; + std::string d_symbol_alias; + vcolor d_color; + bool d_rpc_set; + + msg_queue_map_t msg_queue; + std::vector<boost::any> d_rpc_vars; // container for all RPC variables + + basic_block(void) {} // allows pure virtual interface sub-classes + + //! Protected constructor prevents instantiation by non-derived classes + basic_block(const std::string &name, + gr::io_signature::sptr input_signature, + gr::io_signature::sptr output_signature); + + //! may only be called during constructor + void set_input_signature(gr::io_signature::sptr iosig) { + d_input_signature = iosig; + } + + //! may only be called during constructor + void set_output_signature(gr::io_signature::sptr iosig) { + d_output_signature = iosig; + } + + /*! + * \brief Allow the flowgraph to set for sorting and partitioning + */ + void set_color(vcolor color) { d_color = color; } + vcolor color() const { return d_color; } + + /*! + * \brief Tests if there is a handler attached to port \p which_port + */ + bool has_msg_handler(pmt::pmt_t which_port) { + return (d_msg_handlers.find(which_port) != d_msg_handlers.end()); + } + + /* + * This function is called by the runtime system to dispatch messages. + * + * The thread-safety guarantees mentioned in set_msg_handler are + * implemented by the callers of this method. + */ + virtual void dispatch_msg(pmt::pmt_t which_port, pmt::pmt_t msg) + { + // AA Update this + if(has_msg_handler(which_port)) { // Is there a handler? + d_msg_handlers[which_port](msg); // Yes, invoke it. + } + } + + // Message passing interface + pmt::pmt_t message_subscribers; + + public: + virtual ~basic_block(); + long unique_id() const { return d_unique_id; } + long symbolic_id() const { return d_symbolic_id; } + std::string name() const { return d_name; } + std::string symbol_name() const { return d_symbol_name; } + gr::io_signature::sptr input_signature() const { return d_input_signature; } + gr::io_signature::sptr output_signature() const { return d_output_signature; } + basic_block_sptr to_basic_block(); // Needed for Python type coercion + bool alias_set() { return !d_symbol_alias.empty(); } + std::string alias(){ return alias_set()?d_symbol_alias:symbol_name(); } + pmt::pmt_t alias_pmt(){ return pmt::intern(alias()); } + void set_block_alias(std::string name); + + // ** Message passing interface ** + void message_port_register_in(pmt::pmt_t port_id); + void message_port_register_out(pmt::pmt_t port_id); + void message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg); + void message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target); + void message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target); + + virtual bool message_port_is_hier(pmt::pmt_t port_id) { (void) port_id; std::cout << "is_hier\n"; return false; } + virtual bool message_port_is_hier_in(pmt::pmt_t port_id) { (void) port_id; std::cout << "is_hier_in\n"; return false; } + virtual bool message_port_is_hier_out(pmt::pmt_t port_id) { (void) port_id; std::cout << "is_hier_out\n"; return false; } + + /*! + * \brief Get input message port names. + * + * Returns the available input message ports for a block. The + * return object is a PMT vector that is filled with PMT symbols. + */ + pmt::pmt_t message_ports_in(); + + /*! + * \brief Get output message port names. + * + * Returns the available output message ports for a block. The + * return object is a PMT vector that is filled with PMT symbols. + */ + pmt::pmt_t message_ports_out(); + + /*! + * Accept msg, place in queue, arrange for thread to be awakened if it's not already. + */ + void _post(pmt::pmt_t which_port, pmt::pmt_t msg); + + //! is the queue empty? + //bool empty_p(const pmt::pmt_t &which_port) const { return msg_queue[which_port].empty(); } + bool empty_p(pmt::pmt_t which_port) { + if(msg_queue.find(which_port) == msg_queue.end()) + throw std::runtime_error("port does not exist!"); + return msg_queue[which_port].empty(); + } + bool empty_p() { + bool rv = true; + BOOST_FOREACH(msg_queue_map_t::value_type &i, msg_queue) { + rv &= msg_queue[i.first].empty(); + } + return rv; + } + + //! How many messages in the queue? + size_t nmsgs(pmt::pmt_t which_port) { + if(msg_queue.find(which_port) == msg_queue.end()) + throw std::runtime_error("port does not exist!"); + return msg_queue[which_port].size(); + } + + //| Acquires and release the mutex + void insert_tail( pmt::pmt_t which_port, pmt::pmt_t msg); + /*! + * \returns returns pmt at head of queue or pmt::pmt_t() if empty. + */ + pmt::pmt_t delete_head_nowait( pmt::pmt_t which_port); + + /*! + * \returns returns pmt at head of queue or pmt::pmt_t() if empty. + */ + pmt::pmt_t delete_head_blocking( pmt::pmt_t which_port); + + msg_queue_t::iterator get_iterator(pmt::pmt_t which_port) { + return msg_queue[which_port].begin(); + } + + void erase_msg(pmt::pmt_t which_port, msg_queue_t::iterator it) { + msg_queue[which_port].erase(it); + } + + virtual bool has_msg_port(pmt::pmt_t which_port) { + if(msg_queue.find(which_port) != msg_queue.end()) { + return true; + } + if(pmt::dict_has_key(message_subscribers, which_port)) { + return true; + } + return false; + } + +#ifdef GR_CTRLPORT + /*! + * \brief Add an RPC variable (get or set). + * + * Using controlport, we create new getters/setters and need to + * store them. Each block has a vector to do this, and these never + * need to be accessed again once they are registered with the RPC + * backend. This function takes a + * boost::shared_sptr<rpcbasic_base> so that when the block is + * deleted, all RPC registered variables are cleaned up. + * + * \param s an rpcbasic_sptr of the new RPC variable register to store. + */ + void add_rpc_variable(rpcbasic_sptr s) + { + d_rpc_vars.push_back(s); + } +#endif /* GR_CTRLPORT */ + + /*! + * \brief Set up the RPC registered variables. + * + * This must be overloaded by a block that wants to use + * controlport. This is where rpcbasic_register_{get,set} pointers + * are created, which then get wrapped as shared pointers + * (rpcbasic_sptr(...)) and stored using add_rpc_variable. + */ + virtual void setup_rpc() {}; + + /*! + * \brief Ask if this block has been registered to the RPC. + * + * We can only register a block once, so we use this to protect us + * from calling it multiple times. + */ + bool is_rpc_set() { return d_rpc_set; } + + /*! + * \brief When the block is registered with the RPC, set this. + */ + void rpc_set() { d_rpc_set = true; } + + /*! + * \brief Confirm that ninputs and noutputs is an acceptable combination. + * + * \param ninputs number of input streams connected + * \param noutputs number of output streams connected + * + * \returns true if this is a valid configuration for this block. + * + * This function is called by the runtime system whenever the + * topology changes. Most classes do not need to override this. + * This check is in addition to the constraints specified by the + * input and output gr::io_signatures. + */ + virtual bool check_topology(int ninputs, int noutputs) { + (void)ninputs; + (void)noutputs; + return true; + } + + /*! + * \brief Set the callback that is fired when messages are available. + * + * \p msg_handler can be any kind of function pointer or function object + * that has the signature: + * <pre> + * void msg_handler(pmt::pmt msg); + * </pre> + * + * (You may want to use boost::bind to massage your callable into + * the correct form. See gr::blocks::nop for an example that sets + * up a class method as the callback.) + * + * Blocks that desire to handle messages must call this method in + * their constructors to register the handler that will be invoked + * when messages are available. + * + * If the block inherits from block, the runtime system will + * ensure that msg_handler is called in a thread-safe manner, such + * that work and msg_handler will never be called concurrently. + * This allows msg_handler to update state variables without + * having to worry about thread-safety issues with work, + * general_work or another invocation of msg_handler. + * + * If the block inherits from hier_block2, the runtime system + * will ensure that no reentrant calls are made to msg_handler. + */ + template <typename T> void set_msg_handler(pmt::pmt_t which_port, T msg_handler) { + if(msg_queue.find(which_port) == msg_queue.end()) { + throw std::runtime_error("attempt to set_msg_handler() on bad input message port!"); + } + d_msg_handlers[which_port] = msg_handler_t(msg_handler); + } + }; + + inline bool operator<(basic_block_sptr lhs, basic_block_sptr rhs) + { + return lhs->unique_id() < rhs->unique_id(); + } + + typedef std::vector<basic_block_sptr> basic_block_vector_t; + typedef std::vector<basic_block_sptr>::iterator basic_block_viter_t; + + GR_RUNTIME_API long basic_block_ncurrently_allocated(); + + inline std::ostream &operator << (std::ostream &os, basic_block_sptr basic_block) + { + os << basic_block->name() << "(" << basic_block->unique_id() << ")"; + return os; + } + +} /* namespace gr */ + +#endif /* INCLUDED_GR_BASIC_BLOCK_H */ diff --git a/gnuradio-runtime/include/gnuradio/block.h b/gnuradio-runtime/include/gnuradio/block.h new file mode 100644 index 0000000000..fd6c48c29b --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/block.h @@ -0,0 +1,714 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2007,2009,2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_BLOCK_H +#define INCLUDED_GR_RUNTIME_BLOCK_H + +#include <gnuradio/api.h> +#include <gnuradio/basic_block.h> +#include <gnuradio/tags.h> +#include <gnuradio/logger.h> + +namespace gr { + + /*! + * \brief The abstract base class for all 'terminal' processing blocks. + * \ingroup base_blk + * + * A signal processing flow is constructed by creating a tree of + * hierarchical blocks, which at any level may also contain terminal + * nodes that actually implement signal processing functions. This + * is the base class for all such leaf nodes. + * + * Blocks have a set of input streams and output streams. The + * input_signature and output_signature define the number of input + * streams and output streams respectively, and the type of the data + * items in each stream. + * + * Although blocks may consume data on each input stream at a + * different rate, all outputs streams must produce data at the same + * rate. That rate may be different from any of the input rates. + * + * User derived blocks override two methods, forecast and + * general_work, to implement their signal processing + * behavior. forecast is called by the system scheduler to determine + * how many items are required on each input stream in order to + * produce a given number of output items. + * + * general_work is called to perform the signal processing in the + * block. It reads the input items and writes the output items. + */ + class GR_RUNTIME_API block : public basic_block + { + public: + + //! Magic return values from general_work + enum { + WORK_CALLED_PRODUCE = -2, + WORK_DONE = -1 + }; + + enum tag_propagation_policy_t { + TPP_DONT = 0, + TPP_ALL_TO_ALL = 1, + TPP_ONE_TO_ONE = 2 + }; + + virtual ~block(); + + /*! + * Assume block computes y_i = f(x_i, x_i-1, x_i-2, x_i-3...) + * History is the number of x_i's that are examined to produce one y_i. + * This comes in handy for FIR filters, where we use history to + * ensure that our input contains the appropriate "history" for the + * filter. History should be equal to the number of filter taps. + */ + unsigned history() const { return d_history; } + void set_history(unsigned history) { d_history = history; } + + /*! + * \brief Return true if this block has a fixed input to output rate. + * + * If true, then fixed_rate_in_to_out and fixed_rate_out_to_in may be called. + */ + bool fixed_rate() const { return d_fixed_rate; } + + // ---------------------------------------------------------------- + // override these to define your behavior + // ---------------------------------------------------------------- + + /*! + * \brief Estimate input requirements given output request + * + * \param noutput_items number of output items to produce + * \param ninput_items_required number of input items required on each input stream + * + * Given a request to product \p noutput_items, estimate the + * number of data items required on each input stream. The + * estimate doesn't have to be exact, but should be close. + */ + virtual void forecast(int noutput_items, + gr_vector_int &ninput_items_required); + + /*! + * \brief compute output items from input items + * + * \param noutput_items number of output items to write on each output stream + * \param ninput_items number of input items available on each input stream + * \param input_items vector of pointers to the input items, one entry per input stream + * \param output_items vector of pointers to the output items, one entry per output stream + * + * \returns number of items actually written to each output stream, or -1 on EOF. + * It is OK to return a value less than noutput_items. -1 <= return value <= noutput_items + * + * general_work must call consume or consume_each to indicate how + * many items were consumed on each input stream. + */ + virtual int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + /*! + * \brief Called to enable drivers, etc for i/o devices. + * + * This allows a block to enable an associated driver to begin + * transfering data just before we start to execute the scheduler. + * The end result is that this reduces latency in the pipeline + * when dealing with audio devices, usrps, etc. + */ + virtual bool start(); + + /*! + * \brief Called to disable drivers, etc for i/o devices. + */ + virtual bool stop(); + + // ---------------------------------------------------------------- + + /*! + * \brief Constrain the noutput_items argument passed to forecast and general_work + * + * set_output_multiple causes the scheduler to ensure that the + * noutput_items argument passed to forecast and general_work will + * be an integer multiple of \param multiple The default value of + * output multiple is 1. + */ + void set_output_multiple(int multiple); + int output_multiple() const { return d_output_multiple; } + bool output_multiple_set() const { return d_output_multiple_set; } + + /*! + * \brief Constrains buffers to work on a set item alignment (for SIMD) + * + * set_alignment_multiple causes the scheduler to ensure that the + * noutput_items argument passed to forecast and general_work will + * be an integer multiple of \param multiple The default value is + * 1. + * + * This control is similar to the output_multiple setting, except + * that if the number of items passed to the block is less than + * the output_multiple, this value is ignored and the block can + * produce like normal. The d_unaligned value is set to the number + * of items the block is off by. In the next call to general_work, + * the noutput_items is set to d_unaligned or less until + * d_unaligned==0. The buffers are now aligned again and the + * aligned calls can be performed again. + */ + void set_alignment(int multiple); + int alignment() const { return d_output_multiple; } + + void set_unaligned(int na); + int unaligned() const { return d_unaligned; } + void set_is_unaligned(bool u); + bool is_unaligned() const { return d_is_unaligned; } + + /*! + * \brief Tell the scheduler \p how_many_items of input stream \p + * which_input were consumed. + */ + void consume(int which_input, int how_many_items); + + /*! + * \brief Tell the scheduler \p how_many_items were consumed on + * each input stream. + */ + void consume_each(int how_many_items); + + /*! + * \brief Tell the scheduler \p how_many_items were produced on + * output stream \p which_output. + * + * If the block's general_work method calls produce, \p + * general_work must return WORK_CALLED_PRODUCE. + */ + void produce(int which_output, int how_many_items); + + /*! + * \brief Set the approximate output rate / input rate + * + * Provide a hint to the buffer allocator and scheduler. + * The default relative_rate is 1.0 + * + * decimators have relative_rates < 1.0 + * interpolators have relative_rates > 1.0 + */ + void set_relative_rate(double relative_rate); + + /*! + * \brief return the approximate output rate / input rate + */ + double relative_rate() const { return d_relative_rate; } + + /* + * The following two methods provide special case info to the + * scheduler in the event that a block has a fixed input to output + * ratio. sync_block, sync_decimator and + * sync_interpolator override these. If you're fixed rate, + * subclass one of those. + */ + /*! + * \brief Given ninput samples, return number of output samples that will be produced. + * N.B. this is only defined if fixed_rate returns true. + * Generally speaking, you don't need to override this. + */ + virtual int fixed_rate_ninput_to_noutput(int ninput); + + /*! + * \brief Given noutput samples, return number of input samples required to produce noutput. + * N.B. this is only defined if fixed_rate returns true. + * Generally speaking, you don't need to override this. + */ + virtual int fixed_rate_noutput_to_ninput(int noutput); + + /*! + * \brief Return the number of items read on input stream which_input + */ + uint64_t nitems_read(unsigned int which_input); + + /*! + * \brief Return the number of items written on output stream which_output + */ + uint64_t nitems_written(unsigned int which_output); + + /*! + * \brief Asks for the policy used by the scheduler to moved tags downstream. + */ + tag_propagation_policy_t tag_propagation_policy(); + + /*! + * \brief Set the policy by the scheduler to determine how tags are moved downstream. + */ + void set_tag_propagation_policy(tag_propagation_policy_t p); + + /*! + * \brief Return the minimum number of output items this block can + * produce during a call to work. + * + * Should be 0 for most blocks. Useful if we're dealing with + * packets and the block produces one packet per call to work. + */ + int min_noutput_items() const { return d_min_noutput_items; } + + /*! + * \brief Set the minimum number of output items this block can + * produce during a call to work. + * + * \param m the minimum noutput_items this block can produce. + */ + void set_min_noutput_items(int m) { d_min_noutput_items = m; } + + /*! + * \brief Return the maximum number of output items this block will + * handle during a call to work. + */ + int max_noutput_items(); + + /*! + * \brief Set the maximum number of output items this block will + * handle during a call to work. + * + * \param m the maximum noutput_items this block will handle. + */ + void set_max_noutput_items(int m); + + /*! + * \brief Clear the switch for using the max_noutput_items value of this block. + * + * When is_set_max_noutput_items() returns 'true', the scheduler + * will use the value returned by max_noutput_items() to limit the + * size of the number of items possible for this block's work + * function. If is_set_max_notput_items() returns 'false', then + * the scheduler ignores the internal value and uses the value set + * globally in the top_block. + * + * Use this value to clear the 'is_set' flag so the scheduler will + * ignore this. Use the set_max_noutput_items(m) call to both set + * a new value for max_noutput_items and to reenable its use in + * the scheduler. + */ + void unset_max_noutput_items(); + + /*! + * \brief Ask the block if the flag is or is not set to use the + * internal value of max_noutput_items during a call to work. + */ + bool is_set_max_noutput_items(); + + /* + * Used to expand the vectors that hold the min/max buffer sizes. + * + * Specifically, when -1 is used, the vectors are just initialized + * with 1 value; this is used by the flat_flowgraph to expand when + * required to add a new value for new ports on these blocks. + */ + void expand_minmax_buffer(int port) + { + if((size_t)port >= d_max_output_buffer.size()) + set_max_output_buffer(port, -1); + if((size_t)port >= d_min_output_buffer.size()) + set_min_output_buffer(port, -1); + } + + /*! + * \brief Returns max buffer size on output port \p i. + */ + long max_output_buffer(size_t i) + { + if(i >= d_max_output_buffer.size()) + throw std::invalid_argument("basic_block::max_output_buffer: port out of range."); + return d_max_output_buffer[i]; + } + + /*! + * \brief Sets max buffer size on all output ports. + */ + void set_max_output_buffer(long max_output_buffer) + { + for(int i = 0; i < output_signature()->max_streams(); i++) { + set_max_output_buffer(i, max_output_buffer); + } + } + + /*! + * \brief Sets max buffer size on output port \p port. + */ + void set_max_output_buffer(int port, long max_output_buffer) + { + if((size_t)port >= d_max_output_buffer.size()) + d_max_output_buffer.push_back(max_output_buffer); + else + d_max_output_buffer[port] = max_output_buffer; + } + + /*! + * \brief Returns min buffer size on output port \p i. + */ + long min_output_buffer(size_t i) + { + if(i >= d_min_output_buffer.size()) + throw std::invalid_argument("basic_block::min_output_buffer: port out of range."); + return d_min_output_buffer[i]; + } + + /*! + * \brief Sets min buffer size on all output ports. + */ + void set_min_output_buffer(long min_output_buffer) + { + for(int i=0; i<output_signature()->max_streams(); i++) { + set_min_output_buffer(i, min_output_buffer); + } + } + + /*! + * \brief Sets min buffer size on output port \p port. + */ + void set_min_output_buffer(int port, long min_output_buffer) + { + if((size_t)port >= d_min_output_buffer.size()) + d_min_output_buffer.push_back(min_output_buffer); + else + d_min_output_buffer[port] = min_output_buffer; + } + + // --------------- Performance counter functions ------------- + + /*! + * \brief Gets instantaneous noutput_items performance counter. + */ + float pc_noutput_items(); + + /*! + * \brief Gets average noutput_items performance counter. + */ + float pc_noutput_items_avg(); + + /*! + * \brief Gets variance of noutput_items performance counter. + */ + float pc_noutput_items_var(); + + /*! + * \brief Gets instantaneous num items produced performance counter. + */ + float pc_nproduced(); + + /*! + * \brief Gets average num items produced performance counter. + */ + float pc_nproduced_avg(); + + /*! + * \brief Gets variance of num items produced performance counter. + */ + float pc_nproduced_var(); + + /*! + * \brief Gets instantaneous fullness of \p which input buffer. + */ + float pc_input_buffers_full(int which); + + /*! + * \brief Gets average fullness of \p which input buffer. + */ + float pc_input_buffers_full_avg(int which); + + /*! + * \brief Gets variance of fullness of \p which input buffer. + */ + float pc_input_buffers_full_var(int which); + + /*! + * \brief Gets instantaneous fullness of all input buffers. + */ + std::vector<float> pc_input_buffers_full(); + + /*! + * \brief Gets average fullness of all input buffers. + */ + std::vector<float> pc_input_buffers_full_avg(); + + /*! + * \brief Gets variance of fullness of all input buffers. + */ + std::vector<float> pc_input_buffers_full_var(); + + /*! + * \brief Gets instantaneous fullness of \p which input buffer. + */ + float pc_output_buffers_full(int which); + + /*! + * \brief Gets average fullness of \p which input buffer. + */ + float pc_output_buffers_full_avg(int which); + + /*! + * \brief Gets variance of fullness of \p which input buffer. + */ + float pc_output_buffers_full_var(int which); + + /*! + * \brief Gets instantaneous fullness of all output buffers. + */ + std::vector<float> pc_output_buffers_full(); + + /*! + * \brief Gets average fullness of all output buffers. + */ + std::vector<float> pc_output_buffers_full_avg(); + + /*! + * \brief Gets variance of fullness of all output buffers. + */ + std::vector<float> pc_output_buffers_full_var(); + + /*! + * \brief Gets instantaneous clock cycles spent in work. + */ + float pc_work_time(); + + /*! + * \brief Gets average clock cycles spent in work. + */ + float pc_work_time_avg(); + + /*! + * \brief Gets average clock cycles spent in work. + */ + float pc_work_time_var(); + + /*! + * \brief Resets the performance counters + */ + void reset_perf_counters(); + + /*! + * \brief Sets up export of perf. counters to ControlPort. Only + * called by the scheduler. + */ + void setup_pc_rpc(); + + /*! + * \brief Checks if this block is already exporting perf. counters + * to ControlPort. + */ + bool is_pc_rpc_set() { return d_pc_rpc_set; } + + /*! + * \brief If the block calls this in its constructor, it's + * perf. counters will not be exported. + */ + void no_pc_rpc() { d_pc_rpc_set = true; } + + + // ---------------------------------------------------------------------------- + // Functions to handle thread affinity + + /*! + * \brief Set the thread's affinity to processor core \p n. + * + * \param mask a vector of ints of the core numbers available to this block. + */ + void set_processor_affinity(const std::vector<int> &mask); + + /*! + * \brief Remove processor affinity to a specific core. + */ + void unset_processor_affinity(); + + /*! + * \brief Get the current processor affinity. + */ + std::vector<int> processor_affinity() { return d_affinity; } + + // ---------------------------------------------------------------------------- + + private: + int d_output_multiple; + bool d_output_multiple_set; + int d_unaligned; + bool d_is_unaligned; + double d_relative_rate; // approx output_rate / input_rate + block_detail_sptr d_detail; // implementation details + unsigned d_history; + bool d_fixed_rate; + bool d_max_noutput_items_set; // if d_max_noutput_items is valid + int d_max_noutput_items; // value of max_noutput_items for this block + int d_min_noutput_items; + tag_propagation_policy_t d_tag_propagation_policy; // policy for moving tags downstream + std::vector<int> d_affinity; // thread affinity proc. mask + bool d_pc_rpc_set; + + protected: + block(void) {} // allows pure virtual interface sub-classes + block(const std::string &name, + gr::io_signature::sptr input_signature, + gr::io_signature::sptr output_signature); + + void set_fixed_rate(bool fixed_rate) { d_fixed_rate = fixed_rate; } + + /*! + * \brief Adds a new tag onto the given output buffer. + * + * \param which_output an integer of which output stream to attach the tag + * \param abs_offset a uint64 number of the absolute item number + * assicated with the tag. Can get from nitems_written. + * \param key the tag key as a PMT symbol + * \param value any PMT holding any value for the given key + * \param srcid optional source ID specifier; defaults to PMT_F + */ + inline void add_item_tag(unsigned int which_output, + uint64_t abs_offset, + const pmt::pmt_t &key, + const pmt::pmt_t &value, + const pmt::pmt_t &srcid=pmt::PMT_F) + { + tag_t tag; + tag.offset = abs_offset; + tag.key = key; + tag.value = value; + tag.srcid = srcid; + this->add_item_tag(which_output, tag); + } + + /*! + * \brief Adds a new tag onto the given output buffer. + * + * \param which_output an integer of which output stream to attach the tag + * \param tag the tag object to add + */ + void add_item_tag(unsigned int which_output, const tag_t &tag); + + /*! + * \brief Removes a tag from the given input buffer. + * + * \param which_input an integer of which input stream to remove the tag from + * \param abs_offset a uint64 number of the absolute item number + * assicated with the tag. Can get from nitems_written. + * \param key the tag key as a PMT symbol + * \param value any PMT holding any value for the given key + * \param srcid optional source ID specifier; defaults to PMT_F + * + * If no such tag is found, does nothing. + */ + inline void remove_item_tag(unsigned int which_input, + uint64_t abs_offset, + const pmt::pmt_t &key, + const pmt::pmt_t &value, + const pmt::pmt_t &srcid=pmt::PMT_F) + { + tag_t tag; + tag.offset = abs_offset; + tag.key = key; + tag.value = value; + tag.srcid = srcid; + this->remove_item_tag(which_input, tag); + } + + /*! + * \brief Removes a tag from the given input buffer. + * + * If no such tag is found, does nothing. + * + * \param which_input an integer of which input stream to remove the tag from + * \param tag the tag object to remove + */ + void remove_item_tag(unsigned int which_input, const tag_t &tag); + + /*! + * \brief Given a [start,end), returns a vector of all tags in the range. + * + * Range of counts is from start to end-1. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param which_input an integer of which input stream to pull from + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + */ + void get_tags_in_range(std::vector<tag_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end); + + /*! + * \brief Given a [start,end), returns a vector of all tags in the + * range with a given key. + * + * Range of counts is from start to end-1. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param which_input an integer of which input stream to pull from + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + * \param key a PMT symbol key to filter only tags of this key + */ + void get_tags_in_range(std::vector<tag_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end, + const pmt::pmt_t &key); + + std::vector<long> d_max_output_buffer; + std::vector<long> d_min_output_buffer; + + /*! Used by block's setters and work functions to make + * setting/resetting of parameters thread-safe. + * + * Used by calling gr::thread::scoped_lock l(d_setlock); + */ + gr::thread::mutex d_setlock; + + /*! Used by blocks to access the logger system. + */ + gr::logger_ptr d_logger; + gr::logger_ptr d_debug_logger; + + // These are really only for internal use, but leaving them public avoids + // having to work up an ever-varying list of friend GR_RUNTIME_APIs + + public: + block_detail_sptr detail() const { return d_detail; } + void set_detail(block_detail_sptr detail) { d_detail = detail; } + }; + + typedef std::vector<block_sptr> block_vector_t; + typedef std::vector<block_sptr>::iterator block_viter_t; + + inline block_sptr cast_to_block_sptr(basic_block_sptr p) + { + return boost::dynamic_pointer_cast<block, basic_block>(p); + } + + std::ostream& + operator << (std::ostream& os, const block *m); + +} /* namespace gr */ + +#endif /* INCLUDED_GR_RUNTIME_BLOCK_H */ diff --git a/gnuradio-runtime/include/gnuradio/block_detail.h b/gnuradio-runtime/include/gnuradio/block_detail.h new file mode 100644 index 0000000000..0a8615a2b6 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/block_detail.h @@ -0,0 +1,261 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more detail. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_BLOCK_DETAIL_H +#define INCLUDED_GR_RUNTIME_BLOCK_DETAIL_H + +#include <gnuradio/api.h> +#include <gnuradio/runtime_types.h> +#include <gnuradio/tpb_detail.h> +#include <gnuradio/tags.h> +#include <gnuradio/high_res_timer.h> +#include <stdexcept> + +namespace gr { + + /*! + * \brief Implementation details to support the signal processing abstraction + * \ingroup internal + * + * This class contains implementation detail that should be "out of + * sight" of almost all users of GNU Radio. This decoupling also + * means that we can make changes to the guts without having to + * recompile everything. + */ + class GR_RUNTIME_API block_detail + { + public: + ~block_detail(); + + int ninputs() const { return d_ninputs; } + int noutputs() const { return d_noutputs; } + bool sink_p() const { return d_noutputs == 0; } + bool source_p() const { return d_ninputs == 0; } + + void set_done(bool done); + bool done() const { return d_done; } + + void set_input(unsigned int which, buffer_reader_sptr reader); + buffer_reader_sptr input(unsigned int which) + { + if(which >= d_ninputs) + throw std::invalid_argument("block_detail::input"); + return d_input[which]; + } + + void set_output(unsigned int which, buffer_sptr buffer); + buffer_sptr output(unsigned int which) + { + if(which >= d_noutputs) + throw std::invalid_argument("block_detail::output"); + return d_output[which]; + } + + /*! + * \brief Tell the scheduler \p how_many_items of input stream \p + * which_input were consumed. + */ + void consume(int which_input, int how_many_items); + + /*! + * \brief Tell the scheduler \p how_many_items were consumed on + * each input stream. + */ + void consume_each(int how_many_items); + + /*! + * \brief Tell the scheduler \p how_many_items were produced on + * output stream \p which_output. + */ + void produce(int which_output, int how_many_items); + + /*! + * \brief Tell the scheduler \p how_many_items were produced on + * each output stream. + */ + void produce_each(int how_many_items); + + // Return the number of items read on input stream which_input + uint64_t nitems_read(unsigned int which_input); + + // Return the number of items written on output stream which_output + uint64_t nitems_written(unsigned int which_output); + + /*! + * \brief Adds a new tag to the given output stream. + * + * Calls gr::buffer::add_item_tag(), + * which appends the tag onto its deque. + * + * \param which_output an integer of which output stream to attach the tag + * \param tag the tag object to add + */ + void add_item_tag(unsigned int which_output, const tag_t &tag); + + /*! + * \brief Removes a tag from the given input stream. + * + * Calls gr::buffer::remove_item_tag(), which removes the tag from + * its deque. + * + * \param which_input an integer of which input stream to remove the tag from + * \param tag the tag object to add + */ + void remove_item_tag(unsigned int which_input, const tag_t &tag); + + /*! + * \brief Given a [start,end), returns a vector of all tags in the range. + * + * Pass-through function to gr::buffer_reader to get a vector of + * tags in given range. Range of counts is from start to end-1. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param which_input an integer of which input stream to pull from + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + */ + void get_tags_in_range(std::vector<tag_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end); + + /*! + * \brief Given a [start,end), returns a vector of all tags in the + * range with a given key. + * + * Calls get_tags_in_range(which_input, abs_start, abs_end) to get + * a vector of tags from the buffers. This function then provides + * a secondary filter to the tags to extract only tags with the + * given 'key'. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param which_input an integer of which input stream to pull from + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + * \param key a PMT symbol to select only tags of this key + */ + void get_tags_in_range(std::vector<tag_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end, + const pmt::pmt_t &key); + + /*! + * \brief Set core affinity of block to the cores in the vector + * mask. + * + * \param mask a vector of ints of the core numbers available to + * this block. + */ + void set_processor_affinity(const std::vector<int> &mask); + + /*! + * \brief Unset core affinity. + */ + void unset_processor_affinity(); + + bool threaded; // set if thread is currently running. + gr::thread::gr_thread_t thread; // portable thread handle + + void start_perf_counters(); + void stop_perf_counters(int noutput_items, int nproduced); + void reset_perf_counters(); + + // Calls to get performance counter items + float pc_noutput_items(); + float pc_nproduced(); + float pc_input_buffers_full(size_t which); + std::vector<float> pc_input_buffers_full(); + float pc_output_buffers_full(size_t which); + std::vector<float> pc_output_buffers_full(); + float pc_work_time(); + + float pc_noutput_items_avg(); + float pc_nproduced_avg(); + float pc_input_buffers_full_avg(size_t which); + std::vector<float> pc_input_buffers_full_avg(); + float pc_output_buffers_full_avg(size_t which); + std::vector<float> pc_output_buffers_full_avg(); + float pc_work_time_avg(); + + float pc_noutput_items_var(); + float pc_nproduced_var(); + float pc_input_buffers_full_var(size_t which); + std::vector<float> pc_input_buffers_full_var(); + float pc_output_buffers_full_var(size_t which); + std::vector<float> pc_output_buffers_full_var(); + float pc_work_time_var(); + + tpb_detail d_tpb; // used by thread-per-block scheduler + int d_produce_or; + + // ---------------------------------------------------------------------------- + + private: + unsigned int d_ninputs; + unsigned int d_noutputs; + std::vector<buffer_reader_sptr> d_input; + std::vector<buffer_sptr> d_output; + bool d_done; + + // Performance counters + float d_ins_noutput_items; + float d_avg_noutput_items; + float d_var_noutput_items; + float d_ins_nproduced; + float d_avg_nproduced; + float d_var_nproduced; + std::vector<float> d_ins_input_buffers_full; + std::vector<float> d_avg_input_buffers_full; + std::vector<float> d_var_input_buffers_full; + std::vector<float> d_ins_output_buffers_full; + std::vector<float> d_avg_output_buffers_full; + std::vector<float> d_var_output_buffers_full; + gr::high_res_timer_type d_start_of_work, d_end_of_work; + float d_ins_work_time; + float d_avg_work_time; + float d_var_work_time; + float d_pc_counter; + + block_detail(unsigned int ninputs, unsigned int noutputs); + + friend struct tpb_detail; + + friend GR_RUNTIME_API block_detail_sptr + make_block_detail(unsigned int ninputs, unsigned int noutputs); + }; + + GR_RUNTIME_API block_detail_sptr + make_block_detail(unsigned int ninputs, unsigned int noutputs); + + GR_RUNTIME_API long + block_detail_ncurrently_allocated(); + +} /* namespace gr */ + +#endif /* INCLUDED_GR_RUNTIME_BLOCK_DETAIL_H */ diff --git a/gnuradio-runtime/include/gnuradio/block_gateway.h b/gnuradio-runtime/include/gnuradio/block_gateway.h new file mode 100644 index 0000000000..0f328de2e5 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/block_gateway.h @@ -0,0 +1,271 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011-2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RUNTIME_BLOCK_GATEWAY_H +#define INCLUDED_RUNTIME_BLOCK_GATEWAY_H + +#include <gnuradio/api.h> +#include <gnuradio/block.h> +#include <gnuradio/feval.h> + +namespace gr { + + /*! + * The work type enum tells the gateway what kind of block to + * implement. The choices are familiar gnuradio block overloads + * (sync, decim, interp). + */ + enum block_gw_work_type { + GR_BLOCK_GW_WORK_GENERAL, + GR_BLOCK_GW_WORK_SYNC, + GR_BLOCK_GW_WORK_DECIM, + GR_BLOCK_GW_WORK_INTERP, + }; + + /*! + * Shared message structure between python and gateway. + * Each action type represents a scheduler-called function. + */ + struct block_gw_message_type { + enum action_type { + ACTION_GENERAL_WORK, //dispatch work + ACTION_WORK, //dispatch work + ACTION_FORECAST, //dispatch forecast + ACTION_START, //dispatch start + ACTION_STOP, //dispatch stop + }; + + action_type action; + + int general_work_args_noutput_items; + std::vector<int> general_work_args_ninput_items; + std::vector<void *> general_work_args_input_items; //TODO this should be const void*, but swig cant int cast it right + std::vector<void *> general_work_args_output_items; + int general_work_args_return_value; + + int work_args_ninput_items; + int work_args_noutput_items; + std::vector<void *> work_args_input_items; //TODO this should be const void*, but swig cant int cast it right + std::vector<void *> work_args_output_items; + int work_args_return_value; + + int forecast_args_noutput_items; + std::vector<int> forecast_args_ninput_items_required; + + bool start_args_return_value; + + bool stop_args_return_value; + }; + + /*! + * The gateway block which performs all the magic. + * + * The gateway provides access to all the gr::block routines. + * The methods prefixed with gr::block__ are renamed + * to class methods without the prefix in python. + */ + class GR_RUNTIME_API block_gateway : virtual public gr::block + { + public: + // gr::block_gateway::sptr + typedef boost::shared_ptr<block_gateway> sptr; + + /*! + * Make a new gateway block. + * \param handler the swig director object with callback + * \param name the name of the block (Ex: "Shirley") + * \param in_sig the input signature for this block + * \param out_sig the output signature for this block + * \param work_type the type of block overload to implement + * \param factor the decimation or interpolation factor + * \return a new gateway block + */ + static sptr make(gr::feval_ll *handler, + const std::string &name, + gr::io_signature::sptr in_sig, + gr::io_signature::sptr out_sig, + const block_gw_work_type work_type, + const unsigned factor); + + //! Provide access to the shared message object + virtual block_gw_message_type &block_message(void) = 0; + + long block__unique_id(void) const { + return gr::block::unique_id(); + } + + std::string block__name(void) const { + return gr::block::name(); + } + + unsigned block__history(void) const { + return gr::block::history(); + } + + void block__set_history(unsigned history) { + return gr::block::set_history(history); + } + + void block__set_fixed_rate(bool fixed_rate) { + return gr::block::set_fixed_rate(fixed_rate); + } + + bool block__fixed_rate(void) const { + return gr::block::fixed_rate(); + } + + void block__set_output_multiple(int multiple) { + return gr::block::set_output_multiple(multiple); + } + + int block__output_multiple(void) const { + return gr::block::output_multiple(); + } + + void block__consume(int which_input, int how_many_items) { + return gr::block::consume(which_input, how_many_items); + } + + void block__consume_each(int how_many_items) { + return gr::block::consume_each(how_many_items); + } + + void block__produce(int which_output, int how_many_items) { + return gr::block::produce(which_output, how_many_items); + } + + void block__set_relative_rate(double relative_rate) { + return gr::block::set_relative_rate(relative_rate); + } + + double block__relative_rate(void) const { + return gr::block::relative_rate(); + } + + uint64_t block__nitems_read(unsigned int which_input) { + return gr::block::nitems_read(which_input); + } + + uint64_t block__nitems_written(unsigned int which_output) { + return gr::block::nitems_written(which_output); + } + + block::tag_propagation_policy_t block__tag_propagation_policy(void) { + return gr::block::tag_propagation_policy(); + } + + void block__set_tag_propagation_policy(block::tag_propagation_policy_t p) { + return gr::block::set_tag_propagation_policy(p); + } + + void block__add_item_tag(unsigned int which_output, + const tag_t &tag) + { + return gr::block::add_item_tag(which_output, tag); + } + + void block__add_item_tag(unsigned int which_output, + uint64_t abs_offset, + const pmt::pmt_t &key, + const pmt::pmt_t &value, + const pmt::pmt_t &srcid=pmt::PMT_F) + { + return gr::block::add_item_tag(which_output, abs_offset, + key, value, srcid); + } + + std::vector<tag_t> block__get_tags_in_range(unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end) + { + std::vector<gr::tag_t> tags; + gr::block::get_tags_in_range(tags, which_input, abs_start, abs_end); + return tags; + } + + std::vector<tag_t> block__get_tags_in_range(unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end, + const pmt::pmt_t &key) + { + std::vector<gr::tag_t> tags; + gr::block::get_tags_in_range(tags, which_input, abs_start, abs_end, key); + return tags; + } + + /* Message passing interface */ + void block__message_port_register_in(pmt::pmt_t port_id) { + gr::basic_block::message_port_register_in(port_id); + } + + void block__message_port_register_out(pmt::pmt_t port_id) { + gr::basic_block::message_port_register_out(port_id); + } + + void block__message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg) { + gr::basic_block::message_port_pub(port_id, msg); + } + + void block__message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target) { + gr::basic_block::message_port_sub(port_id, target); + } + + void block__message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target) { + gr::basic_block::message_port_unsub(port_id, target); + } + + pmt::pmt_t block__message_ports_in() { + return gr::basic_block::message_ports_in(); + } + + pmt::pmt_t block__message_ports_out() { + return gr::basic_block::message_ports_out(); + } + + void set_msg_handler_feval(pmt::pmt_t which_port, gr::feval_p *msg_handler) + { + if(msg_queue.find(which_port) == msg_queue.end()) { + throw std::runtime_error("attempt to set_msg_handler_feval() on bad input message port!"); + } + d_msg_handlers_feval[which_port] = msg_handler; + } + + protected: + typedef std::map<pmt::pmt_t, feval_p *, pmt::comperator> msg_handlers_feval_t; + msg_handlers_feval_t d_msg_handlers_feval; + + void dispatch_msg(pmt::pmt_t which_port, pmt::pmt_t msg) + { + // Is there a handler? + if(d_msg_handlers_feval.find(which_port) != d_msg_handlers_feval.end()) { + d_msg_handlers_feval[which_port]->calleval(msg); // Yes, invoke it. + } + else { + // Pass to generic dispatcher if not found + gr::basic_block::dispatch_msg(which_port, msg); + } + } + }; + +} /* namespace gr */ + +#endif /* INCLUDED_RUNTIME_BLOCK_GATEWAY_H */ diff --git a/gnuradio-runtime/include/gnuradio/block_registry.h b/gnuradio-runtime/include/gnuradio/block_registry.h new file mode 100644 index 0000000000..f94be2dafb --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/block_registry.h @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012-2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef GR_RUNTIME_BLOCK_REGISTRY_H +#define GR_RUNTIME_BLOCK_REGISTRY_H + +#include <gnuradio/api.h> +#include <gnuradio/basic_block.h> +#include <map> + +namespace gr { + +#ifndef GR_BASIC_BLOCK_H + class basic_block; + class block; +#endif + + class GR_RUNTIME_API block_registry + { + public: + block_registry(); + + long block_register(basic_block* block); + void block_unregister(basic_block* block); + + std::string register_symbolic_name(basic_block* block); + void register_symbolic_name(basic_block* block, std::string name); + + basic_block_sptr block_lookup(pmt::pmt_t symbol); + + void register_primitive(std::string blk, gr::block* ref); + void unregister_primitive(std::string blk); + void notify_blk(std::string blk); + + private: + //typedef std::map< long, basic_block_sptr > blocksubmap_t; + typedef std::map< long, basic_block* > blocksubmap_t; + typedef std::map< std::string, blocksubmap_t > blockmap_t; + + blockmap_t d_map; + pmt::pmt_t d_ref_map; + std::map< std::string, block*> primitive_map; + }; + +} /* namespace gr */ + +GR_RUNTIME_API extern gr::block_registry global_block_registry; + +#endif /* GR_RUNTIME_BLOCK_REGISTRY_H */ diff --git a/gnuradio-runtime/include/gnuradio/buffer.h b/gnuradio-runtime/include/gnuradio/buffer.h new file mode 100644 index 0000000000..490c8e0e9f --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/buffer.h @@ -0,0 +1,302 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009-2011,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_BUFFER_H +#define INCLUDED_GR_RUNTIME_BUFFER_H + +#include <gnuradio/api.h> +#include <gnuradio/runtime_types.h> +#include <gnuradio/tags.h> +#include <boost/weak_ptr.hpp> +#include <gnuradio/thread/thread.h> +#include <deque> + +namespace gr { + + class vmcircbuf; + + /*! + * \brief Allocate a buffer that holds at least \p nitems of size \p sizeof_item. + * + * The total size of the buffer will be rounded up to a system + * dependent boundary. This is typically the system page size, but + * under MS windows is 64KB. + * + * \param nitems is the minimum number of items the buffer will hold. + * \param sizeof_item is the size of an item in bytes. + * \param link is the block that writes to this buffer. + */ + GR_RUNTIME_API buffer_sptr make_buffer(int nitems, size_t sizeof_item, + block_sptr link=block_sptr()); + + /*! + * \brief Single writer, multiple reader fifo. + * \ingroup internal + */ + class GR_RUNTIME_API buffer + { + public: + virtual ~buffer(); + + /*! + * \brief return number of items worth of space available for writing + */ + int space_available(); + + /*! + * \brief return size of this buffer in items + */ + int bufsize() const { return d_bufsize; } + + /*! + * \brief return pointer to write buffer. + * + * The return value points at space that can hold at least + * space_available() items. + */ + void *write_pointer(); + + /*! + * \brief tell buffer that we wrote \p nitems into it + */ + void update_write_pointer(int nitems); + + void set_done(bool done); + bool done() const { return d_done; } + + /*! + * \brief Return the block that writes to this buffer. + */ + block_sptr link() { return block_sptr(d_link); } + + size_t nreaders() const { return d_readers.size(); } + buffer_reader* reader(size_t index) { return d_readers[index]; } + + gr::thread::mutex *mutex() { return &d_mutex; } + + uint64_t nitems_written() { return d_abs_write_offset; } + + size_t get_sizeof_item() { return d_sizeof_item; } + + /*! + * \brief Adds a new tag to the buffer. + * + * \param tag the new tag + */ + void add_item_tag(const tag_t &tag); + + /*! + * \brief Removes an existing tag from the buffer. + * + * If no such tag is found, does nothing. + * + * \param tag the tag that needs to be removed + */ + void remove_item_tag(const tag_t &tag); + + /*! + * \brief Removes all tags before \p max_time from buffer + * + * \param max_time the time (item number) to trim up until. + */ + void prune_tags(uint64_t max_time); + + std::deque<tag_t>::iterator get_tags_begin() { return d_item_tags.begin(); } + std::deque<tag_t>::iterator get_tags_end() { return d_item_tags.end(); } + + // ------------------------------------------------------------------------- + + private: + friend class buffer_reader; + friend GR_RUNTIME_API buffer_sptr make_buffer(int nitems, size_t sizeof_item, block_sptr link); + friend GR_RUNTIME_API buffer_reader_sptr buffer_add_reader(buffer_sptr buf, int nzero_preload, block_sptr link); + + protected: + char *d_base; // base address of buffer + unsigned int d_bufsize; // in items + private: + gr::vmcircbuf *d_vmcircbuf; + size_t d_sizeof_item; // in bytes + std::vector<buffer_reader *> d_readers; + boost::weak_ptr<block> d_link; // block that writes to this buffer + + // + // The mutex protects d_write_index, d_abs_write_offset, d_done, d_item_tags + // and the d_read_index's and d_abs_read_offset's in the buffer readers. + // + gr::thread::mutex d_mutex; + unsigned int d_write_index; // in items [0,d_bufsize) + uint64_t d_abs_write_offset; // num items written since the start + bool d_done; + std::deque<tag_t> d_item_tags; + uint64_t d_last_min_items_read; + + unsigned index_add(unsigned a, unsigned b) + { + unsigned s = a + b; + + if(s >= d_bufsize) + s -= d_bufsize; + + assert(s < d_bufsize); + return s; + } + + unsigned index_sub(unsigned a, unsigned b) + { + int s = a - b; + + if(s < 0) + s += d_bufsize; + + assert((unsigned) s < d_bufsize); + return s; + } + + virtual bool allocate_buffer(int nitems, size_t sizeof_item); + + /*! + * \brief constructor is private. Use gr_make_buffer to create instances. + * + * Allocate a buffer that holds at least \p nitems of size \p sizeof_item. + * + * \param nitems is the minimum number of items the buffer will hold. + * \param sizeof_item is the size of an item in bytes. + * \param link is the block that writes to this buffer. + * + * The total size of the buffer will be rounded up to a system + * dependent boundary. This is typically the system page size, but + * under MS windows is 64KB. + */ + buffer(int nitems, size_t sizeof_item, block_sptr link); + + /*! + * \brief disassociate \p reader from this buffer + */ + void drop_reader(buffer_reader *reader); + }; + + /*! + * \brief Create a new gr::buffer_reader and attach it to buffer \p buf + * \param buf is the buffer the \p gr::buffer_reader reads from. + * \param nzero_preload -- number of zero items to "preload" into buffer. + * \param link is the block that reads from the buffer using this gr::buffer_reader. + */ + GR_RUNTIME_API buffer_reader_sptr + buffer_add_reader(buffer_sptr buf, int nzero_preload, block_sptr link=block_sptr()); + + //! returns # of buffers currently allocated + GR_RUNTIME_API long buffer_ncurrently_allocated(); + + + // --------------------------------------------------------------------------- + + /*! + * \brief How we keep track of the readers of a gr::buffer. + * \ingroup internal + */ + class GR_RUNTIME_API buffer_reader + { + public: + ~buffer_reader(); + + /*! + * \brief Return number of items available for reading. + */ + int items_available() const; + + /*! + * \brief Return buffer this reader reads from. + */ + buffer_sptr buffer() const { return d_buffer; } + + /*! + * \brief Return maximum number of items that could ever be available for reading. + * This is used as a sanity check in the scheduler to avoid looping forever. + */ + int max_possible_items_available() const { return d_buffer->d_bufsize - 1; } + + /*! + * \brief return pointer to read buffer. + * + * The return value points to items_available() number of items + */ + const void *read_pointer(); + + /* + * \brief tell buffer we read \p items from it + */ + void update_read_pointer(int nitems); + + void set_done(bool done) { d_buffer->set_done(done); } + bool done() const { return d_buffer->done(); } + + gr::thread::mutex *mutex() { return d_buffer->mutex(); } + + uint64_t nitems_read() { return d_abs_read_offset; } + + size_t get_sizeof_item() { return d_buffer->get_sizeof_item(); } + + /*! + * \brief Return the block that reads via this reader. + * + */ + block_sptr link() { return block_sptr(d_link); } + + /*! + * \brief Given a [start,end), returns a vector all tags in the range. + * + * Get a vector of tags in given range. Range of counts is from start to end-1. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + */ + void get_tags_in_range(std::vector<tag_t> &v, + uint64_t abs_start, + uint64_t abs_end); + + // ------------------------------------------------------------------------- + + private: + friend class buffer; + friend GR_RUNTIME_API buffer_reader_sptr + buffer_add_reader(buffer_sptr buf, int nzero_preload, block_sptr link); + + buffer_sptr d_buffer; + unsigned int d_read_index; // in items [0,d->buffer.d_bufsize) + uint64_t d_abs_read_offset; // num items seen since the start + boost::weak_ptr<block> d_link; // block that reads via this buffer reader + + //! constructor is private. Use gr::buffer::add_reader to create instances + buffer_reader(buffer_sptr buffer, unsigned int read_index, block_sptr link); + }; + + //! returns # of buffer_readers currently allocated + GR_RUNTIME_API long buffer_reader_ncurrently_allocated (); + +} /* namespace gr */ + +#endif /* INCLUDED_GR_RUNTIME_BUFFER_H */ diff --git a/gnuradio-runtime/include/gnuradio/constants.h b/gnuradio-runtime/include/gnuradio/constants.h new file mode 100644 index 0000000000..5ae924ca0d --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/constants.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_CONSTANTS_H +#define INCLUDED_GR_CONSTANTS_H + +#include <gnuradio/api.h> +#include <string> + +namespace gr { + + /*! + * \brief return ./configure --prefix argument. Typically /usr/local + */ + GR_RUNTIME_API const std::string prefix(); + + /*! + * \brief return ./configure --sysconfdir argument. Typically $prefix/etc or /etc + */ + GR_RUNTIME_API const std::string sysconfdir(); + + /*! + * \brief return preferences file directory. Typically $sysconfdir/etc/conf.d + */ + GR_RUNTIME_API const std::string prefsdir(); + + /*! + * \brief return date/time of build, as set when 'bootstrap' is run + */ + GR_RUNTIME_API const std::string build_date(); + + /*! + * \brief return version string defined in configure.ac + */ + GR_RUNTIME_API const std::string version(); + +} /* namespace gr */ + +#endif /* INCLUDED_GR_CONSTANTS_H */ diff --git a/gnuradio-runtime/include/gnuradio/dispatcher.h b/gnuradio-runtime/include/gnuradio/dispatcher.h new file mode 100644 index 0000000000..ab1d6190c6 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/dispatcher.h @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_DISPATCHER_H +#define INCLUDED_GR_DISPATCHER_H + +#include <gnuradio/api.h> +#include <gnuradio/select_handler.h> +#include <vector> + +namespace gr { + + class dispatcher; + typedef boost::shared_ptr<dispatcher> dispatcher_sptr; + + GR_RUNTIME_API dispatcher_sptr dispatcher_singleton(); + GR_RUNTIME_API dispatcher_sptr make_dispatcher(); + + /*! + * \brief invoke callbacks based on select. + * \ingroup internal + * + * \sa gr_select_handler + */ + class GR_RUNTIME_API dispatcher + { + dispatcher(); + friend GR_RUNTIME_API dispatcher_sptr make_dispatcher(); + + std::vector<select_handler_sptr> d_handler; + int d_max_index; + + public: + ~dispatcher(); + + bool add_handler(select_handler_sptr handler); + bool del_handler(select_handler_sptr handler); + bool del_handler(select_handler *handler); + + /*! + * \brief Event dispatching loop. + * + * Enter a polling loop that only terminates after all + * gr::select_handlers have been removed. \p timeout sets the + * timeout parameter to the select() call, measured in seconds. + * + * \param timeout maximum number of seconds to block in select. + */ + void loop(double timeout=10); + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_DISPATCHER_H */ diff --git a/gnuradio-runtime/include/gnuradio/endianness.h b/gnuradio-runtime/include/gnuradio/endianness.h new file mode 100644 index 0000000000..43c21a1c15 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/endianness.h @@ -0,0 +1,32 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_ENDIANNESS_H +#define INCLUDED_GR_ENDIANNESS_H + +namespace gr { + + typedef enum {GR_MSB_FIRST, GR_LSB_FIRST} endianness_t; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_ENDIANNESS_H */ diff --git a/gnuradio-runtime/include/gnuradio/error_handler.h b/gnuradio-runtime/include/gnuradio/error_handler.h new file mode 100644 index 0000000000..2d6a8c3883 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/error_handler.h @@ -0,0 +1,125 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +/* + * This code is based on error.hh from the "Click Modular Router". + * Original copyright follows: + */ +/* + * error.{cc,hh} -- flexible classes for error reporting + * Eddie Kohler + * + * Copyright (c) 1999-2000 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, subject to the conditions + * listed in the Click LICENSE file. These conditions include: you must + * preserve this copyright notice, and you cannot mention the copyright + * holders in advertising related to the Software without their permission. + * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This + * notice is a summary of the Click LICENSE file; the license in that file is + * legally binding. + */ + +#ifndef INCLUDED_GR_ERROR_HANDLER_H +#define INCLUDED_GR_ERROR_HANDLER_H + +#include <gnuradio/api.h> +#include <stdarg.h> +#include <string> +#include <cstdio> // for FILE + +namespace gr { + + /*! + * \brief abstract error handler + * \ingroup base + */ + class GR_RUNTIME_API error_handler + { + public: + enum seriousness { + ERR_DEBUG = 0x00000000, + ERR_MESSAGE = 0x00010000, + ERR_WARNING = 0x00020000, + ERR_ERROR = 0x00030000, + ERR_FATAL = 0x00040000 + }; + + error_handler() {} + virtual ~error_handler(); + + static error_handler *default_handler(); + static error_handler *silent_handler(); + + static bool has_default_handler(); + static void set_default_handler(error_handler *errh); + + void debug(const char *format, ...); + void message(const char *format, ...); + void warning(const char *format, ...); + void error(const char *format, ...); + void fatal(const char *format, ...); + + virtual int nwarnings() const = 0; + virtual int nerrors() const = 0; + virtual void reset_counts() = 0; + + void verror(seriousness s, const char *format, va_list); + void verror_text(seriousness s, const std::string &text); + + protected: + virtual void count_error(seriousness s) = 0; + virtual void handle_text(seriousness s, const std::string &str) = 0; + std::string make_text(seriousness s, const char *format, va_list); + }; + + + class GR_RUNTIME_API base_error_handler : public error_handler + { + int d_nwarnings; + int d_nerrors; + + public: + base_error_handler() : d_nwarnings(0), d_nerrors(0) {} + int nwarnings() const { return d_nwarnings; } + int nerrors() const { return d_nerrors; } + void reset_counts() { d_nwarnings = d_nerrors = 0; } + void count_error(seriousness s); + }; + + class GR_RUNTIME_API file_error_handler : public base_error_handler + { + FILE *d_file; + int d_fd; + + public: + file_error_handler(FILE *file); + file_error_handler(int file_descriptor); + ~file_error_handler(); + + void handle_text(seriousness s, const std::string &str); + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_ERROR_HANDLER_H */ diff --git a/gnuradio-runtime/include/gnuradio/expj.h b/gnuradio-runtime/include/gnuradio/expj.h new file mode 100644 index 0000000000..7556e17011 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/expj.h @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_EXPJ_H +#define INCLUDED_GR_EXPJ_H + +#include <gnuradio/api.h> +#include <gnuradio/sincos.h> +#include <gnuradio/types.h> + +static inline gr_complex +gr_expj(float phase) +{ + float t_imag, t_real; + gr::sincosf(phase, &t_imag, &t_real); + return gr_complex(t_real, t_imag); +} + + +#endif /* INCLUDED_GR_EXPJ_H */ diff --git a/gnuradio-runtime/include/gnuradio/feval.h b/gnuradio-runtime/include/gnuradio/feval.h new file mode 100644 index 0000000000..40e3ad9a55 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/feval.h @@ -0,0 +1,187 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_FEVAL_H +#define INCLUDED_GR_FEVAL_H + +#include <gnuradio/api.h> +#include <gnuradio/gr_complex.h> +#include <pmt/pmt.h> + +namespace gr { + + /*! + * \brief base class for evaluating a function: double -> double + * \ingroup misc + * + * This class is designed to be subclassed in Python or C++ and is + * callable from both places. It uses SWIG's "director" feature to + * implement the magic. + * + * It's slow. Don't use it in a performance critical path. + * + * Override eval to define the behavior. + * Use calleval to invoke eval (this kludge is required to allow a + * python specific "shim" to be inserted. + */ + class GR_RUNTIME_API feval_dd + { + protected: + /*! + * \brief override this to define the function + */ + virtual double eval(double x); + + public: + feval_dd() {} + virtual ~feval_dd(); + + virtual double calleval(double x); // invoke "eval" + }; + + /*! + * \brief base class for evaluating a function: complex -> complex + * \ingroup misc + * + * This class is designed to be subclassed in Python or C++ and is + * callable from both places. It uses SWIG's "director" feature to + * implement the magic. + * + * It's slow. Don't use it in a performance critical path. + * + * Override eval to define the behavior. + * Use calleval to invoke eval (this kludge is required to allow a + * python specific "shim" to be inserted. + */ + class GR_RUNTIME_API feval_cc + { + protected: + /*! + * \brief override this to define the function + */ + virtual gr_complex eval(gr_complex x); + + public: + feval_cc() {} + virtual ~feval_cc(); + + virtual gr_complex calleval(gr_complex x); // invoke "eval" + }; + + /*! + * \brief base class for evaluating a function: long -> long + * \ingroup misc + * + * This class is designed to be subclassed in Python or C++ and is + * callable from both places. It uses SWIG's "director" feature to + * implement the magic. + * + * It's slow. Don't use it in a performance critical path. + * + * Override eval to define the behavior. + * Use calleval to invoke eval (this kludge is required to allow a + * python specific "shim" to be inserted. + */ + class GR_RUNTIME_API feval_ll + { + protected: + /*! + * \brief override this to define the function + */ + virtual long eval(long x); + + public: + feval_ll() {} + virtual ~feval_ll(); + + virtual long calleval(long x); // invoke "eval" + }; + + /*! + * \brief base class for evaluating a function: void -> void + * \ingroup misc + * + * This class is designed to be subclassed in Python or C++ and is + * callable from both places. It uses SWIG's "director" feature to + * implement the magic. + * + * It's slow. Don't use it in a performance critical path. + * + * Override eval to define the behavior. + * Use calleval to invoke eval (this kludge is required to allow a + * python specific "shim" to be inserted. + */ + class GR_RUNTIME_API feval + { + protected: + /*! + * \brief override this to define the function + */ + virtual void eval(); + + public: + feval() {} + virtual ~feval(); + + virtual void calleval(); // invoke "eval" + }; + + /*! + * \brief base class for evaluating a function: pmt -> void + * \ingroup misc + * + * This class is designed to be subclassed in Python or C++ and is + * callable from both places. It uses SWIG's "director" feature to + * implement the magic. + * + * It's slow. Don't use it in a performance critical path. + * + * Override eval to define the behavior. + * Use calleval to invoke eval (this kludge is required to allow a + * python specific "shim" to be inserted. + */ + class GR_RUNTIME_API feval_p + { + protected: + /*! + * \brief override this to define the function + */ + virtual void eval(pmt::pmt_t x); + + public: + feval_p() {} + virtual ~feval_p(); + + virtual void calleval(pmt::pmt_t x); // invoke "eval" + }; + + /*! + * \brief trivial examples / test cases showing C++ calling Python code + */ + GR_RUNTIME_API double feval_dd_example(feval_dd *f, double x); + GR_RUNTIME_API gr_complex feval_cc_example(feval_cc *f, gr_complex x); + GR_RUNTIME_API long feval_ll_example(feval_ll *f, long x); + GR_RUNTIME_API void feval_example(feval *f); + +} /* namespace gr */ + +#endif /* INCLUDED_GR_FEVAL_H */ diff --git a/gnuradio-runtime/include/gnuradio/flowgraph.h b/gnuradio-runtime/include/gnuradio/flowgraph.h new file mode 100644 index 0000000000..cfa451f11b --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/flowgraph.h @@ -0,0 +1,256 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2007,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_FLOWGRAPH_H +#define INCLUDED_GR_RUNTIME_FLOWGRAPH_H + +#include <gnuradio/api.h> +#include <gnuradio/basic_block.h> +#include <gnuradio/io_signature.h> +#include <iostream> + +namespace gr { + + /*! + * \brief Class representing a specific input or output graph endpoint + * \ingroup internal + */ + class GR_RUNTIME_API endpoint + { + private: + basic_block_sptr d_basic_block; + int d_port; + + public: + endpoint() : d_basic_block(), d_port(0) { } + endpoint(basic_block_sptr block, int port) { d_basic_block = block; d_port = port; } + basic_block_sptr block() const { return d_basic_block; } + int port() const { return d_port; } + + bool operator==(const endpoint &other) const; + }; + + inline bool endpoint::operator==(const endpoint &other) const + { + return (d_basic_block == other.d_basic_block && + d_port == other.d_port); + } + + class GR_RUNTIME_API msg_endpoint + { + private: + basic_block_sptr d_basic_block; + pmt::pmt_t d_port; + bool d_is_hier; + + public: + msg_endpoint() : d_basic_block(), d_port(pmt::PMT_NIL) { } + msg_endpoint(basic_block_sptr block, pmt::pmt_t port, bool is_hier=false) { + d_basic_block = block; d_port = port; d_is_hier = is_hier; + } + basic_block_sptr block() const { return d_basic_block; } + pmt::pmt_t port() const { return d_port; } + bool is_hier() const { return d_is_hier; } + void set_hier(bool h) { d_is_hier = h; } + + bool operator==(const msg_endpoint &other) const; + }; + + inline bool + msg_endpoint::operator==(const msg_endpoint &other) const + { + return (d_basic_block == other.d_basic_block && + pmt::equal(d_port, other.d_port)); + } + + // Hold vectors of gr::endpoint objects + typedef std::vector<endpoint> endpoint_vector_t; + typedef std::vector<endpoint>::iterator endpoint_viter_t; + + /*! + *\brief Class representing a connection between to graph endpoints + */ + class GR_RUNTIME_API edge + { + public: + edge() : d_src(), d_dst() { }; + edge(const endpoint &src, const endpoint &dst) + : d_src(src), d_dst(dst) { } + ~edge(); + + const endpoint &src() const { return d_src; } + const endpoint &dst() const { return d_dst; } + + private: + endpoint d_src; + endpoint d_dst; + }; + + // Hold vectors of gr::edge objects + typedef std::vector<edge> edge_vector_t; + typedef std::vector<edge>::iterator edge_viter_t; + + + /*! + *\brief Class representing a msg connection between to graph msg endpoints + */ + class GR_RUNTIME_API msg_edge + { + public: + msg_edge() : d_src(), d_dst() { }; + msg_edge(const msg_endpoint &src, const msg_endpoint &dst) + : d_src(src), d_dst(dst) { } + ~msg_edge() {} + + const msg_endpoint &src() const { return d_src; } + const msg_endpoint &dst() const { return d_dst; } + + private: + msg_endpoint d_src; + msg_endpoint d_dst; + }; + + // Hold vectors of gr::msg_edge objects + typedef std::vector<msg_edge> msg_edge_vector_t; + typedef std::vector<msg_edge>::iterator msg_edge_viter_t; + + // Create a shared pointer to a heap allocated flowgraph + // (types defined in runtime_types.h) + GR_RUNTIME_API flowgraph_sptr make_flowgraph(); + + /*! + * \brief Class representing a directed, acyclic graph of basic blocks + * \ingroup internal + */ + class GR_RUNTIME_API flowgraph + { + public: + friend GR_RUNTIME_API flowgraph_sptr make_flowgraph(); + + // Destruct an arbitrary flowgraph + ~flowgraph(); + + // Connect two endpoints + void connect(const endpoint &src, const endpoint &dst); + + // Disconnect two endpoints + void disconnect(const endpoint &src, const endpoint &dst); + + // Connect an output port to an input port (convenience) + void connect(basic_block_sptr src_block, int src_port, + basic_block_sptr dst_block, int dst_port); + + // Disconnect an input port from an output port (convenience) + void disconnect(basic_block_sptr src_block, int src_port, + basic_block_sptr dst_block, int dst_port); + + // Connect two msg endpoints + void connect(const msg_endpoint &src, const msg_endpoint &dst); + + // Disconnect two msg endpoints + void disconnect(const msg_endpoint &src, const msg_endpoint &dst); + + // Validate connectivity, raise exception if invalid + void validate(); + + // Clear existing flowgraph + void clear(); + + // Return vector of edges + const edge_vector_t &edges() const { return d_edges; } + + // Return vector of msg edges + const msg_edge_vector_t &msg_edges() const { return d_msg_edges; } + + // Return vector of connected blocks + basic_block_vector_t calc_used_blocks(); + + // Return toplogically sorted vector of blocks. All the sources come first. + basic_block_vector_t topological_sort(basic_block_vector_t &blocks); + + // Return vector of vectors of disjointly connected blocks, + // topologically sorted. + std::vector<basic_block_vector_t> partition(); + + protected: + basic_block_vector_t d_blocks; + edge_vector_t d_edges; + msg_edge_vector_t d_msg_edges; + + flowgraph(); + std::vector<int> calc_used_ports(basic_block_sptr block, bool check_inputs); + basic_block_vector_t calc_downstream_blocks(basic_block_sptr block, int port); + edge_vector_t calc_upstream_edges(basic_block_sptr block); + bool has_block_p(basic_block_sptr block); + edge calc_upstream_edge(basic_block_sptr block, int port); + + private: + void check_valid_port(gr::io_signature::sptr sig, int port); + void check_valid_port(const msg_endpoint &e); + void check_dst_not_used(const endpoint &dst); + void check_type_match(const endpoint &src, const endpoint &dst); + edge_vector_t calc_connections(basic_block_sptr block, bool check_inputs); // false=use outputs + void check_contiguity(basic_block_sptr block, const std::vector<int> &used_ports, bool check_inputs); + + basic_block_vector_t calc_downstream_blocks(basic_block_sptr block); + basic_block_vector_t calc_reachable_blocks(basic_block_sptr block, basic_block_vector_t &blocks); + void reachable_dfs_visit(basic_block_sptr block, basic_block_vector_t &blocks); + basic_block_vector_t calc_adjacent_blocks(basic_block_sptr block, basic_block_vector_t &blocks); + basic_block_vector_t sort_sources_first(basic_block_vector_t &blocks); + bool source_p(basic_block_sptr block); + void topological_dfs_visit(basic_block_sptr block, basic_block_vector_t &output); + }; + + // Convenience functions + inline + void flowgraph::connect(basic_block_sptr src_block, int src_port, + basic_block_sptr dst_block, int dst_port) + { + connect(endpoint(src_block, src_port), + endpoint(dst_block, dst_port)); + } + + inline + void flowgraph::disconnect(basic_block_sptr src_block, int src_port, + basic_block_sptr dst_block, int dst_port) + { + disconnect(endpoint(src_block, src_port), + endpoint(dst_block, dst_port)); + } + + inline std::ostream& + operator <<(std::ostream &os, const endpoint endp) + { + os << endp.block()->alias() << ":" << endp.port(); + return os; + } + + inline std::ostream& + operator <<(std::ostream &os, const edge edge) + { + os << edge.src() << "->" << edge.dst(); + return os; + } + +} /* namespace gr */ + +#endif /* INCLUDED_GR_RUNTIME_FLOWGRAPH_H */ diff --git a/gnuradio-runtime/include/gnuradio/fxpt.h b/gnuradio-runtime/include/gnuradio/fxpt.h new file mode 100644 index 0000000000..6143acafeb --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/fxpt.h @@ -0,0 +1,108 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_FXPT_H +#define INCLUDED_GR_FXPT_H + +#include <gnuradio/api.h> +#include <gnuradio/types.h> + +namespace gr { + + /*! + * \brief fixed point sine and cosine and friends. + * \ingroup misc + * + * fixed pt radians + * --------- -------- + * -2**31 -pi + * 0 0 + * 2**31-1 pi - epsilon + */ + class GR_RUNTIME_API fxpt + { + static const int WORDBITS = 32; + static const int NBITS = 10; + static const float s_sine_table[1 << NBITS][2]; + static const float PI; + static const float TWO_TO_THE_31; + + public: + static gr_int32 + float_to_fixed(float x) + { + // Fold x into -PI to PI. + int d = (int)floor(x/2/PI+0.5); + x -= d*2*PI; + // And convert to an integer. + return (gr_int32) ((float) x * TWO_TO_THE_31 / PI); + } + + static float + fixed_to_float (gr_int32 x) + { + return x * (PI / TWO_TO_THE_31); + } + + /*! + * \brief Given a fixed point angle x, return float sine (x) + */ + static float + sin(gr_int32 x) + { + gr_uint32 ux = x; + int index = ux >> (WORDBITS - NBITS); + return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1]; + } + + /* + * \brief Given a fixed point angle x, return float cosine (x) + */ + static float + cos (gr_int32 x) + { + gr_uint32 ux = x + 0x40000000; + int index = ux >> (WORDBITS - NBITS); + return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1]; + } + + /* + * \brief Given a fixedpoint angle x, return float cos(x) and sin (x) + */ + static void sincos(gr_int32 x, float *s, float *c) + { + gr_uint32 ux = x; + int sin_index = ux >> (WORDBITS - NBITS); + *s = s_sine_table[sin_index][0] * (ux >> 1) + s_sine_table[sin_index][1]; + + ux = x + 0x40000000; + int cos_index = ux >> (WORDBITS - NBITS); + *c = s_sine_table[cos_index][0] * (ux >> 1) + s_sine_table[cos_index][1]; + + return; + } + + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_FXPT_H */ diff --git a/gnuradio-runtime/include/gnuradio/fxpt_nco.h b/gnuradio-runtime/include/gnuradio/fxpt_nco.h new file mode 100644 index 0000000000..33a176d9b4 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/fxpt_nco.h @@ -0,0 +1,160 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2004,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_FXPT_NCO_H +#define INCLUDED_GR_FXPT_NCO_H + +#include <gnuradio/api.h> +#include <gnuradio/fxpt.h> +#include <gnuradio/gr_complex.h> +#include <stdint.h> + +namespace gr { + + /*! + * \brief Numerically Controlled Oscillator (NCO) + * \ingroup misc + */ + class /*GR_RUNTIME_API*/ fxpt_nco + { + uint32_t d_phase; + int32_t d_phase_inc; + + public: + fxpt_nco() : d_phase(0), d_phase_inc(0) {} + + ~fxpt_nco() {} + + // radians + void set_phase(float angle) { + d_phase = gr::fxpt::float_to_fixed(angle); + } + + void adjust_phase(float delta_phase) { + d_phase += gr::fxpt::float_to_fixed(delta_phase); + } + + // angle_rate is in radians / step + void set_freq(float angle_rate){ + d_phase_inc = gr::fxpt::float_to_fixed(angle_rate); + } + + // angle_rate is a delta in radians / step + void adjust_freq(float delta_angle_rate) + { + d_phase_inc += gr::fxpt::float_to_fixed(delta_angle_rate); + } + + // increment current phase angle + + void step() + { + d_phase += d_phase_inc; + } + + void step(int n) + { + d_phase += d_phase_inc * n; + } + + // units are radians / step + float get_phase() const { return gr::fxpt::fixed_to_float(d_phase); } + float get_freq() const { return gr::fxpt::fixed_to_float(d_phase_inc); } + + // compute sin and cos for current phase angle + void sincos(float *sinx, float *cosx) const + { + *sinx = gr::fxpt::sin(d_phase); + *cosx = gr::fxpt::cos(d_phase); + } + + // compute cos and sin for a block of phase angles + void sincos(gr_complex *output, int noutput_items, double ampl=1.0) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = gr_complex(gr::fxpt::cos(d_phase) * ampl, gr::fxpt::sin(d_phase) * ampl); + step(); + } + } + + // compute sin for a block of phase angles + void sin(float *output, int noutput_items, double ampl=1.0) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (float)(gr::fxpt::sin(d_phase) * ampl); + step(); + } + } + + // compute cos for a block of phase angles + void cos(float *output, int noutput_items, double ampl=1.0) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (float)(gr::fxpt::cos(d_phase) * ampl); + step (); + } + } + + // compute sin for a block of phase angles + void sin(short *output, int noutput_items, double ampl=1.0) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (short)(gr::fxpt::sin(d_phase) * ampl); + step(); + } + } + + // compute cos for a block of phase angles + void cos(short *output, int noutput_items, double ampl=1.0) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (short)(gr::fxpt::cos(d_phase) * ampl); + step(); + } + } + + // compute sin for a block of phase angles + void sin(int *output, int noutput_items, double ampl=1.0) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (int)(gr::fxpt::sin(d_phase) * ampl); + step(); + } + } + + // compute cos for a block of phase angles + void cos(int *output, int noutput_items, double ampl=1.0) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (int)(gr::fxpt::cos(d_phase) * ampl); + step(); + } + } + + // compute cos or sin for current phase angle + float cos() const { return gr::fxpt::cos(d_phase); } + float sin() const { return gr::fxpt::sin(d_phase); } + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_FXPT_NCO_H */ diff --git a/gnuradio-runtime/include/gnuradio/fxpt_vco.h b/gnuradio-runtime/include/gnuradio/fxpt_vco.h new file mode 100644 index 0000000000..77d58677ce --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/fxpt_vco.h @@ -0,0 +1,80 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2004,2005,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_FXPT_VCO_H +#define INCLUDED_GR_FXPT_VCO_H + +#include <gnuradio/api.h> +#include <gnuradio/fxpt.h> +#include <gnuradio/gr_complex.h> + +namespace gr { + + /*! + * \brief Voltage Controlled Oscillator (VCO) + * \ingroup misc + */ + class /*GR_RUNTIME_API*/ fxpt_vco { + gr_int32 d_phase; + + public: + fxpt_vco () : d_phase(0) {} + + ~fxpt_vco() {} + + // radians + void set_phase(float angle) { + d_phase = fxpt::float_to_fixed(angle); + } + + void adjust_phase(float delta_phase) { + d_phase += fxpt::float_to_fixed(delta_phase); + } + + float get_phase() const { + return fxpt::fixed_to_float(d_phase); + } + + // compute sin and cos for current phase angle + void sincos(float *sinx, float *cosx) const + { + *sinx = fxpt::sin(d_phase); + *cosx = fxpt::cos(d_phase); + } + + // compute a block at a time + void cos(float *output, const float *input, int noutput_items, float k, float ampl = 1.0) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (float)(fxpt::cos(d_phase) * ampl); + adjust_phase(input[i] * k); + } + } + + // compute cos or sin for current phase angle + float cos() const { return fxpt::cos(d_phase); } + float sin() const { return fxpt::sin(d_phase); } + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_FXPT_VCO_H */ diff --git a/gnuradio-runtime/include/gnuradio/gr_complex.h b/gnuradio-runtime/include/gnuradio/gr_complex.h new file mode 100644 index 0000000000..bd94c0f0f8 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/gr_complex.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_COMPLEX_H +#define INCLUDED_GR_COMPLEX_H + +#include <complex> +typedef std::complex<float> gr_complex; +typedef std::complex<double> gr_complexd; + +inline bool is_complex (gr_complex x) { (void) x; return true;} +inline bool is_complex (gr_complexd x) { (void) x; return true;} +inline bool is_complex (float x) { (void) x; return false;} +inline bool is_complex (double x) { (void) x; return false;} +inline bool is_complex (int x) { (void) x; return false;} +inline bool is_complex (char x) { (void) x; return false;} +inline bool is_complex (short x) { (void) x; return false;} + +// this doesn't really belong here, but there are worse places for it... + +#define CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected,actual,delta) \ + CPPUNIT_ASSERT_DOUBLES_EQUAL (expected.real(), actual.real(), delta); \ + CPPUNIT_ASSERT_DOUBLES_EQUAL (expected.imag(), actual.imag(), delta); + +#endif /* INCLUDED_GR_COMPLEX_H */ + diff --git a/gnuradio-runtime/include/gnuradio/hier_block2.h b/gnuradio-runtime/include/gnuradio/hier_block2.h new file mode 100644 index 0000000000..ff09f9139d --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/hier_block2.h @@ -0,0 +1,221 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006-2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_HIER_BLOCK2_H +#define INCLUDED_GR_RUNTIME_HIER_BLOCK2_H + +#include <gnuradio/api.h> +#include <gnuradio/basic_block.h> + +namespace gr { + + /*! + * \brief public constructor for hier_block2 + */ + GR_RUNTIME_API hier_block2_sptr + make_hier_block2(const std::string &name, + gr::io_signature::sptr input_signature, + gr::io_signature::sptr output_signature); + + class hier_block2_detail; + + /*! + * \brief Hierarchical container class for gr::block's and gr::hier_block2's + * \ingroup container_blk + * \ingroup base_blk + */ + class GR_RUNTIME_API hier_block2 : public basic_block + { + private: + friend class hier_block2_detail; + friend GR_RUNTIME_API hier_block2_sptr + make_hier_block2(const std::string &name, + gr::io_signature::sptr input_signature, + gr::io_signature::sptr output_signature); + + /*! + * \brief Private implementation details of gr::hier_block2 + */ + hier_block2_detail *d_detail; + + protected: + hier_block2(void) {} // allows pure virtual interface sub-classes + hier_block2(const std::string &name, + gr::io_signature::sptr input_signature, + gr::io_signature::sptr output_signature); + + public: + virtual ~hier_block2(); + + /*! + * \brief typedef for object returned from self(). + * + * This type is only guaranteed to be passable to connect and + * disconnect. No other assumptions should be made about it. + */ + typedef basic_block_sptr opaque_self; + + /*! + * \brief Return an object, representing the current block, which + * can be passed to connect. + * + * The returned object may only be used as an argument to connect + * or disconnect. Any other use of self() results in unspecified + * (erroneous) behavior. + */ + opaque_self self(); + + /*! + * \brief Add a stand-alone (possibly hierarchical) block to + * internal graph + * + * This adds a gr-block or hierarchical block to the internal + * graph without wiring it to anything else. + */ + void connect(basic_block_sptr block); + + /*! + * \brief Add gr-blocks or hierarchical blocks to internal graph + * and wire together + * + * This adds (if not done earlier by another connect) a pair of + * gr-blocks or hierarchical blocks to the internal flowgraph, and + * wires the specified output port to the specified input port. + */ + void connect(basic_block_sptr src, int src_port, + basic_block_sptr dst, int dst_port); + + /*! + * \brief Add gr-blocks or hierarchical blocks to internal graph + * and wire together + * + * This adds (if not done earlier by another connect) a pair of + * gr-blocks or hierarchical blocks to the internal message port + * subscription + */ + void msg_connect(basic_block_sptr src, pmt::pmt_t srcport, + basic_block_sptr dst, pmt::pmt_t dstport); + void msg_connect(basic_block_sptr src, std::string srcport, + basic_block_sptr dst, std::string dstport); + void msg_disconnect(basic_block_sptr src, pmt::pmt_t srcport, + basic_block_sptr dst, pmt::pmt_t dstport); + void msg_disconnect(basic_block_sptr src, std::string srcport, + basic_block_sptr dst, std::string dstport); + + /*! + * \brief Remove a gr-block or hierarchical block from the + * internal flowgraph. + * + * This removes a gr-block or hierarchical block from the internal + * flowgraph, disconnecting it from other blocks as needed. + */ + void disconnect(basic_block_sptr block); + + /*! + * \brief Disconnect a pair of gr-blocks or hierarchical blocks in + * internal flowgraph. + * + * This disconnects the specified input port from the specified + * output port of a pair of gr-blocks or hierarchical blocks. + */ + void disconnect(basic_block_sptr src, int src_port, + basic_block_sptr dst, int dst_port); + + /*! + * \brief Disconnect all connections in the internal flowgraph. + * + * This call removes all output port to input port connections in + * the internal flowgraph. + */ + void disconnect_all(); + + /*! + * Lock a flowgraph in preparation for reconfiguration. When an + * equal number of calls to lock() and unlock() have occurred, the + * flowgraph will be reconfigured. + * + * N.B. lock() and unlock() may not be called from a flowgraph + * thread (E.g., gr::block::work method) or deadlock will occur + * when reconfiguration happens. + */ + virtual void lock(); + + /*! + * Unlock a flowgraph in preparation for reconfiguration. When an + * equal number of calls to lock() and unlock() have occurred, the + * flowgraph will be reconfigured. + * + * N.B. lock() and unlock() may not be called from a flowgraph + * thread (E.g., gr::block::work method) or deadlock will occur + * when reconfiguration happens. + */ + virtual void unlock(); + + // This is a public method for ease of code organization, but should be + // ignored by the user. + flat_flowgraph_sptr flatten() const; + + hier_block2_sptr to_hier_block2(); // Needed for Python type coercion + + bool has_msg_port(pmt::pmt_t which_port) { + return message_port_is_hier(which_port) || basic_block::has_msg_port(which_port); + } + + bool message_port_is_hier(pmt::pmt_t port_id) { + return message_port_is_hier_in(port_id) || message_port_is_hier_out(port_id); + } + + bool message_port_is_hier_in(pmt::pmt_t port_id) { + return pmt::list_has(hier_message_ports_in, port_id); + } + + bool message_port_is_hier_out(pmt::pmt_t port_id) { + return pmt::list_has(hier_message_ports_out, port_id); + } + + pmt::pmt_t hier_message_ports_in; + pmt::pmt_t hier_message_ports_out; + + void message_port_register_hier_in(pmt::pmt_t port_id) { + if(pmt::list_has(hier_message_ports_in, port_id)) + throw std::invalid_argument("hier msg in port by this name already registered"); + if(msg_queue.find(port_id) != msg_queue.end()) + throw std::invalid_argument("block already has a primitive input port by this name"); + hier_message_ports_in = pmt::list_add(hier_message_ports_in, port_id); + } + + void message_port_register_hier_out(pmt::pmt_t port_id) { + if(pmt::list_has(hier_message_ports_out, port_id)) + throw std::invalid_argument("hier msg out port by this name already registered"); + if(pmt::dict_has_key(message_subscribers, port_id)) + throw std::invalid_argument("block already has a primitive output port by this name"); + hier_message_ports_out = pmt::list_add(hier_message_ports_out, port_id); + } + }; + + inline hier_block2_sptr cast_to_hier_block2_sptr(basic_block_sptr block) { + return boost::dynamic_pointer_cast<hier_block2, basic_block>(block); + } + +} /* namespace gr */ + +#endif /* INCLUDED_GR_RUNTIME_HIER_BLOCK2_H */ diff --git a/gnuradio-runtime/include/gnuradio/high_res_timer.h b/gnuradio-runtime/include/gnuradio/high_res_timer.h new file mode 100644 index 0000000000..fc7b007c61 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/high_res_timer.h @@ -0,0 +1,126 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GNURADIO_HIGH_RES_TIMER_H +#define INCLUDED_GNURADIO_HIGH_RES_TIMER_H + +namespace gr { + + //! Typedef for the timer tick count + typedef signed long long high_res_timer_type; + + //! Get the current time in ticks + high_res_timer_type high_res_timer_now(void); + + //! Get the number of ticks per second + high_res_timer_type high_res_timer_tps(void); + + //! Get the tick count at the epoch + high_res_timer_type high_res_timer_epoch(void); + +} /* namespace gr */ + +//////////////////////////////////////////////////////////////////////// +// Use architecture defines to determine the implementation +//////////////////////////////////////////////////////////////////////// +#if defined(linux) || defined(__linux) || defined(__linux__) + #define GNURADIO_HRT_USE_CLOCK_GETTIME +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + #define GNURADIO_HRT_USE_QUERY_PERFORMANCE_COUNTER +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + #define GNURADIO_HRT_USE_MACH_ABSOLUTE_TIME +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) + #define GNURADIO_HRT_USE_CLOCK_GETTIME +#else + #define GNURADIO_HRT_USE_MICROSEC_CLOCK +#endif + +//////////////////////////////////////////////////////////////////////// +#ifdef GNURADIO_HRT_USE_CLOCK_GETTIME + #include <ctime> + + inline gr::high_res_timer_type gr::high_res_timer_now(void){ + timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts.tv_sec*high_res_timer_tps() + ts.tv_nsec; + } + + inline gr::high_res_timer_type gr::high_res_timer_tps(void){ + return 1000000000UL; + } +#endif /* GNURADIO_HRT_USE_CLOCK_GETTIME */ + +//////////////////////////////////////////////////////////////////////// +#ifdef GNURADIO_HRT_USE_MACH_ABSOLUTE_TIME + #include <mach/mach_time.h> + + inline gr::high_res_timer_type gr::high_res_timer_now(void){ + return mach_absolute_time(); + } + + inline gr::high_res_timer_type gr::high_res_timer_tps(void){ + mach_timebase_info_data_t info; + mach_timebase_info(&info); + return gr::high_res_timer_type(info.numer*1000000000UL)/info.denom; + } +#endif + +//////////////////////////////////////////////////////////////////////// +#ifdef GNURADIO_HRT_USE_QUERY_PERFORMANCE_COUNTER + #include <Windows.h> + + inline gr::high_res_timer_type gr::high_res_timer_now(void){ + LARGE_INTEGER counts; + QueryPerformanceCounter(&counts); + return counts.QuadPart; + } + + inline gr::high_res_timer_type gr::high_res_timer_tps(void){ + LARGE_INTEGER freq; + QueryPerformanceFrequency(&freq); + return freq.QuadPart; + } +#endif + +//////////////////////////////////////////////////////////////////////// +#ifdef GNURADIO_HRT_USE_MICROSEC_CLOCK + #include <boost/date_time/posix_time/posix_time.hpp> + + inline gr::high_res_timer_type gr::high_res_timer_now(void){ + static const boost::posix_time::ptime epoch(boost::posix_time::from_time_t(0)); + return (boost::posix_time::microsec_clock::universal_time() - epoch).ticks(); + } + + inline gr::high_res_timer_type gr::high_res_timer_tps(void){ + return boost::posix_time::time_duration::ticks_per_second(); + } +#endif + +//////////////////////////////////////////////////////////////////////// +#include <boost/date_time/posix_time/posix_time.hpp> + +inline gr::high_res_timer_type gr::high_res_timer_epoch(void){ + static const double hrt_ticks_per_utc_ticks = gr::high_res_timer_tps()/double(boost::posix_time::time_duration::ticks_per_second()); + boost::posix_time::time_duration utc = boost::posix_time::microsec_clock::universal_time() - boost::posix_time::from_time_t(0); + return gr::high_res_timer_now() - utc.ticks()*hrt_ticks_per_utc_ticks; +} + +#endif /* INCLUDED_GNURADIO_HIGH_RES_TIMER_H */ diff --git a/gnuradio-runtime/include/gnuradio/ice_application_base.h b/gnuradio-runtime/include/gnuradio/ice_application_base.h new file mode 100644 index 0000000000..1cb60fbf96 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/ice_application_base.h @@ -0,0 +1,231 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef ICE_APPLICATION_BASE_H +#define ICE_APPLICATION_BASE_H + +#ifdef HAVE_WINDOWS_H +#include <winsock2.h> +#include <sys/time.h> +#endif + +#include <gnuradio/api.h> +#include <gnuradio/prefs.h> +#include <Ice/Ice.h> +#include <boost/thread.hpp> +#include <boost/thread/mutex.hpp> +#include <stdio.h> +#include <iostream> +#include <set> +#include <string> +#include <stdio.h> + +namespace { + static const unsigned int ICEAPPLICATION_ACTIVATION_TIMEOUT_MS(600); +}; + +class GR_RUNTIME_API ice_application_common : public Ice::Application +{ + public: + template<typename TserverBase, typename TserverClass> friend class ice_application_base; + static boost::shared_ptr<ice_application_common> Instance(); + ~ice_application_common() {;} + static int d_reacquire_attributes; + + protected: + static bool d_main_called; + static bool d_have_ice_config; + static std::string d_endpointStr; + static boost::shared_ptr<boost::thread> d_thread; + ice_application_common() {;} + int run(int, char*[]); +}; + +template<typename TserverBase, typename TserverClass> +class ice_application_base +{ +public: + boost::shared_ptr<ice_application_common> d_application; + ice_application_base(TserverClass* _this); + ~ice_application_base() {;} + + static TserverBase* i(); + static const std::vector<std::string> endpoints(); + +protected: + bool have_ice_config() { return d_application->d_have_ice_config; } + void set_endpoint(const std::string& endpoint) { d_application->d_endpointStr = endpoint;} + + //this one is the key... overwrite in templated/inherited variants + virtual TserverBase* i_impl() = 0; + + //tools for the i_impl... + //tell it when it has to resync with the communicator + virtual bool reacquire_sync(); + virtual void sync_reacquire(); + + static TserverClass* d_this; + + int d_reacquire; + //static int d_reacquire_attributes; + +private: + void starticeexample(); + + bool application_started(); + + int run(int, char*[]); + + static void kickoff(); +}; + +template<typename TserverBase, typename TserverClass> +TserverClass* ice_application_base<TserverBase, TserverClass>::d_this(0); + +//template<typename TserverBase, typename TserverClass> +//int ice_application_base<TserverBase, TserverClass>::d_reacquire_attributes(0); + +template<typename TserverBase, typename TserverClass> +ice_application_base<TserverBase, TserverClass>::ice_application_base(TserverClass* _this) + : d_reacquire(0) +{ + //d_reacquire_attributes = 0; + d_this = _this; + d_application = ice_application_common::Instance(); +} + +template<typename TserverBase, typename TserverClass> +void ice_application_base<TserverBase, TserverClass>::starticeexample() +{ + char* argv[2]; + argv[0] = (char*)""; + + std::string conffile = gr::prefs::singleton()->get_string("ControlPort", "config", ""); + + if(conffile.size() > 0) { + std::stringstream iceconf; + ice_application_common::d_have_ice_config = true; + ice_application_common::d_main_called = true; + iceconf << conffile; + d_application->main(0, argv, iceconf.str().c_str()); + } + else { + ice_application_common::d_have_ice_config = false; + ice_application_common::d_main_called = true; + d_application->main(0, argv); + } +} + +template<typename TserverBase, typename TserverClass> +void ice_application_base<TserverBase, TserverClass>::kickoff() +{ + static bool run_once = false; + + //if(!d_this->application_started()) { + if(!run_once) { + ++d_this->d_application->d_reacquire_attributes; + + ice_application_common::d_thread = boost::shared_ptr<boost::thread> + (new boost::thread(boost::bind(&ice_application_base::starticeexample, d_this))); + + ::timespec timer_ts, rem_ts; + timer_ts.tv_sec = 0; timer_ts.tv_nsec = ICEAPPLICATION_ACTIVATION_TIMEOUT_MS*1000; + + int iter = 0; + while(!d_this->application_started()) { + #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + ::Sleep(timer_ts.tv_nsec / 1000000); + #else + ::nanosleep(&timer_ts, &rem_ts); + #endif + if(!d_this->application_started()) + std::cout << "@"; + if(iter++ > 100) { + std::cout << "ice_application_base::kickoff(), timeout waiting to get communicator() d_application->main() might have failed?!" << std::endl;; + break; + } + } + + run_once = true; + } + + return; +} + + +template<typename TserverBase, typename TserverClass> +bool ice_application_base<TserverBase, TserverClass>::reacquire_sync() +{ + return (d_this->d_reacquire != d_application->d_reacquire_attributes); +} + +template<typename TserverBase, typename TserverClass> +void ice_application_base<TserverBase, TserverClass>::sync_reacquire() +{ + d_this->d_reacquire = d_application->d_reacquire_attributes; +} + + +template<typename TserverBase, typename TserverClass> +const std::vector<std::string> ice_application_base<TserverBase, TserverClass>::endpoints() +{ + std::vector<std::string> ep; ep.push_back(d_this->d_application->d_endpointStr); return ep; +} + +template<typename TserverBase, typename TserverClass> +TserverBase* ice_application_base<TserverBase, TserverClass>::i() +{ + //printf("indacall\n"); + + assert(d_this != 0); + if(!d_this->application_started()) { + //printf("anotherkickoff\n"); + kickoff(); + } + //printf("donekickedoff\n"); + + /*else if(!d_proxy) { + d_proxy = d_this->i_impl(); + assert(d_proxy != 0); + }*/ + + return d_this->i_impl(); +} + +/*template<typename TserverBase, typename TserverClass> + int ice_application_base<TserverBase, TserverClass>::run(int argc, char* argv[]) { + int implreturn(run_impl(argc, argv)); + ice_application_base<TserverBase, TserverClass>::communicator()->waitForShutdown(); + return implreturn; + }*/ + +template<typename TserverBase, typename TImplClass> +bool ice_application_base<TserverBase, TImplClass>::application_started() +{ + return ice_application_base<TserverBase, TImplClass>::d_this->d_application->communicator(); +} + +/*template<typename TserverBase, typename TImplClass> +int ice_application_base<TserverBase, TImplClass>::run_impl(int argc, char* argv[]) { return EXIT_SUCCESS; } +*/ + +#endif diff --git a/gnuradio-runtime/include/gnuradio/ice_server_template.h b/gnuradio-runtime/include/gnuradio/ice_server_template.h new file mode 100644 index 0000000000..45c1756a48 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/ice_server_template.h @@ -0,0 +1,97 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef ICE_SERVER_TEMPLATE_H +#define ICE_SERVER_TEMPLATE_H + +#include <gnuradio/rpcserver_ice.h> +#include <gnuradio/ice_application_base.h> +#include <iostream> + +template<typename TserverBase, typename TserverClass, typename TImplClass, typename TIceClass> +class ice_server_template : public ice_application_base<TserverBase, TImplClass> +{ +public: + ice_server_template(TImplClass* _this, + const std::string& contolPortName, + const std::string& endpointName); + ~ice_server_template(); + +protected: + //virtual bool application_started(); + TserverBase* i_impl(); + friend class ice_application_base<TserverBase, TImplClass>; + +private: + //virtual int run_impl(int, char*[]); + Ice::ObjectAdapterPtr d_adapter; + TserverBase* d_iceserver; + const std::string d_contolPortName, d_endpointName; +}; + +template<typename TserverBase, typename TserverClass, typename TImplClass, typename TIceClass> +ice_server_template<TserverBase, TserverClass, TImplClass, TIceClass>::ice_server_template + (TImplClass* _this, const std::string& controlPortName, const std::string& endpointName) + : ice_application_base<TserverBase, TImplClass>(_this), + d_iceserver(0), + d_contolPortName(controlPortName), + d_endpointName(endpointName) +{;} + +template<typename TserverBase, typename TserverClass, typename TImplClass, typename TIceClass> +ice_server_template<TserverBase, TserverClass,TImplClass, TIceClass>::~ice_server_template() +{ + if(d_adapter) { + d_adapter->deactivate(); + delete(d_iceserver); + d_adapter = 0; + } +} + +template<typename TserverBase, typename TserverClass, typename TImplClass, typename TIceClass> +TserverBase* ice_server_template<TserverBase, TserverClass, TImplClass, TIceClass>::i_impl() +{ + if(ice_application_base<TserverBase, TImplClass>::d_this->reacquire_sync()) { + d_adapter = (ice_application_base<TserverBase, TImplClass>::d_this->have_ice_config()) ? + ice_application_base<TserverBase, TImplClass>::d_this->d_this->d_application->communicator()->createObjectAdapter(d_contolPortName) : + ice_application_base<TserverBase, TImplClass>::d_this->d_this->d_application->communicator()->createObjectAdapterWithEndpoints(d_contolPortName,"tcp -h *"); + + TserverClass* server_ice(new TserverClass()); + TIceClass obj(server_ice); + + Ice::Identity id(ice_application_base<TserverBase, TImplClass>::d_this->d_this->d_application->communicator()->stringToIdentity(d_endpointName)); + d_adapter->add(obj, id); + d_adapter->activate(); + ice_application_base<TserverBase, TImplClass>::d_this->set_endpoint(ice_application_common::communicator()->proxyToString(d_adapter->createDirectProxy(id))); + + std::cout << std::endl << "Ice Radio Endpoint: " + << ice_server_template<TserverBase, TserverClass, TImplClass, TIceClass>::endpoints()[0] + << std::endl; + + d_iceserver = (TserverBase*) server_ice; + ice_application_base<TserverBase, TImplClass>::d_this->sync_reacquire(); + } + + return d_iceserver; +} + +#endif /* ICE_SERVER_TEMPLATE_H */ diff --git a/gnuradio-runtime/include/gnuradio/io_signature.h b/gnuradio-runtime/include/gnuradio/io_signature.h new file mode 100644 index 0000000000..973f93cd98 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/io_signature.h @@ -0,0 +1,111 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_IO_SIGNATURE_H +#define INCLUDED_IO_SIGNATURE_H + +#include <gnuradio/api.h> +#include <gnuradio/runtime_types.h> + +namespace gr { + + /*! + * \brief i/o signature for input and output ports. + * \brief misc + */ + class GR_RUNTIME_API io_signature + { + int d_min_streams; + int d_max_streams; + std::vector<int> d_sizeof_stream_item; + + io_signature(int min_streams, int max_streams, + const std::vector<int> &sizeof_stream_items); + + public: + typedef boost::shared_ptr<io_signature> sptr; + + static const int IO_INFINITE = -1; + + ~io_signature(); + + /*! + * \brief Create an i/o signature + * + * \ingroup internal + * \param min_streams specify minimum number of streams (>= 0) + * \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite) + * \param sizeof_stream_item specify the size of the items in each stream + */ + static sptr make(int min_streams, int max_streams, + int sizeof_stream_item); + + /*! + * \brief Create an i/o signature + * + * \param min_streams specify minimum number of streams (>= 0) + * \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite) + * \param sizeof_stream_item1 specify the size of the items in the first stream + * \param sizeof_stream_item2 specify the size of the items in the second and subsequent streams + */ + static sptr make2(int min_streams, int max_streams, + int sizeof_stream_item1, + int sizeof_stream_item2); + + /*! + * \brief Create an i/o signature + * + * \param min_streams specify minimum number of streams (>= 0) + * \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite) + * \param sizeof_stream_item1 specify the size of the items in the first stream + * \param sizeof_stream_item2 specify the size of the items in the second stream + * \param sizeof_stream_item3 specify the size of the items in the third and subsequent streams + */ + static sptr make3(int min_streams, int max_streams, + int sizeof_stream_item1, + int sizeof_stream_item2, + int sizeof_stream_item3); + + /*! + * \brief Create an i/o signature + * + * \param min_streams specify minimum number of streams (>= 0) + * \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite) + * \param sizeof_stream_items specify the size of the items in the streams + * + * If there are more streams than there are entries in + * sizeof_stream_items, the value of the last entry in + * sizeof_stream_items is used for the missing values. + * sizeof_stream_items must contain at least 1 entry. + */ + static sptr makev(int min_streams, int max_streams, + const std::vector<int> &sizeof_stream_items); + + int min_streams() const { return d_min_streams; } + int max_streams() const { return d_max_streams; } + int sizeof_stream_item(int index) const; + std::vector<int> sizeof_stream_items() const; + }; + +} /* namespace gr */ + +#endif /* INCLUDED_IO_SIGNATURE_H */ diff --git a/gnuradio-runtime/include/gnuradio/logger.h.in b/gnuradio-runtime/include/gnuradio/logger.h.in new file mode 100644 index 0000000000..87f3611d9c --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/logger.h.in @@ -0,0 +1,747 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012-2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/******************************************************************************* +* Author: Mark Plett +* Description: +* The gr::logger module wraps the log4cpp library for logging in gnuradio +*******************************************************************************/ + +#ifndef INCLUDED_GR_LOGGER_H +#define INCLUDED_GR_LOGGER_H + +/*! +* \ingroup logging +* \brief GNU Radio logging wrapper for log4cpp library (C++ port of log4j) +* +*/ + +#ifndef ENABLE_GR_LOG +#cmakedefine ENABLE_GR_LOG +#endif +#ifndef HAVE_LOG4CPP +#cmakedefine HAVE_LOG4CPP +#endif + +#include <gnuradio/api.h> +#include <assert.h> +#include <iostream> +#include <time.h> +#include <boost/filesystem.hpp> +#include <boost/thread.hpp> +#include <pmt/pmt.h> + +#ifdef ENABLE_GR_LOG + +// We have three configurations... first logging to stdout/stderr +#ifndef HAVE_LOG4CPP + +namespace gr { + //#warning GR logging Enabled and using std::cout + typedef std::string logger_ptr; +} /* namespace gr */ + +#define GR_LOG_DECLARE_LOGPTR(logger) +#define GR_LOG_ASSIGN_LOGPTR(logger,name) +#define GR_CONFIG_LOGGER(config) +#define GR_CONFIG_AND_WATCH_LOGGER(config,period) +#define GR_LOG_GETLOGGER(logger, name) +#define GR_SET_LEVEL(name, level) +#define GR_LOG_SET_LEVEL(logger, level) +#define GR_GET_LEVEL(name, level) +#define GR_LOG_GET_LEVEL(logger, level) +#define GR_ADD_APPENDER(name,appender) +#define GR_LOG_ADD_APPENDER(logger,appender) +#define GR_ADD_CONSOLE_APPENDER(logger,target,pattern) +#define GR_LOG_ADD_CONSOLE_APPENDER(logger,target,pattern) +#define GR_ADD_FILE_APPENDER(name,filename,append,pattern) +#define GR_LOG_ADD_FILE_APPENDER(logger,filename,append,pattern) +#define GR_ADD_ROLLINGFILE_APPENDER(name,filename,filesize,bkup_index,append,mode,pattern) +#define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger,filename,filesize,bkup_index,append,mode,pattern) +#define GR_GET_LOGGER_NAMES(names) +#define GR_RESET_CONFIGURATION() +#define GR_DEBUG(name, msg) std::cout<<"DEBUG: "<<msg<<std::endl +#define GR_INFO(name, msg) std::cout<<"INFO: "<<msg<<std::endl +#define GR_NOTICE(name, msg) std::cout<<"NOTICE: "<<msg<<std::endl +#define GR_WARN(name, msg) std::cerr<<"WARN: "<<msg<<std::endl +#define GR_ERROR(name, msg) std::cerr<<"ERROR: "<<msg<<std::endl +#define GR_ALERT(name, msg) std::cerr<<"ERROR: "<<msg<<std::endl +#define GR_CRIT(name, msg) std::cerr<<"ERROR: "<<msg<<std::endl +#define GR_FATAL(name, msg) std::cerr<<"FATAL: "<<msg<<std::endl +#define GR_EMERG(name, msg) std::cerr<<"EMERG: "<<msg<<std::endl +#define GR_ERRORIF(name, cond, msg) {if((cond)) std::cerr<<"ERROR: "<<msg<<std::endl;} +#define GR_ASSERT(name, cond, msg) {if(!(cond)) std::cerr<<"FATAL: "<<msg<<std::endl; assert(cond);} +#define GR_LOG_DEBUG(logger, msg) std::cout<<"DEBUG: "<<msg<<std::endl +#define GR_LOG_INFO(logger, msg) std::cout<<"INFO: "<<msg<<std::endl +#define GR_LOG_NOTICE(logger, msg) std::cout<<"NOTICE: "<<msg<<std::endl +#define GR_LOG_WARN(logger, msg) std::cerr<<"WARN: "<<msg<<std::endl +#define GR_LOG_ERROR(logger, msg) std::cerr<<"ERROR: "<<msg<<std::endl +#define GR_LOG_ALERT(logger, msg) std::cerr<<"ALERT: "<<msg<<std::endl +#define GR_LOG_CRIT(logger, msg) std::cerr<<"CRIT: "<<msg<<std::endl +#define GR_LOG_FATAL(logger, msg) std::cerr<<"FATAL: "<<msg<<std::endl +#define GR_LOG_EMERG(logger, msg) std::cerr<<"EMERG: "<<msg<<std::endl +#define GR_LOG_ERRORIF(logger, cond, msg) { \ + if((cond)) std::cerr<<"ERROR: "<<msg<<std::endl;} +#define GR_LOG_ASSERT(logger, cond, msg) { \ + if(!(cond)) {std::cerr<<"FATAL: "<<msg<<std::endl; assert(cond);};} + + +#else /* HAVE_LOG4CPP */ + +// Second configuration...logging to log4cpp +#include <log4cpp/Category.hh> +#include <log4cpp/PropertyConfigurator.hh> +#include <log4cpp/FileAppender.hh> +#include <log4cpp/RollingFileAppender.hh> +#include <log4cpp/OstreamAppender.hh> +#include <log4cpp/PatternLayout.hh> + +namespace gr { + + /*! + * \brief GR_LOG macros + * \ingroup logging + * + * These macros wrap the standard LOG4CPP_LEVEL macros. The availablie macros + * are: + * LOG_DEBUG + * LOG_INFO + * LOG_WARN + * LOG_TRACE + * LOG_ERROR + * LOG_ALERT + * LOG_CRIT + * LOG_FATAL + * LOG_EMERG + */ + typedef log4cpp::Category* logger_ptr; + +} /* namespace gr */ + + + /* Macros for Programmatic Configuration */ +#define GR_LOG_DECLARE_LOGPTR(logger) \ + gr::logger_ptr logger; + +#define GR_LOG_ASSIGN_LOGPTR(logger,name) \ + logger = gr::logger_get_logger(name); + +#define GR_CONFIG_LOGGER(config) \ + gr::logger_config::load_config(config) + +#define GR_CONFIG_AND_WATCH_LOGGER(config,period) \ + gr::logger_config::load_config(config,period) + +#define GR_LOG_GETLOGGER(logger, name) \ + gr::logger_ptr logger = gr::logger_get_logger(name); + +#define GR_SET_LEVEL(name, level) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + gr::logger_set_level(logger,level);} + +#define GR_LOG_SET_LEVEL(logger, level) \ + gr::logger_set_level(logger, level); + +#define GR_GET_LEVEL(name, level) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + gr::logger_get_level(logger,level);} + +#define GR_LOG_GET_LEVEL(logger, level) \ + gr::logger_get_level(logger,level); + +#define GR_ADD_APPENDER(name, appender) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + gr::logger_add_appender(logger,appender);} + +#define GR_LOG_ADD_APPENDER(logger, appender) { \ + gr::logger_add_appender(logger, appender);} + +#define GR_ADD_CONSOLE_APPENDER(name, target, pattern) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + gr::logger_add_console_appender(logger,target,pattern);} + +#define GR_LOG_ADD_CONSOLE_APPENDER(logger, target, pattern) { \ + gr::logger_add_console_appender(logger,target,pattern);} + +#define GR_ADD_FILE_APPENDER(name, filename, append, pattern) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + gr::logger_add_file_appender(logger,filename,append,pattern);} + +#define GR_LOG_ADD_FILE_APPENDER(logger, filename, append, pattern) { \ + gr::logger_add_file_appender(logger,filename,append,pattern);} + +#define GR_ADD_ROLLINGFILE_APPENDER(name, filename, filesize, bkup_index, append, mode, pattern) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + gr::logger_add_rollingfile_appender(logger,filename,filesize,bkup_index,append,mode,pattern);} + +#define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger, filename, filesize, bkup_index, append, mode, pattern) { \ + gr::logger_add_rollingfile_appender(logger,filename,filesize,bkup_index,append,mode,pattern);} + +#define GR_GET_LOGGER_NAMES(names) { \ + names = gr::logger_get_logger_names();} + +#define GR_RESET_CONFIGURATION() \ + gr::logger_config::reset_config(); + + /* Logger name referenced macros */ +#define GR_DEBUG(name, msg) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + *logger<< log4cpp::Priority::DEBUG << msg << log4cpp::eol;} + +#define GR_INFO(name, msg) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + *logger<< log4cpp::Priority::INFO << msg << log4cpp::eol;} + +#define GR_NOTICE(name, msg) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + *logger << log4cpp::Priority::NOTICE << msg;} + +#define GR_WARN(name, msg) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + *logger<< log4cpp::Priority::WARN << msg << log4cpp::eol;} + +#define GR_ERROR(name, msg) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + *logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;} + +#define GR_CRIT(name, msg) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + *logger<< log4cpp::Priority::CRIT << msg << log4cpp::eol;} + +#define GR_ALERT(name, msg) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + *logger<< log4cpp::Priority::ALERT << msg << log4cpp::eol;} + +#define GR_FATAL(name, msg) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + *logger<< log4cpp::Priority::FATAL << msg << log4cpp::eol;} + +#define GR_EMERG(name, msg) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + *logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol;} + +#define GR_ERRORIF(name, cond, msg) { \ + if((cond)) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + *logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;} \ + } + +#define GR_ASSERT(name, cond, msg) { \ + if(!(cond)) { \ + gr::logger_ptr logger = gr::logger_get_logger(name); \ + *logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol;} \ + assert(0); \ + } + + /* LoggerPtr Referenced Macros */ +#define GR_LOG_DEBUG(logger, msg) { \ + *logger << log4cpp::Priority::DEBUG << msg << log4cpp::eol;} + +#define GR_LOG_INFO(logger, msg) { \ + *logger << log4cpp::Priority::INFO << msg << log4cpp::eol;} + +#define GR_LOG_NOTICE(logger, msg) { \ + *logger << log4cpp::Priority::NOTICE << msg << log4cpp::eol;} + +#define GR_LOG_WARN(logger, msg) { \ + *logger << log4cpp::Priority::WARN << msg << log4cpp::eol;} + +#define GR_LOG_ERROR(logger, msg) { \ + *logger << log4cpp::Priority::ERROR << msg << log4cpp::eol;} + +#define GR_LOG_CRIT(logger, msg) { \ + *logger << log4cpp::Priority::CRIT << msg << log4cpp::eol;} + +#define GR_LOG_ALERT(logger, msg) { \ + *logger << log4cpp::Priority::ALERT << msg << log4cpp::eol;} + +#define GR_LOG_FATAL(logger, msg) { \ + *logger << log4cpp::Priority::FATAL << msg << log4cpp::eol;} + +#define GR_LOG_EMERG(logger, msg) { \ + *logger << log4cpp::Priority::EMERG << msg << log4cpp::eol;} + +#define GR_LOG_ERRORIF(logger,cond, msg) { \ + if((cond)) { \ + *logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;} \ + } + +#define GR_LOG_ASSERT(logger, cond, msg) { \ + if(!(cond)) { \ + *logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol; \ + assert(0);} \ + } + +namespace gr { + + /*! + * \brief Class to control configuration of logger. + * This is a singleton that cna launch a thread to wathc a config file for changes + * \ingroup logging + */ + class logger_config + { + private: + /*! \brief filename of logger config file */ + std::string filename; + /*! \brief Period (seconds) over which watcher thread checks config file for changes */ + unsigned int watch_period; + /*! \brief Pointer to watch thread for config file changes */ + boost::thread *watch_thread; + + /*! \brief Watcher thread method + * /param filename Name of configuration file + * /param watch_period Seconds between checks for changes in config file + */ + static void watch_file(std::string filename,unsigned int watch_period); + + static bool logger_configured; + + logger_config()/*: + rpc_get_filename("logger_config", "filename", &logger_config::get_filename4rpc, + pmt::mp(""), pmt::mp(""), pmt::mp(""), + "", "filename", RPC_PRIVLVL_MIN, + DISPTIME | DISPOPTSTRIP), + rpc_get_watchperiod("logger_config", "watch_period", &logger_config::get_watchperiod4rpc, + pmt::mp(0), pmt::mp(32768), pmt::mp(0), + "", "watch_period", RPC_PRIVLVL_MIN, + DISPTIME | DISPOPTSTRIP), + rpc_get_config("logger_config", "config", &logger_config::get_config4rpc, + pmt::mp(""), pmt::mp(""), pmt::mp(""), + "", "filename", RPC_PRIVLVL_MIN, + DISPTIME | DISPOPTSTRIP), + rpc_set_config("logger_config","config", &logger_config::set_config4rpc, + pmt::mp(""), pmt::mp(""), pmt::mp(""), + "", "filename", RPC_PRIVLVL_MIN, + DISPTIME | DISPOPTSTRIP) + */ + { + } //!< Constructor + + /* + rpcbasic_register_get<logger_config,std::string> rpc_get_filename; + rpcbasic_register_get<logger_config,int> rpc_get_watchperiod; + rpcbasic_register_get<logger_config,std::string> rpc_get_config; + rpcbasic_register_set<logger_config,std::string> rpc_set_config; + */ + + logger_config(logger_config const&); //!<Copy constructor + void operator=(logger_config const&); //!<Assignment Operator + + std::string get_filename4rpc() { + return filename; + } + int get_watchperiod4rpc(){return watch_period;}; + + std::string get_config4rpc() { + return filename; + } + + void set_config4rpc(std::string set) { + printf("Set string was:%s\n", set.c_str()); + } + + /*! \brief destrcutor stops watch thread before exits */ + ~logger_config() { + stop_watch(); + } + + /*! \brief Instance getter for singleton. Only used by class. */ + static logger_config& get_instance(void); + + public: + /*! \brief Getter for config filename */ + static std::string get_filename(); + /*! \brief Getter for watch period */ + static unsigned int get_watch_period(); + /*! \brief Method to load configuration + * /param filename Name of configuration file + * /param watch_period Seconds between checks for changes in config file + */ + static void load_config(std::string filename,unsigned int watch_period=0); + /*! \brief Method to stop watcher thread */ + static void stop_watch(); + /*! \brief method to reset logger configuration */ + static void reset_config(void); + }; + + /*! + * \brief Retrieve a pointer to a logger by name + * + * Retrives a logger pointer + * \p name. + * + * \param name Name of the logger for which a pointer is requested + */ + GR_RUNTIME_API logger_ptr logger_get_logger(std::string name); + + /*! + * \brief Load logger's configuration file. + * + * Initialize the GNU Radio logger by loading the configuration file + * \p config_filename. + * + * \param config_filename The configuration file. Set to "" for the + * basic logger that outputs to the console. + */ + GR_RUNTIME_API bool logger_load_config(const std::string &config_filename=""); + + /*! + * \brief Reset logger's configuration file. + * + * Remove all appenders from loggers + */ + GR_RUNTIME_API void logger_reset_config(void); + + /*! + * \brief Set the logger's output level. + * + * Sets the level of the logger. This takes a string that is + * translated to the standard levels and can be (case insensitive): + * + * \li off , notset + * \li debug + * \li info + * \li notice + * \li warn + * \li error + * \li crit + * \li alert + * \li fatal + * \li emerg + * + * \param logger the logger to set the level of. + * \param level string to set the level to. + */ + GR_RUNTIME_API void logger_set_level(logger_ptr logger, + const std::string &level); + + /*! + * \brief Set the logger's output level. + * + * Sets the level of the logger. This takes the actual Log4cpp::Priority + * data type, which can be: + * + * \li log4cpp::Priority::NOTSET + * \li log4cpp::Priority::DEBUG + * \li log4cpp::Priority::INFO + * \li log4cpp::Priority::NOTICE + * \li log4cpp::Priority::WARN + * \li log4cpp::Priority::ERROR + * \li log4cpp::Priority::CRIT + * \li log4cpp::Priority::ALERT + * \li log4cpp::Priority::FATAL + * \li log4cpp::Priority::EMERG + * + * \param logger the logger to set the level of. + * \param level new logger level of type Log4cpp::Priority + */ + GR_RUNTIME_API void logger_set_level(logger_ptr logger, + log4cpp::Priority::Value level); + + /*! + * \brief Get the logger's output level. + * + * Gets the level of the logger. This returns a string that + * corresponds to the standard levels and can be (case insensitive): + * + * \li notset + * \li debug + * \li info + * \li notice + * \li warn + * \li error + * \li crit + * \li alert + * \li fatal + * \li emerg + * + * \param logger the logger to get the level of. + * \param level string to get the level into. + */ + GR_RUNTIME_API void logger_get_level(logger_ptr logger, std::string &level); + + /*! + * \brief Get the logger's output level. + * + * Gets the level of the logger. This returns the actual Log4cpp::Level + * data type, which can be: + * + * \li log4cpp::Priority::NOTSET + * \li log4cpp::Priority::DEBUG + * \li log4cpp::Priority::INFO + * \li log4cpp::Priority::NOTICE + * \li log4cpp::Priority::WARN + * \li log4cpp::Priority::ERROR + * \li log4cpp::Priority::CRIT + * \li log4cpp::Priority::ALERT + * \li log4cpp::Priority::FATAL + * \li log4cpp::Priority::EMERG + * + * \param logger the logger to get the level of. + * \param level of the logger. + */ + GR_RUNTIME_API void logger_get_level(logger_ptr logger, + log4cpp::Priority::Value &level); + + /*! + * \brief Add console appender to a given logger + * + * Add console appender to a given logger + * + * \param logger Logger to which appender will be added + * \param target Std target to write 'cout' or 'cerr' (default is cout) + * \param pattern Formating pattern for log messages + */ + GR_RUNTIME_API void logger_add_appender(logger_ptr logger, + std::string appender); + + /*! + * \brief Add console appender to a given logger + * + * Add console appender to a given logger + * + * \param logger Logger to which appender will be added + * \param target Std target to write 'cout' or 'cerr' (default is cout) + * \param pattern Formating pattern for log messages + */ + GR_RUNTIME_API void logger_add_console_appender(logger_ptr logger, + std::string target, + std::string pattern); + + /*! + * \brief Add file appender to a given logger + * + * Add file appender to a given logger + * + * \param logger Logger to which appender will be added + * \param filename File to which log will be written + * \param append Overwrite or append to log file + * \param pattern Formating pattern for log messages + */ + GR_RUNTIME_API void logger_add_file_appender(logger_ptr logger, + std::string filename, + bool append, std::string pattern); + + /*! + * \brief Add rolling file appender to a given logger + * + * Add rolling file appender to a given logger + * + * \param logger Logger to which appender will be added + * \param filename File to which log will be written + * \param filesize Sizez of files to write + * \param bkup_index Number of files to write + * \param append Overwrite or append to log file + * \param mode Permissions to set on log file + * \param pattern Formating pattern for log messages + */ + GR_RUNTIME_API void logger_add_rollingfile_appender(logger_ptr logger, std::string filename, + size_t filesize, int bkup_index, bool append, + mode_t mode,std::string pattern); + + /*! + * \brief Add rolling file appender to a given logger + * + * Add rolling file appender to a given logger + * + * \return vector of string names of loggers + */ + GR_RUNTIME_API std::vector<std::string> logger_get_logger_names(void); + +} /* namespace gr */ + +#endif /* HAVE_LOG4CPP */ + + // If Logger disable do nothing +#else /* ENABLE_GR_LOG */ + +namespace gr { + typedef void* logger_ptr; +} /* namespace gr */ + +#define GR_LOG_DECLARE_LOGPTR(logger) +#define GR_LOG_ASSIGN_LOGPTR(logger,name) +#define GR_CONFIG_LOGGER(config) +#define GR_CONFIG_AND_WATCH_LOGGER(config,period) +#define GR_LOG_GETLOGGER(logger, name) +#define GR_SET_LEVEL(name, level) +#define GR_LOG_SET_LEVEL(logger, level) +#define GR_GET_LEVEL(name, level) +#define GR_LOG_GET_LEVEL(logger, level) +#define GR_ADD_APPENDER(name,appender) +#define GR_LOG_ADD_APPENDER(logger,appender) +#define GR_ADD_CONSOLE_APPENDER(logger,target,pattern) +#define GR_LOG_ADD_CONSOLE_APPENDER(logger,target,pattern) +#define GR_ADD_FILE_APPENDER(name,filename,append,pattern) +#define GR_LOG_ADD_FILE_APPENDER(logger,filename,append,pattern) +#define GR_ADD_ROLLINGFILE_APPENDER(name,filename,filesize,bkup_index,append,mode,pattern) +#define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger,filename,filesize,bkup_index,append,mode,pattern) +#define GR_GET_LOGGER_NAMES(names) +#define GR_RESET_CONFIGURATION() +#define GR_DEBUG(name, msg) +#define GR_INFO(name, msg) +#define GR_NOTICE(name, msg) +#define GR_WARN(name, msg) +#define GR_ERROR(name, msg) +#define GR_ALERT(name, msg) +#define GR_CRIT(name, msg) +#define GR_FATAL(name, msg) +#define GR_EMERG(name, msg) +#define GR_ERRORIF(name, cond, msg) +#define GR_ASSERT(name, cond, msg) +#define GR_LOG_DEBUG(logger, msg) +#define GR_LOG_INFO(logger, msg) +#define GR_LOG_NOTICE(logger, msg) +#define GR_LOG_WARN(logger, msg) +#define GR_LOG_ERROR(logger, msg) +#define GR_LOG_ALERT(logger, msg) +#define GR_LOG_CRIT(logger, msg) +#define GR_LOG_FATAL(logger, msg) +#define GR_LOG_EMERG(logger, msg) +#define GR_LOG_ERRORIF(logger, cond, msg) +#define GR_LOG_ASSERT(logger, cond, msg) + +#endif /* ENABLE_GR_LOG */ + +namespace gr { + + // Even if logger is disabled we'll need for methods below to exist in python. + // The macros these call will be disabled if ENABLE_GR_LOG is undefined + + /********************* Start Classes and Methods for Python ******************/ + /*! + * \brief Logger class for referencing loggers in python. Not + * needed in C++ (use macros) Wraps and manipulates loggers for + * python as python has no macros + * \ingroup logging + * + */ + class logger + { + private: + /*! \brief logger pointer to logger associated wiith this wrapper class */ + logger_ptr d_logger; + public: + /*! + * \brief contructor Provide name of logger to associate with this class + * \param logger_name Name of logger associated with class + */ + logger(std::string logger_name) { + GR_LOG_ASSIGN_LOGPTR(d_logger,logger_name); + }; + + /*! \brief Destructor */ + ~logger(){;} + + // Wrappers for logging macros + /*! \brief inline function, wrapper to set the logger level */ + void set_level(std::string level){GR_LOG_SET_LEVEL(d_logger,level);} + + /*! \brief inline function, wrapper to get the logger level */ + void get_level(std::string &level){GR_LOG_GET_LEVEL(d_logger,level);} + + /*! \brief inline function, wrapper for LOG4CPP_DEBUG for DEBUG message */ + void debug(std::string msg){GR_LOG_DEBUG(d_logger,msg);}; + + /*! \brief inline function, wrapper for LOG4CPP_INFO for INFO message */ + void info(std::string msg){GR_LOG_INFO(d_logger,msg);} + + /*! \brief inline function, wrapper for NOTICE message */ + void notice(std::string msg){GR_LOG_NOTICE(d_logger,msg);} + + /*! \brief inline function, wrapper for LOG4CPP_WARN for WARN message */ + void warn(std::string msg){GR_LOG_WARN(d_logger,msg);} + + /*! \brief inline function, wrapper for LOG4CPP_ERROR for ERROR message */ + void error(std::string msg){GR_LOG_ERROR(d_logger,msg);} + + /*! \brief inline function, wrapper for NOTICE message */ + void crit(std::string msg){GR_LOG_CRIT(d_logger,msg);} + + /*! \brief inline function, wrapper for ALERT message */ + void alert(std::string msg){GR_LOG_ALERT(d_logger,msg);} + + /*! \brief inline function, wrapper for FATAL message */ + void fatal(std::string msg){GR_LOG_FATAL(d_logger,msg);} + + /*! \brief inline function, wrapper for EMERG message */ + void emerg(std::string msg){GR_LOG_EMERG(d_logger,msg);} + + /*! \brief inline function, wrapper for LOG4CPP_ASSERT for conditional ERROR message */ + void errorIF(bool cond,std::string msg){GR_LOG_ERRORIF(d_logger,cond,msg);} + + /*! \brief inline function, wrapper for LOG4CPP_ASSERT for conditional ERROR message */ + void log_assert(bool cond,std::string msg){GR_LOG_ASSERT(d_logger,cond,msg);} + + /*! \brief inline function, Method to add appender to logger by + name (define appender in conf file) */ + void add_appender(std::string appender) { + GR_LOG_ADD_APPENDER(d_logger, appender); + } + + /*! \brief inline function, Method to add console appender to logger */ + void add_console_appender(std::string target,std::string pattern) { + GR_LOG_ADD_CONSOLE_APPENDER(d_logger, target, pattern); + } + + /*! \brief inline function, Method to add file appender to logger */ + void add_file_appender(std::string filename, bool append, std::string pattern) { + GR_LOG_ADD_FILE_APPENDER(d_logger, filename, append, pattern); + } + + /*! \brief inline function, Method to add rolling file appender to logger */ + void add_rollingfile_appender(std::string filename, size_t filesize, + int bkup_index, bool append, mode_t mode, + std::string pattern) { + GR_LOG_ADD_ROLLINGFILE_APPENDER(d_logger,filename,filesize, + bkup_index,append,mode,pattern); + } + }; + +} /* namespace gr */ + +/**************** Start Configuration Class and Methods for Python ************/ +/*! + * \brief Function to call configuration macro from python. + * Note: Configuration is only updated if filename or watch_period has changed. + * \param config_filename Name of configuration file + * \param watch_period Seconds to wait between checking for changes in conf file. + * Watch_period defaults to 0 in which case the file is not watched for changes + */ +GR_RUNTIME_API void gr_logger_config(const std::string config_filename, + unsigned int watch_period = 0); + +/*! + * \brief Function to return logger names to python + * \return Vector of name strings + * + */ +GR_RUNTIME_API std::vector<std::string> gr_logger_get_logger_names(void); + +/*! + * \brief Function to reset logger configuration from python + * + */ +GR_RUNTIME_API void gr_logger_reset_config(void); + +#endif /* INCLUDED_GR_LOGGER_H */ diff --git a/gnuradio-runtime/include/gnuradio/math.h b/gnuradio-runtime/include/gnuradio/math.h new file mode 100644 index 0000000000..ec4cfb014f --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/math.h @@ -0,0 +1,226 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003,2005,2008,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* + * mathematical odds and ends. + */ + +#ifndef _GR_MATH_H_ +#define _GR_MATH_H_ + +#include <gnuradio/api.h> +#include <gnuradio/gr_complex.h> + +namespace gr { + + static inline bool + is_power_of_2(long x) + { + return x != 0 && (x & (x-1)) == 0; + } + + /*! + * \brief Fast arc tangent using table lookup and linear interpolation + * \ingroup misc + * + * \param y component of input vector + * \param x component of input vector + * \returns float angle angle of vector (x, y) in radians + * + * This function calculates the angle of the vector (x,y) based on a + * table lookup and linear interpolation. The table uses a 256 point + * table covering -45 to +45 degrees and uses symetry to determine + * the final angle value in the range of -180 to 180 degrees. Note + * that this function uses the small angle approximation for values + * close to zero. This routine calculates the arc tangent with an + * average error of +/- 0.045 degrees. + */ + GR_RUNTIME_API float fast_atan2f(float y, float x); + + static inline float + fast_atan2f(gr_complex z) + { + return fast_atan2f(z.imag(), z.real()); + } + + /* This bounds x by +/- clip without a branch */ + static inline float + branchless_clip(float x, float clip) + { + float x1 = fabsf(x+clip); + float x2 = fabsf(x-clip); + x1 -= x2; + return 0.5*x1; + } + + static inline float + clip(float x, float clip) + { + float y = x; + if(x > clip) + y = clip; + else if(x < -clip) + y = -clip; + return y; + } + + // Slicer Functions + static inline unsigned int + binary_slicer(float x) + { + if(x >= 0) + return 1; + else + return 0; + } + + static inline unsigned int + quad_45deg_slicer(float r, float i) + { + unsigned int ret = 0; + if((r >= 0) && (i >= 0)) + ret = 0; + else if((r < 0) && (i >= 0)) + ret = 1; + else if((r < 0) && (i < 0)) + ret = 2; + else + ret = 3; + return ret; + } + + static inline unsigned int + quad_0deg_slicer(float r, float i) + { + unsigned int ret = 0; + if(fabsf(r) > fabsf(i)) { + if(r > 0) + ret = 0; + else + ret = 2; + } + else { + if(i > 0) + ret = 1; + else + ret = 3; + } + + return ret; + } + + static inline unsigned int + quad_45deg_slicer(gr_complex x) + { + return quad_45deg_slicer(x.real(), x.imag()); + } + + static inline unsigned int + quad_0deg_slicer(gr_complex x) + { + return quad_0deg_slicer(x.real(), x.imag()); + } + + // Branchless Slicer Functions + static inline unsigned int + branchless_binary_slicer(float x) + { + return (x >= 0); + } + + static inline unsigned int + branchless_quad_0deg_slicer(float r, float i) + { + unsigned int ret = 0; + ret = (fabsf(r) > fabsf(i)) * (((r < 0) << 0x1)); // either 0 (00) or 2 (10) + ret |= (fabsf(i) > fabsf(r)) * (((i < 0) << 0x1) | 0x1); // either 1 (01) or 3 (11) + + return ret; + } + + static inline unsigned int + branchless_quad_0deg_slicer(gr_complex x) + { + return branchless_quad_0deg_slicer(x.real(), x.imag()); + } + + static inline unsigned int + branchless_quad_45deg_slicer(float r, float i) + { + char ret = (r <= 0); + ret |= ((i <= 0) << 1); + return (ret ^ ((ret & 0x2) >> 0x1)); + } + + static inline unsigned int + branchless_quad_45deg_slicer(gr_complex x) + { + return branchless_quad_45deg_slicer(x.real(), x.imag()); + } + + /*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p x rounded down to a multiple of \p pow2. + */ + static inline size_t + p2_round_down(size_t x, size_t pow2) + { + return x & -pow2; + } + + /*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p x rounded up to a multiple of \p pow2. + */ + static inline size_t + p2_round_up(size_t x, size_t pow2) + { + return p2_round_down(x + pow2 - 1, pow2); + } + + /*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p x modulo \p pow2. + */ + static inline size_t + p2_modulo(size_t x, size_t pow2) + { + return x & (pow2 - 1); + } + + /*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p pow2 - (\p x modulo \p pow2). + */ + static inline size_t + p2_modulo_neg(size_t x, size_t pow2) + { + return pow2 - p2_modulo(x, pow2); + } + +} /* namespace gr */ + +#endif /* _GR_MATH_H_ */ diff --git a/gnuradio-runtime/include/gnuradio/message.h b/gnuradio-runtime/include/gnuradio/message.h new file mode 100644 index 0000000000..0fda2d9c8c --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/message.h @@ -0,0 +1,91 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_MESSAGE_H +#define INCLUDED_GR_MESSAGE_H + +#include <gnuradio/api.h> +#include <gnuradio/types.h> +#include <string> + +namespace gr { + + /*! + * \brief Message class. + * + * \ingroup misc + * The ideas and method names for adjustable message length were + * lifted from the click modular router "Packet" class. + */ + class GR_RUNTIME_API message + { + public: + typedef boost::shared_ptr<message> sptr; + + private: + sptr d_next; // link field for msg queue + long d_type; // type of the message + double d_arg1; // optional arg1 + double d_arg2; // optional arg2 + + unsigned char *d_buf_start; // start of allocated buffer + unsigned char *d_msg_start; // where the msg starts + unsigned char *d_msg_end; // one beyond end of msg + unsigned char *d_buf_end; // one beyond end of allocated buffer + + message(long type, double arg1, double arg2, size_t length); + + friend class msg_queue; + + unsigned char *buf_data() const { return d_buf_start; } + size_t buf_len() const { return d_buf_end - d_buf_start; } + + public: + /*! + * \brief public constructor for message + */ + static sptr make(long type = 0, double arg1 = 0, double arg2 = 0, size_t length = 0); + + static sptr make_from_string(const std::string s, long type = 0, + double arg1 = 0, double arg2 = 0); + + + ~message(); + + long type() const { return d_type; } + double arg1() const { return d_arg1; } + double arg2() const { return d_arg2; } + + void set_type(long type) { d_type = type; } + void set_arg1(double arg1) { d_arg1 = arg1; } + void set_arg2(double arg2) { d_arg2 = arg2; } + + unsigned char *msg() const { return d_msg_start; } + size_t length() const { return d_msg_end - d_msg_start; } + std::string to_string() const; + }; + + GR_RUNTIME_API long message_ncurrently_allocated(); + +} /* namespace gr */ + +#endif /* INCLUDED_GR_MESSAGE_H */ diff --git a/gnuradio-runtime/include/gnuradio/messages/CMakeLists.txt b/gnuradio-runtime/include/gnuradio/messages/CMakeLists.txt new file mode 100644 index 0000000000..f79f2bd24f --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/messages/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Install header files +######################################################################## +install(FILES + msg_accepter.h + msg_accepter_msgq.h + msg_passing.h + msg_producer.h + msg_queue.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/messages + COMPONENT "runtime_devel" +) diff --git a/gnuradio-runtime/include/gnuradio/messages/msg_accepter.h b/gnuradio-runtime/include/gnuradio/messages/msg_accepter.h new file mode 100644 index 0000000000..cd87b21dec --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/messages/msg_accepter.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_MSG_ACCEPTER_H +#define INCLUDED_MSG_ACCEPTER_H + +#include <gnuradio/api.h> +#include <pmt/pmt.h> +#include <boost/shared_ptr.hpp> + +namespace gr { + namespace messages { + + /*! + * \brief Virtual base class that accepts messages + */ + class GR_RUNTIME_API msg_accepter + { + public: + msg_accepter() {}; + virtual ~msg_accepter(); + + /*! + * \brief send \p msg to \p msg_accepter on port \p which_port + * + * Sending a message is an asynchronous operation. The \p post + * call will not wait for the message either to arrive at the + * destination or to be received. + */ + virtual void post(pmt::pmt_t which_port, pmt::pmt_t msg) = 0; + }; + + typedef boost::shared_ptr<msg_accepter> msg_accepter_sptr; + + } /* namespace messages */ +} /* namespace gr */ + +#endif /* INCLUDED_MSG_ACCEPTER_H */ diff --git a/gnuradio-runtime/include/gnuradio/messages/msg_accepter_msgq.h b/gnuradio-runtime/include/gnuradio/messages/msg_accepter_msgq.h new file mode 100644 index 0000000000..ba699b8ee6 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/messages/msg_accepter_msgq.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_MSG_ACCEPTER_MSGQ_H +#define INCLUDED_MSG_ACCEPTER_MSGQ_H + +#include <gnuradio/api.h> +#include <gnuradio/messages/msg_accepter.h> +#include <gnuradio/messages/msg_queue.h> + +namespace gr { + namespace messages { + + /*! + * \brief Concrete class that accepts messages and inserts them + * into a message queue. + */ + class GR_RUNTIME_API msg_accepter_msgq : public msg_accepter + { + protected: + msg_queue_sptr d_msg_queue; + + public: + msg_accepter_msgq(msg_queue_sptr msgq); + ~msg_accepter_msgq(); + + virtual void post(pmt::pmt_t msg); + + msg_queue_sptr msg_queue() const { return d_msg_queue; } + }; + + } /* namespace messages */ +} /* namespace gr */ + +#endif /* INCLUDED_MSG_ACCEPTER_MSGQ_H */ diff --git a/gnuradio-runtime/include/gnuradio/messages/msg_passing.h b/gnuradio-runtime/include/gnuradio/messages/msg_passing.h new file mode 100644 index 0000000000..6ad6c40b08 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/messages/msg_passing.h @@ -0,0 +1,123 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_MSG_PASSING_H +#define INCLUDED_MSG_PASSING_H + +/*! + * \brief Include this header to use the message passing features + */ + +#include <gnuradio/api.h> +#include <pmt/pmt.h> +#include <gnuradio/messages/msg_accepter.h> + +namespace gr { + namespace messages { + + /*! + * \brief send message to msg_accepter + * + * \param accepter is the target of the send. + * \param which_port A pmt symbol describing the port by name. + * \param msg is the message to send. It's usually a pmt tuple. + * + * Sending a message is an asynchronous operation. The \p send + * call will not wait for the message either to arrive at the + * destination or to be received. + * + * \returns msg + */ + static inline pmt::pmt_t + send(msg_accepter_sptr accepter, const pmt::pmt_t &which_port, + const pmt::pmt_t &msg) + { + accepter->post(which_port, msg); + return msg; + } + + /*! + * \brief send message to msg_accepter + * + * \param accepter is the target of the send. + * \param which_port A pmt symbol describing the port by name. + * \param msg is the message to send. It's usually a pmt tuple. + * + * Sending a message is an asynchronous operation. The \p send + * call will not wait for the message either to arrive at the + * destination or to be received. + * + * \returns msg + */ + static inline pmt::pmt_t + send(msg_accepter *accepter, const pmt::pmt_t &which_port, + const pmt::pmt_t &msg) + { + accepter->post(which_port, msg); + return msg; + } + + /*! + * \brief send message to msg_accepter + * + * \param accepter is the target of the send. + * \param which_port A pmt symbol describing the port by name. + * \param msg is the message to send. It's usually a pmt tuple. + * + * Sending a message is an asynchronous operation. The \p send + * call will not wait for the message either to arrive at the + * destination or to be received. + * + * \returns msg + */ + static inline pmt::pmt_t + send(msg_accepter &accepter, const pmt::pmt_t &which_port, + const pmt::pmt_t &msg) + { + accepter.post(which_port, msg); + return msg; + } + + /*! + * \brief send message to msg_accepter + * + * \param accepter is the target of the send. + * aprecond: pmt::is_msg_accepter(accepter) + * \param which_port A pmt symbol describing the port by name. + * \param msg is the message to send. It's usually a pmt tuple. + * + * Sending a message is an asynchronous operation. The \p send + * call will not wait for the message either to arrive at the + * destination or to be received. + * + * \returns msg + */ + static inline pmt::pmt_t + send(pmt::pmt_t accepter, const pmt::pmt_t &which_port, + const pmt::pmt_t &msg) + { + return send(pmt::msg_accepter_ref(accepter), which_port, msg); + } + + } /* namespace messages */ +} /* namespace gr */ + +#endif /* INCLUDED_MSG_PASSING_H */ diff --git a/gnuradio-runtime/include/gnuradio/messages/msg_producer.h b/gnuradio-runtime/include/gnuradio/messages/msg_producer.h new file mode 100644 index 0000000000..758320fc6a --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/messages/msg_producer.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_MSG_PRODUCER_H +#define INCLUDED_MSG_PRODUCER_H + +#include <gnuradio/api.h> +#include <pmt/pmt.h> +#include <boost/shared_ptr.hpp> + +namespace gr { + namespace messages { + + /*! + * \brief Virtual base class that produces messages + */ + class GR_RUNTIME_API msg_producer + { + public: + msg_producer() {} + virtual ~msg_producer(); + + /*! + * \brief send \p msg to \p msg_producer + */ + virtual pmt::pmt_t retrieve() = 0; + }; + + typedef boost::shared_ptr<msg_producer> msg_producer_sptr; + + } /* namespace messages */ +} /* namespace gr */ + +#endif /* INCLUDED_MSG_PRODUCER_H */ diff --git a/gnuradio-runtime/include/gnuradio/messages/msg_queue.h b/gnuradio-runtime/include/gnuradio/messages/msg_queue.h new file mode 100644 index 0000000000..dfe1ca97be --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/messages/msg_queue.h @@ -0,0 +1,95 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_MSG_QUEUE_H +#define INCLUDED_MSG_QUEUE_H + +#include <gnuradio/api.h> +#include <gnuradio/thread/thread.h> +#include <pmt/pmt.h> +#include <deque> + +namespace gr { + namespace messages { + + class msg_queue; + typedef boost::shared_ptr<msg_queue> msg_queue_sptr; + + msg_queue_sptr make_msg_queue(unsigned int limit=0); + + /*! + * \brief thread-safe message queue + */ + class GR_RUNTIME_API msg_queue + { + private: + gr::thread::mutex d_mutex; + gr::thread::condition_variable d_not_empty; + gr::thread::condition_variable d_not_full; + unsigned int d_limit; // max # of messages in queue. 0 -> unbounded + + std::deque<pmt::pmt_t> d_msgs; + + public: + msg_queue(unsigned int limit); + ~msg_queue(); + + /*! + * \brief Insert message at tail of queue. + * \param msg message + * + * Block if queue if full. + */ + void insert_tail(pmt::pmt_t msg); + + /*! + * \brief Delete message from head of queue and return it. + * Block if no message is available. + */ + pmt::pmt_t delete_head(); + + /*! + * \brief If there's a message in the q, delete it and return it. + * If no message is available, return pmt::pmt_t(). + */ + pmt::pmt_t delete_head_nowait(); + + //! Delete all messages from the queue + void flush(); + + //! is the queue empty? + bool empty_p() const { return d_msgs.empty(); } + + //! is the queue full? + bool full_p() const { return d_limit != 0 && count() >= d_limit; } + + //! return number of messages in queue + unsigned int count() const { return d_msgs.size(); } + + //! return limit on number of message in queue. 0 -> unbounded + unsigned int limit() const { return d_limit; } + }; + + } /* namespace messages */ +} /* namespace gr */ + +#endif /* INCLUDED_MSG_QUEUE_H */ diff --git a/gnuradio-runtime/include/gnuradio/misc.h b/gnuradio-runtime/include/gnuradio/misc.h new file mode 100644 index 0000000000..290e39b490 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/misc.h @@ -0,0 +1,39 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_MISC_H +#define INCLUDED_GR_MISC_H + +#include <gnuradio/api.h> +#include <gnuradio/types.h> + +GR_RUNTIME_API unsigned int +gr_rounduppow2(unsigned int n); + +// FIXME should be template +GR_RUNTIME_API void gr_zero_vector(std::vector<float> &v); +GR_RUNTIME_API void gr_zero_vector(std::vector<double> &v); +GR_RUNTIME_API void gr_zero_vector(std::vector<int> &v); +GR_RUNTIME_API void gr_zero_vector(std::vector<gr_complex> &v); + + +#endif /* INCLUDED_GR_MISC_H */ diff --git a/gnuradio-runtime/include/gnuradio/msg_accepter.h b/gnuradio-runtime/include/gnuradio/msg_accepter.h new file mode 100644 index 0000000000..1f60a9e555 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/msg_accepter.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_MSG_ACCEPTER_H +#define INCLUDED_GR_RUNTIME_MSG_ACCEPTER_H + +#include <gnuradio/api.h> +#include <gnuradio/messages/msg_accepter.h> +#include <pmt/pmt.h> + +namespace gr { + + /*! + * \brief Accepts messages and inserts them into a message queue, + * then notifies subclass gr::basic_block there is a message pending. + */ + class GR_RUNTIME_API msg_accepter : public gr::messages::msg_accepter + { + public: + msg_accepter(); + ~msg_accepter(); + + void post(pmt::pmt_t which_port, pmt::pmt_t msg); + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_RUNTIME_MSG_ACCEPTER_H */ diff --git a/gnuradio-runtime/include/gnuradio/msg_handler.h b/gnuradio-runtime/include/gnuradio/msg_handler.h new file mode 100644 index 0000000000..b37f215616 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/msg_handler.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_MSG_HANDLER_H +#define INCLUDED_GR_MSG_HANDLER_H + +#include <gnuradio/api.h> +#include <gnuradio/message.h> + +namespace gr { + + class msg_handler; + typedef boost::shared_ptr<msg_handler> msg_handler_sptr; + + /*! + * \brief abstract class of message handlers + * \ingroup base + */ + class GR_RUNTIME_API msg_handler + { + public: + virtual ~msg_handler(); + + //! handle \p msg + virtual void handle(message::sptr msg) = 0; + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_MSG_HANDLER_H */ diff --git a/gnuradio-runtime/include/gnuradio/msg_queue.h b/gnuradio-runtime/include/gnuradio/msg_queue.h new file mode 100644 index 0000000000..3326cf9a7f --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/msg_queue.h @@ -0,0 +1,95 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_MSG_QUEUE_H +#define INCLUDED_GR_MSG_QUEUE_H + +#include <gnuradio/api.h> +#include <gnuradio/msg_handler.h> +#include <gnuradio/thread/thread.h> + +namespace gr { + + /*! + * \brief thread-safe message queue + * \ingroup misc + */ + class GR_RUNTIME_API msg_queue : public msg_handler + { + gr::thread::mutex d_mutex; + gr::thread::condition_variable d_not_empty; + gr::thread::condition_variable d_not_full; + message::sptr d_head; + message::sptr d_tail; + unsigned int d_count; // # of messages in queue. + unsigned int d_limit; // max # of messages in queue. 0 -> unbounded + + public: + typedef boost::shared_ptr<msg_queue> sptr; + + static sptr make(unsigned int limit=0); + + msg_queue(unsigned int limit); + ~msg_queue(); + + //! Generic msg_handler method: insert the message. + void handle(message::sptr msg) { insert_tail (msg); } + + /*! + * \brief Insert message at tail of queue. + * \param msg message + * + * Block if queue if full. + */ + void insert_tail(message::sptr msg); + + /*! + * \brief Delete message from head of queue and return it. + * Block if no message is available. + */ + message::sptr delete_head(); + + /*! + * \brief If there's a message in the q, delete it and return it. + * If no message is available, return 0. + */ + message::sptr delete_head_nowait(); + + //! Delete all messages from the queue + void flush(); + + //! is the queue empty? + bool empty_p() const { return d_count == 0; } + + //! is the queue full? + bool full_p() const { return d_limit != 0 && d_count >= d_limit; } + + //! return number of messages in queue + unsigned int count() const { return d_count; } + + //! return limit on number of message in queue. 0 -> unbounded + unsigned int limit() const { return d_limit; } + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_MSG_QUEUE_H */ diff --git a/gnuradio-runtime/include/gnuradio/nco.h b/gnuradio-runtime/include/gnuradio/nco.h new file mode 100644 index 0000000000..aff72068b9 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/nco.h @@ -0,0 +1,199 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GR_NCO_H_ +#define _GR_NCO_H_ + +#include <gnuradio/sincos.h> +#include <gnuradio/gr_complex.h> +#include <vector> +#include <cmath> + +namespace gr { + + /*! + * \brief base class template for Numerically Controlled Oscillator (NCO) + * \ingroup misc + */ + template<class o_type, class i_type> + class nco + { + public: + nco() : phase(0), phase_inc(0) {} + + virtual ~nco() {} + + // radians + void set_phase(double angle) + { + phase = angle; + } + + void adjust_phase(double delta_phase) + { + phase += delta_phase; + } + + // angle_rate is in radians / step + void set_freq(double angle_rate) + { + phase_inc = angle_rate; + } + + // angle_rate is a delta in radians / step + void adjust_freq(double delta_angle_rate) + { + phase_inc += delta_angle_rate; + } + + // increment current phase angle + void step() + { + phase += phase_inc; + if(fabs(phase) > M_PI) { + while(phase > M_PI) + phase -= 2*M_PI; + + while(phase < -M_PI) + phase += 2*M_PI; + } + } + + void step(int n) + { + phase += phase_inc * n; + if(fabs(phase) > M_PI){ + while(phase > M_PI) + phase -= 2*M_PI; + + while(phase < -M_PI) + phase += 2*M_PI; + } + } + + // units are radians / step + double get_phase() const { return phase; } + double get_freq() const { return phase_inc; } + + // compute sin and cos for current phase angle + void sincos(float *sinx, float *cosx) const; + + // compute cos or sin for current phase angle + float cos() const { return std::cos(phase); } + float sin() const { return std::sin(phase); } + + // compute a block at a time + void sin(float *output, int noutput_items, double ampl = 1.0); + void cos(float *output, int noutput_items, double ampl = 1.0); + void sincos(gr_complex *output, int noutput_items, double ampl = 1.0); + void sin(short *output, int noutput_items, double ampl = 1.0); + void cos(short *output, int noutput_items, double ampl = 1.0); + void sin(int *output, int noutput_items, double ampl = 1.0); + void cos(int *output, int noutput_items, double ampl = 1.0); + + protected: + double phase; + double phase_inc; + }; + + template<class o_type, class i_type> + void + nco<o_type,i_type>::sincos(float *sinx, float *cosx) const + { + gr::sincosf(phase, sinx, cosx); + } + + template<class o_type, class i_type> + void + nco<o_type,i_type>::sin(float *output, int noutput_items, double ampl) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (float)(sin () * ampl); + step(); + } + } + + template<class o_type, class i_type> + void + nco<o_type,i_type>::cos(float *output, int noutput_items, double ampl) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (float)(cos() * ampl); + step(); + } + } + + template<class o_type, class i_type> + void + nco<o_type,i_type>::sin(short *output, int noutput_items, double ampl) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (short)(sin() * ampl); + step(); + } + } + + template<class o_type, class i_type> + void + nco<o_type,i_type>::cos(short *output, int noutput_items, double ampl) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (short)(cos() * ampl); + step(); + } + } + + template<class o_type, class i_type> + void + nco<o_type,i_type>::sin(int *output, int noutput_items, double ampl) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (int)(sin() * ampl); + step(); + } + } + + template<class o_type, class i_type> + void + nco<o_type,i_type>::cos(int *output, int noutput_items, double ampl) + { + for(int i = 0; i < noutput_items; i++) { + output[i] = (int)(cos() * ampl); + step(); + } + } + + template<class o_type, class i_type> + void + nco<o_type,i_type>::sincos(gr_complex *output, int noutput_items, double ampl) + { + for(int i = 0; i < noutput_items; i++) { + float cosx, sinx; + nco::sincos(&sinx, &cosx); + output[i] = gr_complex(cosx * ampl, sinx * ampl); + step(); + } + } + +} /* namespace gr */ + +#endif /* _NCO_H_ */ diff --git a/gnuradio-runtime/include/gnuradio/prefs.h b/gnuradio-runtime/include/gnuradio/prefs.h new file mode 100644 index 0000000000..b675c83491 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/prefs.h @@ -0,0 +1,152 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_PREFS_H +#define INCLUDED_GR_PREFS_H + +#include <gnuradio/api.h> +#include <string> +#include <map> +#include <gnuradio/thread/thread.h> + +namespace gr { + + typedef std::map< std::string, std::map<std::string, std::string> > config_map_t; + typedef std::map< std::string, std::map<std::string, std::string> >::iterator config_map_itr; + typedef std::map<std::string, std::string> config_map_elem_t; + typedef std::map<std::string, std::string>::iterator config_map_elem_itr; + + /*! + * \brief Base class for representing user preferences a la windows INI files. + * \ingroup misc + * + * The real implementation is in Python, and is accessable from C++ + * via the magic of SWIG directors. + */ + class GR_RUNTIME_API prefs + { + public: + static prefs *singleton(); + static void set_singleton(prefs *p); + + prefs(); + virtual ~prefs(); + + /*! + * \brief Returns the configuration options as a string. + */ + std::string to_string(); + + /*! + * \brief Saves the configuration settings to + * ${HOME}/.gnuradio/config.conf. + * + * WARNING: this will overwrite your current config.conf file. + */ + void save(); + + /*! + * \brief Does \p section exist? + */ + virtual bool has_section(const std::string §ion); + + /*! + * \brief Does \p option exist? + */ + virtual bool has_option(const std::string §ion, + const std::string &option); + + /*! + * \brief If option exists return associated value; else + * default_val. + */ + virtual const std::string get_string(const std::string §ion, + const std::string &option, + const std::string &default_val); + + /*! + * \brief Set or add a string \p option to \p section with value + * \p val. + */ + virtual void set_string(const std::string §ion, + const std::string &option, + const std::string &val); + + /*! + * \brief If option exists and value can be converted to bool, + * return it; else default_val. + */ + virtual bool get_bool(const std::string §ion, + const std::string &option, + bool default_val); + + /*! + * \brief Set or add a bool \p option to \p section with value \p val. + */ + virtual void set_bool(const std::string §ion, + const std::string &option, + bool val); + + /*! + * \brief If option exists and value can be converted to long, + * return it; else default_val. + */ + virtual long get_long(const std::string §ion, + const std::string &option, + long default_val); + + /*! + * \brief Set or add a long \p option to \p section with value \p val. + */ + virtual void set_long(const std::string §ion, + const std::string &option, + long val); + + /*! + * \brief If option exists and value can be converted to double, + * return it; else default_val. + */ + virtual double get_double(const std::string §ion, + const std::string &option, + double default_val); + + /*! + * \brief Set or add a double \p option to \p section with value \p val. + */ + virtual void set_double(const std::string §ion, + const std::string &option, + double val); + + protected: + virtual std::vector<std::string> _sys_prefs_filenames(); + virtual void _read_files(); + virtual void _convert_to_map(const std::string &conf); + virtual char * option_to_env(std::string section, std::string option); + + private: + gr::thread::mutex d_mutex; + config_map_t d_config_map; + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_PREFS_H */ diff --git a/gnuradio-runtime/include/gnuradio/py_feval.h b/gnuradio-runtime/include/gnuradio/py_feval.h new file mode 100644 index 0000000000..94def79ca1 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/py_feval.h @@ -0,0 +1,77 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <pmt/pmt.h> + +namespace gr { + + class py_feval_dd : public feval_dd + { + public: + double calleval(double x) + { + ensure_py_gil_state _lock; + return eval(x); + } + }; + + class py_feval_cc : public feval_cc + { + public: + gr_complex calleval(gr_complex x) + { + ensure_py_gil_state _lock; + return eval(x); + } + }; + + class py_feval_ll : public feval_ll + { + public: + long calleval(long x) + { + ensure_py_gil_state _lock; + return eval(x); + } + }; + + class py_feval : public feval + { + public: + void calleval() + { + ensure_py_gil_state _lock; + eval(); + } + }; + + class py_feval_p : public feval_p + { + public: + void calleval(pmt::pmt_t x) + { + ensure_py_gil_state _lock; + eval(x); + } + }; + +} /* namespace gr */ diff --git a/gnuradio-runtime/include/gnuradio/pycallback_object.h b/gnuradio-runtime/include/gnuradio/pycallback_object.h new file mode 100644 index 0000000000..de35181c0b --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/pycallback_object.h @@ -0,0 +1,206 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <iostream> +#include <gnuradio/rpcregisterhelpers.h> +#include <gnuradio/ice_application_base.h> +#include <gnuradio/IcePy_Communicator.h> +#include <pythread.h> +#include <boost/format.hpp> + +enum pyport_t { + PYPORT_STRING, + PYPORT_FLOAT +}; + +class Instance +{ +public: + static boost::shared_ptr<ice_application_common> get_application() + { + return ice_application_common::Instance(); + } + static Ice::CommunicatorPtr get_swig_communicator() + { + return get_application()->communicator(); + } +}; + +int pycallback_object_count = 500; + +// a simple to-PMT converter template class-function +template <class myType> class pmt_assist +{ +public: + static pmt::pmt_t make(myType _val) + { + return pmt::mp(_val); + } +}; + +/* template specializations for vectors that cant use pmt::mp() */ +template<> +pmt::pmt_t pmt_assist<std::vector<float> >::make(std::vector<float> _val) +{ + return pmt::init_f32vector(_val.size(), &_val[0]); +} + +template<> +pmt::pmt_t pmt_assist<std::vector<gr_complex> >::make(std::vector<gr_complex> _val) +{ + return pmt::init_c32vector(_val.size(), &_val[0]); +} + +template <class myType> class pycallback_object +{ +public: + pycallback_object(std::string name, std::string functionbase, + std::string units, std::string desc, + myType min, myType max, myType deflt, + DisplayType dtype) : + d_callback(NULL), + d_functionbase(functionbase), d_units(units), d_desc(desc), + d_min(min), d_max(max), d_deflt(deflt), d_dtype(dtype), + d_name(name), d_id(pycallback_object_count++) + { + d_callback = NULL; + setup_rpc(); + } + + void add_rpc_variable(rpcbasic_sptr s) + { + d_rpc_vars.push_back(s); + } + + myType get() { + myType rVal; + if(d_callback == NULL) { + printf("WARNING: pycallback_object get() called without py callback set!\n"); + return rVal; + } + else { + // obtain PyGIL + PyGILState_STATE state = PyGILState_Ensure(); + + PyObject *func; + //PyObject *arglist; + PyObject *result; + + func = (PyObject *) d_callback; // Get Python function + //arglist = Py_BuildValue(""); // Build argument list + result = PyEval_CallObject(func,NULL); // Call Python + //result = PyEval_CallObject(func,arglist); // Call Python + //Py_DECREF(arglist); // Trash arglist + if(result) { // If no errors, return double + rVal = pyCast(result); + } + Py_XDECREF(result); + + // release PyGIL + PyGILState_Release(state); + return rVal; + } + } + + void set_callback(PyObject *cb) + { + d_callback = cb; + } + + void setup_rpc() + { +#ifdef GR_CTRLPORT + add_rpc_variable( + rpcbasic_sptr(new rpcbasic_register_get<pycallback_object, myType>( + (boost::format("%s%d") % d_name % d_id).str() , d_functionbase.c_str(), + this, &pycallback_object::get, pmt_assist<myType>::make(d_min), + pmt_assist<myType>::make(d_max), pmt_assist<myType>::make(d_deflt), + d_units.c_str(), d_desc.c_str(), RPC_PRIVLVL_MIN, d_dtype))); +#endif /* GR_CTRLPORT */ + } + +private: + PyObject* d_callback; + std::string d_functionbase, d_units, d_desc; + myType d_min, d_max, d_deflt; + DisplayType d_dtype; + + myType pyCast(PyObject* obj) { + printf("TYPE NOT IMPLEMENTED!\n"); + assert(0); + }; + std::vector<boost::any> d_rpc_vars; // container for all RPC variables + std::string d_name; + int d_id; + +}; + + +// template specialization conversion functions +// get data out of the PyObject and into the real world +template<> +std::string pycallback_object<std::string>::pyCast(PyObject* obj) +{ + return std::string(PyString_AsString(obj)); +} + +template<> +double pycallback_object<double>::pyCast(PyObject* obj) +{ + return PyFloat_AsDouble(obj); +} + +template<> +float pycallback_object<float>::pyCast(PyObject* obj) +{ + return (float)PyFloat_AsDouble(obj); +} + +template<> +int pycallback_object<int>::pyCast(PyObject* obj) +{ + return PyInt_AsLong(obj); +} + +template<> +std::vector<float> pycallback_object<std::vector<float> >::pyCast(PyObject* obj) +{ + int size = PyObject_Size(obj); + std::vector<float> rval(size); + for(int i=0; i<size; i++) { + rval[i] = (float)PyFloat_AsDouble(PyList_GetItem(obj, i)); + } + return rval; +} + +template<> +std::vector<gr_complex> pycallback_object<std::vector<gr_complex> >::pyCast(PyObject* obj) +{ + int size = PyObject_Size(obj); + std::vector<gr_complex> rval(size); + for(int i=0; i<size; i++){ rval[i] = \ + gr_complex((float)PyComplex_RealAsDouble(PyList_GetItem(obj, i)), + (float)PyComplex_ImagAsDouble(PyList_GetItem(obj, i))); + } + return rval; +} +// TODO: add more template specializations as needed! diff --git a/gnuradio-runtime/include/gnuradio/random.h b/gnuradio-runtime/include/gnuradio/random.h new file mode 100644 index 0000000000..e01fcb7be7 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/random.h @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RANDOM_H +#define INCLUDED_GR_RANDOM_H + +#include <gnuradio/api.h> +#include <gnuradio/gr_complex.h> + +// While rand(3) specifies RAND_MAX, random(3) says that the output +// ranges from 0 to 2^31-1 but does not specify a macro to denote +// this. We define RANDOM_MAX for cleanliness. We must omit the +// definition for systems that have made the same choice. (Note that +// random(3) is from 4.2BSD, and not specified by POSIX.) + +#ifndef RANDOM_MAX +static const int RANDOM_MAX = 2147483647; // 2^31-1 +#endif /* RANDOM_MAX */ + +#include <stdlib.h> + +namespace gr { + + /*! + * \brief pseudo random number generator + * \ingroup math_blk + */ + class GR_RUNTIME_API random + { + protected: + static const int NTAB = 32; + long d_seed; + long d_iy; + long d_iv[NTAB]; + int d_iset; + float d_gset; + + public: + random(long seed=3021); + + void reseed(long seed); + + /*! + * \brief uniform random deviate in the range [0.0, 1.0) + */ + float ran1(); + + /*! + * \brief normally distributed deviate with zero mean and variance 1 + */ + float gasdev(); + + float laplacian(); + float impulse(float factor); + float rayleigh(); + gr_complex rayleigh_complex(); + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_RANDOM_H */ + diff --git a/gnuradio-runtime/include/gnuradio/realtime.h b/gnuradio-runtime/include/gnuradio/realtime.h new file mode 100644 index 0000000000..f3910f8c7d --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/realtime.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_REALTIME_H +#define INCLUDED_GR_REALTIME_H + +#include <gnuradio/api.h> +#include <gnuradio/realtime_impl.h> + +namespace gr { + + typedef impl::rt_status_t rt_status_t; + + /*! + * \brief If possible, enable high-priority "real time" scheduling. + * \ingroup misc + */ + GR_RUNTIME_API rt_status_t enable_realtime_scheduling(); + +} /* namespace gr */ + +#endif /* INCLUDED_GR_REALTIME_H */ diff --git a/gnuradio-runtime/include/gnuradio/realtime_impl.h b/gnuradio-runtime/include/gnuradio/realtime_impl.h new file mode 100644 index 0000000000..82845918ee --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/realtime_impl.h @@ -0,0 +1,97 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2008,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GNURADIO_REALTIME_H +#define INCLUDED_GNURADIO_REALTIME_H + +#include <gnuradio/api.h> +#include <stdexcept> + +/*! + * \brief System independent way to ask for realtime scheduling + * + * \sa sys_pri.h + */ +namespace gr { + namespace impl { + + typedef enum { + RT_OK = 0, + RT_NOT_IMPLEMENTED, + RT_NO_PRIVS, + RT_OTHER_ERROR + } rt_status_t; + + enum rt_sched_policy { + RT_SCHED_RR = 0, // round robin + RT_SCHED_FIFO = 1, // first in first out + }; + + /* + * Define the range for our virtual priorities (don't change + * these) + * + * Processes (or threads) with numerically higher priority values + * are scheduled before processes with numerically lower priority + * values. Thus, the value returned by rt_priority_max() will be + * greater than the value returned by rt_priority_min(). + */ + static inline int rt_priority_min() { return 0; } + static inline int rt_priority_max() { return 15; } + static inline int rt_priority_default() { return 1; } + + struct GR_RUNTIME_API rt_sched_param { + int priority; + rt_sched_policy policy; + + rt_sched_param() + : priority(rt_priority_default()), policy(RT_SCHED_RR){} + + rt_sched_param(int priority_, rt_sched_policy policy_ = RT_SCHED_RR) + { + if(priority_ < rt_priority_min() || priority_ > rt_priority_max()) + throw std::invalid_argument("rt_sched_param: priority out of range"); + + priority = priority_; + policy = policy_; + } + }; + + /*! + * \brief If possible, enable "realtime" scheduling. + * \ingroup misc + * + * In general, this means that the code will be scheduled before + * any non-realtime (normal) processes. Note that if your code + * contains an non-blocking infinite loop and you enable realtime + * scheduling, it's possible to hang the system. + */ + + // NOTE: If you change this, you need to change the code in + // gnuradio-core/src/lib/runtime/gr_realtime.i, see note there. + rt_status_t + GR_RUNTIME_API enable_realtime_scheduling(rt_sched_param = rt_sched_param()); + + } /* namespace impl */ +} /* namespace gr */ + +#endif /* INCLUDED_GNURADIO_REALTIME_H */ diff --git a/gnuradio-runtime/include/gnuradio/rpccallbackregister_base.h b/gnuradio-runtime/include/gnuradio/rpccallbackregister_base.h new file mode 100644 index 0000000000..3b5b392ec3 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/rpccallbackregister_base.h @@ -0,0 +1,105 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCCALLBACKREGISTER_BASE_H +#define RPCCALLBACKREGISTER_BASE_H + +#include <gnuradio/messages/msg_accepter.h> +#include <gnuradio/messages/msg_producer.h> + +typedef uint32_t DisplayType; + +// DisplayType Plotting types +const uint32_t DISPNULL = 0x0000; +const uint32_t DISPTIME = 0x0001; +const uint32_t DISPXY = 0x0002; +const uint32_t DISPPSD = 0x0004; +const uint32_t DISPSPEC = 0x0008; +const uint32_t DISPRAST = 0x0010; + +// DisplayType Options +const uint32_t DISPOPTCPLX = 0x0100; +const uint32_t DISPOPTLOG = 0x0200; +const uint32_t DISPOPTSTEM = 0x0400; +const uint32_t DISPOPTSTRIP = 0x0800; +const uint32_t DISPOPTSCATTER = 0x1000; + +enum priv_lvl_t { + RPC_PRIVLVL_ALL = 0, + RPC_PRIVLVL_MIN = 9, + RPC_PRIVLVL_NONE = 10 +}; + +enum KnobType { + KNOBBOOL, KNOBCHAR, KNOBINT, KNOBFLOAT, + KNOBDOUBLE, KNOBSTRING, KNOBLONG, KNOBVECBOOL, + KNOBVECCHAR, KNOBVECINT, KNOBVECFLOAT, KNOBVECDOUBLE, + KNOBVECSTRING, KNOBVECLONG +}; + +struct callbackregister_base +{ + struct callback_base_t + { + public: + callback_base_t(const priv_lvl_t priv_, const std::string& units_, + const DisplayType display_, const std::string& desc_, + const pmt::pmt_t min_, const pmt::pmt_t max_, const pmt::pmt_t def) + : priv(priv_), units(units_), description(desc_), + min(min_), max(max_), defaultvalue(def), display(display_) + { + } + + priv_lvl_t priv; + std::string units, description; + pmt::pmt_t min, max, defaultvalue; + DisplayType display; + }; + + template<typename T, typename Tsptr> + class callback_t : public callback_base_t + { + public: + callback_t(T* callback_, priv_lvl_t priv_, + const std::string& units_, const DisplayType display_, const:: std::string& desc_, + const pmt::pmt_t& min_, const pmt::pmt_t& max_, const pmt::pmt_t& def_) : + callback_base_t(priv_, units_, display_, desc_, min_, max_, def_), + callback(callback_) + { + } + + Tsptr callback; + }; + + typedef callback_t<gr::messages::msg_accepter, gr::messages::msg_accepter_sptr> configureCallback_t; + typedef callback_t<gr::messages::msg_producer, gr::messages::msg_producer_sptr> queryCallback_t; + + callbackregister_base() {;} + virtual ~callbackregister_base() {;} + + virtual void registerConfigureCallback(const std::string &id, const configureCallback_t callback) = 0; + virtual void unregisterConfigureCallback(const std::string &id) = 0; + virtual void registerQueryCallback(const std::string &id, const queryCallback_t callback) = 0; + virtual void unregisterQueryCallback(const std::string &id) = 0; +}; + +#endif /* RPCCALLBACKREGISTER_BASE_H */ diff --git a/gnuradio-runtime/include/gnuradio/rpcmanager.h b/gnuradio-runtime/include/gnuradio/rpcmanager.h new file mode 100644 index 0000000000..12cf279406 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/rpcmanager.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCMANAGER_H +#define RPCMANAGER_H + +#include <gnuradio/api.h> +#include <gnuradio/rpcmanager_base.h> +#include <gnuradio/rpcserver_booter_aggregator.h> +#include <memory> +#include <iostream> + +class GR_RUNTIME_API rpcmanager : public virtual rpcmanager_base +{ + public: + rpcmanager(); + ~rpcmanager(); + + static rpcserver_booter_base* get(); + + static void register_booter(rpcserver_booter_base* booter); + + template<typename T> class rpcserver_booter_register_helper + { + public: + rpcserver_booter_register_helper() { + rpcmanager::register_booter(new T()); + } + + //TODO: unregister + }; + + private: + static bool make_aggregator; + static bool booter_registered; + static bool aggregator_registered; + static void rpcserver_booter_base_sptr_dest(rpcserver_booter_base* b) {;} + static rpcserver_booter_base* boot; + static std::auto_ptr<rpcserver_booter_aggregator> aggregator; +}; + +#endif /* RPCMANAGER_H */ diff --git a/gnuradio-runtime/include/gnuradio/rpcmanager_base.h b/gnuradio-runtime/include/gnuradio/rpcmanager_base.h new file mode 100644 index 0000000000..60425c4a15 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/rpcmanager_base.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCMANAGER_BASE_H +#define RPCMANAGER_BASE_H + +#include <boost/shared_ptr.hpp> + +class rpcserver_booter_base; +//class rpcserver_booter_aggregator; + +class rpcmanager_base +{ + public: + typedef boost::shared_ptr<rpcserver_booter_base> rpcserver_booter_base_sptr; + + rpcmanager_base() {;} + ~rpcmanager_base() {;} + + //static rpcserver_booter_base* get(); + + //static void register_booter(rpcserver_booter_base_sptr booter); + +private: +}; + +#endif /* RPCMANAGER_BASE_H */ diff --git a/gnuradio-runtime/include/gnuradio/rpcpmtconverters_ice.h b/gnuradio-runtime/include/gnuradio/rpcpmtconverters_ice.h new file mode 100644 index 0000000000..e592f4cdfb --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/rpcpmtconverters_ice.h @@ -0,0 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCPMTCONVERTERS_ICE_H +#define RPCPMTCONVERTERS_ICE_H + +#include <pmt/pmt.h> +#include <gnuradio.h> + +namespace rpcpmtconverter +{ + pmt::pmt_t to_pmt(const GNURadio::KnobPtr& knob, const Ice::Current& c); + GNURadio::KnobPtr from_pmt(const pmt::pmt_t& knob, const Ice::Current& c); +} + +#endif /* RPCPMTCONVERTERS_ICE_H */ diff --git a/gnuradio-runtime/include/gnuradio/rpcregisterhelpers.h b/gnuradio-runtime/include/gnuradio/rpcregisterhelpers.h new file mode 100644 index 0000000000..e405f4e1ea --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/rpcregisterhelpers.h @@ -0,0 +1,659 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCREGISTERHELPERS_H +#define RPCREGISTERHELPERS_H + +#include <stdio.h> +#include <sstream> +#include <iostream> +#include <gnuradio/rpcserver_booter_base.h> +#include <gnuradio/rpcmanager.h> +#include <gnuradio/rpcserver_selector.h> +#include <gnuradio/rpcserver_base.h> +#include <gnuradio/block_registry.h> + +// Base classes +template<typename T, typename Tto> class rpcextractor_base + : public virtual gr::messages::msg_accepter +{ +public: + rpcextractor_base(T* source, void (T::*func)(Tto)) : + _source(source), _func(func) {;} + ~rpcextractor_base() {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) { + throw std::runtime_error("rpcextractor_base: no post defined for this data type.\n"); + } + +protected: + T* _source; + void (T::*_func)(Tto); +}; + +template<typename T, typename Tto> +class rpcbasic_extractor : public virtual rpcextractor_base<T,Tto> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(Tto)) : + rpcextractor_base<T,Tto>(source, func) + {;} +}; + +template<typename T, typename Tfrom> +class rpcinserter_base : public virtual gr::messages::msg_producer +{ +public: + rpcinserter_base(T* source, Tfrom (T::*func)()) : _source(source), _func(func) {;} + rpcinserter_base() {;} + + pmt::pmt_t retrieve() { assert(0); return pmt::pmt_t(); } + +protected: + T* _source; + Tfrom (T::*_func)(); +}; + +template<typename T, typename Tfrom> +class rpcbasic_inserter : + public virtual rpcinserter_base<T,Tfrom> +{ +public: + rpcbasic_inserter(T* source, Tfrom (T::*func)()const) + : rpcinserter_base<T,Tfrom>(source, func) + {;} + + rpcbasic_inserter(T* source, Tfrom (T::*func)()) + : rpcinserter_base<T,Tfrom>(source, func) + {;} + + pmt::pmt_t retrieve() + { + return pmt::mp((rpcinserter_base<T,Tfrom>:: + _source->*rpcinserter_base<T,Tfrom>::_func)()); + } +}; + +// Specialized Extractor Templates +template<typename T> +class rpcbasic_extractor<T,double> : public virtual rpcextractor_base<T,double> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(double)) + : rpcextractor_base<T,double>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,double>::_source->*rpcextractor_base<T,double>::_func) + (pmt::to_double(msg)); + } +}; + +template<typename T> +class rpcbasic_extractor<T,float> : public virtual rpcextractor_base<T,float> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(float)) + : rpcextractor_base<T,float>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,float>::_source->*rpcextractor_base<T,float>::_func) + (pmt::to_double(msg)); + } +}; + +template<typename T> +class rpcbasic_extractor<T,long> : public virtual rpcextractor_base<T,long> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(long)) + : rpcextractor_base<T,long>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,long>::_source->*rpcextractor_base<T,long>::_func) + (pmt::to_long(msg)); + } +}; + +template<typename T> +class rpcbasic_extractor<T,int> : public virtual rpcextractor_base<T,int> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(int)) + : rpcextractor_base<T,int>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,int>::_source->*rpcextractor_base<T,int>::_func) + (pmt::to_long(msg)); + } +}; + +template<typename T> +class rpcbasic_extractor<T,bool> : public virtual rpcextractor_base<T,bool> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(bool)) + : rpcextractor_base<T,bool>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,bool>::_source->*rpcextractor_base<T,bool>::_func) + (pmt::to_bool(msg)); + } +}; + +template<typename T> +class rpcbasic_extractor<T,std::complex<double> > + : public virtual rpcextractor_base<T,std::complex<double> > +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(std::complex<double>)) + : rpcextractor_base<T,std::complex<double> >(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,std::complex<double> >:: + _source->*rpcextractor_base<T,std::complex<double> >::_func)(pmt::to_complex(msg)); + } +}; + +template<typename T> +class rpcbasic_extractor<T,std::string> + : public virtual rpcextractor_base<T,std::string> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(std::string)) + : rpcextractor_base<T,std::string>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,std::string>:: + _source->*rpcextractor_base<T,std::string>::_func)(pmt::symbol_to_string(msg)); + } +}; + +template<typename T> +class rpcbasic_inserter<T,uint64_t> : public virtual rpcinserter_base<T,uint64_t> +{ +public: + rpcbasic_inserter(T* source, uint64_t (T::*func)() const) + : rpcinserter_base<T,uint64_t>(source, func) + {;} + + rpcbasic_inserter(T* source, uint64_t (T::*func)()) + : rpcinserter_base<T,uint64_t>(source, func) + {;} + + pmt::pmt_t retrieve() + { + return pmt::from_uint64((rpcinserter_base<T,uint64_t>:: + _source->*rpcinserter_base<T,uint64_t>::_func)()); + } +}; + +template<typename T> +class rpcbasic_inserter<T,std::vector< int > > + : public virtual rpcinserter_base<T,std::vector< int > > +{ +public: + rpcbasic_inserter(T* source, std::vector<int > (T::*func)() const) + : rpcinserter_base<T,std::vector<int > >(source, func) + {;} + + rpcbasic_inserter(T* source, std::vector<int > (T::*func)()) + : rpcinserter_base<T,std::vector<int > >(source, func) + {;} + + pmt::pmt_t retrieve() + { + std::vector< int > + vec((rpcinserter_base<T,std::vector<int > >:: + _source->*rpcinserter_base<T,std::vector< int > >::_func)()); + return pmt::init_s32vector(vec.size(), &vec[0]); + } +}; + +template<typename T> +class rpcbasic_inserter<T,std::vector< std::complex<float> > > + : public virtual rpcinserter_base<T,std::vector< std::complex<float> > > +{ +public: + rpcbasic_inserter(T* source, std::vector<std::complex<float> > (T::*func)() const) + : rpcinserter_base<T,std::vector<std::complex<float> > >(source, func) + {;} + + rpcbasic_inserter(T* source, std::vector<std::complex<float> > (T::*func)()) + : rpcinserter_base<T,std::vector<std::complex<float> > >(source, func) + {;} + + pmt::pmt_t retrieve() + { + std::vector< std::complex<float> > + vec((rpcinserter_base<T,std::vector<std::complex<float> > >:: + _source->*rpcinserter_base<T,std::vector< std::complex<float> > >::_func)()); + return pmt::init_c32vector(vec.size(), &vec[0]); + } +}; + +template<typename T> +class rpcbasic_inserter<T,std::vector< float> > + : public virtual rpcinserter_base<T,std::vector< float > > +{ +public: + rpcbasic_inserter(T* source, std::vector<float> (T::*func)() const) + : rpcinserter_base<T,std::vector<float > >(source, func) + {;} + + rpcbasic_inserter(T* source, std::vector<float> (T::*func)()) + : rpcinserter_base<T,std::vector<float> >(source, func) + {;} + + pmt::pmt_t retrieve() + { + std::vector< float > vec((rpcinserter_base<T,std::vector<float> >:: + _source->*rpcinserter_base<T,std::vector< float> >::_func)()); + return pmt::init_f32vector(vec.size(), &vec[0]); + } +}; + +template<typename T> +class rpcbasic_inserter<T,std::vector< uint8_t> > + : public virtual rpcinserter_base<T,std::vector< uint8_t > > { +public: + rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)() const) + : rpcinserter_base<T,std::vector<uint8_t > >(source, func) + {;} + + rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)()) + : rpcinserter_base<T,std::vector<uint8_t> >(source, func) + {;} + + pmt::pmt_t retrieve() + { + std::vector< uint8_t > vec((rpcinserter_base<T,std::vector<uint8_t> >:: + _source->*rpcinserter_base<T,std::vector< uint8_t> >::_func)()); + return pmt::init_u8vector(vec.size(), &vec[0]); + } +}; + +template <typename T> +struct rpc_register_base +{ + rpc_register_base() {count++;} +protected: static int count; +}; + +// Base class to inherit from and create universal shared pointers. +class rpcbasic_base +{ +public: + rpcbasic_base() {} + virtual ~rpcbasic_base() {}; +}; + +typedef boost::shared_ptr<rpcbasic_base> rpcbasic_sptr; + +template<typename T, typename Tto> +struct rpcbasic_register_set : public rpcbasic_base +{ + // Function used to add a 'set' RPC call using a basic_block's alias. + rpcbasic_register_set(const std::string& block_alias, + const char* functionbase, + void (T::*function)(Tto), + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_ = DISPNULL) + { + d_min = min; + d_max = max; + d_def = def; + d_units = units_; + d_desc = desc_; + d_minpriv = minpriv_; + d_display = display_; + d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get()); +#ifdef RPCSERVER_ENABLED + callbackregister_base::configureCallback_t + extractor(new rpcbasic_extractor<T,Tto>(d_object, function), + minpriv_, std::string(units_), + display_, std::string(desc_), min, max, def); + std::ostringstream oss(std::ostringstream::out); + oss << block_alias << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING SET: " << d_id << " " << desc_ << std::endl; + rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor); +#endif + } + + // Function used to add a 'set' RPC call using a name and the object + rpcbasic_register_set(const std::string& name, + const char* functionbase, + T* obj, + void (T::*function)(Tto), + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_ = DISPNULL) + { + d_min = min; + d_max = max; + d_def = def; + d_units = units_; + d_desc = desc_; + d_minpriv = minpriv_; + d_display = display_; + d_object = obj; +#ifdef RPCSERVER_ENABLED + callbackregister_base::configureCallback_t + extractor(new rpcbasic_extractor<T,Tto>(d_object, function), + minpriv_, std::string(units_), + display_, std::string(desc_), min, max, def); + std::ostringstream oss(std::ostringstream::out); + oss << name << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING SET: " << d_id << " " << desc_ << std::endl; + rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor); +#endif + } + + ~rpcbasic_register_set() + { +#ifdef RPCSERVER_ENABLED + rpcmanager::get()->i()->unregisterConfigureCallback(d_id); +#endif + } + + + pmt::pmt_t min() const { return d_min; } + pmt::pmt_t max() const { return d_max; } + pmt::pmt_t def() const { return d_def; } + std::string units() const { return d_units; } + std::string description() const { return d_desc; } + priv_lvl_t privilege_level() const { return d_minpriv; } + DisplayType default_display() const { return d_display; } + + void set_min(pmt::pmt_t p) { d_min = p; } + void set_max(pmt::pmt_t p) { d_max = p; } + void set_def(pmt::pmt_t p) { d_def = p; } + void units(std::string u) { d_units = u; } + void description(std::string d) { d_desc = d; } + void privilege_level(priv_lvl_t p) { d_minpriv = p; } + void default_display(DisplayType d) { d_display = d; } + +private: + std::string d_id; + pmt::pmt_t d_min, d_max, d_def; + std::string d_units, d_desc; + priv_lvl_t d_minpriv; + DisplayType d_display; + T *d_object; +}; + + +template<typename T, typename Tfrom> +class rpcbasic_register_get : public rpcbasic_base +{ +public: + // Function used to add a 'set' RPC call using a basic_block's alias. + // primary constructor to allow for T get() functions + rpcbasic_register_get(const std::string& block_alias, + const char* functionbase, + Tfrom (T::*function)(), + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_ = DISPNULL) + { + d_min = min; + d_max = max; + d_def = def; + d_units = units_; + d_desc = desc_; + d_minpriv = minpriv_; + d_display = display_; + d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get()); +#ifdef RPCSERVER_ENABLED + callbackregister_base::queryCallback_t + inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function), + minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); + std::ostringstream oss(std::ostringstream::out); + oss << block_alias << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING GET: " << d_id << " " << desc_ << std::endl; + rpcmanager::get()->i()->registerQueryCallback(d_id, inserter); +#endif + } + + + // alternate constructor to allow for T get() const functions + rpcbasic_register_get(const std::string& block_alias, + const char* functionbase, + Tfrom (T::*function)() const, + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_ = DISPNULL) + { + d_min = min; + d_max = max; + d_def = def; + d_units = units_; + d_desc = desc_; + d_minpriv = minpriv_; + d_display = display_; + d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get()); +#ifdef RPCSERVER_ENABLED + callbackregister_base::queryCallback_t + inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function), + minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); + std::ostringstream oss(std::ostringstream::out); + oss << block_alias << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING GET CONST: " << d_id << " " << desc_ << " " << display_ << std::endl; + rpcmanager::get()->i()->registerQueryCallback(d_id, inserter); +#endif + } + + // Function used to add a 'set' RPC call using a name and the object + // primary constructor to allow for T get() functions + rpcbasic_register_get(const std::string& name, + const char* functionbase, + T* obj, + Tfrom (T::*function)(), + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_ = DISPNULL) + { + d_min = min; + d_max = max; + d_def = def; + d_units = units_; + d_desc = desc_; + d_minpriv = minpriv_; + d_display = display_; + d_object = obj; +#ifdef RPCSERVER_ENABLED + callbackregister_base::queryCallback_t + inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function), + minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); + std::ostringstream oss(std::ostringstream::out); + oss << name << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING GET: " << d_id << " " << desc_ << std::endl; + rpcmanager::get()->i()->registerQueryCallback(d_id, inserter); +#endif + } + + + // alternate constructor to allow for T get() const functions + rpcbasic_register_get(const std::string& name, + const char* functionbase, + T* obj, + Tfrom (T::*function)() const, + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_ = DISPNULL) + { + d_min = min; + d_max = max; + d_def = def; + d_units = units_; + d_desc = desc_; + d_minpriv = minpriv_; + d_display = display_; + d_object = obj; +#ifdef RPCSERVER_ENABLED + callbackregister_base::queryCallback_t + inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function), + minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); + std::ostringstream oss(std::ostringstream::out); + oss << name << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING GET CONST: " << d_id << " " << desc_ << " " << display_ << std::endl; + rpcmanager::get()->i()->registerQueryCallback(d_id, inserter); +#endif + } + + ~rpcbasic_register_get() + { +#ifdef RPCSERVER_ENABLED + rpcmanager::get()->i()->unregisterQueryCallback(d_id); +#endif + } + + pmt::pmt_t min() const { return d_min; } + pmt::pmt_t max() const { return d_max; } + pmt::pmt_t def() const { return d_def; } + std::string units() const { return d_units; } + std::string description() const { return d_desc; } + priv_lvl_t privilege_level() const { return d_minpriv; } + DisplayType default_display() const { return d_display; } + + void set_min(pmt::pmt_t p) { d_min = p; } + void set_max(pmt::pmt_t p) { d_max = p; } + void set_def(pmt::pmt_t p) { d_def = p; } + void units(std::string u) { d_units = u; } + void description(std::string d) { d_desc = d; } + void privilege_level(priv_lvl_t p) { d_minpriv = p; } + void default_display(DisplayType d) { d_display = d; } + +private: + std::string d_id; + pmt::pmt_t d_min, d_max, d_def; + std::string d_units, d_desc; + priv_lvl_t d_minpriv; + DisplayType d_display; + T *d_object; +}; + +/* + * This class can wrap a pre-existing variable type for you + * it will define the getter and rpcregister call for you. + * + * It should be used for read-only getters. + * + */ +template<typename Tfrom> +class rpcbasic_register_variable : public rpcbasic_base +{ +protected: + rpcbasic_register_get< rpcbasic_register_variable<Tfrom>, Tfrom > d_rpc_reg; + Tfrom *d_variable; + Tfrom get() { return *d_variable; } +public: + // empty constructor which should never be called but needs to exist for ues in varous STL data structures + void setptr(Tfrom* _variable){ rpcbasic_register_variable<Tfrom>::d_variable = _variable; } + rpcbasic_register_variable() : + d_rpc_reg("FAIL", "FAIL", this, &rpcbasic_register_variable::get, + pmt::PMT_NIL, pmt::PMT_NIL, pmt::PMT_NIL, DISPNULL, + "FAIL", "FAIL", RPC_PRIVLVL_MIN), + d_variable(NULL) + { + throw std::runtime_error("ERROR: rpcbasic_register_variable called with no args. If this happens, someone has tried to use rpcbasic_register_variable incorrectly."); + }; + + rpcbasic_register_variable(const std::string& namebase, + const char* functionbase, + Tfrom *variable, + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_=DISPNULL) : + d_rpc_reg(namebase, functionbase, this, &rpcbasic_register_variable::get, + min, max, def, units_, desc_, minpriv_, display_), + d_variable(variable) + { + //std::cerr << "REGISTERING VAR: " << " " << desc_ << std::endl; + } +}; + +template<typename Tfrom> class rpcbasic_register_variable_rw : public rpcbasic_register_variable<Tfrom> { + private: + rpcbasic_register_set< rpcbasic_register_variable_rw<Tfrom>, Tfrom > d_rpc_regset; + public: + // empty constructor which should never be called but needs to exist for ues in varous STL data structures + rpcbasic_register_variable_rw() : + d_rpc_regset("FAIL","FAIL",this,&rpcbasic_register_variable<Tfrom>::get,pmt::PMT_NIL,pmt::PMT_NIL,pmt::PMT_NIL,DISPNULL,"FAIL","FAIL",RPC_PRIVLVL_MIN) + { + throw std::runtime_error("ERROR: rpcbasic_register_variable_rw called with no args. if this happens someone used rpcbasic_register_variable_rw incorrectly.\n"); + }; + void set(Tfrom _variable){ *(rpcbasic_register_variable<Tfrom>::d_variable) = _variable; } + rpcbasic_register_variable_rw( + const std::string& namebase, + const char* functionbase, + Tfrom *variable, + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv = RPC_PRIVLVL_MIN, + DisplayType display_=DISPNULL) : + rpcbasic_register_variable<Tfrom>(namebase,functionbase,variable,min,max,def,units_,desc_), + d_rpc_regset(namebase,functionbase,this,&rpcbasic_register_variable_rw::set,min,max,def,units_,desc_,minpriv,display_) + { + // no action + } +}; + + + + +#endif diff --git a/gnuradio-runtime/include/gnuradio/rpcserver_aggregator.h b/gnuradio-runtime/include/gnuradio/rpcserver_aggregator.h new file mode 100644 index 0000000000..cc19d7ff48 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/rpcserver_aggregator.h @@ -0,0 +1,100 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_AGGREGATOR_H +#define RPCSERVER_AGGREGATOR_H + +#include <vector> +#include <string> +#include <gnuradio/rpcserver_base.h> +#include <gnuradio/rpcmanager_base.h> + +class rpcserver_aggregator : public virtual rpcserver_base +{ +public: + rpcserver_aggregator(); + virtual ~rpcserver_aggregator(); + + void registerConfigureCallback(const std::string &id, const configureCallback_t callback); + void unregisterConfigureCallback(const std::string &id); + + void registerQueryCallback(const std::string &id, const queryCallback_t callback); + void unregisterQueryCallback(const std::string &id); + + void registerServer(rpcmanager_base::rpcserver_booter_base_sptr server); + + const std::string& type(); + + const std::vector<std::string>& registeredServers(); + +private: + template<class T, typename Tcallback> + struct registerConfigureCallback_f: public std::unary_function<T,void> + { + registerConfigureCallback_f(const std::string &_id, const Tcallback _callback) + : id(_id), callback(_callback) + {;} + + void operator()(T& x) { x->i()->registerConfigureCallback(id, callback); } + const std::string& id; const Tcallback& callback; + }; + + template<class T, typename Tcallback> + struct unregisterConfigureCallback_f: public std::unary_function<T,void> + { + unregisterConfigureCallback_f(const std::string &_id) + : id(_id) + {;} + + void operator()(T& x) { x->i()->unregisterConfigureCallback(id); } + const std::string& id; + }; + + template<class T, typename Tcallback> + struct registerQueryCallback_f: public std::unary_function<T,void> + { + registerQueryCallback_f(const std::string &_id, const Tcallback _callback) + : id(_id), callback(_callback) + {;} + + void operator()(T& x) { x->i()->registerQueryCallback(id, callback); } + const std::string& id; const Tcallback& callback; + }; + + template<class T, typename Tcallback> + struct unregisterQueryCallback_f: public std::unary_function<T,void> + { + unregisterQueryCallback_f(const std::string &_id) + : id(_id) + {;} + + void operator()(T& x) { x->i()->unregisterQueryCallback(id); } + const std::string& id; + }; + + const std::string d_type; + typedef std::vector<rpcmanager_base::rpcserver_booter_base_sptr> rpcServerMap_t; + std::vector<std::string> d_registeredServers; + rpcServerMap_t d_serverlist; +}; + +#endif /* RPCSERVER_AGGREGATOR_H */ diff --git a/gnuradio-runtime/include/gnuradio/rpcserver_base.h b/gnuradio-runtime/include/gnuradio/rpcserver_base.h new file mode 100644 index 0000000000..e2a1f6ef24 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/rpcserver_base.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_BASE_H +#define RPCSERVER_BASE_H + +#include <gnuradio/rpccallbackregister_base.h> + +class rpcserver_base : public virtual callbackregister_base +{ +public: + rpcserver_base() : cur_priv(RPC_PRIVLVL_ALL) {;} + virtual ~rpcserver_base() {;} + + virtual void registerConfigureCallback(const std::string &id, const configureCallback_t callback) = 0; + virtual void unregisterConfigureCallback(const std::string &id) = 0; + virtual void registerQueryCallback(const std::string &id, const queryCallback_t callback) = 0; + virtual void unregisterQueryCallback(const std::string &id) = 0; + virtual void setCurPrivLevel(const priv_lvl_t priv) { cur_priv = priv; } + + typedef boost::shared_ptr<rpcserver_base> rpcserver_base_sptr; +protected: + priv_lvl_t cur_priv; + +private: +}; + +#endif /* RPCSERVER_BASE_H */ diff --git a/gnuradio-runtime/include/gnuradio/rpcserver_booter_aggregator.h b/gnuradio-runtime/include/gnuradio/rpcserver_booter_aggregator.h new file mode 100644 index 0000000000..aac9ef8de6 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/rpcserver_booter_aggregator.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_BOOTER_AGGREGATOR +#define RPCSERVER_BOOTER_AGGREGATOR + +#include <gnuradio/api.h> +#include <gnuradio/rpcserver_booter_base.h> +#include <gnuradio/rpcserver_aggregator.h> +#include <boost/shared_ptr.hpp> +#include <string> + +class rpcserver_server; + +class GR_RUNTIME_API rpcserver_booter_aggregator : + public virtual rpcserver_booter_base +{ + public: + rpcserver_booter_aggregator(); + ~rpcserver_booter_aggregator(); + + rpcserver_base* i(); + const std::string& type(); + const std::vector<std::string> endpoints(); + + const std::vector<std::string>& registeredServers(); + + protected: + friend class rpcmanager; + rpcserver_aggregator* agg(); + +private: + std::string d_type; + boost::shared_ptr<rpcserver_aggregator> server; +}; + +#endif /* RPCSERVER_BOOTER_AGGREGATOR */ diff --git a/gnuradio-runtime/include/gnuradio/rpcserver_booter_base.h b/gnuradio-runtime/include/gnuradio/rpcserver_booter_base.h new file mode 100644 index 0000000000..682944dada --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/rpcserver_booter_base.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_BOOTER_BASE +#define RPCSERVER_BOOTER_BASE + +#include <string> +#include <vector> + +class rpcserver_base; + +class rpcserver_booter_base +{ +public: + rpcserver_booter_base() {;} + virtual ~rpcserver_booter_base() {;} + + virtual rpcserver_base* i()=0; + virtual const std::vector<std::string> endpoints()=0; + virtual const std::string& type()=0; + +private: +}; + +#endif /* RPCSERVER_BOOTER_BASE */ diff --git a/gnuradio-runtime/include/gnuradio/rpcserver_booter_ice.h b/gnuradio-runtime/include/gnuradio/rpcserver_booter_ice.h new file mode 100644 index 0000000000..11095ac433 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/rpcserver_booter_ice.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_BOOTER_ICE_H +#define RPCSERVER_BOOTER_ICE_H + +#include <gnuradio/rpcserver_booter_base.h> +#include <gnuradio/ice_server_template.h> +#include <gnuradio.h> + +class rpcserver_base; +class rpcserver_ice; + +class rpcserver_booter_ice : public virtual rpcserver_booter_base, + public virtual ice_server_template<rpcserver_base, rpcserver_ice, + rpcserver_booter_ice, GNURadio::ControlPortPtr> +{ +public: + rpcserver_booter_ice(); + ~rpcserver_booter_ice(); + + rpcserver_base* i(); + const std::string & type() {return d_type;} + const std::vector<std::string> endpoints(); + +private: + std::string d_type; +}; + +#endif /* RPCSERVER_BOOTER_ICE_H */ diff --git a/gnuradio-runtime/include/gnuradio/rpcserver_ice.h b/gnuradio-runtime/include/gnuradio/rpcserver_ice.h new file mode 100644 index 0000000000..c6c9d45717 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/rpcserver_ice.h @@ -0,0 +1,226 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_ICE_H +#define RPCSERVER_ICE_H + +#include <gnuradio/rpcserver_base.h> +#include <gnuradio/rpcpmtconverters_ice.h> +#include <string> +#include <sstream> +#include <map> +#include <gnuradio.h> +#include <Ice/Exception.h> +#include <boost/format.hpp> + +class rpcserver_ice : public virtual rpcserver_base, public GNURadio::ControlPort +{ +public: + rpcserver_ice(); + virtual ~rpcserver_ice(); + + void registerConfigureCallback(const std::string &id, const configureCallback_t callback); + void unregisterConfigureCallback(const std::string &id); + + void registerQueryCallback(const std::string &id, const queryCallback_t callback); + void unregisterQueryCallback(const std::string &id); + + virtual void set(const GNURadio::KnobMap&, const Ice::Current&); + + GNURadio::KnobMap get(const GNURadio::KnobIDList&, const Ice::Current&); + + GNURadio::KnobPropMap properties(const GNURadio::KnobIDList&, const Ice::Current&); + + virtual void shutdown(const Ice::Current&); + +private: + typedef std::map<std::string, configureCallback_t> ConfigureCallbackMap_t; + ConfigureCallbackMap_t d_setcallbackmap; + + typedef std::map<std::string, queryCallback_t> QueryCallbackMap_t; + QueryCallbackMap_t d_getcallbackmap; + + template<typename T, typename TMap> struct set_f + : public std::unary_function<T,void> + { + set_f(const Ice::Current& _c, TMap& _setcallbackmap, const priv_lvl_t& _cur_priv) : + c(_c), d_setcallbackmap(_setcallbackmap), cur_priv(_cur_priv) + {;} + + void operator()(const T& p) + { + ConfigureCallbackMap_t::const_iterator iter(d_setcallbackmap.find(p.first)); + if(iter != d_setcallbackmap.end()) { + if(cur_priv <= iter->second.priv) { + (*iter->second.callback).post(pmt::PMT_NIL, rpcpmtconverter::to_pmt(p.second,c)); + } + else { + std::cout << "Key " << p.first << " requires PRIVLVL <= " + << iter->second.priv << " to set, currently at: " + << cur_priv << std::endl; + } + } + else { + throw IceUtil::NullHandleException(__FILE__, __LINE__); + } + } + + const Ice::Current& c; + TMap& d_setcallbackmap; + const priv_lvl_t& cur_priv; + }; + + template<typename T, typename TMap> + struct get_f : public std::unary_function<T,void> + { + get_f(const Ice::Current& _c, TMap& _getcallbackmap, + const priv_lvl_t& _cur_priv, GNURadio::KnobMap& _outknobs) : + c(_c), d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs) + {} + + void operator()(const T& p) + { + QueryCallbackMap_t::const_iterator iter(d_getcallbackmap.find(p)); + if(iter != d_getcallbackmap.end()) { + if(cur_priv <= iter->second.priv) { + outknobs[p] = rpcpmtconverter::from_pmt((*iter->second.callback).retrieve(), c); + } + else { + std::cout << "Key " << iter->first << " requires PRIVLVL: <= " + << iter->second.priv << " to get, currently at: " + << cur_priv << std::endl; + } + } + else { + std::stringstream ss; + ss << "Ctrlport Key called with unregistered key (" << p << ")\n"; + std::cout << ss.str(); + throw IceUtil::IllegalArgumentException(__FILE__,__LINE__,ss.str().c_str()); + } + } + + const Ice::Current& c; + TMap& d_getcallbackmap; + const priv_lvl_t& cur_priv; + GNURadio::KnobMap& outknobs; + }; + + template<typename T, typename TMap, typename TKnobMap> + struct get_all_f : public std::unary_function<T,void> + { + get_all_f(const Ice::Current& _c, TMap& _getcallbackmap, + const priv_lvl_t& _cur_priv, TKnobMap& _outknobs) : + c(_c), d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs) + {;} + + void operator()(const T& p) + { + if(cur_priv <= p.second.priv) { + outknobs[p.first] = rpcpmtconverter::from_pmt(p.second.callback->retrieve(), c); + } + else { + std::cout << "Key " << p.first << " requires PRIVLVL <= " + << p.second.priv << " to get, currently at: " + << cur_priv << std::endl; + } + } + + const Ice::Current& c; + TMap& d_getcallbackmap; + const priv_lvl_t& cur_priv; + TKnobMap& outknobs; + }; + + template<typename T, typename TMap, typename TKnobMap> + struct properties_all_f : public std::unary_function<T,void> + { + properties_all_f(const Ice::Current& _c, QueryCallbackMap_t& _getcallbackmap, + const priv_lvl_t& _cur_priv, GNURadio::KnobPropMap& _outknobs) : + c(_c), d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs) + {;} + + void operator()(const T& p) + { + if(cur_priv <= p.second.priv) { + GNURadio::KnobProp prop;//(new GNURadio::KnobProp()); + prop.type = GNURadio::KNOBDOUBLE; + prop.units = p.second.units; + prop.description = p.second.description; + prop.min = rpcpmtconverter::from_pmt(p.second.min, c); + prop.max = rpcpmtconverter::from_pmt(p.second.max, c); + prop.display = static_cast<uint32_t>(p.second.display); + outknobs[p.first] = prop; + } + else { + std::cout << "Key " << p.first << " requires PRIVLVL <= " + << p.second.priv << " to get, currently at: " + << cur_priv << std::endl; + } + } + + const Ice::Current& c; + TMap& d_getcallbackmap; + const priv_lvl_t& cur_priv; + TKnobMap& outknobs; + }; + + template<class T, typename TMap, typename TKnobMap> + struct properties_f : public std::unary_function<T,void> + { + properties_f(const Ice::Current& _c, TMap& _getcallbackmap, + const priv_lvl_t& _cur_priv, TKnobMap& _outknobs) : + c(_c), d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs) + {;} + + void operator()(const T& p) + { + typename TMap::const_iterator iter(d_getcallbackmap.find(p)); + if(iter != d_getcallbackmap.end()) { + if(cur_priv <= iter->second.priv) { + GNURadio::KnobProp prop; + prop.type = GNURadio::KNOBDOUBLE; + prop.units = iter->second.units; + prop.description = iter->second.description; + prop.min = rpcpmtconverter::from_pmt(iter->second.min, c); + prop.max = rpcpmtconverter::from_pmt(iter->second.max, c); + prop.display = static_cast<uint32_t>(iter->second.display); + //outknobs[iter->first] = prop; + outknobs[p] = prop; + } + else { + std::cout << "Key " << iter->first << " requires PRIVLVL: <= " << + iter->second.priv << " to get, currently at: " << cur_priv << std::endl; + } + } + else { + throw IceUtil::NullHandleException(__FILE__, __LINE__); + } + } + + const Ice::Current& c; + TMap& d_getcallbackmap; + const priv_lvl_t& cur_priv; + TKnobMap& outknobs; + }; +}; + +#endif /* RPCSERVER_ICE_H */ diff --git a/gnuradio-runtime/include/gnuradio/rpcserver_selector.h b/gnuradio-runtime/include/gnuradio/rpcserver_selector.h new file mode 100644 index 0000000000..fa63c9a2dc --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/rpcserver_selector.h @@ -0,0 +1,32 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_SELECTOR +#define RPCSERVER_SELECTOR + +#define RPCSERVER_ENABLED + +#define RPCSERVER_ICE +//#define RPCSERVER_ERLANG +//#define RPCSERVER_XMLRPC + +#endif diff --git a/gnuradio-runtime/include/gnuradio/runtime_types.h b/gnuradio-runtime/include/gnuradio/runtime_types.h new file mode 100644 index 0000000000..f4674c0f0c --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/runtime_types.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_TYPES_H +#define INCLUDED_GR_RUNTIME_TYPES_H + +#include <gnuradio/api.h> +#include <gnuradio/types.h> + +namespace gr { + + /* + * typedefs for smart pointers we use throughout the runtime system + */ + class basic_block; + class block; + class block_detail; + class buffer; + class buffer_reader; + class hier_block2; + class flat_flowgraph; + class flowgraph; + class top_block; + + typedef boost::shared_ptr<basic_block> basic_block_sptr; + typedef boost::shared_ptr<block> block_sptr; + typedef boost::shared_ptr<block_detail> block_detail_sptr; + typedef boost::shared_ptr<buffer> buffer_sptr; + typedef boost::shared_ptr<buffer_reader> buffer_reader_sptr; + typedef boost::shared_ptr<hier_block2> hier_block2_sptr; + typedef boost::shared_ptr<flat_flowgraph> flat_flowgraph_sptr; + typedef boost::shared_ptr<flowgraph> flowgraph_sptr; + typedef boost::shared_ptr<top_block> top_block_sptr; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_RUNTIME_TYPES_H */ diff --git a/gnuradio-runtime/include/gnuradio/select_handler.h b/gnuradio-runtime/include/gnuradio/select_handler.h new file mode 100644 index 0000000000..df7c753ced --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/select_handler.h @@ -0,0 +1,90 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SELECT_HANDLER_H +#define INCLUDED_GR_SELECT_HANDLER_H + +#include <gnuradio/api.h> +#include <boost/shared_ptr.hpp> + +namespace gr { + + class select_handler; + typedef boost::shared_ptr<select_handler> select_handler_sptr; + + /*! + * \brief Abstract handler for select based notification. + * \ingroup base + * + * \sa gr::dispatcher + */ + class GR_RUNTIME_API select_handler + { + int d_fd; + + protected: + select_handler(int file_descriptor); + + public: + virtual ~select_handler(); + + int fd() const { return d_fd; } + int file_descriptor() const { return d_fd; } + + /*! + * \brief Called when file_descriptor is readable. + * + * Called when the dispatcher detects that file_descriptor can be + * read without blocking. + */ + virtual void handle_read() = 0; + + /*! + * \brief Called when file_descriptor is writable. + * + * Called when dispatcher detects that file descriptor can be + * written without blocking. + */ + virtual void handle_write() = 0; + + /*! + * Called each time around the dispatcher loop to determine + * whether this handler's file descriptor should be added to the + * list on which read events can occur. The default method + * returns true, indicating that by default, all handlers are + * interested in read events. + */ + virtual bool readable() { return true; } + + /*! + * Called each time around the dispatcher loop to determine + * whether this handler's file descriptor should be added to the + * list on which write events can occur. The default method + * returns true, indicating that by default, all handlers are + * interested in write events. + */ + virtual bool writable() { return true; } + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_SELECT_HANDLER_H */ diff --git a/gnuradio-runtime/include/gnuradio/sincos.h b/gnuradio-runtime/include/gnuradio/sincos.h new file mode 100644 index 0000000000..f162f6e31b --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/sincos.h @@ -0,0 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SINCOS_H +#define INCLUDED_GR_SINCOS_H + +#include <gnuradio/api.h> + +namespace gr { + + // compute sine and cosine at the same time + GR_RUNTIME_API void sincos (double x, double *sin, double *cos); + GR_RUNTIME_API void sincosf (float x, float *sin, float *cos); +} + +#endif /* INCLUDED_GR_SINCOS_H */ diff --git a/gnuradio-runtime/include/gnuradio/single_threaded_scheduler.h b/gnuradio-runtime/include/gnuradio/single_threaded_scheduler.h new file mode 100644 index 0000000000..eccbf03b36 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/single_threaded_scheduler.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H +#define INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H + +#include <gnuradio/api.h> +#include <gnuradio/runtime_types.h> +#include <fstream> + +namespace gr { + + class single_threaded_scheduler; + typedef boost::shared_ptr<single_threaded_scheduler> single_threaded_scheduler_sptr; + + /*! + * \brief Simple scheduler for stream computations. + * \ingroup internal + */ + class GR_RUNTIME_API single_threaded_scheduler + { + public: + ~single_threaded_scheduler(); + + void run(); + void stop(); + + private: + const std::vector<block_sptr> d_blocks; + volatile bool d_enabled; + std::ofstream *d_log; + + single_threaded_scheduler(const std::vector<block_sptr> &blocks); + + void main_loop(); + + friend GR_RUNTIME_API single_threaded_scheduler_sptr + make_single_threaded_scheduler(const std::vector<block_sptr> &blocks); + }; + + GR_RUNTIME_API single_threaded_scheduler_sptr + make_single_threaded_scheduler(const std::vector<block_sptr> &blocks); + +} /* namespace gr */ + +#endif /* INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H */ diff --git a/gnuradio-runtime/include/gnuradio/sptr_magic.h b/gnuradio-runtime/include/gnuradio/sptr_magic.h new file mode 100644 index 0000000000..898edc87fd --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/sptr_magic.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_SPTR_MAGIC_H +#define INCLUDED_GR_RUNTIME_SPTR_MAGIC_H + +#include <gnuradio/api.h> +#include <boost/shared_ptr.hpp> + +namespace gr { + class basic_block; + class hier_block2; +} + +namespace gnuradio { + namespace detail { + + class GR_RUNTIME_API sptr_magic + { + public: + static boost::shared_ptr<gr::basic_block> fetch_initial_sptr(gr::basic_block *p); + static void create_and_stash_initial_sptr(gr::hier_block2 *p); + }; + }; + + /* + * \brief New! Improved! Standard method to get/create the + * boost::shared_ptr for a block. + */ + template<class T> + boost::shared_ptr<T> + get_initial_sptr(T *p) + { + return boost::dynamic_pointer_cast<T, gr::basic_block> + (detail::sptr_magic::fetch_initial_sptr(p)); + } +} + +#endif /* INCLUDED_GR_RUNTIME_SPTR_MAGIC_H */ diff --git a/gnuradio-runtime/include/gnuradio/sync_block.h b/gnuradio-runtime/include/gnuradio/sync_block.h new file mode 100644 index 0000000000..4b0022ab7e --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/sync_block.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_SYNC_BLOCK_H +#define INCLUDED_GR_RUNTIME_SYNC_BLOCK_H + +#include <gnuradio/api.h> +#include <gnuradio/block.h> + +namespace gr { + + /*! + * \brief synchronous 1:1 input to output with history + * \ingroup base_blk + * + * Override work to provide the signal processing implementation. + */ + class GR_RUNTIME_API sync_block : public block + { + protected: + sync_block(void) {} // allows pure virtual interface sub-classes + sync_block(const std::string &name, + gr::io_signature::sptr input_signature, + gr::io_signature::sptr output_signature); + + public: + /*! + * \brief just like gr::block::general_work, only this arranges to + * call consume_each for you + * + * The user must override work to define the signal processing code + */ + virtual int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) = 0; + + // gr::sync_block overrides these to assist work + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + int fixed_rate_ninput_to_noutput(int ninput); + int fixed_rate_noutput_to_ninput(int noutput); + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_RUNTIME_SYNC_BLOCK_H */ diff --git a/gnuradio-runtime/include/gnuradio/sync_decimator.h b/gnuradio-runtime/include/gnuradio/sync_decimator.h new file mode 100644 index 0000000000..129abdca79 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/sync_decimator.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004, 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_SYNC_DECIMATOR_H +#define INCLUDED_GR_RUNTIME_SYNC_DECIMATOR_H + +#include <gnuradio/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + + /*! + * \brief synchronous N:1 input to output with history + * \ingroup base_blk + * + * Override work to provide the signal processing implementation. + */ + class GR_RUNTIME_API sync_decimator : public sync_block + { + private: + unsigned d_decimation; + + protected: + sync_decimator(void) {} // allows pure virtual interface sub-classes + sync_decimator(const std::string &name, + gr::io_signature::sptr input_signature, + gr::io_signature::sptr output_signature, + unsigned decimation); + + public: + unsigned decimation() const { return d_decimation; } + void set_decimation(unsigned decimation) + { + d_decimation = decimation; + set_relative_rate(1.0 / decimation); + } + + // gr::sync_decimator overrides these to assist work + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + // derived classes should override work + + int fixed_rate_ninput_to_noutput(int ninput); + int fixed_rate_noutput_to_ninput(int noutput); + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_RUNTIME_SYNC_DECIMATOR_H */ diff --git a/gnuradio-runtime/include/gnuradio/sync_interpolator.h b/gnuradio-runtime/include/gnuradio/sync_interpolator.h new file mode 100644 index 0000000000..bfe79f902e --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/sync_interpolator.h @@ -0,0 +1,74 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2008,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_SYNC_INTERPOLATOR_H +#define INCLUDED_GR_RUNTIME_SYNC_INTERPOLATOR_H + +#include <gnuradio/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + + /*! + * \brief synchronous 1:N input to output with history + * \ingroup base_blk + * + * Override work to provide the signal processing implementation. + */ + class GR_RUNTIME_API sync_interpolator : public sync_block + { + private: + unsigned d_interpolation; + + protected: + sync_interpolator(void) {} // allows pure virtual interface sub-classes + sync_interpolator(const std::string &name, + gr::io_signature::sptr input_signature, + gr::io_signature::sptr output_signature, + unsigned interpolation); + + public: + unsigned interpolation() const { return d_interpolation; } + void set_interpolation(unsigned interpolation) + { + d_interpolation = interpolation; + set_relative_rate(1.0 * interpolation); + set_output_multiple(interpolation); + } + + // gr::sync_interpolator overrides these to assist work + void forecast(int noutput_items, + gr_vector_int &ninput_items_required); + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + // derived classes should override work + + int fixed_rate_ninput_to_noutput(int ninput); + int fixed_rate_noutput_to_ninput(int noutput); + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_RUNTIME_SYNC_INTERPOLATOR_H */ diff --git a/gnuradio-runtime/include/gnuradio/sys_paths.h b/gnuradio-runtime/include/gnuradio/sys_paths.h new file mode 100644 index 0000000000..1bd2e0deb7 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/sys_paths.h @@ -0,0 +1,37 @@ +/* + * Copyright 2011,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef GR_SYS_PATHS_H +#define GR_SYS_PATHS_H + +#include <gnuradio/api.h> + +namespace gr { + + //! directory to create temporary files + GR_RUNTIME_API const char *tmp_path(); + + //! directory to store application data + GR_RUNTIME_API const char *appdata_path(); + +} /* namespace gr */ + +#endif /* GR_SYS_PATHS_H */ diff --git a/gnuradio-runtime/include/gnuradio/sys_pri.h b/gnuradio-runtime/include/gnuradio/sys_pri.h new file mode 100644 index 0000000000..adceb91b9d --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/sys_pri.h @@ -0,0 +1,42 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GNURADIO_SYS_PRI_H +#define INCLUDED_GNURADIO_SYS_PRI_H + +#include <gnuradio/api.h> +#include <realtime.h> + +/* + * A single place to define real-time priorities used by the system itself + */ +namespace gr { + + struct GR_RUNTIME_API sys_pri { + static rt_sched_param python(); // python code + static rt_sched_param normal(); // normal blocks + static rt_sched_param gcell_event_handler(); + static rt_sched_param usrp2_backend(); // thread that services the ethernet + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GNURADIO_SYS_PRI_H */ diff --git a/gnuradio-runtime/include/gnuradio/tagged_stream_block.h b/gnuradio-runtime/include/gnuradio/tagged_stream_block.h new file mode 100644 index 0000000000..1fe92ee25a --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/tagged_stream_block.h @@ -0,0 +1,144 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_TAGGED_STREAM_BLOCK_H +#define INCLUDED_GR_RUNTIME_TAGGED_STREAM_BLOCK_H + +#include <gnuradio/api.h> +#include <gnuradio/block.h> + +namespace gr { + + /*! + * \brief Block that operates on PDUs in form of tagged streams + * \ingroup base_blk + * + * Override work to provide the signal processing implementation. + */ + class GR_RUNTIME_API tagged_stream_block : public block + { + private: + pmt::pmt_t d_length_tag_key; //!< This is the key for the tag that stores the PDU length + gr_vector_int d_n_input_items_reqd; //!< How many input items do I need to process the next PDU? + + protected: + std::string d_length_tag_key_str; + tagged_stream_block(void) {} // allows pure virtual interface sub-classes + tagged_stream_block(const std::string &name, + gr::io_signature::sptr input_signature, + gr::io_signature::sptr output_signature, + const std::string &length_tag_key); + + /*! + * \brief Parse all tags on the first sample of a PDU, return the + * number of items per input and prune the length tags. + * + * In most cases, you don't need to override this, unless the + * number of items read is not directly coded in one single tag. + * + * Default behaviour: + * - Go through all input ports + * - On every input port, search for the tag with the key specified in \p length_tag_key + * - Copy that value as an int to the corresponding position in \p n_input_items_reqd + * - Remove the length tag. + * + * \param[in] tags All the tags found on the first item of every input port. + * \param[out] n_input_items_reqd Number of items which will be read from every input + */ + virtual void parse_length_tags(const std::vector<std::vector<tag_t> > &tags, + gr_vector_int &n_input_items_reqd); + + /*! + * \brief Calculate the number of output items. + * + * This is basically the inverse function to forecast(): Given a + * number of input items, it returns the maximum number of output + * items. + * + * You most likely need to override this function, unless your + * block is a sync block or integer interpolator/decimator. + */ + virtual int calculate_output_stream_length(const gr_vector_int &ninput_items); + + /*! + * \brief Set the new length tags on the output stream + * + * Default behaviour: Set a tag with key \p length_tag_key and the + * number of produced items on every output port. + * + * For anything else, override this. + * + * \param n_produced Length of the new PDU + * \param n_ports Number of output ports + */ + virtual void update_length_tags(int n_produced, int n_ports); + + public: + /*! \brief Don't override this. + */ + void /* final */ forecast (int noutput_items, gr_vector_int &ninput_items_required); + + /*! + * - Reads the number of input items from the tags using parse_length_tags() + * - Checks there's enough data on the input and output buffers + * - If not, inform the scheduler and do nothing + * - Calls work() with the exact number of items per PDU + * - Updates the tags using update_length_tags() + */ + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + /*! + * \brief Just like gr::block::general_work, but makes sure the input is valid + * + * The user must override work to define the signal processing + * code. Check the documentation for general_work() to see what + * happens here. + * + * Like gr::sync_block, this calls consume() for you (it consumes + * ninput_items[i] items from the i-th port). + * + * A note on tag propagation: The PDU length tags are handled by + * other functions, but all other tags are handled just as in any + * other \p gr::block. So, most likely, you either set the tag + * propagation policy to TPP_DONT and handle the tag propagation + * manually, or you propagate tags through the scheduler and don't + * do anything here. + * + * \param noutput_items The size of the writable output buffer + * \param ninput_items The exact size of the items on every input for this particular PDU. + * These will be consumed if a length tag key is provided! + * \param input_items See gr::block + * \param output_items See gr::block + */ + virtual int work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) = 0; + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_RUNTIME_TAGGED_STREAM_BLOCK_H */ + diff --git a/gnuradio-runtime/include/gnuradio/tags.h b/gnuradio-runtime/include/gnuradio/tags.h new file mode 100644 index 0000000000..5600601741 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/tags.h @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_TAGS_H +#define INCLUDED_GR_TAGS_H + +#include <gnuradio/api.h> +#include <pmt/pmt.h> + +namespace gr { + + struct GR_RUNTIME_API tag_t + { + //! the item \p tag occurred at (as a uint64_t) + uint64_t offset; + + //! the key of \p tag (as a PMT symbol) + pmt::pmt_t key; + + //! the value of \p tag (as a PMT) + pmt::pmt_t value; + + //! the source ID of \p tag (as a PMT) + pmt::pmt_t srcid; + + /*! + * Comparison function to test which tag, \p x or \p y, came + * first in time + */ + static inline bool offset_compare(const tag_t &x, + const tag_t &y) + { + return x.offset < y.offset; + } + + inline bool operator == (const tag_t &t) const + { + return (t.key == key) && (t.value == value) && \ + (t.srcid == srcid) && (t.offset == offset); + } + }; + +} /* namespace gr */ + +#endif /*INCLUDED_GR_TAGS_H*/ diff --git a/gnuradio-runtime/include/gnuradio/thread/CMakeLists.txt b/gnuradio-runtime/include/gnuradio/thread/CMakeLists.txt new file mode 100644 index 0000000000..8ea4bfc66e --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/thread/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Install header files +######################################################################## +install(FILES + thread.h + thread_body_wrapper.h + thread_group.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/thread + COMPONENT "runtime_devel" +) diff --git a/gnuradio-runtime/include/gnuradio/thread/thread.h b/gnuradio-runtime/include/gnuradio/thread/thread.h new file mode 100644 index 0000000000..04d67d0821 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/thread/thread.h @@ -0,0 +1,144 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009-2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_THREAD_H +#define INCLUDED_THREAD_H + +#include <gnuradio/api.h> +#include <boost/thread/thread.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/locks.hpp> +#include <boost/thread/condition_variable.hpp> +#include <vector> + +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include <windows.h> + +#endif + +namespace gr { + namespace thread { + + typedef boost::thread thread; + typedef boost::mutex mutex; + typedef boost::unique_lock<boost::mutex> scoped_lock; + typedef boost::condition_variable condition_variable; + + /*! \brief a system-dependent typedef for the underlying thread type. + */ +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + typedef HANDLE gr_thread_t; +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + typedef pthread_t gr_thread_t; +#else + typedef pthread_t gr_thread_t; +#endif + + /*! \brief Get the current thread's ID as a gr_thread_t + * + * We use this when setting the thread affinity or any other + * low-level thread settings. Can be called withing a GNU Radio + * block to get a reference to its current thread ID. + */ + GR_RUNTIME_API gr_thread_t get_current_thread_id(); + + /*! \brief Bind the current thread to a set of cores. + * + * Wrapper for system-dependent calls to set the affinity of the + * current thread to the processor mask. The mask is simply a + * 1-demensional vector containing the processor or core number + * from 0 to N-1 for N cores. + * + * Note: this does not work on OSX; it is a nop call since OSX + * does not support the concept of thread affinity (and what they + * do support in this way since 10.5 is not what we want or can + * use in this fashion). + */ + GR_RUNTIME_API void thread_bind_to_processor(const std::vector<int> &mask); + + /*! \brief Convineince function to bind the current thread to a single core. + * + * Wrapper for system-dependent calls to set the affinity of the + * current thread to a given core from 0 to N-1 for N cores. + * + * Note: this does not work on OSX; it is a nop call since OSX + * does not support the concept of thread affinity (and what they + * do support in this way since 10.5 is not what we want or can + * use in this fashion). + */ + GR_RUNTIME_API void thread_bind_to_processor(int n); + + /*! \brief Bind a thread to a set of cores. + * + * Wrapper for system-dependent calls to set the affinity of the + * given thread ID to the processor mask. The mask is simply a + * 1-demensional vector containing the processor or core number + * from 0 to N-1 for N cores. + * + * Note: this does not work on OSX; it is a nop call since OSX + * does not support the concept of thread affinity (and what they + * do support in this way since 10.5 is not what we want or can + * use in this fashion). + */ + GR_RUNTIME_API void thread_bind_to_processor(gr_thread_t thread, + const std::vector<int> &mask); + + + /*! \brief Convineince function to bind the a thread to a single core. + * + * Wrapper for system-dependent calls to set the affinity of the + * given thread ID to a given core from 0 to N-1 for N cores. + * + * Note: this does not work on OSX; it is a nop call since OSX + * does not support the concept of thread affinity (and what they + * do support in this way since 10.5 is not what we want or can + * use in this fashion). + */ + GR_RUNTIME_API void thread_bind_to_processor(gr_thread_t thread, + unsigned int n); + + /*! \brief Remove any thread-processor affinity for the current thread. + * + * Note: this does not work on OSX; it is a nop call since OSX + * does not support the concept of thread affinity (and what they + * do support in this way since 10.5 is not what we want or can + * use in this fashion). + */ + GR_RUNTIME_API void thread_unbind(); + + /*! \brief Remove any thread-processor affinity for a given thread ID. + * + * Note: this does not work on OSX; it is a nop call since OSX + * does not support the concept of thread affinity (and what they + * do support in this way since 10.5 is not what we want or can + * use in this fashion). + */ + GR_RUNTIME_API void thread_unbind(gr_thread_t thread); + + } /* namespace thread */ +} /* namespace gr */ + +#endif /* INCLUDED_THREAD_H */ diff --git a/gnuradio-runtime/include/gnuradio/thread/thread_body_wrapper.h b/gnuradio-runtime/include/gnuradio/thread/thread_body_wrapper.h new file mode 100644 index 0000000000..9761d3fbe2 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/thread/thread_body_wrapper.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_THREAD_BODY_WRAPPER_H +#define INCLUDED_THREAD_BODY_WRAPPER_H + +#include <gnuradio/api.h> +#include <gnuradio/thread/thread.h> +#include <exception> +#include <iostream> + +namespace gr { + namespace thread { + + GR_RUNTIME_API void mask_signals(); + + template <class F> + class thread_body_wrapper + { + private: + F d_f; + std::string d_name; + + public: + explicit thread_body_wrapper(F f, const std::string &name="") + : d_f(f), d_name(name) {} + + void operator()() + { + mask_signals(); + + try { + d_f(); + } + catch(boost::thread_interrupted const &) + { + } + catch(std::exception const &e) + { + std::cerr << "thread[" << d_name << "]: " + << e.what() << std::endl; + } + catch(...) + { + std::cerr << "thread[" << d_name << "]: " + << "caught unrecognized exception\n"; + } + } + }; + + } /* namespace thread */ +} /* namespace gr */ + +#endif /* INCLUDED_THREAD_BODY_WRAPPER_H */ diff --git a/gnuradio-runtime/include/gnuradio/thread/thread_group.h b/gnuradio-runtime/include/gnuradio/thread/thread_group.h new file mode 100644 index 0000000000..830017d11e --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/thread/thread_group.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright (C) 2001-2003 William E. Kempf + * Copyright (C) 2007 Anthony Williams + * Copyright 2008,2009 Free Software Foundation, Inc. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +/* + * This was extracted from Boost 1.35.0 and fixed. + */ + +#ifndef INCLUDED_THREAD_GROUP_H +#define INCLUDED_THREAD_GROUP_H + +#include <gnuradio/api.h> +#include <gnuradio/thread/thread.h> +#include <boost/utility.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/function.hpp> + +namespace gr { + namespace thread { + + class GR_RUNTIME_API thread_group : public boost::noncopyable + { + public: + thread_group(); + ~thread_group(); + + boost::thread* create_thread(const boost::function0<void>& threadfunc); + void add_thread(boost::thread* thrd); + void remove_thread(boost::thread* thrd); + void join_all(); + void interrupt_all(); + size_t size() const; + + private: + std::list<boost::thread*> m_threads; + mutable boost::shared_mutex m_mutex; + }; + + } /* namespace thread */ +} /* namespace gr */ + +#endif /* INCLUDED_THREAD_GROUP_H */ diff --git a/gnuradio-runtime/include/gnuradio/timer.h b/gnuradio-runtime/include/gnuradio/timer.h new file mode 100644 index 0000000000..d685fd9a19 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/timer.h @@ -0,0 +1,84 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_TIMER_H +#define INCLUDED_GR_TIMER_H + +#include <gnuradio/api.h> +#include <gnuradio/types.h> + +class gr_timer; + +typedef boost::shared_ptr<gr_timer> gr_timer_sptr; + +GR_RUNTIME_API typedef void (*gr_timer_hook)(gr_timer *, void *); + +/*! + * \brief create a timeout. + * + * \ingroup misc + * gr_timer_hook is called when timer fires. + */ +GR_RUNTIME_API gr_timer_sptr gr_make_timer (gr_timer_hook, void *); + +/*! + * \brief implement timeouts + */ +class GR_RUNTIME_API gr_timer { + double d_expiry; + double d_period; + gr_timer_hook d_hook; + void *d_hook_arg; + + friend GR_RUNTIME_API gr_timer_sptr gr_make_timer (gr_timer_hook, void *); + + gr_timer (...); + +public: + ~gr_timer (); + + //! return absolute current time (seconds since the epoc). + static double now (); + + /*! + * \brief schedule timer to fire at abs_when + * \param abs_when absolute time in seconds since the epoc. + */ + void schedule_at (double abs_when); + + /*! + * \brief schedule timer to fire rel_when seconds from now. + * \param rel_when relative time in seconds from now. + */ + void schedule_after (double rel_when); // relative time in seconds + + /*! + * \brief schedule a periodic timeout. + * \param abs_when absolute time to fire first time + * \param period time between firings + */ + void schedule_periodic (double abs_when, double period); + + //! cancel timer + void unschedule (); +}; + +#endif /* INCLUDED_GR_TIMER_H */ diff --git a/gnuradio-runtime/include/gnuradio/top_block.h b/gnuradio-runtime/include/gnuradio/top_block.h new file mode 100644 index 0000000000..b3692e09e2 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/top_block.h @@ -0,0 +1,146 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007-2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_TOP_BLOCK_H +#define INCLUDED_GR_TOP_BLOCK_H + +#include <gnuradio/api.h> +#include <gnuradio/hier_block2.h> + +namespace gr { + + class top_block_impl; + + GR_RUNTIME_API top_block_sptr make_top_block(const std::string &name); + + /*! + *\brief Top-level hierarchical block representing a flowgraph + * \ingroup container_blk + */ + class GR_RUNTIME_API top_block : public hier_block2 + { + private: + friend GR_RUNTIME_API top_block_sptr + make_top_block(const std::string &name); + + top_block_impl *d_impl; + + protected: + top_block(const std::string &name); + + public: + ~top_block(); + + /*! + * \brief The simple interface to running a flowgraph. + * + * Calls start() then wait(). Used to run a flowgraph that will + * stop on its own, or when another thread will call stop(). + * + * \param max_noutput_items the maximum number of output items + * allowed for any block in the flowgraph. This passes through to + * the start function; see that function for more details. + */ + void run(int max_noutput_items=100000000); + + /*! + * Start the contained flowgraph. Creates one or more threads to + * execute the flow graph. Returns to the caller once the threads + * are created. Calling start() on a top_block that is already + * started IS an error. + * + * \param max_noutput_items the maximum number of output items + * allowed for any block in the flowgraph; the noutput_items can + * always be less than this, but this will cap it as a + * maximum. Use this to adjust the maximum latency a flowgraph can + * exhibit. + */ + void start(int max_noutput_items=100000000); + + /*! + * Stop the running flowgraph. Notifies each thread created by the + * scheduler to shutdown, then returns to caller. Calling stop() + * on a top_block that is already stopped IS NOT an error. + */ + void stop(); + + /*! + * Wait for a flowgraph to complete. Flowgraphs complete when + * either (1) all blocks indicate that they are done (typically + * only when using blocks.file_source, or blocks.head, or (2) + * after stop() has been called to request shutdown. Calling wait + * on a top_block that is not running IS NOT an error (wait + * returns w/o blocking). + */ + void wait(); + + /*! + * Lock a flowgraph in preparation for reconfiguration. When an + * equal number of calls to lock() and unlock() have occurred, the + * flowgraph will be reconfigured. + * + * N.B. lock() and unlock() may not be called from a flowgraph + * thread (E.g., block::work method) or deadlock will occur + * when reconfiguration happens. + */ + virtual void lock(); + + /*! + * Unlock a flowgraph in preparation for reconfiguration. When an + * equal number of calls to lock() and unlock() have occurred, the + * flowgraph will be reconfigured. + * + * N.B. lock() and unlock() may not be called from a flowgraph thread + * (E.g., block::work method) or deadlock will occur when + * reconfiguration happens. + */ + virtual void unlock(); + + /*! + * Returns a string that lists the edge connections in the + * flattened flowgraph. + */ + std::string edge_list(); + + /*! + * Displays flattened flowgraph edges and block connectivity + */ + void dump(); + + //! Get the number of max noutput_items in the flowgraph + int max_noutput_items(); + + //! Set the maximum number of noutput_items in the flowgraph + void set_max_noutput_items(int nmax); + + top_block_sptr to_top_block(); // Needed for Python type coercion + + void setup_rpc(); + }; + + inline top_block_sptr cast_to_top_block_sptr(basic_block_sptr block) { + return boost::dynamic_pointer_cast<top_block, basic_block>(block); + } + +} /* namespce gr */ + +#endif /* INCLUDED_GR_TOP_BLOCK_H */ diff --git a/gnuradio-runtime/include/gnuradio/tpb_detail.h b/gnuradio-runtime/include/gnuradio/tpb_detail.h new file mode 100644 index 0000000000..9b7454b508 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/tpb_detail.h @@ -0,0 +1,93 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GR_TPB_DETAIL_H +#define INCLUDED_GR_TPB_DETAIL_H + +#include <gnuradio/api.h> +#include <gnuradio/thread/thread.h> +#include <deque> +#include <pmt/pmt.h> + +namespace gr { + + class block_detail; + + /*! + * \brief used by thread-per-block scheduler + */ + struct GR_RUNTIME_API tpb_detail { + gr::thread::mutex mutex; //< protects all vars + bool input_changed; + gr::thread::condition_variable input_cond; + bool output_changed; + gr::thread::condition_variable output_cond; + + public: + tpb_detail() + : input_changed(false), output_changed(false) { } + + //! Called by us to tell all our upstream blocks that their output + //! may have changed. + void notify_upstream(block_detail *d); + + //! Called by us to tell all our downstream blocks that their + //! input may have changed. + void notify_downstream(block_detail *d); + + //! Called by us to notify both upstream and downstream + void notify_neighbors(block_detail *d); + + //! Called by pmt msg posters + void notify_msg() { + input_cond.notify_one(); + output_cond.notify_one(); + } + + //! Called by us + void clear_changed() + { + gr::thread::scoped_lock guard(mutex); + input_changed = false; + output_changed = false; + } + + private: + //! Used by notify_downstream + void set_input_changed() + { + gr::thread::scoped_lock guard(mutex); + input_changed = true; + input_cond.notify_one(); + } + + //! Used by notify_upstream + void set_output_changed() + { + gr::thread::scoped_lock guard(mutex); + output_changed = true; + output_cond.notify_one(); + } + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GR_TPB_DETAIL_H */ diff --git a/gnuradio-runtime/include/gnuradio/types.h b/gnuradio-runtime/include/gnuradio/types.h new file mode 100644 index 0000000000..6cb0f72834 --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/types.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_TYPES_H +#define INCLUDED_GR_TYPES_H + +#include <gnuradio/api.h> +#include <boost/shared_ptr.hpp> +#include <vector> +#include <stddef.h> // size_t + +#include <gnuradio/gr_complex.h> + +typedef std::vector<int> gr_vector_int; +typedef std::vector<unsigned int> gr_vector_uint; +typedef std::vector<float> gr_vector_float; +typedef std::vector<double> gr_vector_double; +typedef std::vector<void *> gr_vector_void_star; +typedef std::vector<const void *> gr_vector_const_void_star; + +/* + * #include <config.h> must be placed beforehand + * in the source file including gnuradio/types.h for + * the following to work correctly + */ +#ifdef HAVE_STDINT_H +#include <stdint.h> +typedef int16_t gr_int16; +typedef int32_t gr_int32; +typedef int64_t gr_int64; +typedef uint16_t gr_uint16; +typedef uint32_t gr_uint32; +typedef uint64_t gr_uint64; +#else +/* + * Note: these defaults may be wrong on 64-bit systems + */ +typedef short gr_int16; +typedef int gr_int32; +typedef long long gr_int64; +typedef unsigned short gr_uint16; +typedef unsigned int gr_uint32; +typedef unsigned long long gr_uint64; +#endif /* HAVE_STDINT_H */ + +#endif /* INCLUDED_GR_TYPES_H */ diff --git a/gnuradio-runtime/include/gnuradio/unittests.h b/gnuradio-runtime/include/gnuradio/unittests.h new file mode 100644 index 0000000000..209c3ab32a --- /dev/null +++ b/gnuradio-runtime/include/gnuradio/unittests.h @@ -0,0 +1,39 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <gnuradio/api.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string> + +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> + +static std::string get_unittest_path(const std::string &filename){ + boost::filesystem::path path = boost::filesystem::current_path() / ".unittests"; + if (!boost::filesystem::is_directory(path)) boost::filesystem::create_directory(path); + return (path / filename).string(); +} |