diff options
Diffstat (limited to 'host/include')
| -rw-r--r-- | host/include/uhd/device.hpp | 27 | ||||
| -rw-r--r-- | host/include/uhd/device.ipp | 9 | ||||
| -rw-r--r-- | host/include/uhd/transport/alignment_buffer.hpp | 9 | ||||
| -rw-r--r-- | host/include/uhd/transport/alignment_buffer.ipp | 15 | ||||
| -rw-r--r-- | host/include/uhd/transport/bounded_buffer.hpp | 12 | ||||
| -rw-r--r-- | host/include/uhd/transport/bounded_buffer.ipp | 50 | ||||
| -rw-r--r-- | host/include/uhd/transport/udp_zero_copy.hpp | 7 | ||||
| -rw-r--r-- | host/include/uhd/transport/usb_control.hpp | 2 | ||||
| -rw-r--r-- | host/include/uhd/transport/usb_zero_copy.hpp | 17 | ||||
| -rw-r--r-- | host/include/uhd/transport/zero_copy.hpp | 138 | ||||
| -rw-r--r-- | host/include/uhd/types/device_addr.hpp | 20 | ||||
| -rw-r--r-- | host/include/uhd/usrp/single_usrp.hpp | 26 | ||||
| -rw-r--r-- | host/include/uhd/usrp/subdev_props.hpp | 1 | ||||
| -rw-r--r-- | host/include/uhd/usrp/subdev_spec.hpp | 6 | 
14 files changed, 185 insertions, 154 deletions
diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp index 2077cae62..992276928 100644 --- a/host/include/uhd/device.hpp +++ b/host/include/uhd/device.hpp @@ -41,9 +41,6 @@ public:      typedef boost::function<device_addrs_t(const device_addr_t &)> find_t;      typedef boost::function<sptr(const device_addr_t &)> make_t; -    //! A reasonable default timeout for receive -    static const size_t default_recv_timeout_ms = 100; -      /*!       * Register a device into the discovery and factory system.       * @@ -112,12 +109,15 @@ public:       *       * 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( @@ -125,7 +125,8 @@ public:          size_t nsamps_per_buff,          const tx_metadata_t &metadata,          const io_type_t &io_type, -        send_mode_t send_mode +        send_mode_t send_mode, +        double timeout = 0.1      ) = 0;      /*! @@ -136,7 +137,8 @@ public:          size_t nsamps_per_buff,          const tx_metadata_t &metadata,          const io_type_t &io_type, -        send_mode_t send_mode +        send_mode_t send_mode, +        double timeout = 0.1      );      /*! @@ -154,7 +156,9 @@ public:       * 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 or timeout. +     * 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. @@ -165,7 +169,7 @@ public:       * \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_ms the timeout in milliseconds to wait for a packet +     * \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( @@ -174,7 +178,7 @@ public:          rx_metadata_t &metadata,          const io_type_t &io_type,          recv_mode_t recv_mode, -        size_t timeout_ms = default_recv_timeout_ms +        double timeout = 0.1      ) = 0;      /*! @@ -186,7 +190,7 @@ public:          rx_metadata_t &metadata,          const io_type_t &io_type,          recv_mode_t recv_mode, -        size_t timeout_ms = default_recv_timeout_ms +        double timeout = 0.1      );      /*! @@ -204,12 +208,11 @@ public:      /*!       * Receive and asynchronous message from the device.       * \param async_metadata the metadata to be filled in -     * \param timeout_ms the timeout in milliseconds to wait for a message +     * \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, -        size_t timeout_ms = default_recv_timeout_ms +        async_metadata_t &async_metadata, double timeout = 0.1      ) = 0;  }; diff --git a/host/include/uhd/device.ipp b/host/include/uhd/device.ipp index 60a3f535d..e2e51ecd0 100644 --- a/host/include/uhd/device.ipp +++ b/host/include/uhd/device.ipp @@ -25,12 +25,13 @@ namespace uhd{          size_t nsamps_per_buff,          const tx_metadata_t &metadata,          const io_type_t &io_type, -        send_mode_t send_mode +        send_mode_t send_mode, +        double timeout      ){          return this->send(              std::vector<const void *>(1, buff),              nsamps_per_buff, metadata, -            io_type, send_mode +            io_type, send_mode, timeout          );      } @@ -40,12 +41,12 @@ namespace uhd{          rx_metadata_t &metadata,          const io_type_t &io_type,          recv_mode_t recv_mode, -        size_t timeout_ms +        double timeout      ){          return this->recv(              std::vector<void *>(1, buff),              nsamps_per_buff, metadata, -            io_type, recv_mode, timeout_ms +            io_type, recv_mode, timeout          );      } diff --git a/host/include/uhd/transport/alignment_buffer.hpp b/host/include/uhd/transport/alignment_buffer.hpp index 29ba74efc..f44a037f8 100644 --- a/host/include/uhd/transport/alignment_buffer.hpp +++ b/host/include/uhd/transport/alignment_buffer.hpp @@ -48,20 +48,17 @@ namespace uhd{ namespace transport{           * \return true if the element fit without popping for space           */          virtual bool push_with_pop_on_full( -            const elem_type &elem, -            const seq_type &seq, -            size_t index +            const elem_type &elem, const seq_type &seq, size_t index          ) = 0;          /*!           * Pop an aligned set of elements from this alignment buffer.           * \param elems a collection to store the aligned elements -         * \param time the timeout time +         * \param timeout the timeout in seconds           * \return false when the operation times out           */          virtual bool pop_elems_with_timed_wait( -            std::vector<elem_type> &elems, -            const time_duration_t &time +            std::vector<elem_type> &elems, double timeout          ) = 0;      }; diff --git a/host/include/uhd/transport/alignment_buffer.ipp b/host/include/uhd/transport/alignment_buffer.ipp index 61b3b60f5..833b5d399 100644 --- a/host/include/uhd/transport/alignment_buffer.ipp +++ b/host/include/uhd/transport/alignment_buffer.ipp @@ -41,9 +41,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          }          UHD_INLINE bool push_with_pop_on_full( -            const elem_type &elem, -            const seq_type &seq, -            size_t index +            const elem_type &elem, const seq_type &seq, size_t index          ){              //clear the buffer for this index if the seqs are mis-ordered              if (seq < _last_seqs[index]){ @@ -54,17 +52,16 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          }          UHD_INLINE bool pop_elems_with_timed_wait( -            std::vector<elem_type> &elems, -            const time_duration_t &time +            std::vector<elem_type> &elems, double timeout          ){ -            boost::system_time exit_time = boost::get_system_time() + time; +            boost::system_time exit_time = boost::get_system_time() + to_time_dur(timeout);              buff_contents_type buff_contents_tmp;              std::list<size_t> indexes_to_do(_all_indexes);              //do an initial pop to load an initial sequence id              size_t index = indexes_to_do.front();              if (not _buffs[index]->pop_with_timed_wait( -                buff_contents_tmp, exit_time - boost::get_system_time() +                buff_contents_tmp, from_time_dur(exit_time - boost::get_system_time())              )) return false;              elems[index] = buff_contents_tmp.first;              seq_type expected_seq_id = buff_contents_tmp.second; @@ -79,7 +76,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/                      indexes_to_do = _all_indexes;                      index = indexes_to_do.front();                      if (not _buffs[index]->pop_with_timed_wait( -                        buff_contents_tmp, exit_time - boost::get_system_time() +                        buff_contents_tmp, from_time_dur(exit_time - boost::get_system_time())                      )) return false;                      elems[index] = buff_contents_tmp.first;                      expected_seq_id = buff_contents_tmp.second; @@ -89,7 +86,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/                  //pop an element off for this index                  index = indexes_to_do.front();                  if (not _buffs[index]->pop_with_timed_wait( -                    buff_contents_tmp, exit_time - boost::get_system_time() +                    buff_contents_tmp, from_time_dur(exit_time - boost::get_system_time())                  )) return false;                  //if the sequence id matches: diff --git a/host/include/uhd/transport/bounded_buffer.hpp b/host/include/uhd/transport/bounded_buffer.hpp index d1deece96..aca93b071 100644 --- a/host/include/uhd/transport/bounded_buffer.hpp +++ b/host/include/uhd/transport/bounded_buffer.hpp @@ -20,13 +20,9 @@  #include <uhd/config.hpp>  #include <boost/shared_ptr.hpp> -#include <boost/date_time/posix_time/posix_time_types.hpp>  namespace uhd{ namespace transport{ -    //! typedef for the time duration type for wait operations -    typedef boost::posix_time::time_duration time_duration_t; -      /*!       * Implement a templated bounded buffer:       * Used for passing elements between threads in a producer-consumer model. @@ -64,10 +60,10 @@ namespace uhd{ namespace transport{           * 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 time the timeout time +         * \param timeout the timeout in seconds           * \return false when the operation times out           */ -        virtual bool push_with_timed_wait(const elem_type &elem, const time_duration_t &time) = 0; +        virtual bool push_with_timed_wait(const elem_type &elem, double timeout) = 0;          /*!           * Pop an element from the bounded_buffer. @@ -80,10 +76,10 @@ namespace uhd{ namespace transport{           * 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 time the timeout time +         * \param timeout the timeout in seconds           * \return false when the operation times out           */ -        virtual bool pop_with_timed_wait(elem_type &elem, const time_duration_t &time) = 0; +        virtual bool pop_with_timed_wait(elem_type &elem, double timeout) = 0;          /*!           * Clear all elements from the bounded_buffer. diff --git a/host/include/uhd/transport/bounded_buffer.ipp b/host/include/uhd/transport/bounded_buffer.ipp index e106e229e..edc7faa06 100644 --- a/host/include/uhd/transport/bounded_buffer.ipp +++ b/host/include/uhd/transport/bounded_buffer.ipp @@ -19,17 +19,28 @@  #define INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_IPP  #include <boost/bind.hpp> +#include <boost/function.hpp>  #include <boost/circular_buffer.hpp>  #include <boost/thread/condition.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp>  namespace uhd{ namespace transport{ namespace{ /*anon*/ +    static UHD_INLINE boost::posix_time::time_duration to_time_dur(double timeout){ +        return boost::posix_time::microseconds(long(timeout*1e6)); +    } + +    static UHD_INLINE double from_time_dur(const boost::posix_time::time_duration &time_dur){ +        return 1e-6*time_dur.total_microseconds(); +    } +      template <typename elem_type>      class bounded_buffer_impl : public bounded_buffer<elem_type>{      public:          bounded_buffer_impl(size_t capacity) : _buffer(capacity){ -            /* NOP */ +            _not_full_fcn = boost::bind(&bounded_buffer_impl<elem_type>::not_full, this); +            _not_empty_fcn = boost::bind(&bounded_buffer_impl<elem_type>::not_empty, this);          }          UHD_INLINE bool push_with_pop_on_full(const elem_type &elem){ @@ -51,15 +62,17 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          UHD_INLINE void push_with_wait(const elem_type &elem){              boost::unique_lock<boost::mutex> lock(_mutex); -            _full_cond.wait(lock, boost::bind(&bounded_buffer_impl<elem_type>::not_full, this)); +            _full_cond.wait(lock, _not_full_fcn);              _buffer.push_front(elem);              lock.unlock();              _empty_cond.notify_one();          } -        bool push_with_timed_wait(const elem_type &elem, const time_duration_t &time){ +        UHD_INLINE bool push_with_timed_wait(const elem_type &elem, double timeout){              boost::unique_lock<boost::mutex> lock(_mutex); -            if (not _full_cond.timed_wait(lock, time, boost::bind(&bounded_buffer_impl<elem_type>::not_full, this))) return false; +            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(); @@ -68,16 +81,18 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          UHD_INLINE void pop_with_wait(elem_type &elem){              boost::unique_lock<boost::mutex> lock(_mutex); -            _empty_cond.wait(lock, boost::bind(&bounded_buffer_impl<elem_type>::not_empty, this)); -            elem = _buffer.back(); _buffer.pop_back(); +            _empty_cond.wait(lock, _not_empty_fcn); +            elem = this->pop_back();              lock.unlock();              _full_cond.notify_one();          } -        bool pop_with_timed_wait(elem_type &elem, const time_duration_t &time){ +        UHD_INLINE bool pop_with_timed_wait(elem_type &elem, double timeout){              boost::unique_lock<boost::mutex> lock(_mutex); -            if (not _empty_cond.timed_wait(lock, time, boost::bind(&bounded_buffer_impl<elem_type>::not_empty, this))) return false; -            elem = _buffer.back(); _buffer.pop_back(); +            if (not _empty_cond.timed_wait( +                lock, to_time_dur(timeout), _not_empty_fcn +            )) return false; +            elem = this->pop_back();              lock.unlock();              _full_cond.notify_one();              return true; @@ -85,7 +100,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          UHD_INLINE void clear(void){              boost::unique_lock<boost::mutex> lock(_mutex); -            while (not_empty()) _buffer.pop_back(); +            while (not_empty()) this->pop_back();              lock.unlock();              _full_cond.notify_one();          } @@ -97,6 +112,21 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          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 elem_type pop_back(void){ +            elem_type elem = _buffer.back(); +            _buffer.back() = elem_type(); +            _buffer.pop_back(); +            return elem; +        }      };  }}} //namespace diff --git a/host/include/uhd/transport/udp_zero_copy.hpp b/host/include/uhd/transport/udp_zero_copy.hpp index 818709973..bbba97b21 100644 --- a/host/include/uhd/transport/udp_zero_copy.hpp +++ b/host/include/uhd/transport/udp_zero_copy.hpp @@ -20,6 +20,7 @@  #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{ @@ -50,14 +51,12 @@ public:       *       * \param addr a string representing the destination address       * \param port a string representing the destination port -     * \param recv_buff_size size in bytes for the recv buffer, 0 for automatic -     * \param send_buff_size size in bytes for the send buffer, 0 for automatic +     * \param hints optional parameters to pass to the underlying transport       */      static sptr make(          const std::string &addr,          const std::string &port, -        size_t recv_buff_size = 0, -        size_t send_buff_size = 0 +        const device_addr_t &hints = device_addr_t()      );  }; diff --git a/host/include/uhd/transport/usb_control.hpp b/host/include/uhd/transport/usb_control.hpp index f9829c3ec..e6c32f78e 100644 --- a/host/include/uhd/transport/usb_control.hpp +++ b/host/include/uhd/transport/usb_control.hpp @@ -18,7 +18,7 @@  #ifndef INCLUDED_UHD_TRANSPORT_USB_CONTROL_HPP  #define INCLUDED_UHD_TRANSPORT_USB_CONTROL_HPP -#include "usb_device_handle.hpp" +#include <uhd/transport/usb_device_handle.hpp>  namespace uhd { namespace transport { diff --git a/host/include/uhd/transport/usb_zero_copy.hpp b/host/include/uhd/transport/usb_zero_copy.hpp index 61bf380ba..b39171fba 100644 --- a/host/include/uhd/transport/usb_zero_copy.hpp +++ b/host/include/uhd/transport/usb_zero_copy.hpp @@ -18,8 +18,9 @@  #ifndef INCLUDED_UHD_TRANSPORT_USB_ZERO_COPY_HPP  #define INCLUDED_UHD_TRANSPORT_USB_ZERO_COPY_HPP -#include "usb_device_handle.hpp" +#include <uhd/transport/usb_device_handle.hpp>  #include <uhd/transport/zero_copy.hpp> +#include <uhd/types/device_addr.hpp>  namespace uhd { namespace transport { @@ -47,19 +48,13 @@ public:       * \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 recv_xfer_size the number of bytes for each receive transfer -     * \param recv_num_xfers the number of simultaneous receive transfers -     * \param send_xfer_size the number of bytes for each send transfer -     * \param send_num_xfers the number of simultaneous send transfers +     * \param hints optional parameters to pass to the underlying transport       */      static sptr make(          usb_device_handle::sptr handle, -        unsigned int recv_endpoint, -        unsigned int send_endpoint, -        size_t recv_xfer_size = 0, -        size_t recv_num_xfers = 0, -        size_t send_xfer_size = 0, -        size_t send_num_xfers = 0 +        size_t recv_endpoint, +        size_t send_endpoint, +        const device_addr_t &hints = device_addr_t()      );  }; diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp index 8ecafd3fb..7d8fb4b83 100644 --- a/host/include/uhd/transport/zero_copy.hpp +++ b/host/include/uhd/transport/zero_copy.hpp @@ -19,10 +19,10 @@  #define INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP  #include <uhd/config.hpp> -#include <uhd/utils/pimpl.hpp>  #include <boost/asio/buffer.hpp>  #include <boost/utility.hpp>  #include <boost/shared_ptr.hpp> +#include <boost/function.hpp>  namespace uhd{ namespace transport{ @@ -34,14 +34,27 @@ namespace uhd{ namespace transport{      class UHD_API managed_recv_buffer : boost::noncopyable{      public:          typedef boost::shared_ptr<managed_recv_buffer> sptr; +        typedef boost::function<void(void)> release_fcn_t; + +        /*! +         * Make a safe managed receive buffer: +         * A safe managed buffer ensures that release is called once, +         * either by the user or automatically upon deconstruction. +         * \param buff a reference to the constant buffer +         * \param release_fcn callback to release the memory +         * \return a new managed receive buffer +         */ +        static sptr make_safe( +            const boost::asio::const_buffer &buff, +            const release_fcn_t &release_fcn +        );          /*! -         * Managed recv buffer destructor:           * Signal to the transport that we are done with the buffer. -         * This should be called to release the buffer to the transport. +         * This should be called to release the buffer to the transport object.           * After calling, the referenced memory should be considered invalid.           */ -        virtual ~managed_recv_buffer(void) = 0; +        virtual void release(void) = 0;          /*!           * Get the size of the underlying buffer. @@ -71,20 +84,34 @@ namespace uhd{ namespace transport{      /*!       * A managed send buffer:       * Contains a reference to transport-managed memory, -     * and a method to release the memory after writing. +     * and a method to commit the memory after writing.       */      class UHD_API managed_send_buffer : boost::noncopyable{      public:          typedef boost::shared_ptr<managed_send_buffer> sptr; +        typedef boost::function<void(size_t)> commit_fcn_t; + +        /*! +         * Make a safe managed send buffer: +         * A safe managed buffer ensures that commit is called once, +         * either by the user or automatically upon deconstruction. +         * In the later case, the deconstructor will call commit(0). +         * \param buff a reference to the mutable buffer +         * \param commit_fcn callback to commit the memory +         * \return a new managed send buffer +         */ +        static sptr make_safe( +            const boost::asio::mutable_buffer &buff, +            const commit_fcn_t &commit_fcn +        );          /*!           * 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 -         * \return the number of bytes written, 0 for timeout, negative for error           */ -        virtual ssize_t commit(size_t num_bytes) = 0; +        virtual void commit(size_t num_bytes) = 0;          /*!           * Get the size of the underlying buffer. @@ -122,105 +149,46 @@ namespace uhd{ namespace transport{          /*!           * Get a new receive buffer from this transport object. -         * \param timeout_ms the timeout to get the buffer in ms +         * \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(size_t timeout_ms) = 0; +        virtual managed_recv_buffer::sptr get_recv_buff(double timeout = 0.1) = 0;          /*! -         * Get the maximum number of receive frames: -         *   The maximum number of valid managed recv buffers, -         *   or the maximum number of frames in the ring buffer, -         *   depending upon the underlying implementation. +         * 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 a new send buffer from this transport object. -         * \return a managed buffer, or null sptr on timeout/error -         */ -        virtual managed_send_buffer::sptr get_send_buff(void) = 0; - -        /*! -         * Get the maximum number of send frames: -         *   The maximum number of valid managed send buffers, -         *   or the maximum number of frames in the ring buffer, -         *   depending upon the underlying implementation. -         * \return number of frames -         */ -        virtual size_t get_num_send_frames(void) const = 0; - -    }; - -    /*! -     * A phony-zero-copy interface for transport objects that -     * provides a zero-copy interface on top of copying transport. -     * This interface implements the get managed recv buffer, -     * the base class must implement the private recv method. -     */ -    class UHD_API phony_zero_copy_recv_if : public virtual zero_copy_if{ -    public: -        /*! -         * Create a phony zero copy recv interface. -         * \param max_buff_size max buffer size in bytes +         * Get the size of a receive frame: +         * The maximum capacity of a single receive buffer. +         * \return frame size in bytes           */ -        phony_zero_copy_recv_if(size_t max_buff_size); - -        //! destructor -        virtual ~phony_zero_copy_recv_if(void); +        virtual size_t get_recv_frame_size(void) const = 0;          /*! -         * Get a new receive buffer from this transport object. -         * \param timeout_ms the timeout to get the buffer in ms +         * 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           */ -        managed_recv_buffer::sptr get_recv_buff(size_t timeout_ms); +        virtual managed_send_buffer::sptr get_send_buff(double timeout = 0.1) = 0; -    private:          /*! -         * Perform a private copying recv. -         * \param buff the buffer to write data into -         * \param timeout_ms the timeout to get the buffer in ms -         * \return the number of bytes written to buff, 0 for timeout, negative for error -         */ -        virtual ssize_t recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms) = 0; - -        UHD_PIMPL_DECL(impl) _impl; -    }; - -    /*! -     * A phony-zero-copy interface for transport objects that -     * provides a zero-copy interface on top of copying transport. -     * This interface implements the get managed send buffer, -     * the base class must implement the private send method. -     */ -    class UHD_API phony_zero_copy_send_if : public virtual zero_copy_if{ -    public: -        /*! -         * Create a phony zero copy send interface. -         * \param max_buff_size max buffer size in bytes -         */ -        phony_zero_copy_send_if(size_t max_buff_size); - -        //! destructor -        virtual ~phony_zero_copy_send_if(void); - -        /*! -         * Get a new send buffer from this transport object. -         * \return a managed buffer, or null sptr on timeout/error +         * Get the number of send frames: +         * The number of simultaneous send buffers in use. +         * \return number of frames           */ -        managed_send_buffer::sptr get_send_buff(void); +        virtual size_t get_num_send_frames(void) const = 0; -    private:          /*! -         * Perform a private copying send. -         * \param buff the buffer to read data from -         * \return the number of bytes read from buff, 0 for timeout, negative for error +         * Get the size of a send frame: +         * The maximum capacity of a single send buffer. +         * \return frame size in bytes           */ -        virtual ssize_t send(const boost::asio::const_buffer &buff) = 0; +        virtual size_t get_send_frame_size(void) const = 0; -        UHD_PIMPL_DECL(impl) _impl;      };  }} //namespace diff --git a/host/include/uhd/types/device_addr.hpp b/host/include/uhd/types/device_addr.hpp index e359d9467..eb3394230 100644 --- a/host/include/uhd/types/device_addr.hpp +++ b/host/include/uhd/types/device_addr.hpp @@ -20,6 +20,8 @@  #include <uhd/config.hpp>  #include <uhd/types/dict.hpp> +#include <boost/lexical_cast.hpp> +#include <stdexcept>  #include <vector>  #include <string> @@ -62,6 +64,24 @@ namespace uhd{           * \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]); +            } +        }      };      //handy typedef for a vector of device addresses diff --git a/host/include/uhd/usrp/single_usrp.hpp b/host/include/uhd/usrp/single_usrp.hpp index 1b89a3620..3cd263bce 100644 --- a/host/include/uhd/usrp/single_usrp.hpp +++ b/host/include/uhd/usrp/single_usrp.hpp @@ -57,15 +57,21 @@ public:       */      virtual device::sptr get_device(void) = 0; +    /******************************************************************* +     * Mboard methods +     ******************************************************************/      /*!       * Get a printable name for this usrp.       * \return a printable string       */      virtual std::string get_pp_string(void) = 0; -    /******************************************************************* -     * Misc -     ******************************************************************/ +    /*! +     * Get canonical name for this USRP motherboard. +     * \return a string representing the name +     */ +    virtual std::string get_mboard_name(void) = 0; +      /*!       * Gets the current time in the usrp time registers.       * \return a timespec representing current usrp time @@ -110,9 +116,16 @@ public:      /*******************************************************************       * 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. +     */      virtual void set_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec) = 0;      virtual uhd::usrp::subdev_spec_t get_rx_subdev_spec(void) = 0; +    virtual std::string get_rx_subdev_name(size_t chan = 0) = 0; +      virtual void set_rx_rate(double rate) = 0;      virtual double get_rx_rate(void) = 0; @@ -143,9 +156,16 @@ public:      /*******************************************************************       * 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. +     */      virtual void set_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec) = 0;      virtual uhd::usrp::subdev_spec_t get_tx_subdev_spec(void) = 0; +    virtual std::string get_tx_subdev_name(size_t chan = 0) = 0; +      virtual void set_tx_rate(double rate) = 0;      virtual double get_tx_rate(void) = 0; diff --git a/host/include/uhd/usrp/subdev_props.hpp b/host/include/uhd/usrp/subdev_props.hpp index cd07cb7a8..8f096ffe4 100644 --- a/host/include/uhd/usrp/subdev_props.hpp +++ b/host/include/uhd/usrp/subdev_props.hpp @@ -53,6 +53,7 @@ namespace uhd{ namespace usrp{          SUBDEV_PROP_ANTENNA_NAMES     = 'A', //ro, prop_names_t          SUBDEV_PROP_LO_LOCKED         = 'L', //ro, bool          SUBDEV_PROP_CONNECTION        = 'c', //ro, subdev_conn_t +        SUBDEV_PROP_ENABLED           = 'e', //rw, bool          SUBDEV_PROP_USE_LO_OFFSET     = 'l', //ro, bool          SUBDEV_PROP_RSSI              = 'R', //ro, float          SUBDEV_PROP_BANDWIDTH         = 'B'  //rw, double diff --git a/host/include/uhd/usrp/subdev_spec.hpp b/host/include/uhd/usrp/subdev_spec.hpp index 2f32509b9..5de3bb3b8 100644 --- a/host/include/uhd/usrp/subdev_spec.hpp +++ b/host/include/uhd/usrp/subdev_spec.hpp @@ -19,6 +19,7 @@  #define INCLUDED_UHD_USRP_SUBDEV_SPEC_HPP  #include <uhd/config.hpp> +#include <boost/operators.hpp>  #include <vector>  #include <string> @@ -27,7 +28,7 @@ namespace uhd{ namespace usrp{      /*!       * A subdevice specification (daughterboard, subdevice) name pairing.       */ -    struct UHD_API subdev_spec_pair_t{ +    struct UHD_API subdev_spec_pair_t : boost::equality_comparable<subdev_spec_pair_t>{          //! The daughterboard name          std::string db_name; @@ -45,6 +46,9 @@ namespace uhd{ namespace usrp{          );      }; +    //! 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 name, subdevice name) pairs:       *  | 
