summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/include/uhd/device.hpp51
-rw-r--r--host/include/uhd/transport/vrt.hpp110
-rw-r--r--host/include/uhd/types/metadata.hpp14
-rwxr-xr-xhost/lib/transport/gen_vrt.py117
-rw-r--r--host/lib/transport/vrt_packet_handler.hpp252
-rw-r--r--host/lib/types.cpp4
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp32
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp9
-rw-r--r--host/test/vrt_test.cpp147
9 files changed, 401 insertions, 335 deletions
diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp
index d3e9015c4..f04a5b4fb 100644
--- a/host/include/uhd/device.hpp
+++ b/host/include/uhd/device.hpp
@@ -27,6 +27,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <boost/asio/buffer.hpp>
+#include <vector>
namespace uhd{
@@ -96,8 +97,22 @@ public:
RECV_MODE_ONE_PACKET = 1
};
+ //! wrapper call for single buffer recv //TODO put somewhere
+ size_t send(
+ const boost::asio::const_buffer &buff,
+ const tx_metadata_t &metadata,
+ const io_type_t &io_type,
+ send_mode_t send_mode
+ ){
+ return send(
+ std::vector<const void *>(1, boost::asio::buffer_cast<const void *>(buff)),
+ boost::asio::buffer_size(buff)/io_type.size,
+ metadata, io_type, send_mode
+ );
+ }
+
/*!
- * Send a buffer containing IF data with its metadata.
+ * 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,
@@ -108,23 +123,39 @@ public:
* 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 the buffer.
+ * of samples returned have been read out of each buffer.
*
- * \param buff a buffer pointing to some read-only memory
+ * \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
* \return the number of samples sent
*/
virtual size_t send(
- const boost::asio::const_buffer &buff,
+ const std::vector<const void *> &buffs,
+ size_t nsamps_per_buff,
const tx_metadata_t &metadata,
const io_type_t &io_type,
send_mode_t send_mode
) = 0;
+ //! wrapper call for single buffer recv //TODO put somewhere
+ size_t recv(
+ const boost::asio::mutable_buffer &buff,
+ rx_metadata_t &metadata,
+ const io_type_t &io_type,
+ recv_mode_t recv_mode
+ ){
+ return recv(
+ std::vector<void *>(1, boost::asio::buffer_cast<void *>(buff)),
+ boost::asio::buffer_size(buff)/io_type.size,
+ metadata, io_type, recv_mode
+ );
+ }
+
/*!
- * Receive a buffer containing IF data and its metadata.
+ * Receive buffers containing IF data described by the metadata.
*
* Receive handles fragmentation as follows:
* If the buffer has insufficient space to hold all samples
@@ -138,7 +169,7 @@ 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 the buffer.
+ * of samples returned have been written into each buffer.
* However, a call to receive may timeout and return zero samples.
* The timeout duration is decided by the underlying transport layer.
* The caller should assume that the call to receive will not return
@@ -146,17 +177,19 @@ public:
* and that the timeout duration is reasonably tuned for performance.
*
* When using the full buffer recv mode, the metadata only applies
- * to the first packet received and written into the recv buffer.
+ * to the first packet received and written into the recv buffers.
* Use the one packet recv mode to get per packet metadata.
*
- * \param buff the buffer to fill with IF data
+ * \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
* \return the number of samples received
*/
virtual size_t recv(
- const boost::asio::mutable_buffer &buff,
+ const std::vector<void *> &buffs,
+ size_t nsamps_per_buff,
rx_metadata_t &metadata,
const io_type_t &io_type,
recv_mode_t recv_mode
diff --git a/host/include/uhd/transport/vrt.hpp b/host/include/uhd/transport/vrt.hpp
index fb6efc99c..17da2d540 100644
--- a/host/include/uhd/transport/vrt.hpp
+++ b/host/include/uhd/transport/vrt.hpp
@@ -19,93 +19,77 @@
#define INCLUDED_UHD_TRANSPORT_VRT_HPP
#include <uhd/config.hpp>
-#include <uhd/types/metadata.hpp>
-#include <cstddef>
+#include <boost/cstdint.hpp>
+#include <cstddef> //size_t
namespace uhd{ namespace transport{
namespace vrt{
- static const size_t max_header_words32 = 5; //hdr+sid+tsi+tsf (no class id supported)
+ //! 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{
+ //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 metadata the tx metadata with flags and timestamps
- * \param header_buff memory to write the packed vrt header
- * \param num_header_words32 number of words in the vrt header
- * \param num_payload_words32 the length of the payload
- * \param num_packet_words32 the length of the packet
- * \param packet_count the packet count sequence number
- * \param tick_rate ticks per second used in time conversion
+ * \param packet_buff memory to write the packed vrt header
+ * \param if_packet_info the if packet info (read/write)
*/
- UHD_API void pack_be(
- const tx_metadata_t &metadata, //input
- boost::uint32_t *header_buff, //output
- size_t &num_header_words32, //output
- size_t num_payload_words32, //input
- size_t &num_packet_words32, //output
- size_t packet_count, //input
- double tick_rate //input
+ 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 metadata the rx metadata with flags and timestamps
- * \param header_buff memory to read the packed vrt header
- * \param num_header_words32 number of words in the vrt header
- * \param num_payload_words32 the length of the payload
- * \param num_packet_words32 the length of the packet
- * \param packet_count the packet count sequence number
- * \param tick_rate ticks per second used in time conversion
+ * \param packet_buff memory to read the packed vrt header
+ * \param if_packet_info the if packet info (read/write)
*/
- UHD_API void unpack_be(
- rx_metadata_t &metadata, //output
- const boost::uint32_t *header_buff, //input
- size_t &num_header_words32, //output
- size_t &num_payload_words32, //output
- size_t num_packet_words32, //input
- size_t &packet_count, //output
- double tick_rate //input
+ 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 metadata the tx metadata with flags and timestamps
- * \param header_buff memory to write the packed vrt header
- * \param num_header_words32 number of words in the vrt header
- * \param num_payload_words32 the length of the payload
- * \param num_packet_words32 the length of the packet
- * \param packet_count the packet count sequence number
- * \param tick_rate ticks per second used in time conversion
+ * \param packet_buff memory to write the packed vrt header
+ * \param if_packet_info the if packet info (read/write)
*/
- UHD_API void pack_le(
- const tx_metadata_t &metadata, //input
- boost::uint32_t *header_buff, //output
- size_t &num_header_words32, //output
- size_t num_payload_words32, //input
- size_t &num_packet_words32, //output
- size_t packet_count, //input
- double tick_rate //input
+ 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 metadata the rx metadata with flags and timestamps
- * \param header_buff memory to read the packed vrt header
- * \param num_header_words32 number of words in the vrt header
- * \param num_payload_words32 the length of the payload
- * \param num_packet_words32 the length of the packet
- * \param packet_count the packet count sequence number
- * \param tick_rate ticks per second used in time conversion
+ * \param packet_buff memory to read the packed vrt header
+ * \param if_packet_info the if packet info (read/write)
*/
- UHD_API void unpack_le(
- rx_metadata_t &metadata, //output
- const boost::uint32_t *header_buff, //input
- size_t &num_header_words32, //output
- size_t &num_payload_words32, //output
- size_t num_packet_words32, //input
- size_t &packet_count, //output
- double tick_rate //input
+ UHD_API void if_hdr_unpack_le(
+ const boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
);
} //namespace vrt
diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp
index 55add71cc..f4c962ff7 100644
--- a/host/include/uhd/types/metadata.hpp
+++ b/host/include/uhd/types/metadata.hpp
@@ -31,13 +31,6 @@ namespace uhd{
*/
struct UHD_API rx_metadata_t{
/*!
- * Stream IDs may be used to identify source DSP units.
- * --Not currently used in any known device implementation.--
- */
- bool has_stream_id;
- boost::uint32_t stream_id;
-
- /*!
* Time specification:
* Set from timestamps on incoming data when provided.
*/
@@ -84,13 +77,6 @@ namespace uhd{
*/
struct UHD_API tx_metadata_t{
/*!
- * Stream IDs may be used to identify destination DSP units.
- * --Not currently used in any known device implementation.--
- */
- bool has_stream_id;
- boost::uint32_t stream_id;
-
- /*!
* Time specification:
* Set has time spec to false to perform a send "now".
* Or, set to true, and fill in time spec for a send "at".
diff --git a/host/lib/transport/gen_vrt.py b/host/lib/transport/gen_vrt.py
index 8e0fce9ff..ad87b9972 100755
--- a/host/lib/transport/gen_vrt.py
+++ b/host/lib/transport/gen_vrt.py
@@ -61,20 +61,22 @@ using namespace uhd::transport;
#set $tsf_p = 0b01000
#set $tlr_p = 0b10000
-void vrt::pack_$(suffix)(
- const tx_metadata_t &metadata, //input
- boost::uint32_t *header_buff, //output
- size_t &num_header_words32, //output
- size_t num_payload_words32, //input
- size_t &num_packet_words32, //output
- size_t packet_count, //input
- double tick_rate //input
+static UHD_INLINE void pack_uint64_$(suffix)(boost::uint64_t num, boost::uint32_t *mem){
+ *(reinterpret_cast<boost::uint64_t *>(mem)) = $(XE_MACRO)(num);
+}
+
+void vrt::if_hdr_pack_$(suffix)(
+ boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
){
boost::uint32_t vrt_hdr_flags = 0;
boost::uint8_t pred = 0;
- if (metadata.has_stream_id) pred |= $hex($sid_p);
- if (metadata.has_time_spec) pred |= $hex($tsi_p | $tsf_p);
+ if (if_packet_info.has_sid) pred |= $hex($sid_p);
+ if (if_packet_info.has_cid) pred |= $hex($cid_p);
+ if (if_packet_info.has_tsi) pred |= $hex($tsi_p);
+ if (if_packet_info.has_tsf) pred |= $hex($tsf_p);
+ if (if_packet_info.has_tlr) pred |= $hex($tlr_p);
switch(pred){
#for $pred in range(2**5)
@@ -83,79 +85,71 @@ void vrt::pack_$(suffix)(
#set $flags = 0
########## Stream ID ##########
#if $pred & $sid_p
- header_buff[$num_header_words] = $(XE_MACRO)(metadata.stream_id);
+ packet_buff[$num_header_words] = $(XE_MACRO)(if_packet_info.sid);
#set $num_header_words += 1
#set $flags |= (0x1 << 28);
#end if
########## Class ID ##########
#if $pred & $cid_p
- header_buff[$num_header_words] = 0;
- #set $num_header_words += 1
- header_buff[$num_header_words] = 0;
- #set $num_header_words += 1
+ pack_uint64_$(suffix)(if_packet_info.cid, packet_buff+$num_header_words);
+ #set $num_header_words += 2
#set $flags |= (0x1 << 27);
#end if
########## Integer Time ##########
#if $pred & $tsi_p
- header_buff[$num_header_words] = $(XE_MACRO)(boost::uint32_t(metadata.time_spec.get_full_secs()));
+ packet_buff[$num_header_words] = $(XE_MACRO)(if_packet_info.tsi);
#set $num_header_words += 1
#set $flags |= (0x3 << 22);
#end if
########## Fractional Time ##########
#if $pred & $tsf_p
- header_buff[$num_header_words] = 0;
- #set $num_header_words += 1
- header_buff[$num_header_words] = $(XE_MACRO)(boost::uint32_t(metadata.time_spec.get_tick_count(tick_rate)));
- #set $num_header_words += 1
+ pack_uint64_$(suffix)(if_packet_info.tsf, packet_buff+$num_header_words);
+ #set $num_header_words += 2
#set $flags |= (0x1 << 20);
#end if
########## Trailer ##########
#if $pred & $tlr_p
+ packet_buff[$num_header_words+if_packet_info.num_payload_words32] = $(XE_MACRO)(if_packet_info.tlr);
#set $flags |= (0x1 << 26);
#set $num_trailer_words = 1;
#else
#set $num_trailer_words = 0;
#end if
########## Variables ##########
- num_header_words32 = $num_header_words;
- num_packet_words32 = $($num_header_words + $num_trailer_words) + num_payload_words32;
+ if_packet_info.num_header_words32 = $num_header_words;
+ if_packet_info.num_packet_words32 = $($num_header_words + $num_trailer_words) + if_packet_info.num_payload_words32;
vrt_hdr_flags = $hex($flags);
break;
#end for
}
//set the burst flags
- if (metadata.start_of_burst) vrt_hdr_flags |= $hex(0x1 << 25);
- if (metadata.end_of_burst) vrt_hdr_flags |= $hex(0x1 << 24);
+ if (if_packet_info.sob) vrt_hdr_flags |= $hex(0x1 << 25);
+ if (if_packet_info.eob) vrt_hdr_flags |= $hex(0x1 << 24);
//fill in complete header word
- header_buff[0] = $(XE_MACRO)(boost::uint32_t(0
+ packet_buff[0] = $(XE_MACRO)(boost::uint32_t(0
| vrt_hdr_flags
- | ((packet_count & 0xf) << 16)
- | (num_packet_words32 & 0xffff)
+ | ((if_packet_info.packet_count & 0xf) << 16)
+ | (if_packet_info.num_packet_words32 & 0xffff)
));
}
-void vrt::unpack_$(suffix)(
- rx_metadata_t &metadata, //output
- const boost::uint32_t *header_buff, //input
- size_t &num_header_words32, //output
- size_t &num_payload_words32, //output
- size_t num_packet_words32, //input
- size_t &packet_count, //output
- double tick_rate //input
-){
- //clear the metadata
- metadata = rx_metadata_t();
- boost::uint32_t secs = 0, ticks = 0;
+static UHD_INLINE void unpack_uint64_$(suffix)(boost::uint64_t &num, const boost::uint32_t *mem){
+ num = $(XE_MACRO)(*reinterpret_cast<const boost::uint64_t *>(mem));
+}
+void vrt::if_hdr_unpack_$(suffix)(
+ const boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
+){
//extract vrt header
- boost::uint32_t vrt_hdr_word = $(XE_MACRO)(header_buff[0]);
+ boost::uint32_t vrt_hdr_word = $(XE_MACRO)(packet_buff[0]);
size_t packet_words32 = vrt_hdr_word & 0xffff;
- packet_count = (vrt_hdr_word >> 16) & 0xf;
+ if_packet_info.packet_count = (vrt_hdr_word >> 16) & 0xf;
//failure cases
- if (packet_words32 == 0 or num_packet_words32 < packet_words32)
+ if (packet_words32 == 0 or if_packet_info.num_packet_words32 < packet_words32)
throw std::runtime_error("bad vrt header or packet fragment");
if (vrt_hdr_word & (0x7 << 29))
throw std::runtime_error("unsupported vrt packet type");
@@ -174,41 +168,48 @@ void vrt::unpack_$(suffix)(
#set $num_header_words = 1
########## Stream ID ##########
#if $pred & $sid_p
- metadata.has_stream_id = true;
- metadata.stream_id = $(XE_MACRO)(header_buff[$num_header_words]);
+ if_packet_info.has_sid = true;
+ if_packet_info.sid = $(XE_MACRO)(packet_buff[$num_header_words]);
#set $num_header_words += 1
+ #else
+ if_packet_info.has_sid = false;
#end if
########## Class ID ##########
#if $pred & $cid_p
- #set $num_header_words += 1
- #set $num_header_words += 1
+ if_packet_info.has_cid = true;
+ unpack_uint64_$(suffix)(if_packet_info.cid, packet_buff+$num_header_words);
+ #set $num_header_words += 2
+ #else
+ if_packet_info.has_cid = false;
#end if
########## Integer Time ##########
#if $pred & $tsi_p
- #set $has_time_spec = True
- secs = $(XE_MACRO)(header_buff[$num_header_words]);
+ if_packet_info.has_tsi = true;
+ if_packet_info.tsi = $(XE_MACRO)(packet_buff[$num_header_words]);
#set $num_header_words += 1
+ #else
+ if_packet_info.has_tsi = false;
#end if
########## Fractional Time ##########
#if $pred & $tsf_p
- #set $has_time_spec = True
- #set $num_header_words += 1
- ticks = $(XE_MACRO)(header_buff[$num_header_words]);
- #set $num_header_words += 1
- #end if
- #if $has_time_spec
- metadata.has_time_spec = true;
- metadata.time_spec = time_spec_t(secs, ticks, tick_rate);
+ if_packet_info.has_tsf = true;
+ unpack_uint64_$(suffix)(if_packet_info.tsf, packet_buff+$num_header_words);
+ #set $num_header_words += 2
+ #else
+ if_packet_info.has_tsf = false;
#end if
########## Trailer ##########
#if $pred & $tlr_p
+ if_packet_info.has_tlr = true;
+ if_packet_info.tlr = $(XE_MACRO)(packet_buff[$num_header_words+packet_words32]);
#set $num_trailer_words = 1;
#else
+ if_packet_info.has_tlr = false;
#set $num_trailer_words = 0;
#end if
########## Variables ##########
- num_header_words32 = $num_header_words;
- num_payload_words32 = packet_words32 - $($num_header_words + $num_trailer_words);
+ if_packet_info.num_header_words32 = $num_header_words;
+ if_packet_info.num_payload_words32 = packet_words32 - $($num_header_words + $num_trailer_words);
break;
#end for
}
diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp
index 8dfc7b3d0..01cccd81e 100644
--- a/host/lib/transport/vrt_packet_handler.hpp
+++ b/host/lib/transport/vrt_packet_handler.hpp
@@ -20,6 +20,7 @@
#include <uhd/config.hpp>
#include <uhd/device.hpp>
+#include <uhd/utils/assert.hpp>
#include <uhd/types/io_type.hpp>
#include <uhd/types/otw_type.hpp>
#include <uhd/types/metadata.hpp>
@@ -30,37 +31,43 @@
#include <boost/function.hpp>
#include <stdexcept>
#include <iostream>
+#include <vector>
namespace vrt_packet_handler{
/***********************************************************************
* vrt packet handler for recv
**********************************************************************/
+ typedef std::vector<uhd::transport::managed_recv_buffer::sptr> managed_recv_buffs_t;
+
struct recv_state{
+ //width of the receiver in channels
+ size_t width;
+
//init the expected seq number
- size_t next_packet_seq;
+ std::vector<size_t> next_packet_seq;
//state variables to handle fragments
- uhd::transport::managed_recv_buffer::sptr managed_buff;
- boost::asio::const_buffer copy_buff;
+ managed_recv_buffs_t managed_buffs;
+ std::vector<const boost::uint8_t *> copy_buffs;
+ size_t size_of_copy_buffs;
size_t fragment_offset_in_samps;
- recv_state(void){
- //first expected seq is zero
- next_packet_seq = 0;
-
- //initially empty copy buffer
- copy_buff = boost::asio::buffer("", 0);
+ recv_state(size_t width):
+ width(width),
+ next_packet_seq(width, 0),
+ managed_buffs(width),
+ copy_buffs(width, NULL),
+ size_of_copy_buffs(0),
+ fragment_offset_in_samps(0)
+ {
+ /* NOP */
}
};
- typedef boost::function<uhd::transport::managed_recv_buffer::sptr(void)> get_recv_buff_t;
-
- typedef boost::function<void(uhd::transport::managed_recv_buffer::sptr)> recv_cb_t;
+ typedef boost::function<bool(managed_recv_buffs_t &)> get_recv_buffs_t;
- static UHD_INLINE void recv_cb_nop(uhd::transport::managed_recv_buffer::sptr){
- /* NOP */
- }
+ typedef boost::function<void(managed_recv_buffs_t &)> recv_cb_t;
/*******************************************************************
* Unpack a received vrt header and set the copy buffer.
@@ -74,33 +81,41 @@ namespace vrt_packet_handler{
vrt_unpacker_type vrt_unpacker,
size_t vrt_header_offset_words32
){
- size_t num_packet_words32 = state.managed_buff->size()/sizeof(boost::uint32_t);
+ size_t num_packet_words32 = state.managed_buffs[0]->size()/sizeof(boost::uint32_t);
if (num_packet_words32 <= vrt_header_offset_words32){
- state.copy_buff = boost::asio::buffer("", 0);
+ state.size_of_copy_buffs = 0;
return; //must exit here after setting the buffer
}
- const boost::uint32_t *vrt_hdr = state.managed_buff->cast<const boost::uint32_t *>() + vrt_header_offset_words32;
- size_t num_header_words32_out, num_payload_words32_out, packet_count_out;
- vrt_unpacker(
- metadata, //output
- vrt_hdr, //input
- num_header_words32_out, //output
- num_payload_words32_out, //output
- num_packet_words32, //input
- packet_count_out, //output
- tick_rate
- );
- //handle the packet count / sequence number
- if (packet_count_out != state.next_packet_seq){
- std::cerr << "S" << (packet_count_out - state.next_packet_seq)%16;
+ //vrt unpack each managed buffer
+ uhd::transport::vrt::if_packet_info_t if_packet_info;
+ for (size_t i = 0; i < state.width; i++){
+ const boost::uint32_t *vrt_hdr = state.managed_buffs[i]->cast<const boost::uint32_t *>() + vrt_header_offset_words32;
+ if_packet_info.num_packet_words32 = num_packet_words32;
+ vrt_unpacker(vrt_hdr, if_packet_info);
+
+ //handle the packet count / sequence number
+ if (if_packet_info.packet_count != state.next_packet_seq[i]){
+ std::cerr << "S" << (if_packet_info.packet_count - state.next_packet_seq[i])%16;
+ }
+ state.next_packet_seq[i] = (if_packet_info.packet_count+1)%16;
+
+ //setup the buffer to point to the data
+ state.copy_buffs[i] = reinterpret_cast<const boost::uint8_t *>(vrt_hdr + if_packet_info.num_header_words32);
+
+ //store the minimum payload length into the copy buffer length
+ size_t num_payload_bytes = if_packet_info.num_payload_words32*sizeof(boost::uint32_t);
+ if (i == 0 or state.size_of_copy_buffs > num_payload_bytes){
+ state.size_of_copy_buffs = num_payload_bytes;
+ }
}
- state.next_packet_seq = (packet_count_out+1)%16;
- //setup the buffer to point to the data
- state.copy_buff = boost::asio::buffer(
- vrt_hdr + num_header_words32_out,
- num_payload_words32_out*sizeof(boost::uint32_t)
+ //store the last vrt info into the metadata
+ metadata.has_time_spec = if_packet_info.has_tsi or if_packet_info.has_tsf;
+ metadata.time_spec = uhd::time_spec_t(
+ time_t((if_packet_info.has_tsi)? if_packet_info.tsi : 0),
+ size_t((if_packet_info.has_tsf)? if_packet_info.tsf : 0),
+ tick_rate
);
}
@@ -111,24 +126,22 @@ namespace vrt_packet_handler{
template<typename vrt_unpacker_type>
static UHD_INLINE size_t _recv1(
recv_state &state,
- void *recv_mem,
+ const std::vector<void *> &buffs,
+ size_t offset_bytes,
size_t total_samps,
uhd::rx_metadata_t &metadata,
const uhd::io_type_t &io_type,
const uhd::otw_type_t &otw_type,
double tick_rate,
vrt_unpacker_type vrt_unpacker,
- const get_recv_buff_t &get_recv_buff,
+ const get_recv_buffs_t &get_recv_buffs,
//use these two params to handle a layer above vrt
- size_t vrt_header_offset_words32,
- const recv_cb_t &recv_cb
+ size_t vrt_header_offset_words32
){
//perform a receive if no rx data is waiting to be copied
- if (boost::asio::buffer_size(state.copy_buff) == 0){
+ if (state.size_of_copy_buffs == 0){
state.fragment_offset_in_samps = 0;
- state.managed_buff = get_recv_buff();
- if (state.managed_buff.get() == NULL) return 0;
- recv_cb(state.managed_buff); //callback before vrt unpack
+ if (not get_recv_buffs(state.managed_buffs)) return 0;
try{
_recv1_helper(
state, metadata, tick_rate, vrt_unpacker, vrt_header_offset_words32
@@ -141,26 +154,28 @@ namespace vrt_packet_handler{
//extract the number of samples available to copy
size_t bytes_per_item = otw_type.get_sample_size();
- size_t bytes_available = boost::asio::buffer_size(state.copy_buff);
+ size_t bytes_available = state.size_of_copy_buffs;
size_t num_samps = std::min(total_samps, bytes_available/bytes_per_item);
+ size_t bytes_to_copy = num_samps*bytes_per_item;
//setup the fragment flags and offset
metadata.more_fragments = total_samps < num_samps;
metadata.fragment_offset = state.fragment_offset_in_samps;
state.fragment_offset_in_samps += num_samps; //set for next call
- //copy-convert the samples from the recv buffer
- uhd::transport::convert_otw_type_to_io_type(
- boost::asio::buffer_cast<const void*>(state.copy_buff), otw_type,
- recv_mem, io_type, num_samps
- );
+ for (size_t i = 0; i < state.width; i++){
+ //copy-convert the samples from the recv buffer
+ uhd::transport::convert_otw_type_to_io_type(
+ state.copy_buffs[i], otw_type,
+ reinterpret_cast<boost::uint8_t *>(buffs[i]) + offset_bytes,
+ io_type, num_samps
+ );
- //update the rx copy buffer to reflect the bytes copied
- size_t bytes_copied = num_samps*bytes_per_item;
- state.copy_buff = boost::asio::buffer(
- boost::asio::buffer_cast<const boost::uint8_t*>(state.copy_buff) + bytes_copied,
- bytes_available - bytes_copied
- );
+ //update the rx copy buffer to reflect the bytes copied
+ state.copy_buffs[i] = reinterpret_cast<const boost::uint8_t *>(state.copy_buffs[i]) + bytes_to_copy;
+ }
+ //update the copy buffer's availability
+ state.size_of_copy_buffs -= bytes_to_copy;
return num_samps;
}
@@ -171,20 +186,19 @@ namespace vrt_packet_handler{
template<typename vrt_unpacker_type>
static UHD_INLINE size_t recv(
recv_state &state,
- const boost::asio::mutable_buffer &buff,
+ const std::vector<void *> &buffs,
+ const size_t total_num_samps,
uhd::rx_metadata_t &metadata,
uhd::device::recv_mode_t recv_mode,
const uhd::io_type_t &io_type,
const uhd::otw_type_t &otw_type,
double tick_rate,
vrt_unpacker_type vrt_unpacker,
- const get_recv_buff_t &get_recv_buff,
+ const get_recv_buffs_t &get_recv_buffs,
//use these two params to handle a layer above vrt
- size_t vrt_header_offset_words32 = 0,
- const recv_cb_t& recv_cb = &recv_cb_nop
+ size_t vrt_header_offset_words32 = 0
){
metadata = uhd::rx_metadata_t(); //init the metadata
- const size_t total_num_samps = boost::asio::buffer_size(buff)/io_type.size;
switch(recv_mode){
@@ -193,15 +207,14 @@ namespace vrt_packet_handler{
////////////////////////////////////////////////////////////////
return _recv1(
state,
- boost::asio::buffer_cast<void *>(buff),
+ buffs, 0,
total_num_samps,
metadata,
io_type, otw_type,
tick_rate,
vrt_unpacker,
- get_recv_buff,
- vrt_header_offset_words32,
- recv_cb
+ get_recv_buffs,
+ vrt_header_offset_words32
);
}
@@ -213,15 +226,14 @@ namespace vrt_packet_handler{
while(accum_num_samps < total_num_samps){
size_t num_samps = _recv1(
state,
- boost::asio::buffer_cast<boost::uint8_t *>(buff) + (accum_num_samps*io_type.size),
+ buffs, accum_num_samps*io_type.size,
total_num_samps - accum_num_samps,
(accum_num_samps == 0)? metadata : tmp_md, //only the first metadata gets kept
io_type, otw_type,
tick_rate,
vrt_unpacker,
- get_recv_buff,
- vrt_header_offset_words32,
- recv_cb
+ get_recv_buffs,
+ vrt_header_offset_words32
);
if (num_samps == 0) break; //had a recv timeout or error, break loop
accum_num_samps += num_samps;
@@ -236,6 +248,8 @@ namespace vrt_packet_handler{
/***********************************************************************
* vrt packet handler for send
**********************************************************************/
+ typedef std::vector<uhd::transport::managed_send_buffer::sptr> managed_send_buffs_t;
+
struct send_state{
//init the expected seq number
size_t next_packet_seq;
@@ -245,13 +259,9 @@ namespace vrt_packet_handler{
}
};
- typedef boost::function<uhd::transport::managed_send_buffer::sptr(void)> get_send_buff_t;
-
- typedef boost::function<void(uhd::transport::managed_send_buffer::sptr)> send_cb_t;
+ typedef boost::function<bool(managed_send_buffs_t &)> get_send_buffs_t;
- static UHD_INLINE void send_cb_nop(uhd::transport::managed_send_buffer::sptr){
- /* NOP */
- }
+ typedef boost::function<void(managed_send_buffs_t &)> send_cb_t;
/*******************************************************************
* Pack a vrt header, copy-convert the data, and send it.
@@ -260,46 +270,51 @@ namespace vrt_packet_handler{
template<typename vrt_packer_type>
static UHD_INLINE void _send1(
send_state &state,
- const void *send_mem,
+ const std::vector<const void *> &buffs,
+ size_t offset_bytes,
size_t num_samps,
const uhd::tx_metadata_t &metadata,
const uhd::io_type_t &io_type,
const uhd::otw_type_t &otw_type,
double tick_rate,
vrt_packer_type vrt_packer,
- const get_send_buff_t &get_send_buff,
- size_t vrt_header_offset_words32,
- const send_cb_t& send_cb
+ const get_send_buffs_t &get_send_buffs,
+ size_t vrt_header_offset_words32
){
- //get a new managed send buffer
- uhd::transport::managed_send_buffer::sptr send_buff = get_send_buff();
- boost::uint32_t *tx_mem = send_buff->cast<boost::uint32_t *>() + vrt_header_offset_words32;
-
- size_t num_header_words32, num_packet_words32;
- size_t packet_count = state.next_packet_seq++;
-
- //pack metadata into a vrt header
- vrt_packer(
- metadata, //input
- tx_mem, //output
- num_header_words32, //output
- num_samps, //input
- num_packet_words32, //output
- packet_count, //input
- tick_rate
- );
-
- //copy-convert the samples into the send buffer
- uhd::transport::convert_io_type_to_otw_type(
- send_mem, io_type,
- tx_mem + num_header_words32, otw_type,
- num_samps
- );
-
- send_cb(send_buff); //callback after memory filled
+ //translate the metadata to vrt if packet info
+ uhd::transport::vrt::if_packet_info_t if_packet_info;
+ if_packet_info.has_sid = false;
+ if_packet_info.has_cid = false;
+ if_packet_info.has_tsi = metadata.has_time_spec;
+ if_packet_info.tsi = boost::uint32_t(metadata.time_spec.get_full_secs());
+ if_packet_info.has_tsf = metadata.has_time_spec;
+ if_packet_info.tsf = boost::uint64_t(metadata.time_spec.get_tick_count(tick_rate));
+ if_packet_info.has_tlr = false;
+ if_packet_info.num_payload_words32 = (num_samps*io_type.size)/sizeof(boost::uint32_t);
+ if_packet_info.packet_count = state.next_packet_seq++;
+
+ //get send buffers for each channel
+ managed_send_buffs_t send_buffs(buffs.size());
+ UHD_ASSERT_THROW(get_send_buffs(send_buffs));
+
+ for (size_t i = 0; i < buffs.size(); i++){
+ //calculate pointers with offsets to io and otw memory
+ const boost::uint8_t *io_mem = reinterpret_cast<const boost::uint8_t *>(buffs[i]) + offset_bytes;
+ boost::uint32_t *otw_mem = send_buffs[i]->cast<boost::uint32_t *>() + vrt_header_offset_words32;
+
+ //pack metadata into a vrt header
+ vrt_packer(otw_mem, if_packet_info);
+
+ //copy-convert the samples into the send buffer
+ uhd::transport::convert_io_type_to_otw_type(
+ io_mem, io_type,
+ otw_mem + if_packet_info.num_header_words32, otw_type,
+ num_samps
+ );
- //commit the samples to the zero-copy interface
- send_buff->commit(num_packet_words32*sizeof(boost::uint32_t));
+ //commit the samples to the zero-copy interface
+ send_buffs[i]->commit(if_packet_info.num_packet_words32*sizeof(boost::uint32_t));
+ }
}
/*******************************************************************
@@ -308,20 +323,19 @@ namespace vrt_packet_handler{
template<typename vrt_packer_type>
static UHD_INLINE size_t send(
send_state &state,
- const boost::asio::const_buffer &buff,
+ const std::vector<const void *> &buffs,
+ const size_t total_num_samps,
const uhd::tx_metadata_t &metadata,
uhd::device::send_mode_t send_mode,
const uhd::io_type_t &io_type,
const uhd::otw_type_t &otw_type,
double tick_rate,
vrt_packer_type vrt_packer,
- const get_send_buff_t &get_send_buff,
+ const get_send_buffs_t &get_send_buffs,
size_t max_samples_per_packet,
//use these two params to handle a layer above vrt
- size_t vrt_header_offset_words32 = 0,
- const send_cb_t& send_cb = &send_cb_nop
+ size_t vrt_header_offset_words32 = 0
){
- const size_t total_num_samps = boost::asio::buffer_size(buff)/io_type.size;
if (total_num_samps <= max_samples_per_packet) send_mode = uhd::device::SEND_MODE_ONE_PACKET;
switch(send_mode){
@@ -331,15 +345,14 @@ namespace vrt_packet_handler{
size_t num_samps = std::min(total_num_samps, max_samples_per_packet);
_send1(
state,
- boost::asio::buffer_cast<const void *>(buff),
+ buffs, 0,
num_samps,
metadata,
io_type, otw_type,
tick_rate,
vrt_packer,
- get_send_buff,
- vrt_header_offset_words32,
- send_cb
+ get_send_buffs,
+ vrt_header_offset_words32
);
return num_samps;
}
@@ -366,15 +379,14 @@ namespace vrt_packet_handler{
//send the fragment with the helper function
_send1(
state,
- boost::asio::buffer_cast<const boost::uint8_t *>(buff) + (n*max_samples_per_packet*io_type.size),
+ buffs, n*max_samples_per_packet*io_type.size,
(n == final_fragment_index)?(total_num_samps%max_samples_per_packet):max_samples_per_packet,
md,
io_type, otw_type,
tick_rate,
vrt_packer,
- get_send_buff,
- vrt_header_offset_words32,
- send_cb
+ get_send_buffs,
+ vrt_header_offset_words32
);
}
return total_num_samps;
diff --git a/host/lib/types.cpp b/host/lib/types.cpp
index 6a9fcf5b5..9cf2a2220 100644
--- a/host/lib/types.cpp
+++ b/host/lib/types.cpp
@@ -96,8 +96,6 @@ stream_cmd_t::stream_cmd_t(const stream_mode_t &stream_mode):
* metadata
**********************************************************************/
rx_metadata_t::rx_metadata_t(void):
- has_stream_id(false),
- stream_id(0),
has_time_spec(false),
time_spec(time_spec_t()),
more_fragments(false),
@@ -107,8 +105,6 @@ rx_metadata_t::rx_metadata_t(void):
}
tx_metadata_t::tx_metadata_t(void):
- has_stream_id(false),
- stream_id(0),
has_time_spec(false),
time_spec(time_spec_t()),
start_of_burst(false),
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index aa0f63321..e3a3a3b17 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -52,7 +52,7 @@ struct usrp2_impl::io_impl{
bounded_buffer<managed_recv_buffer::sptr>::sptr recv_pirate_booty;
};
-usrp2_impl::io_impl::io_impl(zero_copy_if::sptr zc_if){
+usrp2_impl::io_impl::io_impl(zero_copy_if::sptr zc_if): packet_handler_recv_state(1){
//create a large enough booty
size_t num_frames = zc_if->get_num_recv_frames();
std::cout << "Recv pirate num frames: " << num_frames << std::endl;
@@ -130,19 +130,26 @@ void usrp2_impl::io_init(void){
/***********************************************************************
* Send Data
**********************************************************************/
+bool tmp_todo_fixme_remove_get_send_buffs(vrt_packet_handler::managed_send_buffs_t &buffs, const zero_copy_if::sptr &zc_if){
+ buffs[0] = zc_if->get_send_buff();
+ return buffs[0].get() != NULL;
+}
+
size_t usrp2_impl::send(
- const asio::const_buffer &buff,
+ const std::vector<const void *> &buffs,
+ size_t nsamps_per_buff,
const tx_metadata_t &metadata,
const io_type_t &io_type,
send_mode_t send_mode
){
return vrt_packet_handler::send(
_io_impl->packet_handler_send_state, //last state of the send handler
- buff, metadata, send_mode, //buffer to empty and samples metadata
+ buffs, nsamps_per_buff, //buffer to empty
+ metadata, send_mode, //samples metadata
io_type, _tx_otw_type, //input and output types to convert
get_master_clock_freq(), //master clock tick rate
- uhd::transport::vrt::pack_be,
- boost::bind(&zero_copy_if::get_send_buff, _data_transport),
+ uhd::transport::vrt::if_hdr_pack_be,
+ boost::bind(&tmp_todo_fixme_remove_get_send_buffs, _1, _data_transport),
get_max_send_samps_per_packet()
);
}
@@ -150,18 +157,25 @@ size_t usrp2_impl::send(
/***********************************************************************
* Receive Data
**********************************************************************/
+bool tmp_todo_fixme_remove_get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs, boost::shared_ptr<usrp2_impl::io_impl> impl){
+ buffs[0] = impl->get_recv_buff();
+ return buffs[0].get() != NULL;
+}
+
size_t usrp2_impl::recv(
- const asio::mutable_buffer &buff,
+ const std::vector<void *> &buffs,
+ size_t nsamps_per_buff,
rx_metadata_t &metadata,
const io_type_t &io_type,
recv_mode_t recv_mode
){
return vrt_packet_handler::recv(
_io_impl->packet_handler_recv_state, //last state of the recv handler
- buff, metadata, recv_mode, //buffer to fill and samples metadata
+ buffs, nsamps_per_buff, //buffer to empty
+ metadata, recv_mode, //samples metadata
io_type, _rx_otw_type, //input and output types to convert
get_master_clock_freq(), //master clock tick rate
- uhd::transport::vrt::unpack_be,
- boost::bind(&usrp2_impl::io_impl::get_recv_buff, _io_impl)
+ uhd::transport::vrt::if_hdr_unpack_be,
+ boost::bind(&tmp_todo_fixme_remove_get_recv_buffs, _1, _io_impl)
);
}
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 2126b9565..70735173e 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -108,7 +108,7 @@ public:
return _max_tx_bytes_per_packet/_tx_otw_type.get_sample_size();
}
size_t send(
- const boost::asio::const_buffer &,
+ const std::vector<const void *> &, size_t,
const uhd::tx_metadata_t &,
const uhd::io_type_t &,
uhd::device::send_mode_t
@@ -117,12 +117,14 @@ public:
return _max_rx_bytes_per_packet/_rx_otw_type.get_sample_size();
}
size_t recv(
- const boost::asio::mutable_buffer &,
+ const std::vector<void *> &, size_t,
uhd::rx_metadata_t &,
const uhd::io_type_t &,
uhd::device::recv_mode_t
);
+ UHD_PIMPL_DECL(io_impl) _io_impl;
+
private:
inline double get_master_clock_freq(void){
return _clock_ctrl->get_master_clock_rate();
@@ -148,11 +150,10 @@ private:
;
static const size_t _max_tx_bytes_per_packet =
USRP2_UDP_BYTES -
- uhd::transport::vrt::max_header_words32*sizeof(boost::uint32_t)
+ uhd::transport::vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
;
uhd::otw_type_t _rx_otw_type, _tx_otw_type;
- UHD_PIMPL_DECL(io_impl) _io_impl;
void io_init(void);
//udp transports for control and data
diff --git a/host/test/vrt_test.cpp b/host/test/vrt_test.cpp
index 3776e33aa..3f74a836e 100644
--- a/host/test/vrt_test.cpp
+++ b/host/test/vrt_test.cpp
@@ -17,84 +17,123 @@
#include <boost/test/unit_test.hpp>
#include <uhd/transport/vrt.hpp>
+#include <cstdlib>
using namespace uhd::transport;
static void pack_and_unpack(
- const uhd::tx_metadata_t &metadata,
- size_t num_payload_words32,
- size_t packet_count
+ vrt::if_packet_info_t &if_packet_info_in
){
- boost::uint32_t header_buff[vrt::max_header_words32];
- size_t num_header_words32;
- size_t num_packet_words32;
+ boost::uint32_t header_buff[vrt::max_if_hdr_words32];
//pack metadata into a vrt header
- vrt::pack_be(
- metadata, //input
- header_buff, //output
- num_header_words32, //output
- num_payload_words32, //input
- num_packet_words32, //output
- packet_count, //input
- 100e6
+ vrt::if_hdr_pack_be(
+ header_buff, if_packet_info_in
);
- uhd::rx_metadata_t metadata_out;
- size_t num_header_words32_out;
- size_t num_payload_words32_out;
- size_t packet_count_out;
+ vrt::if_packet_info_t if_packet_info_out;
+ if_packet_info_out.num_packet_words32 = if_packet_info_in.num_packet_words32;
//unpack the vrt header back into metadata
- vrt::unpack_be(
- metadata_out, //output
- header_buff, //input
- num_header_words32_out, //output
- num_payload_words32_out, //output
- num_packet_words32, //input
- packet_count_out, //output
- 100e6
+ vrt::if_hdr_unpack_be(
+ header_buff, if_packet_info_out
);
//check the the unpacked metadata is the same
- BOOST_CHECK_EQUAL(packet_count, packet_count_out);
- BOOST_CHECK_EQUAL(num_header_words32, num_header_words32_out);
- BOOST_CHECK_EQUAL(num_payload_words32, num_payload_words32_out);
- BOOST_CHECK_EQUAL(metadata.has_stream_id, metadata_out.has_stream_id);
- if (metadata.has_stream_id and metadata_out.has_stream_id){
- BOOST_CHECK_EQUAL(metadata.stream_id, metadata_out.stream_id);
+ BOOST_CHECK_EQUAL(if_packet_info_in.packet_count, if_packet_info_out.packet_count);
+ BOOST_CHECK_EQUAL(if_packet_info_in.num_header_words32, if_packet_info_out.num_header_words32);
+ BOOST_CHECK_EQUAL(if_packet_info_in.num_payload_words32, if_packet_info_out.num_payload_words32);
+ BOOST_CHECK_EQUAL(if_packet_info_in.has_sid, if_packet_info_out.has_sid);
+ if (if_packet_info_in.has_sid and if_packet_info_out.has_sid){
+ BOOST_CHECK_EQUAL(if_packet_info_in.sid, if_packet_info_out.sid);
}
- BOOST_CHECK_EQUAL(metadata.has_time_spec, metadata_out.has_time_spec);
- if (metadata.has_time_spec and metadata_out.has_time_spec){
- BOOST_CHECK_EQUAL(metadata.time_spec.get_full_secs(), metadata_out.time_spec.get_full_secs());
- BOOST_CHECK_EQUAL(metadata.time_spec.get_frac_secs(), metadata_out.time_spec.get_frac_secs());
+ BOOST_CHECK_EQUAL(if_packet_info_in.has_cid, if_packet_info_out.has_cid);
+ if (if_packet_info_in.has_cid and if_packet_info_out.has_cid){
+ BOOST_CHECK_EQUAL(if_packet_info_in.cid, if_packet_info_out.cid);
+ }
+ BOOST_CHECK_EQUAL(if_packet_info_in.has_tsi, if_packet_info_out.has_tsi);
+ if (if_packet_info_in.has_tsi and if_packet_info_out.has_tsi){
+ BOOST_CHECK_EQUAL(if_packet_info_in.tsi, if_packet_info_out.tsi);
+ }
+ BOOST_CHECK_EQUAL(if_packet_info_in.has_tsf, if_packet_info_out.has_tsf);
+ if (if_packet_info_in.has_tsf and if_packet_info_out.has_tsf){
+ BOOST_CHECK_EQUAL(if_packet_info_in.tsf, if_packet_info_out.tsf);
+ }
+ BOOST_CHECK_EQUAL(if_packet_info_in.has_tlr, if_packet_info_out.has_tlr);
+ if (if_packet_info_in.has_tlr and if_packet_info_out.has_tlr){
+ BOOST_CHECK_EQUAL(if_packet_info_in.tlr, if_packet_info_out.tlr);
}
}
+/***********************************************************************
+ * Loopback test the vrt packer/unpacker with various packet info combos
+ * The trailer is not tested as it is not convenient to do so.
+ **********************************************************************/
+
BOOST_AUTO_TEST_CASE(test_with_none){
- uhd::tx_metadata_t metadata;
- pack_and_unpack(metadata, 300, 1);
+ vrt::if_packet_info_t if_packet_info;
+ if_packet_info.packet_count = 0;
+ if_packet_info.has_sid = false;
+ if_packet_info.has_cid = false;
+ if_packet_info.has_tsi = false;
+ if_packet_info.has_tsf = false;
+ if_packet_info.has_tlr = false;
+ if_packet_info.num_payload_words32 = 0;
+ pack_and_unpack(if_packet_info);
}
BOOST_AUTO_TEST_CASE(test_with_sid){
- uhd::tx_metadata_t metadata;
- metadata.has_stream_id = true;
- metadata.stream_id = 6;
- pack_and_unpack(metadata, 400, 2);
+ vrt::if_packet_info_t if_packet_info;
+ if_packet_info.packet_count = 1;
+ if_packet_info.has_sid = true;
+ if_packet_info.has_cid = false;
+ if_packet_info.has_tsi = false;
+ if_packet_info.has_tsf = false;
+ if_packet_info.has_tlr = false;
+ if_packet_info.sid = std::rand();
+ if_packet_info.num_payload_words32 = 1111;
+ pack_and_unpack(if_packet_info);
+}
+
+BOOST_AUTO_TEST_CASE(test_with_cid){
+ vrt::if_packet_info_t if_packet_info;
+ if_packet_info.packet_count = 2;
+ if_packet_info.has_sid = false;
+ if_packet_info.has_cid = true;
+ if_packet_info.has_tsi = false;
+ if_packet_info.has_tsf = false;
+ if_packet_info.has_tlr = false;
+ if_packet_info.cid = std::rand();
+ if_packet_info.num_payload_words32 = 2222;
+ pack_and_unpack(if_packet_info);
}
-BOOST_AUTO_TEST_CASE(test_with_time_spec){
- uhd::tx_metadata_t metadata;
- metadata.has_time_spec = true;
- metadata.time_spec = uhd::time_spec_t(7, 0.2);
- pack_and_unpack(metadata, 500, 3);
+BOOST_AUTO_TEST_CASE(test_with_time){
+ vrt::if_packet_info_t if_packet_info;
+ if_packet_info.packet_count = 3;
+ if_packet_info.has_sid = false;
+ if_packet_info.has_cid = false;
+ if_packet_info.has_tsi = true;
+ if_packet_info.has_tsf = true;
+ if_packet_info.has_tlr = false;
+ if_packet_info.tsi = std::rand();
+ if_packet_info.tsf = std::rand();
+ if_packet_info.num_payload_words32 = 33333;
+ pack_and_unpack(if_packet_info);
}
-BOOST_AUTO_TEST_CASE(test_with_sid_and_time_spec){
- uhd::tx_metadata_t metadata;
- metadata.has_stream_id = true;
- metadata.stream_id = 2;
- metadata.has_time_spec = true;
- metadata.time_spec = uhd::time_spec_t(5, 0.1);
- pack_and_unpack(metadata, 600, 4);
+BOOST_AUTO_TEST_CASE(test_with_all){
+ vrt::if_packet_info_t if_packet_info;
+ if_packet_info.packet_count = 4;
+ if_packet_info.has_sid = true;
+ if_packet_info.has_cid = true;
+ if_packet_info.has_tsi = true;
+ if_packet_info.has_tsf = true;
+ if_packet_info.has_tlr = false;
+ if_packet_info.sid = std::rand();
+ if_packet_info.cid = std::rand();
+ if_packet_info.tsi = std::rand();
+ if_packet_info.tsf = std::rand();
+ if_packet_info.num_payload_words32 = 44444;
+ pack_and_unpack(if_packet_info);
}