summaryrefslogtreecommitdiffstats
path: root/host/include
diff options
context:
space:
mode:
Diffstat (limited to 'host/include')
-rw-r--r--host/include/uhd/device.hpp27
-rw-r--r--host/include/uhd/device.ipp9
-rw-r--r--host/include/uhd/transport/alignment_buffer.hpp9
-rw-r--r--host/include/uhd/transport/alignment_buffer.ipp15
-rw-r--r--host/include/uhd/transport/bounded_buffer.hpp12
-rw-r--r--host/include/uhd/transport/bounded_buffer.ipp50
-rw-r--r--host/include/uhd/transport/udp_zero_copy.hpp7
-rw-r--r--host/include/uhd/transport/usb_control.hpp2
-rw-r--r--host/include/uhd/transport/usb_device_handle.hpp2
-rw-r--r--host/include/uhd/transport/usb_zero_copy.hpp17
-rw-r--r--host/include/uhd/transport/zero_copy.hpp133
-rw-r--r--host/include/uhd/types/device_addr.hpp20
-rw-r--r--host/include/uhd/usrp/dboard_iface.hpp9
13 files changed, 166 insertions, 146 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_device_handle.hpp b/host/include/uhd/transport/usb_device_handle.hpp
index 9bb7db9c4..6f8d868be 100644
--- a/host/include/uhd/transport/usb_device_handle.hpp
+++ b/host/include/uhd/transport/usb_device_handle.hpp
@@ -38,7 +38,7 @@ namespace uhd { namespace transport {
* a true descriptor serial number string. This interface returns the
* actual string descriptor.
*/
-class usb_device_handle : boost::noncopyable {
+class UHD_API usb_device_handle : boost::noncopyable {
public:
typedef boost::shared_ptr<usb_device_handle> sptr;
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 513291b63..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,100 +149,46 @@ namespace uhd{ namespace transport{
/*!
* 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(void) = 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 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(void) = 0;
+ virtual managed_send_buffer::sptr get_send_buff(double timeout = 0.1) = 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.
+ * 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;
- };
-
- /*!
- * 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
- */
- phony_zero_copy_recv_if(size_t max_buff_size);
-
- //! destructor
- virtual ~phony_zero_copy_recv_if(void);
-
- /*!
- * Get a new receive buffer from this transport object.
- */
- managed_recv_buffer::sptr get_recv_buff(void);
-
- private:
- /*!
- * Perform a private copying recv.
- * \param buff the buffer to write data into
- * \return the number of bytes written to buff, 0 for timeout, negative for error
- */
- virtual ssize_t recv(const boost::asio::mutable_buffer &buff) = 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.
- */
- managed_send_buffer::sptr get_send_buff(void);
-
- 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/dboard_iface.hpp b/host/include/uhd/usrp/dboard_iface.hpp
index c7db244f2..c430ecd3f 100644
--- a/host/include/uhd/usrp/dboard_iface.hpp
+++ b/host/include/uhd/usrp/dboard_iface.hpp
@@ -242,6 +242,15 @@ public:
* \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;
};
}} //namespace