aboutsummaryrefslogtreecommitdiffstats
path: root/host/include
diff options
context:
space:
mode:
Diffstat (limited to 'host/include')
-rw-r--r--host/include/CMakeLists.txt19
-rw-r--r--host/include/uhd/CMakeLists.txt35
-rw-r--r--host/include/uhd/config.hpp92
-rw-r--r--host/include/uhd/convert.hpp90
-rw-r--r--host/include/uhd/device.hpp209
-rw-r--r--host/include/uhd/exception.hpp166
-rw-r--r--host/include/uhd/property_tree.hpp158
-rw-r--r--host/include/uhd/property_tree.ipp95
-rw-r--r--host/include/uhd/transport/CMakeLists.txt33
-rw-r--r--host/include/uhd/transport/bounded_buffer.hpp121
-rw-r--r--host/include/uhd/transport/bounded_buffer.ipp147
-rw-r--r--host/include/uhd/transport/buffer_pool.hpp59
-rw-r--r--host/include/uhd/transport/if_addrs.hpp46
-rw-r--r--host/include/uhd/transport/udp_simple.hpp84
-rw-r--r--host/include/uhd/transport/udp_zero_copy.hpp65
-rw-r--r--host/include/uhd/transport/usb_control.hpp65
-rw-r--r--host/include/uhd/transport/usb_device_handle.hpp73
-rw-r--r--host/include/uhd/transport/usb_zero_copy.hpp82
-rw-r--r--host/include/uhd/transport/vrt_if_packet.hpp106
-rw-r--r--host/include/uhd/transport/zero_copy.hpp184
-rw-r--r--host/include/uhd/types/CMakeLists.txt38
-rw-r--r--host/include/uhd/types/clock_config.hpp63
-rw-r--r--host/include/uhd/types/device_addr.hpp98
-rw-r--r--host/include/uhd/types/dict.hpp129
-rw-r--r--host/include/uhd/types/dict.ipp140
-rw-r--r--host/include/uhd/types/io_type.hpp76
-rw-r--r--host/include/uhd/types/mac_addr.hpp66
-rw-r--r--host/include/uhd/types/metadata.hpp154
-rw-r--r--host/include/uhd/types/otw_type.hpp69
-rw-r--r--host/include/uhd/types/ranges.hpp120
-rw-r--r--host/include/uhd/types/ref_vector.hpp85
-rw-r--r--host/include/uhd/types/sensors.hpp137
-rw-r--r--host/include/uhd/types/serial.hpp202
-rw-r--r--host/include/uhd/types/stream_cmd.hpp64
-rw-r--r--host/include/uhd/types/time_spec.hpp117
-rw-r--r--host/include/uhd/types/tune_request.hpp95
-rw-r--r--host/include/uhd/types/tune_result.hpp44
-rw-r--r--host/include/uhd/usrp/CMakeLists.txt40
-rw-r--r--host/include/uhd/usrp/dboard_base.hpp154
-rw-r--r--host/include/uhd/usrp/dboard_eeprom.hpp59
-rw-r--r--host/include/uhd/usrp/dboard_id.hpp96
-rw-r--r--host/include/uhd/usrp/dboard_iface.hpp298
-rw-r--r--host/include/uhd/usrp/dboard_manager.hpp102
-rw-r--r--host/include/uhd/usrp/gps_ctrl.hpp62
-rw-r--r--host/include/uhd/usrp/mboard_eeprom.hpp65
-rw-r--r--host/include/uhd/usrp/mboard_iface.hpp71
-rw-r--r--host/include/uhd/usrp/multi_usrp.hpp654
-rw-r--r--host/include/uhd/usrp/single_usrp.hpp30
-rw-r--r--host/include/uhd/usrp/subdev_spec.hpp91
-rw-r--r--host/include/uhd/utils/CMakeLists.txt37
-rw-r--r--host/include/uhd/utils/algorithm.hpp90
-rw-r--r--host/include/uhd/utils/assert_has.hpp47
-rw-r--r--host/include/uhd/utils/assert_has.ipp53
-rw-r--r--host/include/uhd/utils/byteswap.hpp56
-rw-r--r--host/include/uhd/utils/byteswap.ipp136
-rw-r--r--host/include/uhd/utils/gain_group.hpp108
-rw-r--r--host/include/uhd/utils/images.hpp38
-rw-r--r--host/include/uhd/utils/log.hpp97
-rw-r--r--host/include/uhd/utils/msg.hpp74
-rw-r--r--host/include/uhd/utils/pimpl.hpp55
-rw-r--r--host/include/uhd/utils/props.hpp81
-rw-r--r--host/include/uhd/utils/safe_call.hpp45
-rw-r--r--host/include/uhd/utils/safe_main.hpp44
-rw-r--r--host/include/uhd/utils/static.hpp46
-rw-r--r--host/include/uhd/utils/tasks.hpp53
-rw-r--r--host/include/uhd/utils/thread_priority.hpp58
-rw-r--r--host/include/uhd/version.hpp28
-rw-r--r--host/include/uhd/wax.hpp169
68 files changed, 6663 insertions, 0 deletions
diff --git a/host/include/CMakeLists.txt b/host/include/CMakeLists.txt
new file mode 100644
index 000000000..3f7ca2cb7
--- /dev/null
+++ b/host/include/CMakeLists.txt
@@ -0,0 +1,19 @@
+#
+# Copyright 2010 Ettus Research LLC
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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, see <http://www.gnu.org/licenses/>.
+#
+
+
+ADD_SUBDIRECTORY(uhd)
diff --git a/host/include/uhd/CMakeLists.txt b/host/include/uhd/CMakeLists.txt
new file mode 100644
index 000000000..49562a7a0
--- /dev/null
+++ b/host/include/uhd/CMakeLists.txt
@@ -0,0 +1,35 @@
+#
+# Copyright 2010-2011 Ettus Research LLC
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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, see <http://www.gnu.org/licenses/>.
+#
+
+
+ADD_SUBDIRECTORY(transport)
+ADD_SUBDIRECTORY(types)
+ADD_SUBDIRECTORY(usrp)
+ADD_SUBDIRECTORY(utils)
+
+INSTALL(FILES
+ config.hpp
+ convert.hpp
+ device.hpp
+ exception.hpp
+ property_tree.ipp
+ property_tree.hpp
+ version.hpp
+ wax.hpp
+ DESTINATION ${INCLUDE_DIR}/uhd
+ COMPONENT headers
+)
diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp
new file mode 100644
index 000000000..6fd2932cf
--- /dev/null
+++ b/host/include/uhd/config.hpp
@@ -0,0 +1,92 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_CONFIG_HPP
+#define INCLUDED_UHD_CONFIG_HPP
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_MSVC
+// suppress warnings
+//# pragma warning(push)
+//# pragma warning(disable: 4511) // copy constructor can't not be generated
+//# pragma warning(disable: 4512) // assignment operator can't not be generated
+//# pragma warning(disable: 4100) // unreferenced formal parameter
+//# pragma warning(disable: 4996) // <symbol> was declared deprecated
+# pragma warning(disable: 4355) // 'this' : used in base member initializer list
+//# pragma warning(disable: 4706) // assignment within conditional expression
+# pragma warning(disable: 4251) // class 'A<T>' needs to have dll-interface to be used by clients of class 'B'
+//# pragma warning(disable: 4127) // conditional expression is constant
+//# pragma warning(disable: 4290) // C++ exception specification ignored except to ...
+//# pragma warning(disable: 4180) // qualifier applied to function type has no meaning; ignored
+# pragma warning(disable: 4275) // non dll-interface class ... used as base for dll-interface class ...
+//# pragma warning(disable: 4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data
+//# pragma warning(disable: 4511) // 'class' : copy constructor could not be generated
+//# pragma warning(disable: 4250) // 'class' : inherits 'method' via dominance
+# pragma warning(disable: 4200) // nonstandard extension used : zero-sized array in struct/union
+
+// define logical operators
+#include <ciso646>
+
+// define ssize_t
+#include <cstddef>
+typedef ptrdiff_t ssize_t;
+
+#endif //BOOST_MSVC
+
+//define cross platform attribute macros
+#if defined(BOOST_MSVC)
+ #define UHD_EXPORT __declspec(dllexport)
+ #define UHD_IMPORT __declspec(dllimport)
+ #define UHD_INLINE __forceinline
+ #define UHD_DEPRECATED __declspec(deprecated)
+ #define UHD_ALIGNED(x) __declspec(align(x))
+#elif defined(__GNUG__) && __GNUG__ >= 4
+ #define UHD_EXPORT __attribute__((visibility("default")))
+ #define UHD_IMPORT __attribute__((visibility("default")))
+ #define UHD_INLINE inline __attribute__((always_inline))
+ #define UHD_DEPRECATED __attribute__((deprecated))
+ #define UHD_ALIGNED(x) __attribute__((aligned(x)))
+#else
+ #define UHD_EXPORT
+ #define UHD_IMPORT
+ #define UHD_INLINE inline
+ #define UHD_DEPRECATED
+ #define UHD_ALIGNED(x)
+#endif
+
+// Define API declaration macro
+#ifdef UHD_DLL_EXPORTS
+ #define UHD_API UHD_EXPORT
+#else
+ #define UHD_API UHD_IMPORT
+#endif // UHD_DLL_EXPORTS
+
+// Platform defines for conditional parts of headers:
+// Taken from boost/config/select_platform_config.hpp,
+// however, we define macros, not strings for platforms.
+#if defined(linux) || defined(__linux) || defined(__linux__)
+ #define UHD_PLATFORM_LINUX
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+ #define UHD_PLATFORM_WIN32
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+ #define UHD_PLATFORM_MACOS
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+ #define UHD_PLATFORM_BSD
+#endif
+
+#endif /* INCLUDED_UHD_CONFIG_HPP */
diff --git a/host/include/uhd/convert.hpp b/host/include/uhd/convert.hpp
new file mode 100644
index 000000000..99f1860ae
--- /dev/null
+++ b/host/include/uhd/convert.hpp
@@ -0,0 +1,90 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_CONVERT_HPP
+#define INCLUDED_UHD_CONVERT_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/types/io_type.hpp>
+#include <uhd/types/otw_type.hpp>
+#include <uhd/types/ref_vector.hpp>
+#include <boost/function.hpp>
+#include <string>
+
+namespace uhd{ namespace convert{
+
+ typedef uhd::ref_vector<void *> output_type;
+ typedef uhd::ref_vector<const void *> input_type;
+ typedef boost::function<void(const input_type&, const output_type&, size_t, double)> function_type;
+
+ /*!
+ * Describe the priority of a converter function.
+ * A higher priority function takes precedence.
+ * The general case function are the lowest.
+ * Next comes the liborc implementations.
+ * Custom intrinsics implementations are highest.
+ */
+ enum priority_type{
+ PRIORITY_GENERAL = 0,
+ PRIORITY_LIBORC = 1,
+ PRIORITY_CUSTOM = 2,
+ PRIORITY_EMPTY = -1,
+ };
+
+ /*!
+ * Register a converter function that converts cpu type to/from otw type.
+ * \param markup representing the signature
+ * \param fcn a pointer to the converter
+ * \param prio the function priority
+ */
+ UHD_API void register_converter(
+ const std::string &markup,
+ function_type fcn,
+ priority_type prio
+ );
+
+ /*!
+ * Get a converter function that converts cpu to otw.
+ * \param io_type the type of the input samples
+ * \param otw_type the type of the output samples
+ * \param num_input_buffs the number of inputs
+ * \param num_output_buffs the number of outputs
+ */
+ UHD_API const function_type &get_converter_cpu_to_otw(
+ const io_type_t &io_type,
+ const otw_type_t &otw_type,
+ size_t num_input_buffs,
+ size_t num_output_buffs
+ );
+
+ /*!
+ * Get a converter function that converts otw to cpu.
+ * \param io_type the type of the input samples
+ * \param otw_type the type of the output samples
+ * \param num_input_buffs the number of inputs
+ * \param num_output_buffs the number of outputs
+ */
+ UHD_API const function_type &get_converter_otw_to_cpu(
+ const io_type_t &io_type,
+ const otw_type_t &otw_type,
+ size_t num_input_buffs,
+ size_t num_output_buffs
+ );
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_CONVERT_HPP */
diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp
new file mode 100644
index 000000000..a6571d027
--- /dev/null
+++ b/host/include/uhd/device.hpp
@@ -0,0 +1,209 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_DEVICE_HPP
+#define INCLUDED_UHD_DEVICE_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/types/device_addr.hpp>
+#include <uhd/types/metadata.hpp>
+#include <uhd/types/io_type.hpp>
+#include <uhd/types/ref_vector.hpp>
+#include <uhd/wax.hpp>
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
+
+namespace uhd{
+
+class property_tree; //forward declaration
+
+/*!
+ * The usrp device interface represents the usrp hardware.
+ * The api allows for discovery, configuration, and streaming.
+ */
+class UHD_API device : boost::noncopyable, public wax::obj{
+
+public:
+ typedef boost::shared_ptr<device> sptr;
+ typedef boost::function<device_addrs_t(const device_addr_t &)> find_t;
+ typedef boost::function<sptr(const device_addr_t &)> make_t;
+
+ /*!
+ * Register a device into the discovery and factory system.
+ *
+ * \param find a function that discovers devices
+ * \param make a factory function that makes a device
+ */
+ static void register_device(
+ const find_t &find,
+ const make_t &make
+ );
+
+ /*!
+ * \brief Find usrp devices attached to the host.
+ *
+ * The hint device address should be used to narrow down the search
+ * to particular transport types and/or transport arguments.
+ *
+ * \param hint a partially (or fully) filled in device address
+ * \return a vector of device addresses for all usrps on the system
+ */
+ static device_addrs_t find(const device_addr_t &hint);
+
+ /*!
+ * \brief Create a new usrp device from the device address hint.
+ *
+ * The make routine will call find and pick one of the results.
+ * By default, the first result will be used to create a new device.
+ * Use the which parameter as an index into the list of results.
+ *
+ * \param hint a partially (or fully) filled in device address
+ * \param which which address to use when multiple are found
+ * \return a shared pointer to a new device instance
+ */
+ static sptr make(const device_addr_t &hint, size_t which = 0);
+
+ /*!
+ * Send modes for the device send routine.
+ */
+ enum send_mode_t{
+ //! Tells the send routine to send the entire buffer
+ SEND_MODE_FULL_BUFF = 0,
+ //! Tells the send routine to return after one packet
+ SEND_MODE_ONE_PACKET = 1
+ };
+
+ /*!
+ * Recv modes for the device recv routine.
+ */
+ enum recv_mode_t{
+ //! Tells the recv routine to recv the entire buffer
+ RECV_MODE_FULL_BUFF = 0,
+ //! Tells the recv routine to return after one packet
+ RECV_MODE_ONE_PACKET = 1
+ };
+
+ //! Typedef for a pointer to a single, or a collection of send buffers
+ typedef ref_vector<const void *> send_buffs_type;
+
+ //! Typedef for a pointer to a single, or a collection of recv buffers
+ typedef ref_vector<void *> recv_buffs_type;
+
+ /*!
+ * Send buffers containing IF data described by the metadata.
+ *
+ * Send handles fragmentation as follows:
+ * If the buffer has more samples than the maximum per packet,
+ * the send method will fragment the samples across several packets.
+ * Send will respect the burst flags when fragmenting to ensure
+ * that start of burst can only be set on the first fragment and
+ * that end of burst can only be set on the final fragment.
+ * Fragmentation only applies in the full buffer send mode.
+ *
+ * This is a blocking call and will not return until the number
+ * of samples returned have been read out of each buffer.
+ * Under a timeout condition, the number of samples returned
+ * may be less than the number of samples specified.
+ *
+ * \param buffs a vector of read-only memory containing IF data
+ * \param nsamps_per_buff the number of samples to send, per buffer
+ * \param metadata data describing the buffer's contents
+ * \param io_type the type of data loaded in the buffer
+ * \param send_mode tells send how to unload the buffer
+ * \param timeout the timeout in seconds to wait on a packet
+ * \return the number of samples sent
+ */
+ virtual size_t send(
+ const send_buffs_type &buffs,
+ size_t nsamps_per_buff,
+ const tx_metadata_t &metadata,
+ const io_type_t &io_type,
+ send_mode_t send_mode,
+ double timeout = 0.1
+ ) = 0;
+
+ /*!
+ * Receive buffers containing IF data described by the metadata.
+ *
+ * Receive handles fragmentation as follows:
+ * If the buffer has insufficient space to hold all samples
+ * that were received in a single packet over-the-wire,
+ * then the buffer will be completely filled and the implementation
+ * will hold a pointer into the remaining portion of the packet.
+ * Subsequent calls will load from the remainder of the packet,
+ * and will flag the metadata to show that this is a fragment.
+ * The next call to receive, after the remainder becomes exahausted,
+ * will perform an over-the-wire receive as usual.
+ * See the rx metadata fragment flags and offset fields for details.
+ *
+ * This is a blocking call and will not return until the number
+ * of samples returned have been written into each buffer.
+ * Under a timeout condition, the number of samples returned
+ * may be less than the number of samples specified.
+ *
+ * When using the full buffer recv mode, the metadata only applies
+ * to the first packet received and written into the recv buffers.
+ * Use the one packet recv mode to get per packet metadata.
+ *
+ * \param buffs a vector of writable memory to fill with IF data
+ * \param nsamps_per_buff the size of each buffer in number of samples
+ * \param metadata data to fill describing the buffer
+ * \param io_type the type of data to fill into the buffer
+ * \param recv_mode tells recv how to load the buffer
+ * \param timeout the timeout in seconds to wait for a packet
+ * \return the number of samples received or 0 on error
+ */
+ virtual size_t recv(
+ const recv_buffs_type &buffs,
+ size_t nsamps_per_buff,
+ rx_metadata_t &metadata,
+ const io_type_t &io_type,
+ recv_mode_t recv_mode,
+ double timeout = 0.1
+ ) = 0;
+
+ /*!
+ * Get the maximum number of samples per packet on send.
+ * \return the number of samples
+ */
+ virtual size_t get_max_send_samps_per_packet(void) const = 0;
+
+ /*!
+ * Get the maximum number of samples per packet on recv.
+ * \return the number of samples
+ */
+ virtual size_t get_max_recv_samps_per_packet(void) const = 0;
+
+ /*!
+ * Receive and asynchronous message from the device.
+ * \param async_metadata the metadata to be filled in
+ * \param timeout the timeout in seconds to wait for a message
+ * \return true when the async_metadata is valid, false for timeout
+ */
+ virtual bool recv_async_msg(
+ async_metadata_t &async_metadata, double timeout = 0.1
+ ) = 0;
+
+ //! Get access to the underlying property structure
+ virtual boost::shared_ptr<property_tree> get_tree(void) const = 0;
+
+};
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_DEVICE_HPP */
diff --git a/host/include/uhd/exception.hpp b/host/include/uhd/exception.hpp
new file mode 100644
index 000000000..c05861788
--- /dev/null
+++ b/host/include/uhd/exception.hpp
@@ -0,0 +1,166 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_EXCEPTION_HPP
+#define INCLUDED_UHD_EXCEPTION_HPP
+
+#include <uhd/config.hpp>
+#include <boost/current_function.hpp>
+#include <stdexcept>
+#include <string>
+
+/*!
+ * Define common exceptions used throughout the code:
+ *
+ * - The python built-in exceptions were used as inspiration.
+ * - Exceptions inherit from std::exception to provide what().
+ * - Exceptions inherit from uhd::exception to provide code().
+ *
+ * The code() provides an error code which allows the application
+ * the option of printing a cryptic error message from the 1990s.
+ *
+ * The dynamic_clone() and dynamic_throw() methods allow us to:
+ * catch an exception by dynamic type (i.e. derived class), save it,
+ * and later rethrow it, knowing only the static type (i.e. base class),
+ * and then finally to catch it again using the derived type.
+ *
+ * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2106.html
+ */
+namespace uhd{
+
+ struct UHD_API exception : std::runtime_error{
+ exception(const std::string &what);
+ virtual unsigned code(void) const = 0;
+ virtual exception *dynamic_clone(void) const = 0;
+ virtual void dynamic_throw(void) const = 0;
+ };
+
+ struct UHD_API assertion_error : exception{
+ assertion_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual assertion_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct UHD_API lookup_error : exception{
+ lookup_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual lookup_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct UHD_API index_error : lookup_error{
+ index_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual index_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct UHD_API key_error : lookup_error{
+ key_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual key_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct UHD_API type_error : exception{
+ type_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual type_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct UHD_API value_error : exception{
+ value_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual value_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct UHD_API runtime_error : exception{
+ runtime_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual runtime_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct UHD_API not_implemented_error : runtime_error{
+ not_implemented_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual not_implemented_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct UHD_API environment_error : exception{
+ environment_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual environment_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct UHD_API io_error : environment_error{
+ io_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual io_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct UHD_API os_error : environment_error{
+ os_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual os_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct UHD_API system_error : exception{
+ system_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual system_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ /*!
+ * Create a formated string with throw-site information.
+ * Fills in the function name, file name, and line number.
+ * \param what the std::exeption message
+ * \return the formatted exception message
+ */
+ #define UHD_THROW_SITE_INFO(what) std::string( \
+ std::string(what) + "\n" + \
+ " in " + std::string(BOOST_CURRENT_FUNCTION) + "\n" + \
+ " at " + std::string(__FILE__) + ":" + BOOST_STRINGIZE(__LINE__) + "\n" \
+ )
+
+ /*!
+ * Throws an invalid code path exception with throw-site information.
+ * Use this macro in places that code execution is not supposed to go.
+ */
+ #define UHD_THROW_INVALID_CODE_PATH() \
+ throw uhd::system_error(UHD_THROW_SITE_INFO("invalid code path"))
+
+ /*!
+ * Assert the result of the code evaluation.
+ * If the code evaluates to false, throw an assertion error.
+ * \param code the code that resolved to a boolean
+ */
+ #define UHD_ASSERT_THROW(code) if (not (code)) \
+ throw uhd::assertion_error(UHD_THROW_SITE_INFO(#code)); \
+ else void(0)
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_EXCEPTION_HPP */
diff --git a/host/include/uhd/property_tree.hpp b/host/include/uhd/property_tree.hpp
new file mode 100644
index 000000000..47b2c5736
--- /dev/null
+++ b/host/include/uhd/property_tree.hpp
@@ -0,0 +1,158 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_PROPERTY_TREE_HPP
+#define INCLUDED_UHD_PROPERTY_TREE_HPP
+
+#include <uhd/config.hpp>
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
+#include <vector>
+
+namespace uhd{
+
+/*!
+ * A templated property interface for holding a value
+ * and registering callbacks when that value changes.
+ */
+template <typename T> class property : boost::noncopyable{
+public:
+ typedef boost::function<void(const T &)> subscriber_type;
+ typedef boost::function<T(void)> publisher_type;
+ typedef boost::function<T(const T &)> coercer_type;
+
+ /*!
+ * Register a coercer into the property.
+ * A coercer is a special subscribes that coerces the value.
+ * Only one coercer may be registered per property.
+ * Registering a coercer replaces the previous coercer.
+ * \param coercer the coercer callback function
+ * \return a reference to this property for chaining
+ */
+ virtual property<T> &coerce(const coercer_type &coercer) = 0;
+
+ /*!
+ * Register a publisher into the property.
+ * A publisher is a special callback the provides the value.
+ * Publishers are useful for creating read-only properties.
+ * Only one publisher may be registered per property.
+ * Registering a publisher replaces the previous publisher.
+ * \param publisher the publisher callback function
+ * \return a reference to this property for chaining
+ */
+ virtual property<T> &publish(const publisher_type &publisher) = 0;
+
+ /*!
+ * Register a subscriber into the property.
+ * All subscribers are called when the value changes.
+ * Once a subscriber is registered, it cannot be unregistered.
+ * \param subscriber the subscriber callback function
+ * \return a reference to this property for chaining
+ */
+ virtual property<T> &subscribe(const subscriber_type &subscriber) = 0;
+
+ /*!
+ * Update calls all subscribers w/ the current value.
+ * \return a reference to this property for chaining
+ */
+ virtual property<T> &update(void) = 0;
+
+ /*!
+ * Set the new value and call all subscribers.
+ * The coercer (when provided) is called initially,
+ * and the coerced value is used to set the subscribers.
+ * \param value the new value to set on this property
+ * \return a reference to this property for chaining
+ */
+ virtual property<T> &set(const T &value) = 0;
+
+ /*!
+ * Get the current value of this property.
+ * The publisher (when provided) yields the value,
+ * otherwise an internal shadow is used for the value.
+ * \return the current value in the property
+ */
+ virtual T get(void) const = 0;
+
+ /*!
+ * A property is empty if it has never been set.
+ * A property with a publisher is never empty.
+ * \return true if the property is empty
+ */
+ virtual bool empty(void) const = 0;
+};
+
+/*!
+ * FS Path: A glorified string with path manipulations.
+ * Inspired by boost filesystem path, but without the dependency.
+ *
+ * Notice: we do not declare UHD_API on the whole structure
+ * because MSVC will do weird things with std::string and linking.
+ */
+struct fs_path : std::string{
+ UHD_API fs_path(void);
+ UHD_API fs_path(const char *);
+ UHD_API fs_path(const std::string &);
+ UHD_API std::string leaf(void) const;
+ UHD_API fs_path branch_path(void) const;
+};
+
+UHD_API fs_path operator/(const fs_path &, const fs_path &);
+
+/*!
+ * The property tree provides a file system structure for accessing properties.
+ */
+class UHD_API property_tree : boost::noncopyable{
+public:
+ typedef boost::shared_ptr<property_tree> sptr;
+
+ //! Create a new + empty property tree
+ static sptr make(void);
+
+ //! Get a subtree with a new root starting at path
+ virtual sptr subtree(const fs_path &path) const = 0;
+
+ //! Remove a property or directory (recursive)
+ virtual void remove(const fs_path &path) = 0;
+
+ //! True if the path exists in the tree
+ virtual bool exists(const fs_path &path) const = 0;
+
+ //! Get an iterable to all things in the given path
+ virtual std::vector<std::string> list(const fs_path &path) const = 0;
+
+ //! Create a new property entry in the tree
+ template <typename T> property<T> &create(const fs_path &path);
+
+ //! Get access to a property in the tree
+ template <typename T> property<T> &access(const fs_path &path);
+
+private:
+ //! Internal create property with wild-card type
+ virtual void _create(const fs_path &path, const boost::shared_ptr<void> &prop) = 0;
+
+ //! Internal access property with wild-card type
+ virtual boost::shared_ptr<void> &_access(const fs_path &path) const = 0;
+
+};
+
+} //namespace uhd
+
+#include <uhd/property_tree.ipp>
+
+#endif /* INCLUDED_UHD_PROPERTY_TREE_HPP */
diff --git a/host/include/uhd/property_tree.ipp b/host/include/uhd/property_tree.ipp
new file mode 100644
index 000000000..85720dc6b
--- /dev/null
+++ b/host/include/uhd/property_tree.ipp
@@ -0,0 +1,95 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_PROPERTY_TREE_IPP
+#define INCLUDED_UHD_PROPERTY_TREE_IPP
+
+#include <uhd/exception.hpp>
+#include <boost/foreach.hpp>
+#include <vector>
+
+/***********************************************************************
+ * Implement templated property impl
+ **********************************************************************/
+namespace uhd{ namespace /*anon*/{
+
+template <typename T> class property_impl : public property<T>{
+public:
+
+ property<T> &coerce(const typename property<T>::coercer_type &coercer){
+ _coercer = coercer;
+ return *this;
+ }
+
+ property<T> &publish(const typename property<T>::publisher_type &publisher){
+ _publisher = publisher;
+ return *this;
+ }
+
+ property<T> &subscribe(const typename property<T>::subscriber_type &subscriber){
+ _subscribers.push_back(subscriber);
+ return *this;
+ }
+
+ property<T> &update(void){
+ this->set(this->get());
+ return *this;
+ }
+
+ property<T> &set(const T &value){
+ _value = boost::shared_ptr<T>(new T(_coercer.empty()? value : _coercer(value)));
+ BOOST_FOREACH(typename property<T>::subscriber_type &subscriber, _subscribers){
+ subscriber(*_value); //let errors propagate
+ }
+ return *this;
+ }
+
+ T get(void) const{
+ if (empty()) throw uhd::runtime_error("Cannot get() on an empty property");
+ return _publisher.empty()? *_value : _publisher();
+ }
+
+ bool empty(void) const{
+ return _publisher.empty() and _value.get() == NULL;
+ }
+
+private:
+ std::vector<typename property<T>::subscriber_type> _subscribers;
+ typename property<T>::publisher_type _publisher;
+ typename property<T>::coercer_type _coercer;
+ boost::shared_ptr<T> _value;
+};
+
+}} //namespace uhd::/*anon*/
+
+/***********************************************************************
+ * Implement templated methods for the property tree
+ **********************************************************************/
+namespace uhd{
+
+ template <typename T> property<T> &property_tree::create(const fs_path &path){
+ this->_create(path, typename boost::shared_ptr<property<T> >(new property_impl<T>()));
+ return this->access<T>(path);
+ }
+
+ template <typename T> property<T> &property_tree::access(const fs_path &path){
+ return *boost::static_pointer_cast<property<T> >(this->_access(path));
+ }
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_PROPERTY_TREE_IPP */
diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt
new file mode 100644
index 000000000..bf7497ee7
--- /dev/null
+++ b/host/include/uhd/transport/CMakeLists.txt
@@ -0,0 +1,33 @@
+#
+# Copyright 2010-2011 Ettus Research LLC
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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, see <http://www.gnu.org/licenses/>.
+#
+
+
+INSTALL(FILES
+ bounded_buffer.hpp
+ bounded_buffer.ipp
+ buffer_pool.hpp
+ if_addrs.hpp
+ udp_simple.hpp
+ udp_zero_copy.hpp
+ usb_control.hpp
+ usb_zero_copy.hpp
+ usb_device_handle.hpp
+ vrt_if_packet.hpp
+ zero_copy.hpp
+ DESTINATION ${INCLUDE_DIR}/uhd/transport
+ COMPONENT headers
+)
diff --git a/host/include/uhd/transport/bounded_buffer.hpp b/host/include/uhd/transport/bounded_buffer.hpp
new file mode 100644
index 000000000..620a708d0
--- /dev/null
+++ b/host/include/uhd/transport/bounded_buffer.hpp
@@ -0,0 +1,121 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_HPP
+#define INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_HPP
+
+#include <uhd/transport/bounded_buffer.ipp> //detail
+
+namespace uhd{ namespace transport{
+
+ /*!
+ * Implement a templated bounded buffer:
+ * Used for passing elements between threads in a producer-consumer model.
+ * The bounded buffer implemented waits and timed waits with condition variables.
+ * The pop operation blocks on the bounded_buffer to become non empty.
+ * The push operation blocks on the bounded_buffer to become non full.
+ */
+ template <typename elem_type> class bounded_buffer{
+ public:
+
+ /*!
+ * Create a new bounded buffer object.
+ * \param capacity the bounded_buffer capacity
+ */
+ bounded_buffer(size_t capacity):
+ _detail(capacity)
+ {
+ /* NOP */
+ }
+
+ /*!
+ * Push a new element into the bounded buffer immediately.
+ * The element will not be pushed when the buffer is full.
+ * \param elem the element reference pop to
+ * \return false when the buffer is full
+ */
+ UHD_INLINE bool push_with_haste(const elem_type &elem){
+ return _detail.push_with_haste(elem);
+ }
+
+ /*!
+ * Push a new element into the bounded buffer.
+ * If the buffer is full prior to the push,
+ * make room by poping the oldest element.
+ * \param elem the new element to push
+ * \return true if the element fit without popping for space
+ */
+ UHD_INLINE bool push_with_pop_on_full(const elem_type &elem){
+ return _detail.push_with_pop_on_full(elem);
+ }
+
+ /*!
+ * Push a new element into the bounded_buffer.
+ * Wait until the bounded_buffer becomes non-full.
+ * \param elem the new element to push
+ */
+ UHD_INLINE void push_with_wait(const elem_type &elem){
+ return _detail.push_with_wait(elem);
+ }
+
+ /*!
+ * Push a new element into the bounded_buffer.
+ * Wait until the bounded_buffer becomes non-full or timeout.
+ * \param elem the new element to push
+ * \param timeout the timeout in seconds
+ * \return false when the operation times out
+ */
+ UHD_INLINE bool push_with_timed_wait(const elem_type &elem, double timeout){
+ return _detail.push_with_timed_wait(elem, timeout);
+ }
+
+ /*!
+ * Pop an element from the bounded buffer immediately.
+ * The element will not be popped when the buffer is empty.
+ * \param elem the element reference pop to
+ * \return false when the buffer is empty
+ */
+ UHD_INLINE bool pop_with_haste(elem_type &elem){
+ return _detail.pop_with_haste(elem);
+ }
+
+ /*!
+ * Pop an element from the bounded_buffer.
+ * Wait until the bounded_buffer becomes non-empty.
+ * \param elem the element reference pop to
+ */
+ UHD_INLINE void pop_with_wait(elem_type &elem){
+ return _detail.pop_with_wait(elem);
+ }
+
+ /*!
+ * Pop an element from the bounded_buffer.
+ * Wait until the bounded_buffer becomes non-empty or timeout.
+ * \param elem the element reference pop to
+ * \param timeout the timeout in seconds
+ * \return false when the operation times out
+ */
+ UHD_INLINE bool pop_with_timed_wait(elem_type &elem, double timeout){
+ return _detail.pop_with_timed_wait(elem, timeout);
+ }
+
+ private: bounded_buffer_detail<elem_type> _detail;
+ };
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_HPP */
diff --git a/host/include/uhd/transport/bounded_buffer.ipp b/host/include/uhd/transport/bounded_buffer.ipp
new file mode 100644
index 000000000..9c24005b7
--- /dev/null
+++ b/host/include/uhd/transport/bounded_buffer.ipp
@@ -0,0 +1,147 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_IPP
+#define INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_IPP
+
+#include <uhd/config.hpp>
+#include <boost/bind.hpp>
+#include <boost/utility.hpp>
+#include <boost/function.hpp>
+#include <boost/circular_buffer.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/locks.hpp>
+
+namespace uhd{ namespace transport{ namespace{ /*anon*/
+
+ template <typename elem_type> class bounded_buffer_detail : boost::noncopyable{
+ public:
+
+ bounded_buffer_detail(size_t capacity):
+ _buffer(capacity)
+ {
+ _not_full_fcn = boost::bind(&bounded_buffer_detail<elem_type>::not_full, this);
+ _not_empty_fcn = boost::bind(&bounded_buffer_detail<elem_type>::not_empty, this);
+ }
+
+ UHD_INLINE bool push_with_haste(const elem_type &elem){
+ boost::mutex::scoped_lock lock(_mutex);
+ if (_buffer.full()) return false;
+ _buffer.push_front(elem);
+ lock.unlock();
+ _empty_cond.notify_one();
+ return true;
+ }
+
+ UHD_INLINE bool push_with_pop_on_full(const elem_type &elem){
+ boost::mutex::scoped_lock lock(_mutex);
+ if (_buffer.full()){
+ _buffer.pop_back();
+ _buffer.push_front(elem);
+ lock.unlock();
+ _empty_cond.notify_one();
+ return false;
+ }
+ else{
+ _buffer.push_front(elem);
+ lock.unlock();
+ _empty_cond.notify_one();
+ return true;
+ }
+ }
+
+ UHD_INLINE void push_with_wait(const elem_type &elem){
+ if (this->push_with_haste(elem)) return;
+ boost::mutex::scoped_lock lock(_mutex);
+ _full_cond.wait(lock, _not_full_fcn);
+ _buffer.push_front(elem);
+ lock.unlock();
+ _empty_cond.notify_one();
+ }
+
+ UHD_INLINE bool push_with_timed_wait(const elem_type &elem, double timeout){
+ if (this->push_with_haste(elem)) return true;
+ boost::mutex::scoped_lock lock(_mutex);
+ if (not _full_cond.timed_wait(
+ lock, to_time_dur(timeout), _not_full_fcn
+ )) return false;
+ _buffer.push_front(elem);
+ lock.unlock();
+ _empty_cond.notify_one();
+ return true;
+ }
+
+ UHD_INLINE bool pop_with_haste(elem_type &elem){
+ boost::mutex::scoped_lock lock(_mutex);
+ if (_buffer.empty()) return false;
+ this->pop_back(elem);
+ lock.unlock();
+ _full_cond.notify_one();
+ return true;
+ }
+
+ UHD_INLINE void pop_with_wait(elem_type &elem){
+ if (this->pop_with_haste(elem)) return;
+ boost::mutex::scoped_lock lock(_mutex);
+ _empty_cond.wait(lock, _not_empty_fcn);
+ this->pop_back(elem);
+ lock.unlock();
+ _full_cond.notify_one();
+ }
+
+ UHD_INLINE bool pop_with_timed_wait(elem_type &elem, double timeout){
+ if (this->pop_with_haste(elem)) return true;
+ boost::mutex::scoped_lock lock(_mutex);
+ if (not _empty_cond.timed_wait(
+ lock, to_time_dur(timeout), _not_empty_fcn
+ )) return false;
+ this->pop_back(elem);
+ lock.unlock();
+ _full_cond.notify_one();
+ return true;
+ }
+
+ private:
+ boost::mutex _mutex;
+ boost::condition _empty_cond, _full_cond;
+ boost::circular_buffer<elem_type> _buffer;
+
+ bool not_full(void) const{return not _buffer.full();}
+ bool not_empty(void) const{return not _buffer.empty();}
+
+ boost::function<bool(void)> _not_full_fcn, _not_empty_fcn;
+
+ /*!
+ * Three part operation to pop an element:
+ * 1) assign elem to the back element
+ * 2) assign the back element to empty
+ * 3) pop the back to move the counter
+ */
+ UHD_INLINE void pop_back(elem_type &elem){
+ elem = _buffer.back();
+ _buffer.back() = elem_type();
+ _buffer.pop_back();
+ }
+
+ static UHD_INLINE boost::posix_time::time_duration to_time_dur(double timeout){
+ return boost::posix_time::microseconds(long(timeout*1e6));
+ }
+
+ };
+}}} //namespace
+
+#endif /* INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_IPP */
diff --git a/host/include/uhd/transport/buffer_pool.hpp b/host/include/uhd/transport/buffer_pool.hpp
new file mode 100644
index 000000000..84a338097
--- /dev/null
+++ b/host/include/uhd/transport/buffer_pool.hpp
@@ -0,0 +1,59 @@
+//
+// Copyright 2011-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_BUFFER_POOL_HPP
+#define INCLUDED_UHD_TRANSPORT_BUFFER_POOL_HPP
+
+#include <uhd/config.hpp>
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace uhd{ namespace transport{
+
+ /*!
+ * A buffer pool manages memory for a homogeneous set of buffers.
+ * Each buffer is the pool start at a 16-byte alignment boundary.
+ */
+ class UHD_API buffer_pool : boost::noncopyable{
+ public:
+ typedef boost::shared_ptr<buffer_pool> sptr;
+ typedef void * ptr_type;
+
+ /*!
+ * Make a new buffer pool.
+ * \param num_buffs the number of buffers to allocate
+ * \param buff_size the size of each buffer in bytes
+ * \param alignment the alignment boundary in bytes
+ * \return a new buffer pool buff_size X num_buffs
+ */
+ static sptr make(
+ const size_t num_buffs,
+ const size_t buff_size,
+ const size_t alignment = 16
+ );
+
+ //! Get a pointer to the buffer start at the specified index
+ virtual ptr_type at(const size_t index) const = 0;
+
+ //! Get the number of buffers in this pool
+ virtual size_t size(void) const = 0;
+ };
+
+}} //namespace
+
+
+#endif /* INCLUDED_UHD_TRANSPORT_BUFFER_POOL_HPP */
diff --git a/host/include/uhd/transport/if_addrs.hpp b/host/include/uhd/transport/if_addrs.hpp
new file mode 100644
index 000000000..689aff42c
--- /dev/null
+++ b/host/include/uhd/transport/if_addrs.hpp
@@ -0,0 +1,46 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_IF_ADDRS_HPP
+#define INCLUDED_UHD_TRANSPORT_IF_ADDRS_HPP
+
+#include <uhd/config.hpp>
+#include <string>
+#include <vector>
+
+namespace uhd{ namespace transport{
+
+ /*!
+ * The address for a network interface.
+ */
+ struct UHD_API if_addrs_t{
+ std::string inet;
+ std::string mask;
+ std::string bcast;
+ };
+
+ /*!
+ * Get a list of network interface addresses.
+ * The internal implementation is system-dependent.
+ * \return a vector of if addrs
+ */
+ UHD_API std::vector<if_addrs_t> get_if_addrs(void);
+
+}} //namespace
+
+
+#endif /* INCLUDED_UHD_TRANSPORT_IF_ADDRS_HPP */
diff --git a/host/include/uhd/transport/udp_simple.hpp b/host/include/uhd/transport/udp_simple.hpp
new file mode 100644
index 000000000..83f895ba9
--- /dev/null
+++ b/host/include/uhd/transport/udp_simple.hpp
@@ -0,0 +1,84 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_UDP_SIMPLE_HPP
+#define INCLUDED_UHD_TRANSPORT_UDP_SIMPLE_HPP
+
+#include <uhd/config.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace uhd{ namespace transport{
+
+class UHD_API udp_simple : boost::noncopyable{
+public:
+ typedef boost::shared_ptr<udp_simple> sptr;
+
+ //! The maximum number of bytes per udp packet.
+ static const size_t mtu = 1500 - 20 - 8; //default ipv4 mtu - ipv4 header - udp header
+
+ /*!
+ * Make a new connected udp transport:
+ * This transport is for sending and receiving
+ * between this host and a single endpoint.
+ * The primary usage for this transport will be control transactions.
+ * The underlying implementation is simple and portable (not fast).
+ *
+ * The address will be resolved, it can be a host name or ipv4.
+ * The port will be resolved, it can be a port type or number.
+ *
+ * \param addr a string representing the destination address
+ * \param port a string representing the destination port
+ */
+ static sptr make_connected(const std::string &addr, const std::string &port);
+
+ /*!
+ * Make a new broadcasting udp transport:
+ * This transport can send udp broadcast datagrams
+ * and receive datagrams from multiple sources.
+ * The primary usage for this transport will be to discover devices.
+ *
+ * The address will be resolved, it can be a host name or ipv4.
+ * The port will be resolved, it can be a port type or number.
+ *
+ * \param addr a string representing the destination address
+ * \param port a string representing the destination port
+ */
+ static sptr make_broadcast(const std::string &addr, const std::string &port);
+
+ /*!
+ * Send a single buffer.
+ * Blocks until the data is sent.
+ * \param buff single asio buffer
+ * \return the number of bytes sent
+ */
+ virtual size_t send(const boost::asio::const_buffer &buff) = 0;
+
+ /*!
+ * Receive into the provided buffer.
+ * Blocks until data is received or a timeout occurs.
+ * \param buff a mutable buffer to receive into
+ * \param timeout the timeout in seconds
+ * \return the number of bytes received or zero on timeout
+ */
+ virtual size_t recv(const boost::asio::mutable_buffer &buff, double timeout = 0.1) = 0;
+};
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_TRANSPORT_UDP_SIMPLE_HPP */
diff --git a/host/include/uhd/transport/udp_zero_copy.hpp b/host/include/uhd/transport/udp_zero_copy.hpp
new file mode 100644
index 000000000..bbba97b21
--- /dev/null
+++ b/host/include/uhd/transport/udp_zero_copy.hpp
@@ -0,0 +1,65 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP
+#define INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/transport/zero_copy.hpp>
+#include <uhd/types/device_addr.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace uhd{ namespace transport{
+
+/*!
+ * A zero copy udp transport provides an efficient way to handle data.
+ * by avoiding the extra copy when recv() or send() is called on the socket.
+ * Rather, the zero copy transport gives the caller memory references.
+ * The caller informs the transport when it is finished with the reference.
+ *
+ * On linux systems, the zero copy transport can use a kernel packet ring.
+ * If no platform specific solution is available, make returns a boost asio
+ * implementation that wraps the functionality around a standard send/recv calls.
+ */
+class UHD_API udp_zero_copy : public virtual zero_copy_if{
+public:
+ typedef boost::shared_ptr<udp_zero_copy> sptr;
+
+ /*!
+ * Make a new zero copy udp transport:
+ * This transport is for sending and receiving
+ * between this host and a single endpoint.
+ * The primary usage for this transport will be data transactions.
+ * The underlying implementation is fast and platform specific.
+ *
+ * The address will be resolved, it can be a host name or ipv4.
+ * The port will be resolved, it can be a port type or number.
+ *
+ * \param addr a string representing the destination address
+ * \param port a string representing the destination port
+ * \param hints optional parameters to pass to the underlying transport
+ */
+ static sptr make(
+ const std::string &addr,
+ const std::string &port,
+ const device_addr_t &hints = device_addr_t()
+ );
+};
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP */
diff --git a/host/include/uhd/transport/usb_control.hpp b/host/include/uhd/transport/usb_control.hpp
new file mode 100644
index 000000000..e6c32f78e
--- /dev/null
+++ b/host/include/uhd/transport/usb_control.hpp
@@ -0,0 +1,65 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_USB_CONTROL_HPP
+#define INCLUDED_UHD_TRANSPORT_USB_CONTROL_HPP
+
+#include <uhd/transport/usb_device_handle.hpp>
+
+namespace uhd { namespace transport {
+
+class UHD_API usb_control : boost::noncopyable {
+public:
+ typedef boost::shared_ptr<usb_control> sptr;
+
+ /*!
+ * Create a new usb control transport:
+ * This transport is for sending and receiving control information from
+ * the host to device using the Default Control Pipe.
+ *
+ * \param handle a device handle that uniquely identifies a USB device
+ */
+ static sptr make(usb_device_handle::sptr handle);
+
+ /*!
+ * Submit a USB device request:
+ * Blocks until the request returns
+ *
+ * For format and corresponding USB request fields
+ * see USB Specification Revision 2.0 - 9.3 USB Device Requests
+ *
+ * Usage is device specific
+ *
+ * \param request_type 1-byte bitmask (bmRequestType)
+ * \param request 1-byte (bRequest)
+ * \param value 2-byte (wValue)
+ * \param index 2-byte (wIndex)
+ * \param buff buffer to hold send or receive data
+ * \param length 2-byte (wLength)
+ * \return number of bytes submitted or error code
+ */
+ virtual ssize_t submit(boost::uint8_t request_type,
+ boost::uint8_t request,
+ boost::uint16_t value,
+ boost::uint16_t index,
+ unsigned char *buff,
+ boost::uint16_t length) = 0;
+};
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_TRANSPORT_USB_CONTROL_HPP */
diff --git a/host/include/uhd/transport/usb_device_handle.hpp b/host/include/uhd/transport/usb_device_handle.hpp
new file mode 100644
index 000000000..6f8d868be
--- /dev/null
+++ b/host/include/uhd/transport/usb_device_handle.hpp
@@ -0,0 +1,73 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_USB_DEVICE_HANDLE_HPP
+#define INCLUDED_UHD_TRANSPORT_USB_DEVICE_HANDLE_HPP
+
+#include <uhd/config.hpp>
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/cstdint.hpp>
+#include <vector>
+
+namespace uhd { namespace transport {
+
+/*!
+ * Device handle class that represents a USB device
+ * Used for identifying devices on the USB bus and selecting which device is
+ * used when creating a USB transport. A minimal subset of USB descriptor
+ * fields are used. Fields can be found in the USB 2.0 specification Table
+ * 9-8 (Standard Device Descriptor). In addition to fields of the device
+ * descriptor, the interface returns the device's USB device address.
+ *
+ * Note: The USB 2.0 Standard Device Descriptor contains an index rather then
+ * a true descriptor serial number string. This interface returns the
+ * actual string descriptor.
+ */
+class UHD_API usb_device_handle : boost::noncopyable {
+public:
+ typedef boost::shared_ptr<usb_device_handle> sptr;
+
+ /*!
+ * Return the device's serial number
+ * \return a string describing the device's serial number
+ */
+ virtual std::string get_serial() const = 0;
+
+ /*!
+ * Return the device's Vendor ID (usually assigned by the USB-IF)
+ * \return a Vendor ID
+ */
+ virtual boost::uint16_t get_vendor_id() const = 0;
+
+ /*!
+ * Return the device's Product ID (usually assigned by manufacturer)
+ * \return a Product ID
+ */
+ virtual boost::uint16_t get_product_id() const = 0;
+
+ /*!
+ * Return a vector of USB devices on this host
+ * \return a vector of USB device handles that match vid and pid
+ */
+ static std::vector<usb_device_handle::sptr> get_device_list(boost::uint16_t vid, boost::uint16_t pid);
+
+}; //namespace usb
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_TRANSPORT_USB_DEVICE_HANDLE_HPP */
diff --git a/host/include/uhd/transport/usb_zero_copy.hpp b/host/include/uhd/transport/usb_zero_copy.hpp
new file mode 100644
index 000000000..dc344ad8b
--- /dev/null
+++ b/host/include/uhd/transport/usb_zero_copy.hpp
@@ -0,0 +1,82 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_USB_ZERO_COPY_HPP
+#define INCLUDED_UHD_TRANSPORT_USB_ZERO_COPY_HPP
+
+#include <uhd/transport/usb_device_handle.hpp>
+#include <uhd/transport/zero_copy.hpp>
+#include <uhd/types/device_addr.hpp>
+
+namespace uhd { namespace transport {
+
+/*!
+ * A zero copy usb transport provides an efficient way to handle data.
+ * by avoiding the extra copy when recv() or send() is called on the handle.
+ * Rather, the zero copy transport gives the caller memory references.
+ * The caller informs the transport when it is finished with the reference.
+ *
+ * On linux systems, the zero copy transport can use a kernel packet ring.
+ * If no platform specific solution is available, make returns a boost asio
+ * implementation that wraps functionality around standard send/recv calls.
+ */
+class UHD_API usb_zero_copy : public virtual zero_copy_if {
+public:
+ typedef boost::shared_ptr<usb_zero_copy> sptr;
+
+ /*!
+ * Make a new zero copy usb transport:
+ * This transport is for sending and receiving between the host
+ * and a pair of USB bulk transfer endpoints.
+ * The primary usage for this transport is data transactions.
+ * The underlying implementation may be platform specific.
+ *
+ * \param handle a device handle that uniquely identifying the device
+ * \param recv_endpoint an integer specifiying an IN endpoint number
+ * \param send_endpoint an integer specifiying an OUT endpoint number
+ * \param hints optional parameters to pass to the underlying transport
+ * \return a new zero copy usb object
+ */
+ static sptr make(
+ usb_device_handle::sptr handle,
+ size_t recv_endpoint,
+ size_t send_endpoint,
+ const device_addr_t &hints = device_addr_t()
+ );
+
+ /*!
+ * Make a wrapper around a zero copy implementation.
+ * The wrapper performs the following functions:
+ * - Pad commits to the frame boundary
+ * - Extract multiple packets on recv
+ *
+ * When enable multiple receive packets is set to true,
+ * the implementation inspects the vita length on transfers,
+ * and may split a single transfer into multiple managed buffers.
+ *
+ * \param usb_zc a usb zero copy interface object
+ * \param usb_frame_boundary bytes per frame
+ * \return a new zero copy wrapper object
+ */
+ static sptr make_wrapper(
+ sptr usb_zc, size_t usb_frame_boundary = 512
+ );
+};
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_TRANSPORT_USB_ZERO_COPY_HPP */
diff --git a/host/include/uhd/transport/vrt_if_packet.hpp b/host/include/uhd/transport/vrt_if_packet.hpp
new file mode 100644
index 000000000..51bd81bb1
--- /dev/null
+++ b/host/include/uhd/transport/vrt_if_packet.hpp
@@ -0,0 +1,106 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_VRT_IF_PACKET_HPP
+#define INCLUDED_UHD_TRANSPORT_VRT_IF_PACKET_HPP
+
+#include <uhd/config.hpp>
+#include <boost/cstdint.hpp>
+#include <cstddef> //size_t
+
+namespace uhd{ namespace transport{
+
+namespace vrt{
+
+ //! The maximum number of 32-bit words in a vrt if packet header
+ static const size_t max_if_hdr_words32 = 7; //hdr+sid+cid+tsi+tsf
+
+ /*!
+ * Definition for fields that can be packed into a vrt if header.
+ * The size fields are used for input and output depending upon
+ * the operation used (ie the pack or unpack function call).
+ */
+ struct UHD_API if_packet_info_t{
+ //packet type (pack only supports data)
+ enum packet_type_t {
+ PACKET_TYPE_DATA = 0x0,
+ PACKET_TYPE_EXTENSION = 0x1,
+ PACKET_TYPE_CONTEXT = 0x2
+ } packet_type;
+
+ //size fields
+ size_t num_payload_words32; //required in pack, derived in unpack
+ size_t num_header_words32; //derived in pack, derived in unpack
+ size_t num_packet_words32; //derived in pack, required in unpack
+
+ //header fields
+ size_t packet_count;
+ bool sob, eob;
+
+ //optional fields
+ bool has_sid; boost::uint32_t sid;
+ bool has_cid; boost::uint64_t cid;
+ bool has_tsi; boost::uint32_t tsi;
+ bool has_tsf; boost::uint64_t tsf;
+ bool has_tlr; boost::uint32_t tlr;
+ };
+
+ /*!
+ * Pack a vrt header from metadata (big endian format).
+ * \param packet_buff memory to write the packed vrt header
+ * \param if_packet_info the if packet info (read/write)
+ */
+ UHD_API void if_hdr_pack_be(
+ boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
+ );
+
+ /*!
+ * Unpack a vrt header to metadata (big endian format).
+ * \param packet_buff memory to read the packed vrt header
+ * \param if_packet_info the if packet info (read/write)
+ */
+ UHD_API void if_hdr_unpack_be(
+ const boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
+ );
+
+ /*!
+ * Pack a vrt header from metadata (little endian format).
+ * \param packet_buff memory to write the packed vrt header
+ * \param if_packet_info the if packet info (read/write)
+ */
+ UHD_API void if_hdr_pack_le(
+ boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
+ );
+
+ /*!
+ * Unpack a vrt header to metadata (little endian format).
+ * \param packet_buff memory to read the packed vrt header
+ * \param if_packet_info the if packet info (read/write)
+ */
+ UHD_API void if_hdr_unpack_le(
+ const boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
+ );
+
+} //namespace vrt
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_TRANSPORT_VRT_IF_PACKET_HPP */
diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp
new file mode 100644
index 000000000..f80c738aa
--- /dev/null
+++ b/host/include/uhd/transport/zero_copy.hpp
@@ -0,0 +1,184 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP
+#define INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP
+
+#include <uhd/config.hpp>
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/intrusive_ptr.hpp>
+
+namespace uhd{ namespace transport{
+
+ //! Create smart pointer to a reusable managed buffer
+ template <typename T> UHD_INLINE boost::intrusive_ptr<T> make_managed_buffer(T *p){
+ p->_ref_count = 1; //reset the count to 1 reference
+ return boost::intrusive_ptr<T>(p, false);
+ }
+
+ /*!
+ * A managed receive buffer:
+ * Contains a reference to transport-managed memory,
+ * and a method to release the memory after reading.
+ */
+ class UHD_API managed_recv_buffer{
+ public:
+ typedef boost::intrusive_ptr<managed_recv_buffer> sptr;
+
+ /*!
+ * Signal to the transport that we are done with the buffer.
+ * This should be called to release the buffer to the transport object.
+ * After calling, the referenced memory should be considered invalid.
+ */
+ virtual void release(void) = 0;
+
+ /*!
+ * Get a pointer to the underlying buffer.
+ * \return a pointer into memory
+ */
+ template <class T> inline T cast(void) const{
+ return static_cast<T>(this->get_buff());
+ }
+
+ /*!
+ * Get the size of the underlying buffer.
+ * \return the number of bytes
+ */
+ inline size_t size(void) const{
+ return this->get_size();
+ }
+
+ private:
+ virtual const void *get_buff(void) const = 0;
+ virtual size_t get_size(void) const = 0;
+
+ public: int _ref_count;
+ };
+
+ UHD_INLINE void intrusive_ptr_add_ref(managed_recv_buffer *p){
+ ++(p->_ref_count);
+ }
+
+ UHD_INLINE void intrusive_ptr_release(managed_recv_buffer *p){
+ if (--(p->_ref_count) == 0) p->release();
+ }
+
+ /*!
+ * A managed send buffer:
+ * Contains a reference to transport-managed memory,
+ * and a method to commit the memory after writing.
+ */
+ class UHD_API managed_send_buffer{
+ public:
+ typedef boost::intrusive_ptr<managed_send_buffer> sptr;
+
+ /*!
+ * Signal to the transport that we are done with the buffer.
+ * This should be called to commit the write to the transport object.
+ * After calling, the referenced memory should be considered invalid.
+ * \param num_bytes the number of bytes written into the buffer
+ */
+ virtual void commit(size_t num_bytes) = 0;
+
+ /*!
+ * Get a pointer to the underlying buffer.
+ * \return a pointer into memory
+ */
+ template <class T> inline T cast(void) const{
+ return static_cast<T>(this->get_buff());
+ }
+
+ /*!
+ * Get the size of the underlying buffer.
+ * \return the number of bytes
+ */
+ inline size_t size(void) const{
+ return this->get_size();
+ }
+
+ private:
+ virtual void *get_buff(void) const = 0;
+ virtual size_t get_size(void) const = 0;
+
+ public: int _ref_count;
+ };
+
+ UHD_INLINE void intrusive_ptr_add_ref(managed_send_buffer *p){
+ ++(p->_ref_count);
+ }
+
+ UHD_INLINE void intrusive_ptr_release(managed_send_buffer *p){
+ if (--(p->_ref_count) == 0) p->commit(0);
+ }
+
+ /*!
+ * A zero-copy interface for transport objects.
+ * Provides a way to get send and receive buffers
+ * with memory managed by the transport object.
+ */
+ class UHD_API zero_copy_if : boost::noncopyable{
+ public:
+ typedef boost::shared_ptr<zero_copy_if> sptr;
+
+ /*!
+ * Get a new receive buffer from this transport object.
+ * \param timeout the timeout to get the buffer in seconds
+ * \return a managed buffer, or null sptr on timeout/error
+ */
+ virtual managed_recv_buffer::sptr get_recv_buff(double timeout = 0.1) = 0;
+
+ /*!
+ * Get the number of receive frames:
+ * The number of simultaneous receive buffers in use.
+ * \return number of frames
+ */
+ virtual size_t get_num_recv_frames(void) const = 0;
+
+ /*!
+ * Get the size of a receive frame:
+ * The maximum capacity of a single receive buffer.
+ * \return frame size in bytes
+ */
+ virtual size_t get_recv_frame_size(void) const = 0;
+
+ /*!
+ * Get a new send buffer from this transport object.
+ * \param timeout the timeout to get the buffer in seconds
+ * \return a managed buffer, or null sptr on timeout/error
+ */
+ virtual managed_send_buffer::sptr get_send_buff(double timeout = 0.1) = 0;
+
+ /*!
+ * Get the number of send frames:
+ * The number of simultaneous send buffers in use.
+ * \return number of frames
+ */
+ virtual size_t get_num_send_frames(void) const = 0;
+
+ /*!
+ * Get the size of a send frame:
+ * The maximum capacity of a single send buffer.
+ * \return frame size in bytes
+ */
+ virtual size_t get_send_frame_size(void) const = 0;
+
+ };
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP */
diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt
new file mode 100644
index 000000000..0971ca472
--- /dev/null
+++ b/host/include/uhd/types/CMakeLists.txt
@@ -0,0 +1,38 @@
+#
+# Copyright 2010-2011 Ettus Research LLC
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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, see <http://www.gnu.org/licenses/>.
+#
+
+
+INSTALL(FILES
+ clock_config.hpp
+ device_addr.hpp
+ dict.ipp
+ dict.hpp
+ io_type.hpp
+ mac_addr.hpp
+ metadata.hpp
+ otw_type.hpp
+ ranges.hpp
+ ref_vector.hpp
+ sensors.hpp
+ serial.hpp
+ stream_cmd.hpp
+ time_spec.hpp
+ tune_request.hpp
+ tune_result.hpp
+ DESTINATION ${INCLUDE_DIR}/uhd/types
+ COMPONENT headers
+)
diff --git a/host/include/uhd/types/clock_config.hpp b/host/include/uhd/types/clock_config.hpp
new file mode 100644
index 000000000..24bd96d14
--- /dev/null
+++ b/host/include/uhd/types/clock_config.hpp
@@ -0,0 +1,63 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_CLOCK_CONFIG_HPP
+#define INCLUDED_UHD_TYPES_CLOCK_CONFIG_HPP
+
+#include <uhd/config.hpp>
+
+namespace uhd{
+
+ /*!
+ * Clock configuration settings:
+ * The source for the 10MHz reference clock.
+ * The source and polarity for the PPS clock.
+ *
+ * Use the convenience functions external() and internal(),
+ * unless you have a special purpose and cannot use them.
+ */
+ struct UHD_API clock_config_t{
+ //------ simple usage --------//
+
+ //! A convenience function to create an external clock configuration
+ static clock_config_t external(void);
+
+ //! A convenience function to create an internal clock configuration
+ static clock_config_t internal(void);
+
+ //------ advanced usage --------//
+ enum ref_source_t {
+ REF_AUTO = int('a'), //automatic (device specific)
+ REF_INT = int('i'), //internal reference
+ REF_SMA = int('s'), //external sma port
+ REF_MIMO = int('m'), //reference from mimo cable
+ } ref_source;
+ enum pps_source_t {
+ PPS_INT = int('i'), //there is no internal
+ PPS_SMA = int('s'), //external sma port
+ PPS_MIMO = int('m'), //time sync from mimo cable
+ } pps_source;
+ enum pps_polarity_t {
+ PPS_NEG = int('n'), //negative edge
+ PPS_POS = int('p') //positive edge
+ } pps_polarity;
+ clock_config_t(void);
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_CLOCK_CONFIG_HPP */
diff --git a/host/include/uhd/types/device_addr.hpp b/host/include/uhd/types/device_addr.hpp
new file mode 100644
index 000000000..2c0841146
--- /dev/null
+++ b/host/include/uhd/types/device_addr.hpp
@@ -0,0 +1,98 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_DEVICE_ADDR_HPP
+#define INCLUDED_UHD_TYPES_DEVICE_ADDR_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/types/dict.hpp>
+#include <boost/lexical_cast.hpp>
+#include <stdexcept>
+#include <vector>
+#include <string>
+
+namespace uhd{
+
+ /*!
+ * Mapping of key/value pairs for locating devices on the system.
+ * When left empty, the device discovery routines will search
+ * all available transports on the system (ethernet, usb...).
+ *
+ * To narrow down the discovery process to a particular device,
+ * specify a transport key/value pair specific to your device.
+ * - Ex, to find a usrp2: my_dev_addr["addr"] = [resolvable_hostname_or_ip]
+ *
+ * The device address can also be used to pass arguments into
+ * the transport layer control to set (for example) buffer sizes.
+ *
+ * An arguments string, is a way to represent a device address
+ * using a single string with delimiter characters.
+ * - Ex: addr=192.168.10.2
+ * - Ex: addr=192.168.10.2, recv_buff_size=1e6
+ */
+ class UHD_API device_addr_t : public dict<std::string, std::string>{
+ public:
+ /*!
+ * Create a device address from an args string.
+ * \param args the arguments string
+ */
+ device_addr_t(const std::string &args = "");
+
+ /*!
+ * Convert a device address into a pretty print string.
+ * \return a printable string representing the device address
+ */
+ std::string to_pp_string(void) const;
+
+ /*!
+ * Convert the device address into an args string.
+ * The args string contains delimiter symbols.
+ * \return a string with delimiter markup
+ */
+ std::string to_string(void) const;
+
+ /*!
+ * Lexically cast a parameter to the specified type,
+ * or use the default value if the key is not found.
+ * \param key the key as one of the address parameters
+ * \param def the value to use when key is not present
+ * \return the casted value as type T or the default
+ * \throw error when the parameter cannot be casted
+ */
+ template <typename T> T cast(const std::string &key, const T &def) const{
+ if (not this->has_key(key)) return def;
+ try{
+ return boost::lexical_cast<T>((*this)[key]);
+ }
+ catch(const boost::bad_lexical_cast &){
+ throw std::runtime_error("cannot cast " + key + " = " + (*this)[key]);
+ }
+ }
+ };
+
+ //! A typedef for a vector of device addresses
+ typedef std::vector<device_addr_t> device_addrs_t;
+
+ //! Separate an indexed device address into a vector of device addresses
+ UHD_API device_addrs_t separate_device_addr(const device_addr_t &dev_addr);
+
+ //! Combine a vector of device addresses into an indexed device address
+ UHD_API device_addr_t combine_device_addrs(const device_addrs_t &dev_addrs);
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_DEVICE_ADDR_HPP */
diff --git a/host/include/uhd/types/dict.hpp b/host/include/uhd/types/dict.hpp
new file mode 100644
index 000000000..97fa8f09c
--- /dev/null
+++ b/host/include/uhd/types/dict.hpp
@@ -0,0 +1,129 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_DICT_HPP
+#define INCLUDED_UHD_TYPES_DICT_HPP
+
+#include <uhd/config.hpp>
+#include <vector>
+#include <list>
+
+namespace uhd{
+
+ /*!
+ * A templated dictionary class with a python-like interface.
+ */
+ template <typename Key, typename Val> class dict{
+ public:
+ /*!
+ * Create a new empty dictionary.
+ */
+ dict(void);
+
+ /*!
+ * Input iterator constructor:
+ * Makes boost::assign::map_list_of work.
+ * \param first the begin iterator
+ * \param last the end iterator
+ */
+ template <typename InputIterator>
+ dict(InputIterator first, InputIterator last);
+
+ /*!
+ * Get the number of elements in this dict.
+ * \return the number of elements
+ */
+ std::size_t size(void) const;
+
+ /*!
+ * Get a list of the keys in this dict.
+ * Key order depends on insertion precedence.
+ * \return vector of keys
+ */
+ std::vector<Key> keys(void) const;
+
+ /*!
+ * Get a list of the values in this dict.
+ * Value order depends on insertion precedence.
+ * \return vector of values
+ */
+ std::vector<Val> vals(void) const;
+
+ /*!
+ * Does the dictionary contain this key?
+ * \param key the key to look for
+ * \return true if found
+ */
+ bool has_key(const Key &key) const;
+
+ /*!
+ * Get a value in the dict or default.
+ * \param key the key to look for
+ * \param other use if key not found
+ * \return the value or default
+ */
+ const Val &get(const Key &key, const Val &other) const;
+
+ /*!
+ * Get a value in the dict or throw.
+ * \param key the key to look for
+ * \return the value or default
+ */
+ const Val &get(const Key &key) const;
+
+ /*!
+ * Set a value in the dict at the key.
+ * \param key the key to set at
+ * \param val the value to set
+ */
+ void set(const Key &key, const Val &val);
+
+ /*!
+ * Get a value for the given key if it exists.
+ * If the key is not found throw an error.
+ * \param key the key to look for
+ * \return the value at the key
+ * \throw an exception when not found
+ */
+ const Val &operator[](const Key &key) const;
+
+ /*!
+ * Set a value for the given key, however, in reality
+ * it really returns a reference which can be assigned to.
+ * \param key the key to set to
+ * \return a reference to the value
+ */
+ Val &operator[](const Key &key);
+
+ /*!
+ * Pop an item out of the dictionary.
+ * \param key the item key
+ * \return the value of the item
+ * \throw an exception when not found
+ */
+ Val pop(const Key &key);
+
+ private:
+ typedef std::pair<Key, Val> pair_t;
+ std::list<pair_t> _map; //private container
+ };
+
+} //namespace uhd
+
+#include <uhd/types/dict.ipp>
+
+#endif /* INCLUDED_UHD_TYPES_DICT_HPP */
diff --git a/host/include/uhd/types/dict.ipp b/host/include/uhd/types/dict.ipp
new file mode 100644
index 000000000..5e9cf97ad
--- /dev/null
+++ b/host/include/uhd/types/dict.ipp
@@ -0,0 +1,140 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_DICT_IPP
+#define INCLUDED_UHD_TYPES_DICT_IPP
+
+#include <uhd/exception.hpp>
+#include <boost/foreach.hpp>
+#include <boost/format.hpp>
+#include <boost/lexical_cast.hpp>
+#include <typeinfo>
+
+namespace uhd{
+
+ namespace /*anon*/{
+ template<typename Key, typename Val>
+ struct key_not_found: uhd::key_error{
+ key_not_found(const Key &key): uhd::key_error(
+ str(boost::format(
+ "key \"%s\" not found in dict(%s, %s)"
+ ) % boost::lexical_cast<std::string>(key)
+ % typeid(Key).name() % typeid(Val).name()
+ )
+ ){
+ /* NOP */
+ }
+ };
+ } // namespace /*anon*/
+
+ template <typename Key, typename Val>
+ dict<Key, Val>::dict(void){
+ /* NOP */
+ }
+
+ template <typename Key, typename Val> template <typename InputIterator>
+ dict<Key, Val>::dict(InputIterator first, InputIterator last):
+ _map(first, last)
+ {
+ /* NOP */
+ }
+
+ template <typename Key, typename Val>
+ std::size_t dict<Key, Val>::size(void) const{
+ return _map.size();
+ }
+
+ template <typename Key, typename Val>
+ std::vector<Key> dict<Key, Val>::keys(void) const{
+ std::vector<Key> keys;
+ BOOST_FOREACH(const pair_t &p, _map){
+ keys.push_back(p.first);
+ }
+ return keys;
+ }
+
+ template <typename Key, typename Val>
+ std::vector<Val> dict<Key, Val>::vals(void) const{
+ std::vector<Val> vals;
+ BOOST_FOREACH(const pair_t &p, _map){
+ vals.push_back(p.second);
+ }
+ return vals;
+ }
+
+ template <typename Key, typename Val>
+ bool dict<Key, Val>::has_key(const Key &key) const{
+ BOOST_FOREACH(const pair_t &p, _map){
+ if (p.first == key) return true;
+ }
+ return false;
+ }
+
+ template <typename Key, typename Val>
+ const Val &dict<Key, Val>::get(const Key &key, const Val &other) const{
+ BOOST_FOREACH(const pair_t &p, _map){
+ if (p.first == key) return p.second;
+ }
+ return other;
+ }
+
+ template <typename Key, typename Val>
+ const Val &dict<Key, Val>::get(const Key &key) const{
+ BOOST_FOREACH(const pair_t &p, _map){
+ if (p.first == key) return p.second;
+ }
+ throw key_not_found<Key, Val>(key);
+ }
+
+ template <typename Key, typename Val>
+ void dict<Key, Val>::set(const Key &key, const Val &val){
+ (*this)[key] = val;
+ }
+
+ template <typename Key, typename Val>
+ const Val &dict<Key, Val>::operator[](const Key &key) const{
+ BOOST_FOREACH(const pair_t &p, _map){
+ if (p.first == key) return p.second;
+ }
+ throw key_not_found<Key, Val>(key);
+ }
+
+ template <typename Key, typename Val>
+ Val &dict<Key, Val>::operator[](const Key &key){
+ BOOST_FOREACH(pair_t &p, _map){
+ if (p.first == key) return p.second;
+ }
+ _map.push_back(std::make_pair(key, Val()));
+ return _map.back().second;
+ }
+
+ template <typename Key, typename Val>
+ Val dict<Key, Val>::pop(const Key &key){
+ typename std::list<pair_t>::iterator it;
+ for (it = _map.begin(); it != _map.end(); it++){
+ if (it->first == key){
+ Val val = it->second;
+ _map.erase(it);
+ return val;
+ }
+ }
+ throw key_not_found<Key, Val>(key);
+ }
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_DICT_IPP */
diff --git a/host/include/uhd/types/io_type.hpp b/host/include/uhd/types/io_type.hpp
new file mode 100644
index 000000000..ace643abc
--- /dev/null
+++ b/host/include/uhd/types/io_type.hpp
@@ -0,0 +1,76 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_IO_TYPE_HPP
+#define INCLUDED_UHD_TYPES_IO_TYPE_HPP
+
+#include <uhd/config.hpp>
+
+namespace uhd{
+
+ /*!
+ * The Input/Output configuration struct:
+ * Used to specify the IO type with device send/recv.
+ */
+ class UHD_API io_type_t{
+ public:
+
+ /*!
+ * Built in IO types known to the system.
+ */
+ enum tid_t{
+ //! Custom type (technically unsupported by implementation)
+ CUSTOM_TYPE = int('?'),
+ //! Complex floating point (64-bit floats) range [-1.0, +1.0]
+ COMPLEX_FLOAT64 = int('d'),
+ //! Complex floating point (32-bit floats) range [-1.0, +1.0]
+ COMPLEX_FLOAT32 = int('f'),
+ //! Complex signed integer (16-bit integers) range [-32768, +32767]
+ COMPLEX_INT16 = int('s'),
+ //! Complex signed integer (8-bit integers) range [-128, 127]
+ COMPLEX_INT8 = int('b')
+ };
+
+ /*!
+ * The size of this io type in bytes.
+ */
+ const size_t size;
+
+ /*!
+ * The type id of this io type.
+ * Good for using with switch statements.
+ */
+ const tid_t tid;
+
+ /*!
+ * Create an io type from a built-in type id.
+ * \param tid a type id known to the system
+ */
+ io_type_t(tid_t tid);
+
+ /*!
+ * Create an io type from attributes.
+ * The tid will be set to custom.
+ * \param size the size in bytes
+ */
+ io_type_t(size_t size);
+
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_IO_TYPE_HPP */
diff --git a/host/include/uhd/types/mac_addr.hpp b/host/include/uhd/types/mac_addr.hpp
new file mode 100644
index 000000000..0ced2e734
--- /dev/null
+++ b/host/include/uhd/types/mac_addr.hpp
@@ -0,0 +1,66 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_MAC_ADDR_HPP
+#define INCLUDED_UHD_TYPES_MAC_ADDR_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/types/serial.hpp>
+#include <string>
+
+namespace uhd{
+
+ /*!
+ * Wrapper for an ethernet mac address.
+ * Provides conversion between string and binary formats.
+ */
+ class UHD_API mac_addr_t{
+ public:
+ /*!
+ * Create a mac address a byte array.
+ * \param bytes a vector of bytes
+ * \return a new mac address
+ */
+ static mac_addr_t from_bytes(const byte_vector_t &bytes);
+
+ /*!
+ * Create a mac address from a string.
+ * \param mac_addr_str the string with delimiters
+ * \return a new mac address
+ */
+ static mac_addr_t from_string(const std::string &mac_addr_str);
+
+ /*!
+ * Get the byte representation of the mac address.
+ * \return a vector of bytes
+ */
+ byte_vector_t to_bytes(void) const;
+
+ /*!
+ * Get the string representation of this mac address.
+ * \return a string with delimiters
+ */
+ std::string to_string(void) const;
+
+ private:
+ mac_addr_t(const byte_vector_t &bytes); //private constructor
+ const byte_vector_t _bytes; //internal representation
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_MAC_ADDR_HPP */
diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp
new file mode 100644
index 000000000..269c77c7c
--- /dev/null
+++ b/host/include/uhd/types/metadata.hpp
@@ -0,0 +1,154 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_METADATA_HPP
+#define INCLUDED_UHD_TYPES_METADATA_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/types/time_spec.hpp>
+
+namespace uhd{
+
+ /*!
+ * RX metadata structure for describing sent IF data.
+ * Includes time specification, fragmentation flags, burst flags, and error codes.
+ * The receive routines will convert IF data headers into metadata.
+ */
+ struct UHD_API rx_metadata_t{
+ //! Has time specification?
+ bool has_time_spec;
+
+ //! Time of the first sample.
+ time_spec_t time_spec;
+
+ /*!
+ * Fragmentation flag:
+ * Similar to IPv4 fragmentation: http://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly
+ * More fragments is true when the input buffer has insufficient size to fit
+ * an entire received packet. More fragments will be false for the last fragment.
+ */
+ bool more_fragments;
+
+ /*!
+ * Fragmentation offset:
+ * The fragment offset is the sample number at the start of the receive buffer.
+ * For non-fragmented receives, the fragment offset should always be zero.
+ */
+ size_t fragment_offset;
+
+ //! Start of burst will be true for the first packet in the chain.
+ bool start_of_burst;
+
+ //! End of burst will be true for the last packet in the chain.
+ bool end_of_burst;
+
+ /*!
+ * The error condition on a receive call.
+ *
+ * Note: When an overrun occurs in continuous streaming mode,
+ * the device will continue to send samples to the host.
+ * For other streaming modes, streaming will discontinue
+ * until the user issues a new stream command.
+ *
+ * The metadata fields have meaning for the following error codes:
+ * - none
+ * - late command
+ * - broken chain
+ * - overflow
+ */
+ enum error_code_t {
+ //! No error associated with this metadata.
+ ERROR_CODE_NONE = 0x0,
+ //! No packet received, implementation timed-out.
+ ERROR_CODE_TIMEOUT = 0x1,
+ //! A stream command was issued in the past.
+ ERROR_CODE_LATE_COMMAND = 0x2,
+ //! Expected another stream command.
+ ERROR_CODE_BROKEN_CHAIN = 0x4,
+ //! An internal receive buffer has filled.
+ ERROR_CODE_OVERFLOW = 0x8,
+ //! Multi-channel alignment failed.
+ ERROR_CODE_ALIGNMENT = 0xc,
+ //! The packet could not be parsed.
+ ERROR_CODE_BAD_PACKET = 0xf
+ } error_code;
+ };
+
+ /*!
+ * TX metadata structure for describing received IF data.
+ * Includes time specification, and start and stop burst flags.
+ * The send routines will convert the metadata to IF data headers.
+ */
+ struct UHD_API tx_metadata_t{
+ /*!
+ * Has time specification?
+ * - Set false to send immediately.
+ * - Set true to send at the time specified by time spec.
+ */
+ bool has_time_spec;
+
+ //! When to send the first sample.
+ time_spec_t time_spec;
+
+ //! Set start of burst to true for the first packet in the chain.
+ bool start_of_burst;
+
+ //! Set end of burst to true for the last packet in the chain.
+ bool end_of_burst;
+
+ /*!
+ * The default constructor:
+ * Sets the fields to default values (flags set to false).
+ */
+ tx_metadata_t(void);
+ };
+
+ /*!
+ * Async metadata structure for describing transmit related events.
+ */
+ struct UHD_API async_metadata_t{
+ //! The channel number in a mimo configuration
+ size_t channel;
+
+ //! Has time specification?
+ bool has_time_spec;
+
+ //! When the async event occurred.
+ time_spec_t time_spec;
+
+ /*!
+ * The type of event for a receive async message call.
+ */
+ enum event_code_t {
+ //! A burst was successfully transmitted.
+ EVENT_CODE_BURST_ACK = 0x1,
+ //! An internal send buffer has emptied.
+ EVENT_CODE_UNDERFLOW = 0x2,
+ //! Packet loss between host and device.
+ EVENT_CODE_SEQ_ERROR = 0x4,
+ //! Packet had time that was late (or too early).
+ EVENT_CODE_TIME_ERROR = 0x8,
+ //! Underflow occurred inside a packet.
+ EVENT_CODE_UNDERFLOW_IN_PACKET = 0x10,
+ //! Packet loss within a burst.
+ EVENT_CODE_SEQ_ERROR_IN_BURST = 0x20
+ } event_code;
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_METADATA_HPP */
diff --git a/host/include/uhd/types/otw_type.hpp b/host/include/uhd/types/otw_type.hpp
new file mode 100644
index 000000000..11a6af38e
--- /dev/null
+++ b/host/include/uhd/types/otw_type.hpp
@@ -0,0 +1,69 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_OTW_TYPE_HPP
+#define INCLUDED_UHD_TYPES_OTW_TYPE_HPP
+
+#include <uhd/config.hpp>
+
+namespace uhd{
+
+ /*!
+ * Description for over-the-wire integers:
+ * The DSP units in the FPGA deal with signed 16-bit integers.
+ * The width and shift define the translation between OTW and DSP,
+ * defined by the following relation: otw_int = dsp_int >> shift
+ *
+ * Note: possible combinations of width, shift, and byteorder
+ * depend on the internals of the FPGA. Not all are supported!
+ */
+ struct UHD_API otw_type_t{
+
+ /*!
+ * Width of an over-the-wire integer in bits.
+ */
+ size_t width; //in bits
+
+ /*!
+ * Shift of an over-the-wire integer in bits.
+ * otw_int = dsp_int >> shift
+ * dsp_int = otw_int << shift
+ */
+ size_t shift; //in bits
+
+ /*!
+ * Constants for byte order (borrowed from numpy's dtype)
+ */
+ enum /*bo_t*/ {
+ BO_NATIVE = int('='),
+ BO_LITTLE_ENDIAN = int('<'),
+ BO_BIG_ENDIAN = int('>'),
+ BO_NOT_APPLICABLE = int('|')
+ } byteorder;
+
+ /*!
+ * Get the sample size of this otw type.
+ * \return the size of a sample in bytes
+ */
+ size_t get_sample_size(void) const;
+
+ otw_type_t(void);
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_OTW_TYPE_HPP */
diff --git a/host/include/uhd/types/ranges.hpp b/host/include/uhd/types/ranges.hpp
new file mode 100644
index 000000000..f0d0e1c0b
--- /dev/null
+++ b/host/include/uhd/types/ranges.hpp
@@ -0,0 +1,120 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_RANGES_HPP
+#define INCLUDED_UHD_TYPES_RANGES_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/utils/pimpl.hpp>
+#include <string>
+#include <vector>
+
+namespace uhd{
+
+ /*!
+ * A range object describes a set of discrete values of the form:
+ * y = start + step*n, where n is an integer between 0 and (stop - start)/step
+ */
+ class UHD_API range_t{
+ public:
+
+ /*!
+ * Create a range from a single value.
+ * The step size will be taken as zero.
+ * \param value the only possible value in this range
+ */
+ range_t(double value = 0);
+
+ /*!
+ * Create a range from a full set of values.
+ * A step size of zero implies infinite precision.
+ * \param start the minimum value for this range
+ * \param stop the maximum value for this range
+ * \param step the step size for this range
+ */
+ range_t(double start, double stop, double step = 0);
+
+ //! Get the start value for this range.
+ double start(void) const;
+
+ //! Get the stop value for this range.
+ double stop(void) const;
+
+ //! Get the step value for this range.
+ double step(void) const;
+
+ //! Convert this range to a printable string
+ const std::string to_pp_string(void) const;
+
+ private: UHD_PIMPL_DECL(impl) _impl;
+ };
+
+ /*!
+ * A meta-range object holds a list of individual ranges.
+ */
+ struct UHD_API meta_range_t : std::vector<range_t>{
+
+ //! A default constructor for an empty meta-range
+ meta_range_t(void);
+
+ /*!
+ * Input iterator constructor:
+ * Makes boost::assign::list_of work.
+ * \param first the begin iterator
+ * \param last the end iterator
+ */
+ template <typename InputIterator>
+ meta_range_t(InputIterator first, InputIterator last):
+ std::vector<range_t>(first, last){ /* NOP */ }
+
+ /*!
+ * A convenience constructor for a single range.
+ * A step size of zero implies infinite precision.
+ * \param start the minimum value for this range
+ * \param stop the maximum value for this range
+ * \param step the step size for this range
+ */
+ meta_range_t(double start, double stop, double step = 0);
+
+ //! Get the overall start value for this meta-range.
+ double start(void) const;
+
+ //! Get the overall stop value for this meta-range.
+ double stop(void) const;
+
+ //! Get the overall step value for this meta-range.
+ double step(void) const;
+
+ /*!
+ * Clip the target value to a possible range value.
+ * \param value the value to clip to this range
+ * \param clip_step if true, clip to steps as well
+ * \return a value that is in one of the ranges
+ */
+ double clip(double value, bool clip_step = false) const;
+
+ //! Convert this meta-range to a printable string
+ const std::string to_pp_string(void) const;
+
+ };
+
+ typedef meta_range_t gain_range_t;
+ typedef meta_range_t freq_range_t;
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_RANGES_HPP */
diff --git a/host/include/uhd/types/ref_vector.hpp b/host/include/uhd/types/ref_vector.hpp
new file mode 100644
index 000000000..bbfb5434d
--- /dev/null
+++ b/host/include/uhd/types/ref_vector.hpp
@@ -0,0 +1,85 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_REF_VECTOR_HPP
+#define INCLUDED_UHD_TYPES_REF_VECTOR_HPP
+
+#include <uhd/config.hpp>
+
+namespace uhd{
+
+/*!
+ * Reference vector:
+ * - Provides a std::vector-like interface for an array.
+ * - Statically sized, and does not manage the memory.
+ */
+template <typename T> class UHD_API ref_vector{
+public:
+ /*!
+ * Create a reference vector of size 1 from a pointer.
+ * Therefore: rv[0] == ptr and rv.size() == 1
+ * \param ptr a pointer to a chunk of memory
+ */
+ template <typename Ptr> ref_vector(Ptr *ptr):
+ _ptr(T(ptr)), _mem(_mem_t(&_ptr)), _size(1)
+ {
+ /* NOP */
+ }
+
+ /*!
+ * Create a reference vector from a std::vector container.
+ * Therefore: rv[n] == vec[n] and rv.size() == vec.size()
+ * \param vec a const reference to an std::vector
+ */
+ template <typename Vector> ref_vector(const Vector &vec):
+ _ptr(T()), _mem(_mem_t(&vec.front())), _size(vec.size())
+ {
+ /* NOP */
+ }
+
+ /*!
+ * Create a reference vector from a pointer and a length
+ * Therefore: rv[n] == mem[n] and rv.size() == len
+ * \param mem a pointer to an array of pointers
+ * \param len the length of the array of pointers
+ */
+ ref_vector(const T *mem, size_t len):
+ _ptr(T()), _mem(_mem_t(mem)), _size(len)
+ {
+ /* NOP */
+ }
+
+ //! Index operator gets the value of rv[index]
+ const T &operator[](size_t index) const{
+ return _mem[index];
+ }
+
+ //! The number of elements in this container
+ size_t size(void) const{
+ return _size;
+ }
+
+private:
+ const T _ptr;
+ typedef T* _mem_t;
+ const _mem_t _mem;
+ const size_t _size;
+};
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_REF_VECTOR_HPP */
diff --git a/host/include/uhd/types/sensors.hpp b/host/include/uhd/types/sensors.hpp
new file mode 100644
index 000000000..529e1e3e3
--- /dev/null
+++ b/host/include/uhd/types/sensors.hpp
@@ -0,0 +1,137 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_SENSORS_HPP
+#define INCLUDED_UHD_TYPES_SENSORS_HPP
+
+#include <uhd/config.hpp>
+#include <string>
+
+namespace uhd{
+
+ /*!
+ * A sensor value stores a sensor reading as a string with unit and data type.
+ * The sensor value class can be used in the following way:
+ *
+ * sensor_value_t ref_lock_sensor("Reference", my_lock, "unlocked", "locked");
+ * std::cout << ref_lock_sensor.to_pp_string() << std::endl;
+ * //prints Reference: locked
+ *
+ * sensor_value_t temp_sensor("Temperature", my_temp, "C");
+ * std::cout << temp_sensor.to_pp_string() << std::endl;
+ * //prints Temperature: 38.5 C
+ */
+ struct UHD_API sensor_value_t{
+
+ /*!
+ * Create a sensor value from a boolean.
+ * \param name the name of the sensor
+ * \param value the value true or false
+ * \param utrue the unit string when value is true
+ * \param ufalse the unit string when value is false
+ */
+ sensor_value_t(
+ const std::string &name,
+ bool value,
+ const std::string &utrue,
+ const std::string &ufalse
+ );
+
+ /*!
+ * Create a sensor value from an integer.
+ * \param name the name of the sensor
+ * \param value the signed integer value
+ * \param unit the associated unit type
+ * \param formatter the formatter string
+ */
+ sensor_value_t(
+ const std::string &name,
+ signed value,
+ const std::string &unit,
+ const std::string &formatter = "%d"
+ );
+
+ /*!
+ * Create a sensor value from a real number.
+ * \param name the name of the sensor
+ * \param value the real number value
+ * \param unit the associated unit type
+ * \param formatter the formatter string
+ */
+ sensor_value_t(
+ const std::string &name,
+ double value,
+ const std::string &unit,
+ const std::string &formatter = "%f"
+ );
+
+ /*!
+ * Create a sensor value from a string.
+ * \param name the name of the sensor
+ * \param value the real number value
+ * \param unit the associated unit type
+ */
+ sensor_value_t(
+ const std::string &name,
+ const std::string &value,
+ const std::string &unit
+ );
+
+ //! convert the sensor value to a boolean
+ bool to_bool(void) const;
+
+ //! convert the sensor value to an integer
+ signed to_int(void) const;
+
+ //! convert the sensor value to real number
+ double to_real(void) const;
+
+ //! The name of the sensor value
+ const std::string name;
+
+ /*!
+ * The sensor value as a string.
+ * For integer and real number types, this will be the output of the formatter.
+ * For boolean types, the value will be the string literal "true" or "false".
+ */
+ const std::string value;
+
+ /*!
+ * The sensor value's unit type.
+ * For boolean types, this will be the one of the two units
+ * depending upon the value of the boolean true or false.
+ */
+ const std::string unit;
+
+ //! Enumeration of possible data types in a sensor
+ enum data_type_t {
+ BOOLEAN = 'b',
+ INTEGER = 'i',
+ REALNUM = 'r',
+ STRING = 's'
+ };
+
+ //! The data type of the value
+ const data_type_t type;
+
+ //! Convert this sensor value into a printable string
+ std::string to_pp_string(void) const;
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_SENSORS_HPP */
diff --git a/host/include/uhd/types/serial.hpp b/host/include/uhd/types/serial.hpp
new file mode 100644
index 000000000..8a5ed1c32
--- /dev/null
+++ b/host/include/uhd/types/serial.hpp
@@ -0,0 +1,202 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_SERIAL_HPP
+#define INCLUDED_UHD_TYPES_SERIAL_HPP
+
+#include <uhd/config.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/cstdint.hpp>
+#include <vector>
+
+namespace uhd{
+
+ /*!
+ * Byte vector typedef for passing data in and out of I2C interfaces.
+ */
+ typedef std::vector<boost::uint8_t> byte_vector_t;
+
+ /*!
+ * The i2c interface class:
+ * Provides i2c and eeprom functionality.
+ * A subclass should only have to implement the i2c routines.
+ * An eeprom implementation comes for free with the interface.
+ *
+ * The eeprom routines are implemented on top of i2c.
+ * The built in eeprom implementation only does single
+ * byte reads and byte writes over the i2c interface,
+ * so it should be portable across multiple eeproms.
+ * Override the eeprom routines if this is not acceptable.
+ */
+ class UHD_API i2c_iface{
+ public:
+ typedef boost::shared_ptr<i2c_iface> sptr;
+
+ /*!
+ * Write bytes over the i2c.
+ * \param addr the address
+ * \param buf the vector of bytes
+ */
+ virtual void write_i2c(
+ boost::uint8_t addr,
+ const byte_vector_t &buf
+ ) = 0;
+
+ /*!
+ * Read bytes over the i2c.
+ * \param addr the address
+ * \param num_bytes number of bytes to read
+ * \return a vector of bytes
+ */
+ virtual byte_vector_t read_i2c(
+ boost::uint8_t addr,
+ size_t num_bytes
+ ) = 0;
+
+ /*!
+ * Write bytes to an eeprom.
+ * \param addr the address
+ * \param offset byte offset
+ * \param buf the vector of bytes
+ */
+ virtual void write_eeprom(
+ boost::uint8_t addr,
+ boost::uint8_t offset,
+ const byte_vector_t &buf
+ );
+
+ /*!
+ * Read bytes from an eeprom.
+ * \param addr the address
+ * \param offset byte offset
+ * \param num_bytes number of bytes to read
+ * \return a vector of bytes
+ */
+ virtual byte_vector_t read_eeprom(
+ boost::uint8_t addr,
+ boost::uint8_t offset,
+ size_t num_bytes
+ );
+ };
+
+ /*!
+ * The SPI configuration struct:
+ * Used to configure a SPI transaction interface.
+ */
+ struct UHD_API spi_config_t{
+ /*!
+ * The edge type specifies when data is valid
+ * relative to the edge of the serial clock.
+ */
+ enum edge_t{
+ EDGE_RISE = 'r',
+ EDGE_FALL = 'f'
+ };
+
+ //! on what edge is the mosi data valid?
+ edge_t mosi_edge;
+
+ //! on what edge is the miso data valid?
+ edge_t miso_edge;
+
+ /*!
+ * Create a new spi config.
+ * \param edge the default edge for mosi and miso
+ */
+ spi_config_t(edge_t edge = EDGE_RISE);
+ };
+
+ /*!
+ * The SPI interface class.
+ * Provides routines to transact SPI and do other useful things which haven't been defined yet.
+ */
+ class UHD_API spi_iface{
+ public:
+ typedef boost::shared_ptr<spi_iface> sptr;
+
+ /*!
+ * Perform a spi transaction.
+ * \param which_slave the slave device number
+ * \param config spi config args
+ * \param data the bits to write
+ * \param num_bits how many bits in data
+ * \param readback true to readback a value
+ * \return spi data if readback set
+ */
+ virtual boost::uint32_t transact_spi(
+ int which_slave,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits,
+ bool readback
+ ) = 0;
+
+ /*!
+ * Read from the SPI bus.
+ * \param which_slave the slave device number
+ * \param config spi config args
+ * \param data the bits to write out (be sure to set write bit)
+ * \param num_bits how many bits in data
+ * \return spi data
+ */
+ virtual boost::uint32_t read_spi(
+ int which_slave,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits
+ );
+
+ /*!
+ * Write to the SPI bus.
+ * \param which_slave the slave device number
+ * \param config spi config args
+ * \param data the bits to write
+ * \param num_bits how many bits in data
+ */
+ virtual void write_spi(
+ int which_slave,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits
+ );
+ };
+
+ /*!
+ * UART interface to write and read bytes.
+ */
+ class UHD_API uart_iface{
+ public:
+ typedef boost::shared_ptr<uart_iface> sptr;
+
+ /*!
+ * Write to a serial port.
+ * \param dev which UART to write to
+ * \param buf the data to write
+ */
+ virtual void write_uart(boost::uint8_t dev, const std::string &buf) = 0;
+
+ /*!
+ * Read from a serial port.
+ * \param dev which UART to read from
+ * \return the data read from the serial port
+ */
+ virtual std::string read_uart(boost::uint8_t dev) = 0;
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_SERIAL_HPP */
diff --git a/host/include/uhd/types/stream_cmd.hpp b/host/include/uhd/types/stream_cmd.hpp
new file mode 100644
index 000000000..41708e2e2
--- /dev/null
+++ b/host/include/uhd/types/stream_cmd.hpp
@@ -0,0 +1,64 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_STREAM_CMD_HPP
+#define INCLUDED_UHD_TYPES_STREAM_CMD_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/types/time_spec.hpp>
+
+namespace uhd{
+
+ /*!
+ * Command struct for configuration and control of streaming:
+ *
+ * A stream command defines how the device sends samples to the host.
+ * Streaming is controlled by submitting a stream command to the rx dsp.
+ * Granular control over what the device streams to the host can be
+ * achieved through submission of multiple (carefully-crafted) commands.
+ *
+ * The mode parameter controls how streaming is issued to the device:
+ * - "Start continuous" tells the device to stream samples indefinitely.
+ * - "Stop continuous" tells the device to end continuous streaming.
+ * - "Num samps and done" tells the device to stream num samps and
+ * to not expect a future stream command for contiguous samples.
+ * - "Num samps and more" tells the device to stream num samps and
+ * to expect a future stream command for contiguous samples.
+ *
+ * The stream now parameter controls when the stream begins.
+ * When true, the device will begin streaming ASAP. When false,
+ * the device will begin streaming at a time specified by time_spec.
+ */
+ struct UHD_API stream_cmd_t{
+
+ enum stream_mode_t {
+ STREAM_MODE_START_CONTINUOUS = 'a',
+ STREAM_MODE_STOP_CONTINUOUS = 'o',
+ STREAM_MODE_NUM_SAMPS_AND_DONE = 'd',
+ STREAM_MODE_NUM_SAMPS_AND_MORE = 'm'
+ } stream_mode;
+ size_t num_samps;
+
+ bool stream_now;
+ time_spec_t time_spec;
+
+ stream_cmd_t(const stream_mode_t &stream_mode);
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_STREAM_CMD_HPP */
diff --git a/host/include/uhd/types/time_spec.hpp b/host/include/uhd/types/time_spec.hpp
new file mode 100644
index 000000000..02de20ea1
--- /dev/null
+++ b/host/include/uhd/types/time_spec.hpp
@@ -0,0 +1,117 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_TIME_SPEC_HPP
+#define INCLUDED_UHD_TYPES_TIME_SPEC_HPP
+
+#include <uhd/config.hpp>
+#include <boost/operators.hpp>
+#include <ctime>
+
+namespace uhd{
+
+ /*!
+ * A time_spec_t holds a seconds and a fractional seconds time value.
+ * Depending upon usage, the time_spec_t can represent absolute times,
+ * relative times, or time differences (between absolute times).
+ *
+ * The time_spec_t provides clock-domain independent time storage,
+ * but can convert fractional seconds to/from clock-domain specific units.
+ *
+ * The fractional seconds are stored as double precision floating point.
+ * This gives the fractional seconds enough precision to unambiguously
+ * specify a clock-tick/sample-count up to rates of several petahertz.
+ */
+ class UHD_API time_spec_t : boost::additive<time_spec_t>, boost::totally_ordered<time_spec_t>{
+ public:
+
+ /*!
+ * Get the system time in time_spec_t format.
+ * Uses the highest precision clock available.
+ * \return the system time as a time_spec_t
+ */
+ static time_spec_t get_system_time(void);
+
+ /*!
+ * Create a time_spec_t from a real-valued seconds count.
+ * \param secs the real-valued seconds count (default = 0)
+ */
+ time_spec_t(double secs = 0);
+
+ /*!
+ * Create a time_spec_t from whole and fractional seconds.
+ * \param full_secs the whole/integer seconds count
+ * \param frac_secs the fractional seconds count (default = 0)
+ */
+ time_spec_t(time_t full_secs, double frac_secs = 0);
+
+ /*!
+ * Create a time_spec_t from whole and fractional seconds.
+ * Translation from clock-domain specific units.
+ * \param full_secs the whole/integer seconds count
+ * \param tick_count the fractional seconds tick count
+ * \param tick_rate the number of ticks per second
+ */
+ time_spec_t(time_t full_secs, long tick_count, double tick_rate);
+
+ /*!
+ * Convert the fractional seconds to clock ticks.
+ * Translation into clock-domain specific units.
+ * \param tick_rate the number of ticks per second
+ * \return the fractional seconds tick count
+ */
+ long get_tick_count(double tick_rate) const;
+
+ /*!
+ * Get the time as a real-valued seconds count.
+ * Note: If this time_spec_t represents an absolute time,
+ * the precision of the fractional seconds may be lost.
+ * \return the real-valued seconds
+ */
+ double get_real_secs(void) const;
+
+ /*!
+ * Get the whole/integer part of the time in seconds.
+ * \return the whole/integer seconds
+ */
+ time_t get_full_secs(void) const;
+
+ /*!
+ * Get the fractional part of the time in seconds.
+ * \return the fractional seconds
+ */
+ double get_frac_secs(void) const;
+
+ //! Implement addable interface
+ time_spec_t &operator+=(const time_spec_t &);
+
+ //! Implement subtractable interface
+ time_spec_t &operator-=(const time_spec_t &);
+
+ //private time storage details
+ private: time_t _full_secs; double _frac_secs;
+ };
+
+ //! Implement equality_comparable interface
+ UHD_API bool operator==(const time_spec_t &, const time_spec_t &);
+
+ //! Implement less_than_comparable interface
+ UHD_API bool operator<(const time_spec_t &, const time_spec_t &);
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_TIME_SPEC_HPP */
diff --git a/host/include/uhd/types/tune_request.hpp b/host/include/uhd/types/tune_request.hpp
new file mode 100644
index 000000000..9c498bfe9
--- /dev/null
+++ b/host/include/uhd/types/tune_request.hpp
@@ -0,0 +1,95 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_TUNE_REQUEST_HPP
+#define INCLUDED_UHD_TYPES_TUNE_REQUEST_HPP
+
+#include <uhd/config.hpp>
+
+namespace uhd{
+
+ /*!
+ * A tune request instructs the implementation how to tune the RF chain.
+ * The policies can be used to select automatic tuning or
+ * fined control over the daughterboard IF and DSP tuning.
+ * Not all combinations of policies are applicable.
+ * Convenience constructors are supplied for most use cases.
+ */
+ struct UHD_API tune_request_t{
+ /*!
+ * Make a new tune request for a particular center frequency.
+ * Use an automatic policy for the RF and DSP frequency
+ * to tune the chain as close as possible to the target frequency.
+ * \param target_freq the target frequency in Hz
+ */
+ tune_request_t(double target_freq = 0);
+
+ /*!
+ * Make a new tune request for a particular center frequency.
+ * Use a manual policy for the RF frequency,
+ * and an automatic policy for the DSP frequency,
+ * to tune the chain as close as possible to the target frequency.
+ * \param target_freq the target frequency in Hz
+ * \param lo_off the LO offset frequency in Hz
+ */
+ tune_request_t(double target_freq, double lo_off);
+
+ //! Policy options for tunable elements in the RF chain.
+ enum policy_t {
+ //! Do not set this argument, use current setting.
+ POLICY_NONE = int('N'),
+ //! Automatically determine the argument's value.
+ POLICY_AUTO = int('A'),
+ //! Use the argument's value for the setting.
+ POLICY_MANUAL = int('M')
+ };
+
+ /*!
+ * The target frequency of the overall chain in Hz.
+ * Set this even if all policies are set to manual.
+ */
+ double target_freq;
+
+ /*!
+ * The policy for the RF frequency.
+ * Automatic behavior: the target frequency + default LO offset.
+ */
+ policy_t rf_freq_policy;
+
+ /*!
+ * The RF frequency in Hz.
+ * Set when the policy is set to manual.
+ */
+ double rf_freq;
+
+ /*!
+ * The policy for the DSP frequency.
+ * Automatic behavior: the difference between the target and IF.
+ */
+ policy_t dsp_freq_policy;
+
+ /*!
+ * The DSP frequency in Hz.
+ * Set when the policy is set to manual.
+ */
+ double dsp_freq;
+
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_TUNE_REQUEST_HPP */
diff --git a/host/include/uhd/types/tune_result.hpp b/host/include/uhd/types/tune_result.hpp
new file mode 100644
index 000000000..e51473085
--- /dev/null
+++ b/host/include/uhd/types/tune_result.hpp
@@ -0,0 +1,44 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_TUNE_RESULT_HPP
+#define INCLUDED_UHD_TYPES_TUNE_RESULT_HPP
+
+#include <uhd/config.hpp>
+#include <string>
+
+namespace uhd{
+
+ /*!
+ * The tune result struct holds result of a 2-phase tuning.
+ */
+ struct UHD_API tune_result_t{
+ double target_rf_freq;
+ double actual_rf_freq;
+ double target_dsp_freq;
+ double actual_dsp_freq;
+
+ /*!
+ * Create a pretty print string for this tune result struct.
+ * \return the printable string
+ */
+ std::string to_pp_string(void) const;
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_TUNE_RESULT_HPP */
diff --git a/host/include/uhd/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt
new file mode 100644
index 000000000..ba38a67ea
--- /dev/null
+++ b/host/include/uhd/usrp/CMakeLists.txt
@@ -0,0 +1,40 @@
+#
+# Copyright 2010-2011 Ettus Research LLC
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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, see <http://www.gnu.org/licenses/>.
+#
+
+
+INSTALL(FILES
+
+ #### dboard headers ###
+ dboard_base.hpp
+ dboard_eeprom.hpp
+ dboard_id.hpp
+ dboard_iface.hpp
+ dboard_manager.hpp
+
+ ### utilities ###
+ gps_ctrl.hpp
+ mboard_eeprom.hpp
+ subdev_spec.hpp
+
+ ### interfaces ###
+ single_usrp.hpp
+ multi_usrp.hpp
+ mboard_iface.hpp
+
+ DESTINATION ${INCLUDE_DIR}/uhd/usrp
+ COMPONENT headers
+)
diff --git a/host/include/uhd/usrp/dboard_base.hpp b/host/include/uhd/usrp/dboard_base.hpp
new file mode 100644
index 000000000..7e9557a95
--- /dev/null
+++ b/host/include/uhd/usrp/dboard_base.hpp
@@ -0,0 +1,154 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_USRP_DBOARD_BASE_HPP
+#define INCLUDED_UHD_USRP_DBOARD_BASE_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/wax.hpp>
+#include <uhd/utils/pimpl.hpp>
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
+#include <uhd/usrp/dboard_id.hpp>
+#include <uhd/usrp/dboard_iface.hpp>
+
+namespace uhd{ namespace usrp{
+
+ /*!
+ * Possible subdev connection types:
+ *
+ * A complex subdevice is physically connected to both channels,
+ * which may be connected in one of two ways: IQ or QI (swapped).
+ *
+ * A real subdevice is only physically connected one channel,
+ * either only the I channel or only the Q channel.
+ */
+ enum subdev_conn_t{
+ SUBDEV_CONN_COMPLEX_IQ = 'C',
+ SUBDEV_CONN_COMPLEX_QI = 'c',
+ SUBDEV_CONN_REAL_I = 'R',
+ SUBDEV_CONN_REAL_Q = 'r'
+ };
+
+ /*!
+ * Possible device subdev properties
+ */
+ enum subdev_prop_t{
+ SUBDEV_PROP_NAME, //ro, std::string
+ SUBDEV_PROP_OTHERS, //ro, prop_names_t
+ SUBDEV_PROP_SENSOR, //ro, sensor_value_t
+ SUBDEV_PROP_SENSOR_NAMES, //ro, prop_names_t
+ SUBDEV_PROP_GAIN, //rw, double
+ SUBDEV_PROP_GAIN_RANGE, //ro, gain_range_t
+ SUBDEV_PROP_GAIN_NAMES, //ro, prop_names_t
+ SUBDEV_PROP_FREQ, //rw, double
+ SUBDEV_PROP_FREQ_RANGE, //ro, freq_range_t
+ SUBDEV_PROP_ANTENNA, //rw, std::string
+ SUBDEV_PROP_ANTENNA_NAMES, //ro, prop_names_t
+ SUBDEV_PROP_CONNECTION, //ro, subdev_conn_t
+ SUBDEV_PROP_ENABLED, //rw, bool
+ SUBDEV_PROP_USE_LO_OFFSET, //ro, bool
+ SUBDEV_PROP_BANDWIDTH //rw, double
+ };
+
+/*!
+ * A daughter board dboard_base class for all dboards.
+ * Only other dboard dboard_base classes should inherit this.
+ */
+class UHD_API dboard_base : boost::noncopyable{
+public:
+ typedef boost::shared_ptr<dboard_base> sptr;
+ /*!
+ * An opaque type for the dboard constructor args.
+ * Derived classes should pass the args into the base class,
+ * but should not deal with the internals of the args.
+ */
+ typedef void * ctor_args_t;
+
+ //structors
+ dboard_base(ctor_args_t);
+ virtual ~dboard_base(void);
+
+ //interface
+ virtual void rx_get(const wax::obj &key, wax::obj &val) = 0;
+ virtual void rx_set(const wax::obj &key, const wax::obj &val) = 0;
+ virtual void tx_get(const wax::obj &key, wax::obj &val) = 0;
+ virtual void tx_set(const wax::obj &key, const wax::obj &val) = 0;
+
+protected:
+ std::string get_subdev_name(void);
+ dboard_iface::sptr get_iface(void);
+ dboard_id_t get_rx_id(void);
+ dboard_id_t get_tx_id(void);
+
+private:
+ UHD_PIMPL_DECL(impl) _impl;
+};
+
+/*!
+ * A xcvr daughter board implements rx and tx methods
+ * Sub classes for xcvr boards should inherit this.
+ */
+class UHD_API xcvr_dboard_base : public dboard_base{
+public:
+ /*!
+ * Create a new xcvr dboard object, override in subclasses.
+ */
+ xcvr_dboard_base(ctor_args_t);
+
+ virtual ~xcvr_dboard_base(void);
+};
+
+/*!
+ * A rx daughter board only implements rx methods.
+ * Sub classes for rx-only boards should inherit this.
+ */
+class UHD_API rx_dboard_base : public dboard_base{
+public:
+ /*!
+ * Create a new rx dboard object, override in subclasses.
+ */
+ rx_dboard_base(ctor_args_t);
+
+ virtual ~rx_dboard_base(void);
+
+ //override here so the derived classes cannot
+ void tx_get(const wax::obj &key, wax::obj &val);
+ void tx_set(const wax::obj &key, const wax::obj &val);
+};
+
+/*!
+ * A tx daughter board only implements tx methods.
+ * Sub classes for rx-only boards should inherit this.
+ */
+class UHD_API tx_dboard_base : public dboard_base{
+public:
+ /*!
+ * Create a new rx dboard object, override in subclasses.
+ */
+ tx_dboard_base(ctor_args_t);
+
+ virtual ~tx_dboard_base(void);
+
+ //override here so the derived classes cannot
+ void rx_get(const wax::obj &key, wax::obj &val);
+ void rx_set(const wax::obj &key, const wax::obj &val);
+};
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_USRP_DBOARD_BASE_HPP */
diff --git a/host/include/uhd/usrp/dboard_eeprom.hpp b/host/include/uhd/usrp/dboard_eeprom.hpp
new file mode 100644
index 000000000..f0190e233
--- /dev/null
+++ b/host/include/uhd/usrp/dboard_eeprom.hpp
@@ -0,0 +1,59 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_USRP_DBOARD_EEPROM_HPP
+#define INCLUDED_UHD_USRP_DBOARD_EEPROM_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/usrp/dboard_id.hpp>
+#include <uhd/types/serial.hpp>
+#include <string>
+
+namespace uhd{ namespace usrp{
+
+struct UHD_API dboard_eeprom_t{
+
+ //! The ID for the daughterboard type
+ dboard_id_t id;
+
+ //! The unique serial number
+ std::string serial;
+
+ /*!
+ * Create an empty dboard eeprom struct.
+ */
+ dboard_eeprom_t(void);
+
+ /*!
+ * Load the object with bytes from the eeprom.
+ * \param iface the serial interface with i2c
+ * \param addr the i2c address for the eeprom
+ */
+ void load(i2c_iface &iface, boost::uint8_t addr);
+
+ /*!
+ * Store the object to bytes in the eeprom.
+ * \param iface the serial interface with i2c
+ * \param addr the i2c address for the eeprom
+ */
+ void store(i2c_iface &iface, boost::uint8_t addr) const;
+
+};
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_USRP_DBOARD_EEPROM_HPP */
diff --git a/host/include/uhd/usrp/dboard_id.hpp b/host/include/uhd/usrp/dboard_id.hpp
new file mode 100644
index 000000000..1fda8182e
--- /dev/null
+++ b/host/include/uhd/usrp/dboard_id.hpp
@@ -0,0 +1,96 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_USRP_DBOARD_ID_HPP
+#define INCLUDED_UHD_USRP_DBOARD_ID_HPP
+
+#include <uhd/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/operators.hpp>
+#include <string>
+
+namespace uhd{ namespace usrp{
+
+ class UHD_API dboard_id_t : boost::equality_comparable<dboard_id_t>{
+ public:
+ /*!
+ * Create a dboard id from an integer.
+ * \param id the integer representation
+ */
+ dboard_id_t(boost::uint16_t id = 0xffff);
+
+ /*!
+ * Obtain a dboard id that represents no dboard.
+ * \return the dboard id with the 0xffff id.
+ */
+ static dboard_id_t none(void);
+
+ /*!
+ * Create a new dboard id from an integer representation.
+ * \param uint16 an unsigned 16 bit integer
+ * \return a new dboard id containing the integer
+ */
+ static dboard_id_t from_uint16(boost::uint16_t uint16);
+
+ /*!
+ * Get the dboard id represented as an integer.
+ * \return an unsigned 16 bit integer representation
+ */
+ boost::uint16_t to_uint16(void) const;
+
+ /*!
+ * Create a new dboard id from a string representation.
+ * If the string has a 0x prefix, it will be parsed as hex.
+ * \param string a numeric string, possibly hex
+ * \return a new dboard id containing the integer
+ */
+ static dboard_id_t from_string(const std::string &string);
+
+ /*!
+ * Get the dboard id represented as an integer.
+ * \return a hex string representation with 0x prefix
+ */
+ std::string to_string(void) const;
+
+ /*!
+ * Get the dboard id represented as a canonical name.
+ * \return the canonical string representation
+ */
+ std::string to_cname(void) const;
+
+ /*!
+ * Get the pretty print representation of this dboard id.
+ * \return a string with the dboard name and id number
+ */
+ std::string to_pp_string(void) const;
+
+ private:
+ boost::uint16_t _id; //internal representation
+ };
+
+ /*!
+ * Comparator operator overloaded for dboard ids.
+ * The boost::equality_comparable provides the !=.
+ * \param lhs the dboard id to the left of the operator
+ * \param rhs the dboard id to the right of the operator
+ * \return true when the dboard ids are equal
+ */
+ UHD_API bool operator==(const dboard_id_t &lhs, const dboard_id_t &rhs);
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_USRP_DBOARD_ID_HPP */
diff --git a/host/include/uhd/usrp/dboard_iface.hpp b/host/include/uhd/usrp/dboard_iface.hpp
new file mode 100644
index 000000000..ca5de5c2f
--- /dev/null
+++ b/host/include/uhd/usrp/dboard_iface.hpp
@@ -0,0 +1,298 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_USRP_DBOARD_IFACE_HPP
+#define INCLUDED_UHD_USRP_DBOARD_IFACE_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/utils/pimpl.hpp>
+#include <uhd/types/serial.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/cstdint.hpp>
+#include <string>
+#include <vector>
+
+namespace uhd{ namespace usrp{
+
+//! Special properties that differentiate this daughterboard slot
+struct UHD_API dboard_iface_special_props_t{
+ /*!
+ * Soft clock divider:
+ * When a motherboard cannot provided a divided dboard clock,
+ * it may provided a "soft" divided clock over an FPGA GPIO.
+ * The implementation must know the type of clock provided.
+ */
+ bool soft_clock_divider;
+
+ /*!
+ * Mangle i2c addresses:
+ * When i2c is shared across multiple daugterboard slots,
+ * the i2c addresses will be mangled on the secondary slot
+ * to avoid conflicts between slots in the i2c address space.
+ * The mangling is daguhterboard specific so the implementation
+ * needs to know whether it should use mangled addresses or not.
+ */
+ bool mangle_i2c_addrs;
+};
+
+/*!
+ * The daughter board dboard interface to be subclassed.
+ * A dboard instance interfaces with the mboard though this api.
+ * This interface provides i2c, spi, gpio, atr, aux dac/adc access.
+ * Each mboard should have a specially tailored iface for its dboard.
+ */
+class UHD_API dboard_iface : public uhd::i2c_iface{
+public:
+ typedef boost::shared_ptr<dboard_iface> sptr;
+ typedef dboard_iface_special_props_t special_props_t;
+
+ //! tells the host which unit to use
+ enum unit_t{
+ UNIT_RX = int('r'),
+ UNIT_TX = int('t')
+ };
+
+ //! possible atr registers
+ enum atr_reg_t{
+ ATR_REG_IDLE = int('i'),
+ ATR_REG_TX_ONLY = int('t'),
+ ATR_REG_RX_ONLY = int('r'),
+ ATR_REG_FULL_DUPLEX = int('f')
+ };
+
+ //! aux dac selection enums (per unit)
+ enum aux_dac_t{
+ AUX_DAC_A = int('a'),
+ AUX_DAC_B = int('b'),
+ AUX_DAC_C = int('c'),
+ AUX_DAC_D = int('d')
+ };
+
+ //! aux adc selection enums (per unit)
+ enum aux_adc_t{
+ AUX_ADC_A = int('a'),
+ AUX_ADC_B = int('b')
+ };
+
+ /*!
+ * Get special properties information for this dboard slot.
+ * This call helps the dboard code to handle implementation
+ * differences between different motherboards and dboard slots.
+ * \return the special properties struct
+ */
+ virtual special_props_t get_special_props(void) = 0;
+
+ /*!
+ * Write to an aux dac.
+ *
+ * \param unit which unit rx or tx
+ * \param which_dac the dac index 0, 1, 2, 3...
+ * \param value the value in volts
+ */
+ virtual void write_aux_dac(unit_t unit, aux_dac_t which_dac, double value) = 0;
+
+ /*!
+ * Read from an aux adc.
+ *
+ * \param unit which unit rx or tx
+ * \param which_adc the adc index 0, 1, 2, 3...
+ * \return the value in volts
+ */
+ virtual double read_aux_adc(unit_t unit, aux_adc_t which_adc) = 0;
+
+ /*!
+ * Set a daughterboard output pin control source.
+ *
+ * \param unit which unit rx or tx
+ * \param value 16-bits, 0=GPIO controlled, 1=ATR controlled
+ * \param mask 16-bits, 0=do not change, 1=change value
+ */
+ virtual void set_pin_ctrl(
+ unit_t unit, boost::uint16_t value, boost::uint16_t mask = 0xffff
+ );
+
+ /*!
+ * Read back the pin control setting.
+ *
+ * \param unit which unit rx or tx
+ * \return the 16-bit settings value
+ */
+ virtual boost::uint16_t get_pin_ctrl(unit_t unit);
+
+ /*!
+ * Set a daughterboard ATR register.
+ *
+ * \param unit which unit rx or tx
+ * \param reg which ATR register
+ * \param value 16-bits, 0=ATR output low, 1=ATR output high
+ * \param mask 16-bits, 0=do not change, 1=change value
+ */
+ virtual void set_atr_reg(
+ unit_t unit, atr_reg_t reg, boost::uint16_t value, boost::uint16_t mask = 0xffff
+ );
+
+ /*!
+ * Read back an ATR register setting.
+ *
+ * \param unit which unit rx or tx
+ * \param reg which ATR register
+ * \return the 16-bit settings value
+ */
+ virtual boost::uint16_t get_atr_reg(unit_t unit, atr_reg_t reg);
+
+ /*!
+ * Set daughterboard GPIO data direction setting.
+ *
+ * \param unit which unit rx or tx
+ * \param value 16-bits, 0=GPIO input, 1=GPIO output
+ * \param mask 16-bits, 0=do not change, 1=change value
+ */
+ virtual void set_gpio_ddr(
+ unit_t unit, boost::uint16_t value, boost::uint16_t mask = 0xffff
+ );
+
+ /*!
+ * Read back the GPIO data direction setting.
+ *
+ * \param unit which unit rx or tx
+ * \return the 16-bit settings value
+ */
+ virtual boost::uint16_t get_gpio_ddr(unit_t unit);
+
+ /*!
+ * Set daughterboard GPIO pin output setting.
+ *
+ * \param unit which unit rx or tx
+ * \param value 16-bits, 0=GPIO output low, 1=GPIO output high
+ * \param mask 16-bits, 0=do not change, 1=change value
+ */
+ virtual void set_gpio_out(
+ unit_t unit, boost::uint16_t value, boost::uint16_t mask = 0xffff
+ );
+
+ /*!
+ * Read back the GPIO pin output setting.
+ *
+ * \param unit which unit rx or tx
+ * \return the 16-bit settings value
+ */
+ virtual boost::uint16_t get_gpio_out(unit_t unit);
+
+ /*!
+ * Setup the GPIO debug mux.
+ *
+ * \param unit which unit rx or tx
+ * \param which which debug: 0, 1
+ */
+ virtual void set_gpio_debug(unit_t unit, int which) = 0;
+
+ /*!
+ * Read daughterboard GPIO pin values.
+ *
+ * \param unit which unit rx or tx
+ * \return the value of the gpio unit
+ */
+ virtual boost::uint16_t read_gpio(unit_t unit) = 0;
+
+ /*!
+ * Write data to SPI bus peripheral.
+ *
+ * \param unit which unit, rx or tx
+ * \param config configuration settings
+ * \param data the bits to write LSB first
+ * \param num_bits the number of bits in data
+ */
+ virtual void write_spi(
+ unit_t unit,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits
+ ) = 0;
+
+ /*!
+ * Read and write data to SPI bus peripheral.
+ *
+ * \param unit which unit, rx or tx
+ * \param config configuration settings
+ * \param data the bits to write LSB first
+ * \param num_bits the number of bits in data
+ * \return the data that was read
+ */
+ virtual boost::uint32_t read_write_spi(
+ unit_t unit,
+ const spi_config_t &config,
+ boost::uint32_t data,
+ size_t num_bits
+ ) = 0;
+
+ /*!
+ * Set the rate of a dboard clock.
+ *
+ * \param unit which unit rx or tx
+ * \param rate the clock rate in Hz
+ */
+ virtual void set_clock_rate(unit_t unit, double rate) = 0;
+
+ /*!
+ * Get the rate of a dboard clock.
+ *
+ * \param unit which unit rx or tx
+ * \return the clock rate in Hz
+ */
+ virtual double get_clock_rate(unit_t unit) = 0;
+
+ /*!
+ * Get a list of possible rates for the dboard clock.
+ *
+ * \param unit which unit rx or tx
+ * \return a list of clock rates in Hz
+ */
+ virtual std::vector<double> get_clock_rates(unit_t unit) = 0;
+
+ /*!
+ * Enable or disable a dboard clock.
+ *
+ * \param unit which unit rx or tx
+ * \param enb true for enabled
+ */
+ virtual void set_clock_enabled(unit_t unit, bool enb) = 0;
+
+ /*!
+ * Get the rate of the codec.
+ * For rx, this is the rate the ADC feeds the DSP.
+ * For tx, this is the rate the DSP feeds the DAC.
+ * \param unit which unit rx or tx
+ * \return the codec rate in Hz
+ */
+ virtual double get_codec_rate(unit_t unit) = 0;
+
+private:
+ UHD_PIMPL_DECL(impl) _impl;
+
+ virtual void _set_pin_ctrl(unit_t unit, boost::uint16_t value) = 0;
+ virtual void _set_atr_reg(unit_t unit, atr_reg_t reg, boost::uint16_t value) = 0;
+ virtual void _set_gpio_ddr(unit_t unit, boost::uint16_t value) = 0;
+ virtual void _set_gpio_out(unit_t unit, boost::uint16_t value) = 0;
+
+protected:
+ dboard_iface(void);
+
+};
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_USRP_DBOARD_IFACE_HPP */
diff --git a/host/include/uhd/usrp/dboard_manager.hpp b/host/include/uhd/usrp/dboard_manager.hpp
new file mode 100644
index 000000000..091769a5c
--- /dev/null
+++ b/host/include/uhd/usrp/dboard_manager.hpp
@@ -0,0 +1,102 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_USRP_DBOARD_MANAGER_HPP
+#define INCLUDED_UHD_USRP_DBOARD_MANAGER_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/property_tree.hpp>
+#include <uhd/utils/props.hpp>
+#include <uhd/usrp/dboard_base.hpp>
+#include <uhd/usrp/dboard_id.hpp>
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace uhd{ namespace usrp{
+
+/*!
+ * A daughter board subdev dboard_manager class.
+ * Create subdev instances for each subdev on a dboard.
+ * Provide wax::obj access to the subdevs inside.
+ */
+class UHD_API dboard_manager : boost::noncopyable{
+public:
+ typedef boost::shared_ptr<dboard_manager> sptr;
+
+ //! It does what it says...
+ static void populate_prop_tree_from_subdev(
+ property_tree::sptr subtree, wax::obj subdev
+ );
+
+ //dboard constructor (each dboard should have a ::make with this signature)
+ typedef dboard_base::sptr(*dboard_ctor_t)(dboard_base::ctor_args_t);
+
+ /*!
+ * Register a rx or tx dboard into the system.
+ * For single subdevice boards, omit subdev_names.
+ * \param dboard_id the dboard id (rx or tx)
+ * \param dboard_ctor the dboard constructor function pointer
+ * \param name the canonical name for the dboard represented
+ * \param subdev_names the names of the subdevs on this dboard
+ */
+ static void register_dboard(
+ const dboard_id_t &dboard_id,
+ dboard_ctor_t dboard_ctor,
+ const std::string &name,
+ const prop_names_t &subdev_names = prop_names_t(1, "0")
+ );
+
+ /*!
+ * Register an xcvr dboard into the system.
+ * For single subdevice boards, omit subdev_names.
+ * \param rx_dboard_id the rx unit dboard id
+ * \param tx_dboard_id the tx unit dboard id
+ * \param dboard_ctor the dboard constructor function pointer
+ * \param name the canonical name for the dboard represented
+ * \param subdev_names the names of the subdevs on this dboard
+ */
+ static void register_dboard(
+ const dboard_id_t &rx_dboard_id,
+ const dboard_id_t &tx_dboard_id,
+ dboard_ctor_t dboard_ctor,
+ const std::string &name,
+ const prop_names_t &subdev_names = prop_names_t(1, "0")
+ );
+
+ /*!
+ * Make a new dboard manager.
+ * \param rx_dboard_id the id of the rx dboard
+ * \param tx_dboard_id the id of the tx dboard
+ * \param iface the custom dboard interface
+ * \return an sptr to the new dboard manager
+ */
+ static sptr make(
+ dboard_id_t rx_dboard_id,
+ dboard_id_t tx_dboard_id,
+ dboard_iface::sptr iface
+ );
+
+ //dboard manager interface
+ virtual prop_names_t get_rx_subdev_names(void) = 0;
+ virtual prop_names_t get_tx_subdev_names(void) = 0;
+ virtual wax::obj get_rx_subdev(const std::string &subdev_name) = 0;
+ virtual wax::obj get_tx_subdev(const std::string &subdev_name) = 0;
+};
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_USRP_DBOARD_MANAGER_HPP */
diff --git a/host/include/uhd/usrp/gps_ctrl.hpp b/host/include/uhd/usrp/gps_ctrl.hpp
new file mode 100644
index 000000000..6ff00e03c
--- /dev/null
+++ b/host/include/uhd/usrp/gps_ctrl.hpp
@@ -0,0 +1,62 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_GPS_CTRL_HPP
+#define INCLUDED_GPS_CTRL_HPP
+
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include <boost/function.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <vector>
+#include <uhd/types/sensors.hpp>
+
+using namespace boost::posix_time;
+
+typedef boost::function<void(std::string)> gps_send_fn_t;
+typedef boost::function<std::string(void)> gps_recv_fn_t;
+
+class gps_ctrl : boost::noncopyable{
+public:
+ typedef boost::shared_ptr<gps_ctrl> sptr;
+
+ /*!
+ * Make a GPS config for Jackson Labs or generic NMEA GPS devices
+ */
+ static sptr make(gps_send_fn_t, gps_recv_fn_t);
+
+ /*!
+ * Retrieve the list of sensors this GPS object provides
+ */
+ virtual std::vector<std::string> get_sensors(void) = 0;
+
+ /*!
+ * Retrieve the named sensor
+ */
+ virtual uhd::sensor_value_t get_sensor(std::string key) = 0;
+
+ /*!
+ * Tell you if there's a supported GPS connected or not
+ * \return true if a supported GPS is connected
+ */
+ virtual bool gps_detected(void) = 0;
+
+ //TODO: other fun things you can do with a GPS.
+
+};
+
+#endif /* INCLUDED_GPS_CTRL_HPP */
diff --git a/host/include/uhd/usrp/mboard_eeprom.hpp b/host/include/uhd/usrp/mboard_eeprom.hpp
new file mode 100644
index 000000000..ea66bb2e0
--- /dev/null
+++ b/host/include/uhd/usrp/mboard_eeprom.hpp
@@ -0,0 +1,65 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_USRP_MBOARD_EEPROM_HPP
+#define INCLUDED_UHD_USRP_MBOARD_EEPROM_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/types/dict.hpp>
+#include <uhd/types/serial.hpp>
+#include <string>
+
+namespace uhd{ namespace usrp{
+
+ /*!
+ * The motherboard EEPROM object:
+ * Knows how to read and write the EEPROM for various USRPs.
+ * The class inherits from a string, string dictionary.
+ * Use the dictionary interface to get and set values.
+ * Commit to the EEPROM to save changed settings.
+ */
+ struct UHD_API mboard_eeprom_t : uhd::dict<std::string, std::string>{
+
+ //! Possible EEPROM maps types
+ enum map_type{
+ MAP_N100,
+ MAP_B000,
+ MAP_E100
+ };
+
+ //! Make a new empty mboard eeprom
+ mboard_eeprom_t(void);
+
+ /*!
+ * Make a new mboard EEPROM handler.
+ * \param iface the interface to i2c
+ * \param map the map type enum
+ */
+ mboard_eeprom_t(i2c_iface &iface, map_type map);
+
+ /*!
+ * Write the contents of this object to the EEPROM.
+ * \param iface the interface to i2c
+ * \param map the map type enum
+ */
+ void commit(i2c_iface &iface, map_type map) const;
+
+ };
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_USRP_MBOARD_EEPROM_HPP */
diff --git a/host/include/uhd/usrp/mboard_iface.hpp b/host/include/uhd/usrp/mboard_iface.hpp
new file mode 100644
index 000000000..bbee8f2de
--- /dev/null
+++ b/host/include/uhd/usrp/mboard_iface.hpp
@@ -0,0 +1,71 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_USRP_MBOARD_IFACE_HPP
+#define INCLUDED_UHD_USRP_MBOARD_IFACE_HPP
+
+#include <uhd/types/serial.hpp>
+#include <uhd/usrp/mboard_eeprom.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include <boost/cstdint.hpp>
+#include <utility>
+#include <string>
+
+namespace uhd{ namespace usrp{
+
+/*!
+ * The mboard interface class:
+ * Provides a set of functions to implementation layer.
+ * Including spi, peek, poke, control...
+ */
+class mboard_iface : public uhd::i2c_iface, public uhd::spi_iface, public uhd::uart_iface {
+public:
+ typedef boost::shared_ptr<mboard_iface> sptr;
+ /*!
+ * Write a register (32 bits)
+ * \param addr the address
+ * \param data the 32bit data
+ */
+ virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0;
+
+ /*!
+ * Read a register (32 bits)
+ * \param addr the address
+ * \return the 32bit data
+ */
+ virtual boost::uint32_t peek32(boost::uint32_t addr) = 0;
+
+ /*!
+ * Write a register (16 bits)
+ * \param addr the address
+ * \param data the 16bit data
+ */
+ virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0;
+
+ /*!
+ * Read a register (16 bits)
+ * \param addr the address
+ * \return the 16bit data
+ */
+ virtual boost::uint16_t peek16(boost::uint32_t addr) = 0;
+
+};
+
+}}
+
+#endif //INCLUDED_UHD_USRP_DBOARD_IFACE_HPP
diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp
new file mode 100644
index 000000000..00d5dfe7c
--- /dev/null
+++ b/host/include/uhd/usrp/multi_usrp.hpp
@@ -0,0 +1,654 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_USRP_MULTI_USRP_HPP
+#define INCLUDED_UHD_USRP_MULTI_USRP_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/device.hpp>
+#include <uhd/types/ranges.hpp>
+#include <uhd/types/stream_cmd.hpp>
+#include <uhd/types/clock_config.hpp>
+#include <uhd/types/tune_request.hpp>
+#include <uhd/types/tune_result.hpp>
+#include <uhd/types/sensors.hpp>
+#include <uhd/usrp/subdev_spec.hpp>
+#include <uhd/usrp/dboard_iface.hpp>
+#include <uhd/usrp/mboard_iface.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/utility.hpp>
+#include <vector>
+
+namespace uhd{ namespace usrp{
+
+/*!
+ * The Multi-USRP device class:
+ *
+ * This class facilitates ease-of-use for most use-case scenarios.
+ * The wrapper provides convenience functions to tune the devices,
+ * set the dboard gains, antennas, filters, and other properties.
+ * This class can be used to interface with a single USRP with
+ * one or more channels, or multiple USRPs in a homogeneous setup.
+ * All members take an optional parameter for board number or channel number.
+ * In the single device, single channel case, these parameters can be unspecified.
+ *
+ * When using a single device with multiple channels:
+ * - Channel mapping is determined by the subdevice specifications
+ * - All channels share a common RX sample rate
+ * - All channels share a common TX sample rate
+ *
+ * When using multiple devices in a configuration:
+ * - Channel mapping is determined by the device address arguments
+ * - All boards share a common RX sample rate
+ * - All boards share a common TX sample rate
+ * - All boards share a common RX subdevice specification size
+ * - All boards share a common TX subdevice specification size
+ * - All boards must have synchronized times (see the set_time_*() calls)
+ *
+ * Example to setup channel mapping for multiple devices:
+ * <pre>
+ *
+ * //create a multi_usrp with two boards in the configuration
+ * device_addr_t dev_addr;
+ * dev_addr["addr0"] = "192.168.10.2"
+ * dev_addr["addr1"] = "192.168.10.3";
+ * multi_usrp::sptr dev = multi_usrp::make(dev_addr);
+ *
+ * //set the board on 10.2 to use the A RX subdevice (RX channel 0)
+ * dev->set_rx_subdev_spec("A:A", 0);
+ *
+ * //set the board on 10.3 to use the B RX subdevice (RX channel 1)
+ * dev->set_rx_subdev_spec("A:B", 1);
+ *
+ * //set both boards to use the AB TX subdevice (TX channels 0 and 1)
+ * dev->set_tx_subdev_spec("A:AB", multi_usrp::ALL_MBOARDS);
+ *
+ * //now that all the channels are mapped, continue with configuration...
+ *
+ * </pre>
+ */
+class UHD_API multi_usrp : boost::noncopyable{
+public:
+ typedef boost::shared_ptr<multi_usrp> sptr;
+
+ //! A wildcard motherboard index
+ static const size_t ALL_MBOARDS = size_t(~0);
+
+ //! A wildcard channel index
+ static const size_t ALL_CHANS = size_t(~0);
+
+ //! A wildcard gain element name
+ static const std::string ALL_GAINS;
+
+ /*!
+ * Make a new multi usrp from the device address.
+ * \param dev_addr the device address
+ * \return a new single usrp object
+ */
+ static sptr make(const device_addr_t &dev_addr);
+
+ /*!
+ * Get the underlying device object.
+ * This is needed to get access to the streaming API and properties.
+ * \return the device object within this single usrp
+ */
+ virtual device::sptr get_device(void) = 0;
+
+ /*******************************************************************
+ * Mboard methods
+ ******************************************************************/
+
+ /*!
+ * Set the master clock rate.
+ * This controls the rate of the clock that feeds the FPGA DSP.
+ * On some devices, this re-tunes the clock to the specified rate.
+ * If the specified rate is not available, this method will throw.
+ * On other devices, this method notifies the software of the rate,
+ * but requires the the user has made the necessary hardware change.
+ * \param rate the new master clock rate in Hz
+ * \param mboard the motherboard index 0 to M-1
+ */
+ virtual void set_master_clock_rate(double rate, size_t mboard = ALL_MBOARDS) = 0;
+
+ /*!
+ * Get the master clock rate.
+ * \param mboard the motherboard index 0 to M-1
+ * \return the master clock rate in Hz.
+ */
+ virtual double get_master_clock_rate(size_t mboard = 0) = 0;
+
+ /*!
+ * Get a printable summary for this USRP configuration.
+ * \return a printable string
+ */
+ virtual std::string get_pp_string(void) = 0;
+
+ /*!
+ * Get canonical name for this USRP motherboard.
+ * \param mboard which motherboard to query
+ * \return a string representing the name
+ */
+ virtual std::string get_mboard_name(size_t mboard = 0) = 0;
+
+ /*!
+ * Get the current time in the usrp time registers.
+ * \param mboard which motherboard to query
+ * \return a timespec representing current usrp time
+ */
+ virtual time_spec_t get_time_now(size_t mboard = 0) = 0;
+
+ /*!
+ * Get the time when the last pps pulse occured.
+ * \param mboard which motherboard to query
+ * \return a timespec representing the last pps
+ */
+ virtual time_spec_t get_time_last_pps(size_t mboard = 0) = 0;
+
+ /*!
+ * Sets the time registers on the usrp immediately.
+ *
+ * If only one MIMO master is present in your configuration, set_time_now is
+ * safe to use because the slave's time automatically follows the master's time.
+ * Otherwise, this call cannot set the time synchronously across multiple devices.
+ * Please use the set_time_next_pps or set_time_unknown_pps calls with a PPS signal.
+ *
+ * \param time_spec the time to latch into the usrp device
+ * \param mboard the motherboard index 0 to M-1
+ */
+ virtual void set_time_now(const time_spec_t &time_spec, size_t mboard = ALL_MBOARDS) = 0;
+
+ /*!
+ * Set the time registers on the usrp at the next pps tick.
+ * The values will not be latched in until the pulse occurs.
+ * It is recommended that the user sleep(1) after calling to ensure
+ * that the time registers will be in a known state prior to use.
+ *
+ * Note: Because this call sets the time on the "next" pps,
+ * the seconds in the time spec should be current seconds + 1.
+ *
+ * \param time_spec the time to latch into the usrp device
+ */
+ virtual void set_time_next_pps(const time_spec_t &time_spec) = 0;
+
+ /*!
+ * Synchronize the times across all motherboards in this configuration.
+ * Use this method to sync the times when the edge of the PPS is unknown.
+ *
+ * Ex: Host machine is not attached to serial port of GPSDO
+ * and can therefore not query the GPSDO for the PPS edge.
+ *
+ * This is a 2-step process, and will take at most 2 seconds to complete.
+ * Upon completion, the times will be synchronized to the time provided.
+ *
+ * - Step1: wait for the last pps time to transition to catch the edge
+ * - Step2: set the time at the next pps (synchronous for all boards)
+ *
+ * \param time_spec the time to latch at the next pps after catching the edge
+ */
+ virtual void set_time_unknown_pps(const time_spec_t &time_spec) = 0;
+
+ /*!
+ * Are the times across all motherboards in this configuration synchronized?
+ * Checks that all time registers are approximately close but not exact,
+ * given that the RTT may varying for a control packet transaction.
+ * \return true when all motherboards time registers are in sync
+ */
+ virtual bool get_time_synchronized(void) = 0;
+
+ /*!
+ * Issue a stream command to the usrp device.
+ * This tells the usrp to send samples into the host.
+ * See the documentation for stream_cmd_t for more info.
+ *
+ * With multiple devices, the first stream command in a chain of commands
+ * should have a time spec in the near future and stream_now = false;
+ * to ensure that the packets can be aligned by their time specs.
+ *
+ * \param stream_cmd the stream command to issue
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd, size_t chan = ALL_CHANS) = 0;
+
+ /*!
+ * Set the clock configuration for the usrp device.
+ * This tells the usrp how to get a 10Mhz reference and PPS clock.
+ * See the documentation for clock_config_t for more info.
+ * \param clock_config the clock configuration to set
+ * \param mboard which motherboard to set the config
+ */
+ virtual void set_clock_config(const clock_config_t &clock_config, size_t mboard = ALL_MBOARDS) = 0;
+
+ /*!
+ * Get the number of USRP motherboards in this configuration.
+ */
+ virtual size_t get_num_mboards(void) = 0;
+
+ /*!
+ * Get a motherboard sensor value.
+ * \param name the name of the sensor
+ * \param mboard the motherboard index 0 to M-1
+ * \return a sensor value object
+ */
+ virtual sensor_value_t get_mboard_sensor(const std::string &name, size_t mboard = 0) = 0;
+
+ /*!
+ * Get a list of possible motherboard sensor names.
+ * \param mboard the motherboard index 0 to M-1
+ * \return a vector of sensor names
+ */
+ virtual std::vector<std::string> get_mboard_sensor_names(size_t mboard = 0) = 0;
+
+ /*!
+ * Get a handle to the mboard_iface object which controls peripheral access.
+ * \return a mboard_iface::sptr object
+ */
+ virtual mboard_iface::sptr get_mboard_iface(size_t mboard) = 0;
+
+ /*******************************************************************
+ * RX methods
+ ******************************************************************/
+ /*!
+ * Set the RX subdevice specification:
+ * The subdev spec maps a physical part of a daughter-board to a channel number.
+ * Set the subdev spec before calling into any methods with a channel number.
+ * The subdev spec must be the same size across all motherboards.
+ * \param spec the new subdevice specification
+ * \param mboard the motherboard index 0 to M-1
+ */
+ virtual void set_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec, size_t mboard = ALL_MBOARDS) = 0;
+
+ /*!
+ * Get the RX subdevice specification.
+ * \param mboard the motherboard index 0 to M-1
+ * \return the subdevice specification in use
+ */
+ virtual uhd::usrp::subdev_spec_t get_rx_subdev_spec(size_t mboard = 0) = 0;
+
+ /*!
+ * Get the number of RX channels in this configuration.
+ * This is the number of USRPs times the number of RX channels per board,
+ * where the number of RX channels per board is homogeneous among all USRPs.
+ */
+ virtual size_t get_rx_num_channels(void) = 0;
+
+ /*!
+ * Get the name of the RX subdevice.
+ * \param chan the channel index 0 to N-1
+ * \return the subdevice name
+ */
+ virtual std::string get_rx_subdev_name(size_t chan = 0) = 0;
+
+ /*!
+ * Set the RX sample rate.
+ * \param rate the rate in Sps
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_rx_rate(double rate, size_t chan = ALL_CHANS) = 0;
+
+ /*!
+ * Gets the RX sample rate.
+ * \param chan the channel index 0 to N-1
+ * \return the rate in Sps
+ */
+ virtual double get_rx_rate(size_t chan = 0) = 0;
+
+ /*!
+ * Set the RX center frequency.
+ * \param tune_request tune request instructions
+ * \param chan the channel index 0 to N-1
+ * \return a tune result object
+ */
+ virtual tune_result_t set_rx_freq(
+ const tune_request_t &tune_request, size_t chan = 0
+ ) = 0;
+
+ /*!
+ * Get the RX center frequency.
+ * \param chan the channel index 0 to N-1
+ * \return the frequency in Hz
+ */
+ virtual double get_rx_freq(size_t chan = 0) = 0;
+
+ /*!
+ * Get the RX center frequency range.
+ * \param chan the channel index 0 to N-1
+ * \return a frequency range object
+ */
+ virtual freq_range_t get_rx_freq_range(size_t chan = 0) = 0;
+
+ /*!
+ * Set the RX gain value for the specified gain element.
+ * For an empty name, distribute across all gain elements.
+ * \param gain the gain in dB
+ * \param name the name of the gain element
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_rx_gain(double gain, const std::string &name, size_t chan = 0) = 0;
+
+ //! A convenience wrapper for setting overall RX gain
+ void set_rx_gain(double gain, size_t chan = 0){
+ return this->set_rx_gain(gain, ALL_GAINS, chan);
+ }
+
+ /*!
+ * Get the RX gain value for the specified gain element.
+ * For an empty name, sum across all gain elements.
+ * \param name the name of the gain element
+ * \param chan the channel index 0 to N-1
+ * \return the gain in dB
+ */
+ virtual double get_rx_gain(const std::string &name, size_t chan = 0) = 0;
+
+ //! A convenience wrapper for getting overall RX gain
+ double get_rx_gain(size_t chan = 0){
+ return this->get_rx_gain(ALL_GAINS, chan);
+ }
+
+ /*!
+ * Get the RX gain range for the specified gain element.
+ * For an empty name, calculate the overall gain range.
+ * \param name the name of the gain element
+ * \param chan the channel index 0 to N-1
+ * \return a gain range object
+ */
+ virtual gain_range_t get_rx_gain_range(const std::string &name, size_t chan = 0) = 0;
+
+ //! A convenience wrapper for getting overall RX gain range
+ gain_range_t get_rx_gain_range(size_t chan = 0){
+ return this->get_rx_gain_range(ALL_GAINS, chan);
+ }
+
+ /*!
+ * Get the names of the gain elements in the RX chain.
+ * Gain elements are ordered from antenna to FPGA.
+ * \param chan the channel index 0 to N-1
+ * \return a vector of gain element names
+ */
+ virtual std::vector<std::string> get_rx_gain_names(size_t chan = 0) = 0;
+
+ /*!
+ * Select the RX antenna on the subdevice.
+ * \param ant the antenna name
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_rx_antenna(const std::string &ant, size_t chan = 0) = 0;
+
+ /*!
+ * Get the selected RX antenna on the subdevice.
+ * \param chan the channel index 0 to N-1
+ * \return the antenna name
+ */
+ virtual std::string get_rx_antenna(size_t chan = 0) = 0;
+
+ /*!
+ * Get a list of possible RX antennas on the subdevice.
+ * \param chan the channel index 0 to N-1
+ * \return a vector of antenna names
+ */
+ virtual std::vector<std::string> get_rx_antennas(size_t chan = 0) = 0;
+
+ /*!
+ * Get the locked status of the LO on the subdevice.
+ * \param chan the channel index 0 to N-1
+ * \return true for locked
+ */
+ UHD_DEPRECATED bool get_rx_lo_locked(size_t chan = 0){
+ return this->get_rx_sensor("lo_locked", chan).to_bool();
+ }
+
+ /*!
+ * Set the RX bandwidth on the subdevice.
+ * \param bandwidth the bandwidth in Hz
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_rx_bandwidth(double bandwidth, size_t chan = 0) = 0;
+
+ /*!
+ * Get the RX bandwidth on the subdevice.
+ * \param chan the channel index 0 to N-1
+ * \return the bandwidth in Hz
+ */
+ virtual double get_rx_bandwidth(size_t chan = 0) = 0;
+
+ /*!
+ * Read the RSSI value on the RX subdevice.
+ * \param chan the channel index 0 to N-1
+ * \return the rssi in dB
+ * \throw exception if RSSI readback not supported
+ */
+ UHD_DEPRECATED double read_rssi(size_t chan = 0){
+ return this->get_rx_sensor("rssi", chan).to_real();
+ }
+
+ /*!
+ * Get the dboard interface object for the RX subdevice.
+ * The dboard interface gives access to GPIOs, SPI, I2C, low-speed ADC and DAC.
+ * Use at your own risk!
+ * \param chan the channel index 0 to N-1
+ * \return the dboard interface sptr
+ */
+ virtual dboard_iface::sptr get_rx_dboard_iface(size_t chan = 0) = 0;
+
+ /*!
+ * Get an RX subdevice sensor value.
+ * \param name the name of the sensor
+ * \param chan the channel index 0 to N-1
+ * \return a sensor value object
+ */
+ virtual sensor_value_t get_rx_sensor(const std::string &name, size_t chan = 0) = 0;
+
+ /*!
+ * Get a list of possible RX subdevice sensor names.
+ * \param chan the channel index 0 to N-1
+ * \return a vector of sensor names
+ */
+ virtual std::vector<std::string> get_rx_sensor_names(size_t chan = 0) = 0;
+
+ /*******************************************************************
+ * TX methods
+ ******************************************************************/
+ /*!
+ * Set the TX subdevice specification:
+ * The subdev spec maps a physical part of a daughter-board to a channel number.
+ * Set the subdev spec before calling into any methods with a channel number.
+ * The subdev spec must be the same size across all motherboards.
+ * \param spec the new subdevice specification
+ * \param mboard the motherboard index 0 to M-1
+ */
+ virtual void set_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec, size_t mboard = ALL_MBOARDS) = 0;
+
+ /*!
+ * Get the TX subdevice specification.
+ * \param mboard the motherboard index 0 to M-1
+ * \return the subdevice specification in use
+ */
+ virtual uhd::usrp::subdev_spec_t get_tx_subdev_spec(size_t mboard = 0) = 0;
+
+ /*!
+ * Get the number of TX channels in this configuration.
+ * This is the number of USRPs times the number of TX channels per board,
+ * where the number of TX channels per board is homogeneous among all USRPs.
+ */
+ virtual size_t get_tx_num_channels(void) = 0;
+
+ /*!
+ * Get the name of the TX subdevice.
+ * \param chan the channel index 0 to N-1
+ * \return the subdevice name
+ */
+ virtual std::string get_tx_subdev_name(size_t chan = 0) = 0;
+
+ /*!
+ * Set the TX sample rate.
+ * \param rate the rate in Sps
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_tx_rate(double rate, size_t chan = ALL_CHANS) = 0;
+
+ /*!
+ * Gets the TX sample rate.
+ * \param chan the channel index 0 to N-1
+ * \return the rate in Sps
+ */
+ virtual double get_tx_rate(size_t chan = 0) = 0;
+
+ /*!
+ * Set the TX center frequency.
+ * \param tune_request tune request instructions
+ * \param chan the channel index 0 to N-1
+ * \return a tune result object
+ */
+ virtual tune_result_t set_tx_freq(
+ const tune_request_t &tune_request, size_t chan = 0
+ ) = 0;
+
+ /*!
+ * Get the TX center frequency.
+ * \param chan the channel index 0 to N-1
+ * \return the frequency in Hz
+ */
+ virtual double get_tx_freq(size_t chan = 0) = 0;
+
+ /*!
+ * Get the TX center frequency range.
+ * \param chan the channel index 0 to N-1
+ * \return a frequency range object
+ */
+ virtual freq_range_t get_tx_freq_range(size_t chan = 0) = 0;
+
+ /*!
+ * Set the TX gain value for the specified gain element.
+ * For an empty name, distribute across all gain elements.
+ * \param gain the gain in dB
+ * \param name the name of the gain element
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_tx_gain(double gain, const std::string &name, size_t chan = 0) = 0;
+
+ //! A convenience wrapper for setting overall TX gain
+ void set_tx_gain(double gain, size_t chan = 0){
+ return this->set_tx_gain(gain, ALL_GAINS, chan);
+ }
+
+ /*!
+ * Get the TX gain value for the specified gain element.
+ * For an empty name, sum across all gain elements.
+ * \param name the name of the gain element
+ * \param chan the channel index 0 to N-1
+ * \return the gain in dB
+ */
+ virtual double get_tx_gain(const std::string &name, size_t chan = 0) = 0;
+
+ //! A convenience wrapper for getting overall TX gain
+ double get_tx_gain(size_t chan = 0){
+ return this->get_tx_gain(ALL_GAINS, chan);
+ }
+
+ /*!
+ * Get the TX gain range for the specified gain element.
+ * For an empty name, calculate the overall gain range.
+ * \param name the name of the gain element
+ * \param chan the channel index 0 to N-1
+ * \return a gain range object
+ */
+ virtual gain_range_t get_tx_gain_range(const std::string &name, size_t chan = 0) = 0;
+
+ //! A convenience wrapper for getting overall TX gain range
+ gain_range_t get_tx_gain_range(size_t chan = 0){
+ return this->get_tx_gain_range(ALL_GAINS, chan);
+ }
+
+ /*!
+ * Get the names of the gain elements in the TX chain.
+ * Gain elements are ordered from antenna to FPGA.
+ * \param chan the channel index 0 to N-1
+ * \return a vector of gain element names
+ */
+ virtual std::vector<std::string> get_tx_gain_names(size_t chan = 0) = 0;
+
+ /*!
+ * Select the TX antenna on the subdevice.
+ * \param ant the antenna name
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_tx_antenna(const std::string &ant, size_t chan = 0) = 0;
+
+ /*!
+ * Get the selected TX antenna on the subdevice.
+ * \param chan the channel index 0 to N-1
+ * \return the antenna name
+ */
+ virtual std::string get_tx_antenna(size_t chan = 0) = 0;
+
+ /*!
+ * Get a list of possible TX antennas on the subdevice.
+ * \param chan the channel index 0 to N-1
+ * \return a vector of antenna names
+ */
+ virtual std::vector<std::string> get_tx_antennas(size_t chan = 0) = 0;
+
+ /*!
+ * Get the locked status of the LO on the subdevice.
+ * \param chan the channel index 0 to N-1
+ * \return true for locked
+ */
+ UHD_DEPRECATED bool get_tx_lo_locked(size_t chan = 0){
+ return this->get_tx_sensor("lo_locked", chan).to_bool();
+ }
+
+ /*!
+ * Set the TX bandwidth on the subdevice.
+ * \param bandwidth the bandwidth in Hz
+ * \param chan the channel index 0 to N-1
+ */
+ virtual void set_tx_bandwidth(double bandwidth, size_t chan = 0) = 0;
+
+ /*!
+ * Get the TX bandwidth on the subdevice.
+ * \param chan the channel index 0 to N-1
+ * \return the bandwidth in Hz
+ */
+ virtual double get_tx_bandwidth(size_t chan = 0) = 0;
+
+ /*!
+ * Get the dboard interface object for the TX subdevice.
+ * The dboard interface gives access to GPIOs, SPI, I2C, low-speed ADC and DAC.
+ * Use at your own risk!
+ * \param chan the channel index 0 to N-1
+ * \return the dboard interface sptr
+ */
+ virtual dboard_iface::sptr get_tx_dboard_iface(size_t chan = 0) = 0;
+
+ /*!
+ * Get an TX subdevice sensor value.
+ * \param name the name of the sensor
+ * \param chan the channel index 0 to N-1
+ * \return a sensor value object
+ */
+ virtual sensor_value_t get_tx_sensor(const std::string &name, size_t chan = 0) = 0;
+
+ /*!
+ * Get a list of possible TX subdevice sensor names.
+ * \param chan the channel index 0 to N-1
+ * \return a vector of sensor names
+ */
+ virtual std::vector<std::string> get_tx_sensor_names(size_t chan = 0) = 0;
+};
+
+}}
+
+#endif /* INCLUDED_UHD_USRP_MULTI_USRP_HPP */
diff --git a/host/include/uhd/usrp/single_usrp.hpp b/host/include/uhd/usrp/single_usrp.hpp
new file mode 100644
index 000000000..0520db162
--- /dev/null
+++ b/host/include/uhd/usrp/single_usrp.hpp
@@ -0,0 +1,30 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_USRP_SINGLE_USRP_HPP
+#define INCLUDED_UHD_USRP_SINGLE_USRP_HPP
+
+#include <uhd/usrp/multi_usrp.hpp>
+
+namespace uhd{ namespace usrp{
+
+ //! Multi-USRP is a superset of Single-USRP
+ typedef multi_usrp single_usrp;
+
+}}
+
+#endif /* INCLUDED_UHD_USRP_SINGLE_USRP_HPP */
diff --git a/host/include/uhd/usrp/subdev_spec.hpp b/host/include/uhd/usrp/subdev_spec.hpp
new file mode 100644
index 000000000..62c1fc177
--- /dev/null
+++ b/host/include/uhd/usrp/subdev_spec.hpp
@@ -0,0 +1,91 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_USRP_SUBDEV_SPEC_HPP
+#define INCLUDED_UHD_USRP_SUBDEV_SPEC_HPP
+
+#include <uhd/config.hpp>
+#include <boost/operators.hpp>
+#include <vector>
+#include <string>
+
+namespace uhd{ namespace usrp{
+
+ /*!
+ * A subdevice specification (daughterboard slot, subdevice) name pairing.
+ */
+ struct UHD_API subdev_spec_pair_t : boost::equality_comparable<subdev_spec_pair_t>{
+ //! The daughterboard slot name
+ std::string db_name;
+
+ //! The subdevice name
+ std::string sd_name;
+
+ /*!
+ * Create a new subdevice specification pair from dboard and subdev names.
+ * \param db_name the name of a daughterboard slot
+ * \param sd_name the name of a subdevice on that daughterboard
+ */
+ subdev_spec_pair_t(
+ const std::string &db_name = "",
+ const std::string &sd_name = ""
+ );
+ };
+
+ //! overloaded comparison operator for subdev_spec_pair_t
+ UHD_API bool operator==(const subdev_spec_pair_t &, const subdev_spec_pair_t &);
+
+ /*!
+ * A list of (daughterboard slot name, subdevice name) pairs:
+ *
+ * A subdevice specification represents a list of subdevices on a motherboard.
+ * The subdevices specified may span across multiple daughterboards;
+ * Hence the need for a subdevice specification over a simple list of strings.
+ * Typically, the user will pass a RX or TX subdevice specification into the API,
+ * and the implementation will infer the channel configuration from the specification.
+ *
+ * The subdevice specification can be represented as a markup-string.
+ * The markup-string is a whitespace separated list of dboard:subdev pairs.
+ * The first pair represents the subdevice for channel zero,
+ * the second pair represents the subdevice for channel one, and so on.
+ */
+ class UHD_API subdev_spec_t : public std::vector<subdev_spec_pair_t>{
+ public:
+
+ /*!
+ * Create a subdev specification from a markup string.
+ * \param markup the markup string
+ */
+ subdev_spec_t(const std::string &markup = "");
+
+ /*!
+ * Convert a subdev specification into a pretty print string.
+ * \return a printable string representing the subdev specification
+ */
+ std::string to_pp_string(void) const;
+
+ /*!
+ * Convert the subdevice specification into a markup string.
+ * The markup string contains the delimiter symbols.
+ * \return a string with delimiter markup
+ */
+ std::string to_string(void) const;
+ };
+
+}}
+
+#endif /* INCLUDED_UHD_USRP_SUBDEV_SPEC_HPP */
diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt
new file mode 100644
index 000000000..0bf98fb67
--- /dev/null
+++ b/host/include/uhd/utils/CMakeLists.txt
@@ -0,0 +1,37 @@
+#
+# Copyright 2010-2011 Ettus Research LLC
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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, see <http://www.gnu.org/licenses/>.
+#
+
+INSTALL(FILES
+ algorithm.hpp
+ assert_has.hpp
+ assert_has.ipp
+ byteswap.hpp
+ byteswap.ipp
+ gain_group.hpp
+ images.hpp
+ log.hpp
+ msg.hpp
+ pimpl.hpp
+ props.hpp
+ safe_call.hpp
+ safe_main.hpp
+ static.hpp
+ tasks.hpp
+ thread_priority.hpp
+ DESTINATION ${INCLUDE_DIR}/uhd/utils
+ COMPONENT headers
+)
diff --git a/host/include/uhd/utils/algorithm.hpp b/host/include/uhd/utils/algorithm.hpp
new file mode 100644
index 000000000..5598d862b
--- /dev/null
+++ b/host/include/uhd/utils/algorithm.hpp
@@ -0,0 +1,90 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_ALGORITHM_HPP
+#define INCLUDED_UHD_UTILS_ALGORITHM_HPP
+
+#include <algorithm>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+
+/*!
+ * Useful templated functions and classes that I like to pretend are part of stl.
+ * Many of the range wrapper functions come with recent versions of boost (1.43).
+ */
+namespace uhd{
+
+ /*!
+ * A wrapper around std::sort that takes a range instead of an iterator.
+ *
+ * The elements are sorted into ascending order using the less-than operator.
+ * This wrapper sorts the elements non-destructively into a new range.
+ * Based on the builtin python function sorted(...)
+ *
+ * \param range the range of elements to be sorted
+ * \return a new range with the elements sorted
+ */
+ template<typename Range> inline Range sorted(const Range &range){
+ Range r(range); std::sort(boost::begin(r), boost::end(r)); return r;
+ }
+
+ /*!
+ * A wrapper around std::reverse that takes a range instead of an iterator.
+ *
+ * The elements are reversed into descending order using the less-than operator.
+ * This wrapper reverses the elements non-destructively into a new range.
+ * Based on the builtin python function reversed(...)
+ *
+ * \param range the range of elements to be reversed
+ * \return a new range with the elements reversed
+ */
+ template<typename Range> inline Range reversed(const Range &range){
+ Range r(range); std::reverse(boost::begin(r), boost::end(r)); return r;
+ }
+
+ /*!
+ * Is the value found within the elements in this range?
+ *
+ * Uses std::find to search the iterable for an element.
+ *
+ * \param range the elements to search through
+ * \param value the match to look for in the range
+ * \return true when the value is found in the range
+ */
+ template<typename Range, typename T> inline
+ bool has(const Range &range, const T &value){
+ return boost::end(range) != std::find(boost::begin(range), boost::end(range), value);
+ }
+
+ /*!
+ * A templated clip implementation.
+ * \param val the value to clip between an upper and lower limit
+ * \param bound1 the upper or lower bound
+ * \param bound2 the upper or lower bound
+ * \return the value clipped at the bounds
+ */
+ template<typename T> inline T clip(const T &val, const T &bound1, const T &bound2){
+ const T minimum = std::min(bound1, bound2);
+ if (val < minimum) return minimum;
+ const T maximum = std::max(bound1, bound2);
+ if (val > maximum) return maximum;
+ return val;
+ }
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_UTILS_ALGORITHM_HPP */
diff --git a/host/include/uhd/utils/assert_has.hpp b/host/include/uhd/utils/assert_has.hpp
new file mode 100644
index 000000000..eae7652ad
--- /dev/null
+++ b/host/include/uhd/utils/assert_has.hpp
@@ -0,0 +1,47 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_ASSERT_HAS_HPP
+#define INCLUDED_UHD_UTILS_ASSERT_HAS_HPP
+
+#include <uhd/config.hpp>
+#include <string>
+
+namespace uhd{
+
+ /*!
+ * Check that an element is found in a container.
+ * If not, throw a meaningful assertion error.
+ * The "what" in the error will show what is
+ * being set and a list of known good values.
+ *
+ * \param range a list of possible settings
+ * \param value an element that may be in the list
+ * \param what a description of what the value is
+ * \throw assertion_error when elem not in list
+ */
+ template<typename T, typename Range> void assert_has(
+ const Range &range,
+ const T &value,
+ const std::string &what = "unknown"
+ );
+
+}//namespace uhd
+
+#include <uhd/utils/assert_has.ipp>
+
+#endif /* INCLUDED_UHD_UTILS_ASSERT_HAS_HPP */
diff --git a/host/include/uhd/utils/assert_has.ipp b/host/include/uhd/utils/assert_has.ipp
new file mode 100644
index 000000000..7b3c88cb7
--- /dev/null
+++ b/host/include/uhd/utils/assert_has.ipp
@@ -0,0 +1,53 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_ASSERT_HAS_IPP
+#define INCLUDED_UHD_UTILS_ASSERT_HAS_IPP
+
+#include <uhd/utils/algorithm.hpp>
+#include <uhd/exception.hpp>
+#include <boost/format.hpp>
+#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace uhd{
+
+ template<typename T, typename Range> UHD_INLINE void assert_has(
+ const Range &range,
+ const T &value,
+ const std::string &what
+ ){
+ if (uhd::has(range, value)) return;
+ std::string possible_values = "";
+ size_t i = 0;
+ BOOST_FOREACH(const T &v, range){
+ if (i++ > 0) possible_values += ", ";
+ possible_values += boost::lexical_cast<std::string>(v);
+ }
+ throw uhd::assertion_error(str(boost::format(
+ "assertion failed:\n"
+ " %s is not a valid %s.\n"
+ " possible values are: [%s].\n"
+ )
+ % boost::lexical_cast<std::string>(value)
+ % what % possible_values
+ ));
+ }
+
+}//namespace uhd
+
+#endif /* INCLUDED_UHD_UTILS_ASSERT_HAS_IPP */
diff --git a/host/include/uhd/utils/byteswap.hpp b/host/include/uhd/utils/byteswap.hpp
new file mode 100644
index 000000000..2b5a46c66
--- /dev/null
+++ b/host/include/uhd/utils/byteswap.hpp
@@ -0,0 +1,56 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_BYTESWAP_HPP
+#define INCLUDED_UHD_UTILS_BYTESWAP_HPP
+
+#include <uhd/config.hpp>
+#include <boost/cstdint.hpp>
+
+/*! \file byteswap.hpp
+ * Provide fast byteswaping routines for 16, 32, and 64 bit integers,
+ * by using the system's native routines/intrinsics when available.
+ */
+
+namespace uhd{
+
+ //! perform a byteswap on a 16 bit integer
+ boost::uint16_t byteswap(boost::uint16_t);
+
+ //! perform a byteswap on a 32 bit integer
+ boost::uint32_t byteswap(boost::uint32_t);
+
+ //! perform a byteswap on a 64 bit integer
+ boost::uint64_t byteswap(boost::uint64_t);
+
+ //! network to host: short, long, or long-long
+ template<typename T> T ntohx(T);
+
+ //! host to network: short, long, or long-long
+ template<typename T> T htonx(T);
+
+ //! worknet to host: short, long, or long-long
+ template<typename T> T wtohx(T);
+
+ //! host to worknet: short, long, or long-long
+ template<typename T> T htowx(T);
+
+} //namespace uhd
+
+#include <uhd/utils/byteswap.ipp>
+
+#endif /* INCLUDED_UHD_UTILS_BYTESWAP_HPP */
diff --git a/host/include/uhd/utils/byteswap.ipp b/host/include/uhd/utils/byteswap.ipp
new file mode 100644
index 000000000..51e9c28a0
--- /dev/null
+++ b/host/include/uhd/utils/byteswap.ipp
@@ -0,0 +1,136 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_BYTESWAP_IPP
+#define INCLUDED_UHD_UTILS_BYTESWAP_IPP
+
+/***********************************************************************
+ * Platform-specific implementation details for byteswap below:
+ **********************************************************************/
+#if defined(BOOST_MSVC) //http://msdn.microsoft.com/en-us/library/a3140177%28VS.80%29.aspx
+ #include <cstdlib>
+
+ UHD_INLINE boost::uint16_t uhd::byteswap(boost::uint16_t x){
+ return _byteswap_ushort(x);
+ }
+
+ UHD_INLINE boost::uint32_t uhd::byteswap(boost::uint32_t x){
+ return _byteswap_ulong(x);
+ }
+
+ UHD_INLINE boost::uint64_t uhd::byteswap(boost::uint64_t x){
+ return _byteswap_uint64(x);
+ }
+
+#elif defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 2
+
+ UHD_INLINE boost::uint16_t uhd::byteswap(boost::uint16_t x){
+ return (x>>8) | (x<<8); //DNE return __builtin_bswap16(x);
+ }
+
+ UHD_INLINE boost::uint32_t uhd::byteswap(boost::uint32_t x){
+ return __builtin_bswap32(x);
+ }
+
+ UHD_INLINE boost::uint64_t uhd::byteswap(boost::uint64_t x){
+ return __builtin_bswap64(x);
+ }
+
+#elif defined(UHD_PLATFORM_MACOS)
+ #include <libkern/OSByteOrder.h>
+
+ UHD_INLINE boost::uint16_t uhd::byteswap(boost::uint16_t x){
+ return OSSwapInt16(x);
+ }
+
+ UHD_INLINE boost::uint32_t uhd::byteswap(boost::uint32_t x){
+ return OSSwapInt32(x);
+ }
+
+ UHD_INLINE boost::uint64_t uhd::byteswap(boost::uint64_t x){
+ return OSSwapInt64(x);
+ }
+
+#elif defined(UHD_PLATFORM_LINUX)
+ #include <byteswap.h>
+
+ UHD_INLINE boost::uint16_t uhd::byteswap(boost::uint16_t x){
+ return bswap_16(x);
+ }
+
+ UHD_INLINE boost::uint32_t uhd::byteswap(boost::uint32_t x){
+ return bswap_32(x);
+ }
+
+ UHD_INLINE boost::uint64_t uhd::byteswap(boost::uint64_t x){
+ return bswap_64(x);
+ }
+
+#else //http://www.koders.com/c/fidB93B34CD44F0ECF724F1A4EAE3854BA2FE692F59.aspx
+
+ UHD_INLINE boost::uint16_t uhd::byteswap(boost::uint16_t x){
+ return (x>>8) | (x<<8);
+ }
+
+ UHD_INLINE boost::uint32_t uhd::byteswap(boost::uint32_t x){
+ return (boost::uint32_t(uhd::byteswap(boost::uint16_t(x&0xfffful)))<<16) | (uhd::byteswap(boost::uint16_t(x>>16)));
+ }
+
+ UHD_INLINE boost::uint64_t uhd::byteswap(boost::uint64_t x){
+ return (boost::uint64_t(uhd::byteswap(boost::uint32_t(x&0xffffffffull)))<<32) | (uhd::byteswap(boost::uint32_t(x>>32)));
+ }
+
+#endif
+
+/***********************************************************************
+ * Define the templated network to/from host conversions
+ **********************************************************************/
+#include <boost/detail/endian.hpp>
+
+template<typename T> UHD_INLINE T uhd::ntohx(T num){
+ #ifdef BOOST_BIG_ENDIAN
+ return num;
+ #else
+ return uhd::byteswap(num);
+ #endif
+}
+
+template<typename T> UHD_INLINE T uhd::htonx(T num){
+ #ifdef BOOST_BIG_ENDIAN
+ return num;
+ #else
+ return uhd::byteswap(num);
+ #endif
+}
+
+template<typename T> UHD_INLINE T uhd::wtohx(T num){
+ #ifdef BOOST_BIG_ENDIAN
+ return uhd::byteswap(num);
+ #else
+ return num;
+ #endif
+}
+
+template<typename T> UHD_INLINE T uhd::htowx(T num){
+ #ifdef BOOST_BIG_ENDIAN
+ return uhd::byteswap(num);
+ #else
+ return num;
+ #endif
+}
+
+#endif /* INCLUDED_UHD_UTILS_BYTESWAP_IPP */
diff --git a/host/include/uhd/utils/gain_group.hpp b/host/include/uhd/utils/gain_group.hpp
new file mode 100644
index 000000000..7ef7bdcf5
--- /dev/null
+++ b/host/include/uhd/utils/gain_group.hpp
@@ -0,0 +1,108 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_GAIN_GROUP_HPP
+#define INCLUDED_UHD_UTILS_GAIN_GROUP_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/types/ranges.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/utility.hpp>
+#include <vector>
+#include <string>
+
+namespace uhd{
+
+/*!
+ * A set of function to control a gain element.
+ */
+struct UHD_API gain_fcns_t{
+ boost::function<gain_range_t(void)> get_range;
+ boost::function<double(void)> get_value;
+ boost::function<void(double)> set_value;
+};
+
+class UHD_API gain_group : boost::noncopyable{
+public:
+ typedef boost::shared_ptr<gain_group> sptr;
+
+ /*!
+ * Get the gain range for the gain element specified by name.
+ * For an empty name, get the overall gain range for this group.
+ * Overall step is defined as the minimum step size.
+ * \param name name of the gain element (optional)
+ * \return a gain range with overall min, max, step
+ */
+ virtual gain_range_t get_range(const std::string &name = "") = 0;
+
+ /*!
+ * Get the gain value for the gain element specified by name.
+ * For an empty name, get the overall gain value for this group.
+ * \param name name of the gain element (optional)
+ * \return a gain value of the element or all elements
+ */
+ virtual double get_value(const std::string &name = "") = 0;
+
+ /*!
+ * Set the gain value for the gain element specified by name.
+ * For an empty name, set the overall gain value for this group.
+ * The power will be distributed across individual gain elements.
+ * The semantics of how to do this are determined by the priority.
+ * \param gain the gain to set for the lement or across the group
+ * \param name name of the gain element (optional)
+ */
+ virtual void set_value(double gain, const std::string &name = "") = 0;
+
+ /*!
+ * Get a list of names of registered gain elements.
+ * The names are in the order that they were registered.
+ * \return a vector of gain name strings
+ */
+ virtual const std::vector<std::string> get_names(void) = 0;
+
+ /*!
+ * Register a set of gain functions into this group:
+ *
+ * The name should be a unique and non-empty name.
+ * Othwerwise, the implementation will rename it.
+ *
+ * Priority determines how power will be distributed
+ * with higher priorities getting the power first,
+ * and lower priorities getting the remainder power.
+ *
+ * \param name the name of the gain element
+ * \param gain_fcns the set of gain functions
+ * \param priority the priority of the gain element
+ */
+ virtual void register_fcns(
+ const std::string &name,
+ const gain_fcns_t &gain_fcns,
+ size_t priority = 0
+ ) = 0;
+
+ /*!
+ * Make a new empty gain group.
+ * \return a gain group object.
+ */
+ static sptr make(void);
+};
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_UTILS_GAIN_GROUP_HPP */
+
diff --git a/host/include/uhd/utils/images.hpp b/host/include/uhd/utils/images.hpp
new file mode 100644
index 000000000..8b5a1eedd
--- /dev/null
+++ b/host/include/uhd/utils/images.hpp
@@ -0,0 +1,38 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_IMAGES_HPP
+#define INCLUDED_UHD_UTILS_IMAGES_HPP
+
+#include <uhd/config.hpp>
+#include <string>
+
+namespace uhd{
+
+ /*!
+ * Search for an image in the system image paths:
+ * Search compiled-in paths and environment variable paths
+ * for a specific image file with the provided file name.
+ * \param image_name the name of the file
+ * \return the full system path to the file
+ * \throw exception if the image was not found
+ */
+ UHD_API std::string find_image_path(const std::string &image_name);
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_UTILS_IMAGES_HPP */
diff --git a/host/include/uhd/utils/log.hpp b/host/include/uhd/utils/log.hpp
new file mode 100644
index 000000000..1f515c15e
--- /dev/null
+++ b/host/include/uhd/utils/log.hpp
@@ -0,0 +1,97 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_LOG_HPP
+#define INCLUDED_UHD_UTILS_LOG_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/utils/pimpl.hpp>
+#include <boost/current_function.hpp>
+#include <ostream>
+#include <string>
+
+/*! \file log.hpp
+ * The UHD logging facility.
+ *
+ * The logger enables UHD library code to easily log events into a file.
+ * Log entries are time-stamped and stored with file, line, and function.
+ * Each call to the UHD_LOG macros is synchronous and thread-safe.
+ *
+ * The log file can be found in the path <temp-directory>/uhd.log,
+ * where <temp-directory> is the user or system's temporary directory.
+ * To override <temp-directory>, set the UHD_TEMP_PATH environment variable.
+ *
+ * All log messages with verbosity greater than or equal to the log level
+ * (in other words, as often or less often than the current log level)
+ * are recorded into the log file. All other messages are sent to null.
+ *
+ * The default log level is "never", but can be overridden:
+ * - at compile time by setting the pre-processor define UHD_LOG_LEVEL.
+ * - at runtime by setting the environment variable UHD_LOG_LEVEL.
+ *
+ * UHD_LOG_LEVEL can be the name of a verbosity enum or integer value:
+ * - Example pre-processor define: -DUHD_LOG_LEVEL=3
+ * - Example pre-processor define: -DUHD_LOG_LEVEL=regularly
+ * - Example environment variable: export UHD_LOG_LEVEL=3
+ * - Example environment variable: export UHD_LOG_LEVEL=regularly
+ */
+
+/*!
+ * A UHD logger macro with configurable verbosity.
+ * Usage: UHD_LOGV(very_rarely) << "the log message" << std::endl;
+ */
+#define UHD_LOGV(verbosity) \
+ uhd::_log::log(uhd::_log::verbosity, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION)()
+
+/*!
+ * A UHD logger macro with default verbosity.
+ * Usage: UHD_LOG << "the log message" << std::endl;
+ */
+#define UHD_LOG \
+ UHD_LOGV(regularly)
+
+
+namespace uhd{ namespace _log{
+
+ //! Verbosity levels for the logger
+ enum verbosity_t{
+ always = 1,
+ often = 2,
+ regularly = 3,
+ rarely = 4,
+ very_rarely = 5,
+ never = 6,
+ };
+
+ //! Internal logging object (called by UHD_LOG macros)
+ class UHD_API log{
+ public:
+ log(
+ const verbosity_t verbosity,
+ const std::string &file,
+ const unsigned int line,
+ const std::string &function
+ );
+ ~log(void);
+ std::ostream &operator()(void);
+ private:
+ UHD_PIMPL_DECL(impl) _impl;
+ };
+
+}} //namespace uhd::_log
+
+#endif /* INCLUDED_UHD_UTILS_LOG_HPP */
diff --git a/host/include/uhd/utils/msg.hpp b/host/include/uhd/utils/msg.hpp
new file mode 100644
index 000000000..3aac9577a
--- /dev/null
+++ b/host/include/uhd/utils/msg.hpp
@@ -0,0 +1,74 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_MSG_HPP
+#define INCLUDED_UHD_UTILS_MSG_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/utils/pimpl.hpp>
+#include <ostream>
+#include <string>
+
+/*!
+ * A UHD message macro with configurable type.
+ * Usage: UHD_MSG(warning) << "some warning message" << std::endl;
+ */
+#define UHD_MSG(type) \
+ uhd::msg::_msg(uhd::msg::type)()
+
+//! Helpful debug tool to print site info
+#define UHD_HERE() \
+ UHD_MSG(status) << __FILE__ << ":" << __LINE__ << std::endl
+
+//! Helpful debug tool to print a variable
+#define UHD_VAR(var) \
+ UHD_MSG(status) << #var << " = " << var << std::endl;
+
+namespace uhd{ namespace msg{
+
+ //! Possible message types
+ enum type_t{
+ status = 's',
+ warning = 'w',
+ error = 'e',
+ fastpath= 'f'
+ };
+
+ //! Typedef for a user-registered message handler
+ typedef void (*handler_t)(type_t, const std::string &);
+
+ /*!
+ * Register the handler for uhd system messages.
+ * Only one handler can be registered at once.
+ * This replaces the default std::cout/cerr handler.
+ * \param handler a new handler callback function
+ */
+ UHD_API void register_handler(const handler_t &handler);
+
+ //! Internal message object (called by UHD_MSG macro)
+ class UHD_API _msg{
+ public:
+ _msg(const type_t type);
+ ~_msg(void);
+ std::ostream &operator()(void);
+ private:
+ UHD_PIMPL_DECL(impl) _impl;
+ };
+
+}} //namespace uhd::msg
+
+#endif /* INCLUDED_UHD_UTILS_MSG_HPP */
diff --git a/host/include/uhd/utils/pimpl.hpp b/host/include/uhd/utils/pimpl.hpp
new file mode 100644
index 000000000..09bf0c0a2
--- /dev/null
+++ b/host/include/uhd/utils/pimpl.hpp
@@ -0,0 +1,55 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_PIMPL_HPP
+#define INCLUDED_UHD_UTILS_PIMPL_HPP
+
+#include <uhd/config.hpp>
+#include <boost/shared_ptr.hpp>
+
+/*! \file pimpl.hpp
+ * "Pimpl idiom" (pointer to implementation idiom).
+ * The UHD_PIMPL_* macros simplify code overhead for declaring and making pimpls.
+ *
+ * Each pimpl is implemented as a shared pointer to the implementation:
+ * - The container class will not have to deallocate the pimpl.
+ * - The container class will use the pimpl as a regular pointer.
+ * - Usage: _impl->method(arg0, arg1)
+ * - Usage: _impl->member = value;
+ *
+ * \see http://en.wikipedia.org/wiki/Opaque_pointer
+ */
+
+/*!
+ * Make a declaration for a pimpl in a header file.
+ * - Usage: UHD_PIMPL_DECL(impl) _impl;
+ * \param _name the name of the pimpl class
+ */
+#define UHD_PIMPL_DECL(_name) \
+ struct _name; boost::shared_ptr<_name>
+
+/*!
+ * Make an instance of a pimpl in a source file.
+ * - Usage: _impl = UHD_PIMPL_MAKE(impl, ());
+ * - Usage: _impl = UHD_PIMPL_MAKE(impl, (a0, a1));
+ * \param _name the name of the pimpl class
+ * \param _args the constructor args for the pimpl
+ */
+#define UHD_PIMPL_MAKE(_name, _args) \
+ boost::shared_ptr<_name>(new _name _args)
+
+#endif /* INCLUDED_UHD_UTILS_PIMPL_HPP */
diff --git a/host/include/uhd/utils/props.hpp b/host/include/uhd/utils/props.hpp
new file mode 100644
index 000000000..81737423a
--- /dev/null
+++ b/host/include/uhd/utils/props.hpp
@@ -0,0 +1,81 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_PROPS_HPP
+#define INCLUDED_UHD_UTILS_PROPS_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/wax.hpp>
+#include <uhd/exception.hpp>
+#include <vector>
+#include <string>
+
+namespace uhd{
+
+ //! The type for a vector of property names
+ typedef std::vector<std::string> prop_names_t;
+
+ /*!
+ * A named prop struct holds a key and a name.
+ * Allows properties to be sub-sectioned by name.
+ */
+ struct UHD_API named_prop_t{
+ const wax::obj key;
+ const std::string name;
+
+ //! Convert the key to the specified type
+ template<typename T> inline T as(void){
+ return key.as<T>();
+ }
+
+ /*!
+ * Utility function to convert generic key into a named prop.
+ * If the key was already a named prop, the prop will be split.
+ * Otherwise, the key will be the key, and the name will be used.
+ * \param key a reference to the prop object
+ * \param name a reference to the name object
+ * \return a named property struct with key and name
+ */
+ static named_prop_t extract(
+ const wax::obj &key, const std::string &name = ""
+ );
+
+ /*!
+ * Create a new named prop from key and name.
+ * \param key the property key
+ * \param name the string name
+ */
+ named_prop_t(const wax::obj &key, const std::string &name);
+ };
+
+ /*!
+ * Throw when getting a not-implemented or write-only property.
+ * Throw-site information will be included with this error.
+ */
+ #define UHD_THROW_PROP_GET_ERROR() \
+ throw uhd::key_error(UHD_THROW_SITE_INFO("cannot get this property"))
+
+ /*!
+ * Throw when setting a not-implemented or read-only property.
+ * Throw-site information will be included with this error.
+ */
+ #define UHD_THROW_PROP_SET_ERROR() \
+ throw uhd::key_error(UHD_THROW_SITE_INFO("cannot set this property"))
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_UTILS_PROPS_HPP */
diff --git a/host/include/uhd/utils/safe_call.hpp b/host/include/uhd/utils/safe_call.hpp
new file mode 100644
index 000000000..ab287cc66
--- /dev/null
+++ b/host/include/uhd/utils/safe_call.hpp
@@ -0,0 +1,45 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_SAFE_CALL_HPP
+#define INCLUDED_UHD_UTILS_SAFE_CALL_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/exception.hpp>
+#include <uhd/utils/log.hpp>
+
+//! helper macro for safe call to produce warnings
+#define _UHD_SAFE_CALL_WARNING(code, what) UHD_LOGV(rarely) << \
+ UHD_THROW_SITE_INFO("Exception caught in safe-call.") + #code + " -> " + what \
+;
+
+/*!
+ * A safe-call catches all exceptions thrown by code,
+ * and creates a verbose warning about the exception.
+ * Usage: UHD_SAFE_CALL(some_code_to_call();)
+ * \param code the block of code to call safely
+ */
+#define UHD_SAFE_CALL(code) \
+ try{code} \
+ catch(const std::exception &e){ \
+ _UHD_SAFE_CALL_WARNING(code, e.what()); \
+ } \
+ catch(...){ \
+ _UHD_SAFE_CALL_WARNING(code, "unknown exception"); \
+ }
+
+#endif /* INCLUDED_UHD_UTILS_SAFE_CALL_HPP */
diff --git a/host/include/uhd/utils/safe_main.hpp b/host/include/uhd/utils/safe_main.hpp
new file mode 100644
index 000000000..b682aa540
--- /dev/null
+++ b/host/include/uhd/utils/safe_main.hpp
@@ -0,0 +1,44 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_SAFE_MAIN_HPP
+#define INCLUDED_UHD_UTILS_SAFE_MAIN_HPP
+
+#include <uhd/config.hpp>
+#include <iostream>
+#include <stdexcept>
+
+/*!
+ * Defines a safe wrapper that places a catch-all around main.
+ * If an exception is thrown, it prints to stderr and returns.
+ * Usage: int UHD_SAFE_MAIN(int argc, char *argv[]){ main code here }
+ * \param _argc the declaration for argc
+ * \param _argv the declaration for argv
+ */
+#define UHD_SAFE_MAIN(_argc, _argv) _main(int, char*[]); \
+int main(int argc, char *argv[]){ \
+ try { \
+ return _main(argc, argv); \
+ } catch(const std::exception &e) { \
+ std::cerr << "Error: " << e.what() << std::endl; \
+ } catch(...) { \
+ std::cerr << "Error: unknown exception" << std::endl; \
+ } \
+ return ~0; \
+} int _main(_argc, _argv)
+
+#endif /* INCLUDED_UHD_UTILS_SAFE_MAIN_HPP */
diff --git a/host/include/uhd/utils/static.hpp b/host/include/uhd/utils/static.hpp
new file mode 100644
index 000000000..82cdf36d9
--- /dev/null
+++ b/host/include/uhd/utils/static.hpp
@@ -0,0 +1,46 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_STATIC_HPP
+#define INCLUDED_UHD_UTILS_STATIC_HPP
+
+#include <uhd/config.hpp>
+
+/*!
+ * Defines a function that implements the "construct on first use" idiom
+ * \param _t the type definition for the instance
+ * \param _x the name of the defined function
+ * \return a reference to the lazy instance
+ */
+#define UHD_SINGLETON_FCN(_t, _x) static _t &_x(){static _t _x; return _x;}
+
+/*!
+ * Defines a static code block that will be called before main()
+ * The static block will catch and print exceptions to std error.
+ * \param _x the unique name of the fixture (unique per source)
+ */
+#define UHD_STATIC_BLOCK(_x) \
+ void _x(void); \
+ static _uhd_static_fixture _x##_fixture(&_x, #_x); \
+ void _x(void)
+
+//! Helper for static block, constructor calls function
+struct UHD_API _uhd_static_fixture{
+ _uhd_static_fixture(void (*)(void), const char *);
+};
+
+#endif /* INCLUDED_UHD_UTILS_STATIC_HPP */
diff --git a/host/include/uhd/utils/tasks.hpp b/host/include/uhd/utils/tasks.hpp
new file mode 100644
index 000000000..38b2bddf0
--- /dev/null
+++ b/host/include/uhd/utils/tasks.hpp
@@ -0,0 +1,53 @@
+//
+// Copyright 2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_TASKS_HPP
+#define INCLUDED_UHD_UTILS_TASKS_HPP
+
+#include <uhd/config.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/utility.hpp>
+
+namespace uhd{
+
+ class task : boost::noncopyable{
+ public:
+ typedef boost::shared_ptr<task> sptr;
+ typedef boost::function<void(void)> task_fcn_type;
+
+ /*!
+ * Create a new task object with function callback.
+ * The task function callback will be run in a loop.
+ * until the thread is interrupted by the deconstructor.
+ *
+ * A task should return in a reasonable amount of time
+ * or may block forever under the following conditions:
+ * - The blocking call is interruptible.
+ * - The task polls the interrupt condition.
+ *
+ * \param task_fcn the task callback function
+ * \return a new task object
+ */
+ static sptr make(const task_fcn_type &task_fcn);
+
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_UTILS_TASKS_HPP */
+
diff --git a/host/include/uhd/utils/thread_priority.hpp b/host/include/uhd/utils/thread_priority.hpp
new file mode 100644
index 000000000..988fc3012
--- /dev/null
+++ b/host/include/uhd/utils/thread_priority.hpp
@@ -0,0 +1,58 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_UTILS_THREAD_PRIORITY_HPP
+#define INCLUDED_UHD_UTILS_THREAD_PRIORITY_HPP
+
+#include <uhd/config.hpp>
+
+namespace uhd{
+
+ static const float default_thread_priority = float(0.5);
+
+ /*!
+ * Set the scheduling priority on the current thread.
+ *
+ * A new thread or calling process should make this call
+ * with the defailts this to enable realtime scheduling.
+ *
+ * A priority of zero corresponds to normal priority.
+ * Positive priority values are higher than normal.
+ * Negative priority values are lower than normal.
+ *
+ * \param priority a value between -1 and 1
+ * \param realtime true to use realtime mode
+ * \throw exception on set priority failure
+ */
+ UHD_API void set_thread_priority(
+ float priority = default_thread_priority,
+ bool realtime = true
+ );
+
+ /*!
+ * Set the scheduling priority on the current thread.
+ * Same as set_thread_priority but does not throw on failure.
+ * \return true on success, false on failure
+ */
+ UHD_API bool set_thread_priority_safe(
+ float priority = default_thread_priority,
+ bool realtime = true
+ );
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_UTILS_THREAD_PRIORITY_HPP */
diff --git a/host/include/uhd/version.hpp b/host/include/uhd/version.hpp
new file mode 100644
index 000000000..19d672e65
--- /dev/null
+++ b/host/include/uhd/version.hpp
@@ -0,0 +1,28 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_VERSION_HPP
+#define INCLUDED_UHD_VERSION_HPP
+
+#include <uhd/config.hpp>
+#include <string>
+
+namespace uhd{
+ UHD_API std::string get_version_string(void);
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_VERSION_HPP */
diff --git a/host/include/uhd/wax.hpp b/host/include/uhd/wax.hpp
new file mode 100644
index 000000000..6fd2b8652
--- /dev/null
+++ b/host/include/uhd/wax.hpp
@@ -0,0 +1,169 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program 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 of the License, or
+// (at your option) any later version.
+//
+// This program 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, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_WAX_HPP
+#define INCLUDED_WAX_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/exception.hpp>
+#include <boost/any.hpp>
+#include <typeinfo>
+#include <string>
+
+/*!
+ * WAX - it's a metaphor!
+ *
+ * The WAX framework allows an object to have generic/anyobj properties.
+ * These properties can be addressed through generic/anyobj identifiers.
+ *
+ * The WAX object itself is an anytype container much like boost::any.
+ * To retrieve the value of the appropriate type, use my_obj.as<type>().
+ *
+ * Proprties may be referenced though the [] overloaded operator.
+ * The [] operator returns a special proxy that allows for assigment.
+ * Also, the [] operators may be chained as in the folowing examples:
+ * my_obj[prop1][prop2][prop3] = value;
+ * value = my_obj[prop1][prop2][prop3].as<type>();
+ *
+ * Property nesting occurs when a WAX object gets another object's link.
+ * This special link is obtained through a call to my_obj.get_link().
+ *
+ * Note: Do not put a class derived from wax::obj into an stl container.
+ * MSVC will compile the code, but the binaries will crash at runtime.
+ * Rather, use pointers or smart pointers to instances of the derived class.
+ */
+
+namespace wax{
+
+ /*!
+ * WAX object base class:
+ *
+ * A wax obj has two major purposes:
+ * 1) to act as a polymorphic container, just like boost any
+ * 2) to provide a nested set/get properties interface
+ *
+ * Internally, the polymorphic container is handled by a boost any.
+ * For properties, a subclass should override the set and get methods.
+ * For property nesting, wax obj subclasses return special links
+ * to other wax obj subclasses, and the api handles the magic.
+ */
+ class UHD_API obj{
+ public:
+
+ /*!
+ * Default constructor:
+ * The contents will be empty.
+ */
+ obj(void);
+
+ /*!
+ * Copy constructor:
+ * The contents will be cloned.
+ * \param o another wax::obj
+ */
+ obj(const obj &o);
+
+ /*!
+ * Templated any type constructor:
+ * The contents can be anything.
+ * Uses the boost::any to handle the magic.
+ * \param o an object of any type
+ */
+ template<class T> obj(const T &o){
+ _contents = o;
+ }
+
+ /*!
+ * Destructor.
+ */
+ virtual ~obj(void);
+
+ /*!
+ * The chaining operator:
+ * This operator allows access objs with properties.
+ * A call to the [] operator will return a new proxy obj.
+ * The proxy object is an obj with special proxy contents.
+ * Assignment and casting can be used on this special object
+ * to access the property referenced by the obj key.
+ * \param key a key to identify a property within this obj
+ * \return a special wax obj that proxies the obj and key
+ */
+ obj operator[](const obj &key);
+
+ /*!
+ * The assignment operator:
+ * This operator allows for assignment of new contents.
+ * In the special case where this obj contains a proxy,
+ * the value will be set to the proxy's property reference.
+ * \param val the new value to assign to the wax obj
+ * \return a reference to this obj (*this)
+ */
+ obj & operator=(const obj &val);
+
+ /*!
+ * Get a link in the chain:
+ * When a wax obj returns another wax obj as part of a get call,
+ * the return value should be set to the result of this method.
+ * Doing so will ensure chain-ability of the returned object.
+ * \return an obj containing a valid link to a wax obj
+ */
+ obj get_link(void) const;
+
+ /*!
+ * Get the type of the contents of this obj.
+ * \return a reference to the type_info
+ */
+ const std::type_info & type(void) const;
+
+ /*!
+ * Cast this obj into the desired type.
+ * Usage: myobj.as<type>()
+ *
+ * \return an object of the desired type
+ * \throw wax::bad_cast when the cast fails
+ */
+ template<class T> T as(void) const{
+ try{
+ return boost::any_cast<T>(resolve());
+ }
+ catch(const boost::bad_any_cast &e){
+ throw uhd::type_error(std::string("") + "Cannot wax cast " + type().name() + " to " + typeid(T).name() + " " + e.what());
+ }
+ }
+
+ private:
+ //private interface (override in subclasses)
+ virtual void get(const obj &, obj &);
+ virtual void set(const obj &, const obj &);
+
+ /*!
+ * Resolve the contents of this obj.
+ * In the case where this obj is a proxy,
+ * the referenced property will be resolved.
+ * Otherwise, just get the private contents.
+ * \return a boost any type with contents
+ */
+ boost::any resolve(void) const;
+
+ //private contents of this obj
+ boost::any _contents;
+
+ };
+
+} //namespace wax
+
+#endif /* INCLUDED_WAX_HPP */