From 51cb8da5837adacbc626ee20aa58264e1b4b7a78 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 24 Jun 2010 20:29:11 -0700 Subject: uhd: reworked time_spec_t to be more flexible: arithmetic, comparison operators... Replaced nsecs with fractional seconds in units of seconds. Replaced nsecs and secs members with public function members. time_spec_t has a more diverse set of constructors and methods. It can handle the cases where frac secs are greater than 1 second. --- host/test/vrt_test.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'host/test') diff --git a/host/test/vrt_test.cpp b/host/test/vrt_test.cpp index 3e596164c..3776e33aa 100644 --- a/host/test/vrt_test.cpp +++ b/host/test/vrt_test.cpp @@ -66,8 +66,8 @@ static void pack_and_unpack( } 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.secs, metadata_out.time_spec.secs); - BOOST_CHECK_EQUAL(metadata.time_spec.nsecs, metadata_out.time_spec.nsecs); + 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()); } } @@ -86,8 +86,7 @@ BOOST_AUTO_TEST_CASE(test_with_sid){ BOOST_AUTO_TEST_CASE(test_with_time_spec){ uhd::tx_metadata_t metadata; metadata.has_time_spec = true; - metadata.time_spec.secs = 7; - metadata.time_spec.nsecs = 2000; + metadata.time_spec = uhd::time_spec_t(7, 0.2); pack_and_unpack(metadata, 500, 3); } @@ -96,7 +95,6 @@ BOOST_AUTO_TEST_CASE(test_with_sid_and_time_spec){ metadata.has_stream_id = true; metadata.stream_id = 2; metadata.has_time_spec = true; - metadata.time_spec.secs = 5; - metadata.time_spec.nsecs = 1000; + metadata.time_spec = uhd::time_spec_t(5, 0.1); pack_and_unpack(metadata, 600, 4); } -- cgit v1.2.3 From 08fad28f209a2f6c79d939ad54ca3a1d4e270b0b Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 29 Jun 2010 22:55:45 -0700 Subject: uhd: work vectorizing the vrt packet handler, reworked vrt packet stuff, needs testing --- host/include/uhd/device.hpp | 51 ++++-- host/include/uhd/transport/vrt.hpp | 110 ++++++------- host/include/uhd/types/metadata.hpp | 14 -- host/lib/transport/gen_vrt.py | 117 +++++++------- host/lib/transport/vrt_packet_handler.hpp | 252 ++++++++++++++++-------------- host/lib/types.cpp | 4 - host/lib/usrp/usrp2/io_impl.cpp | 32 ++-- host/lib/usrp/usrp2/usrp2_impl.hpp | 9 +- host/test/vrt_test.cpp | 147 ++++++++++------- 9 files changed, 401 insertions(+), 335 deletions(-) (limited to 'host/test') 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 #include #include +#include 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(1, boost::asio::buffer_cast(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 &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(1, boost::asio::buffer_cast(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 &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 -#include -#include +#include +#include //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 @@ -30,13 +30,6 @@ namespace uhd{ * The receive routines will convert IF data headers into metadata. */ 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. @@ -83,13 +76,6 @@ namespace uhd{ * The send routines will convert the metadata to IF data headers. */ 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". 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(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(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 #include +#include #include #include #include @@ -30,37 +31,43 @@ #include #include #include +#include namespace vrt_packet_handler{ /*********************************************************************** * vrt packet handler for recv **********************************************************************/ + typedef std::vector 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 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 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 get_recv_buff_t; - - typedef boost::function recv_cb_t; + typedef boost::function get_recv_buffs_t; - static UHD_INLINE void recv_cb_nop(uhd::transport::managed_recv_buffer::sptr){ - /* NOP */ - } + typedef boost::function 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() + 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() + 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(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 static UHD_INLINE size_t _recv1( recv_state &state, - void *recv_mem, + const std::vector &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(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(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(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(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 static UHD_INLINE size_t recv( recv_state &state, - const boost::asio::mutable_buffer &buff, + const std::vector &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(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(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 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 get_send_buff_t; - - typedef boost::function send_cb_t; + typedef boost::function get_send_buffs_t; - static UHD_INLINE void send_cb_nop(uhd::transport::managed_send_buffer::sptr){ - /* NOP */ - } + typedef boost::function send_cb_t; /******************************************************************* * Pack a vrt header, copy-convert the data, and send it. @@ -260,46 +270,51 @@ namespace vrt_packet_handler{ template static UHD_INLINE void _send1( send_state &state, - const void *send_mem, + const std::vector &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() + 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(buffs[i]) + offset_bytes; + boost::uint32_t *otw_mem = send_buffs[i]->cast() + 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 static UHD_INLINE size_t send( send_state &state, - const boost::asio::const_buffer &buff, + const std::vector &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(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(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::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 &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 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 &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 &, 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 &, 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 #include +#include 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); } -- cgit v1.2.3 From deaade7bd0ae4dd9cab7f304fb69eea153ce592a Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 30 Jun 2010 17:44:47 -0700 Subject: uhd: renamed the vrt header to vrt_if_packet header --- host/include/uhd/transport/CMakeLists.txt | 2 +- host/include/uhd/transport/vrt.hpp | 99 ------------ host/include/uhd/transport/vrt_if_packet.hpp | 99 ++++++++++++ host/lib/transport/CMakeLists.txt | 4 +- host/lib/transport/gen_vrt.py | 233 --------------------------- host/lib/transport/gen_vrt_if_packet.py | 233 +++++++++++++++++++++++++++ host/lib/transport/vrt_packet_handler.hpp | 2 +- host/lib/usrp/usrp2/usrp2_impl.hpp | 2 +- host/test/vrt_test.cpp | 2 +- 9 files changed, 338 insertions(+), 338 deletions(-) delete mode 100644 host/include/uhd/transport/vrt.hpp create mode 100644 host/include/uhd/transport/vrt_if_packet.hpp delete mode 100755 host/lib/transport/gen_vrt.py create mode 100755 host/lib/transport/gen_vrt_if_packet.py (limited to 'host/test') diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt index 23a4aae94..4e1f7aca5 100644 --- a/host/include/uhd/transport/CMakeLists.txt +++ b/host/include/uhd/transport/CMakeLists.txt @@ -23,7 +23,7 @@ INSTALL(FILES if_addrs.hpp udp_simple.hpp udp_zero_copy.hpp - vrt.hpp + vrt_if_packet.hpp zero_copy.hpp DESTINATION ${INCLUDE_DIR}/uhd/transport ) diff --git a/host/include/uhd/transport/vrt.hpp b/host/include/uhd/transport/vrt.hpp deleted file mode 100644 index 17da2d540..000000000 --- a/host/include/uhd/transport/vrt.hpp +++ /dev/null @@ -1,99 +0,0 @@ -// -// Copyright 2010 Ettus Research LLC -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// - -#ifndef INCLUDED_UHD_TRANSPORT_VRT_HPP -#define INCLUDED_UHD_TRANSPORT_VRT_HPP - -#include -#include -#include //size_t - -namespace uhd{ namespace transport{ - -namespace vrt{ - - //! The maximum number of 32-bit words in a vrt if packet header - static const size_t max_if_hdr_words32 = 7; //hdr+sid+cid+tsi+tsf - - /*! - * Definition for fields that can be packed into a vrt if header. - * The size fields are used for input and output depending upon - * the operation used (ie the pack or unpack function call). - */ - struct UHD_API if_packet_info_t{ - //size fields - size_t num_payload_words32; //required in pack, derived in unpack - size_t num_header_words32; //derived in pack, derived in unpack - size_t num_packet_words32; //derived in pack, required in unpack - - //header fields - size_t packet_count; - bool sob, eob; - - //optional fields - bool has_sid; boost::uint32_t sid; - bool has_cid; boost::uint64_t cid; - bool has_tsi; boost::uint32_t tsi; - bool has_tsf; boost::uint64_t tsf; - bool has_tlr; boost::uint32_t tlr; - }; - - /*! - * Pack a vrt header from metadata (big endian format). - * \param packet_buff memory to write the packed vrt header - * \param if_packet_info the if packet info (read/write) - */ - UHD_API void if_hdr_pack_be( - boost::uint32_t *packet_buff, - if_packet_info_t &if_packet_info - ); - - /*! - * Unpack a vrt header to metadata (big endian format). - * \param packet_buff memory to read the packed vrt header - * \param if_packet_info the if packet info (read/write) - */ - UHD_API void if_hdr_unpack_be( - const boost::uint32_t *packet_buff, - if_packet_info_t &if_packet_info - ); - - /*! - * Pack a vrt header from metadata (little endian format). - * \param packet_buff memory to write the packed vrt header - * \param if_packet_info the if packet info (read/write) - */ - UHD_API void if_hdr_pack_le( - boost::uint32_t *packet_buff, - if_packet_info_t &if_packet_info - ); - - /*! - * Unpack a vrt header to metadata (little endian format). - * \param packet_buff memory to read the packed vrt header - * \param if_packet_info the if packet info (read/write) - */ - UHD_API void if_hdr_unpack_le( - const boost::uint32_t *packet_buff, - if_packet_info_t &if_packet_info - ); - -} //namespace vrt - -}} //namespace - -#endif /* INCLUDED_UHD_TRANSPORT_VRT_HPP */ diff --git a/host/include/uhd/transport/vrt_if_packet.hpp b/host/include/uhd/transport/vrt_if_packet.hpp new file mode 100644 index 000000000..ccefe14ea --- /dev/null +++ b/host/include/uhd/transport/vrt_if_packet.hpp @@ -0,0 +1,99 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef INCLUDED_UHD_TRANSPORT_VRT_IF_PACKET_HPP +#define INCLUDED_UHD_TRANSPORT_VRT_IF_PACKET_HPP + +#include +#include +#include //size_t + +namespace uhd{ namespace transport{ + +namespace vrt{ + + //! The maximum number of 32-bit words in a vrt if packet header + static const size_t max_if_hdr_words32 = 7; //hdr+sid+cid+tsi+tsf + + /*! + * Definition for fields that can be packed into a vrt if header. + * The size fields are used for input and output depending upon + * the operation used (ie the pack or unpack function call). + */ + struct UHD_API if_packet_info_t{ + //size fields + size_t num_payload_words32; //required in pack, derived in unpack + size_t num_header_words32; //derived in pack, derived in unpack + size_t num_packet_words32; //derived in pack, required in unpack + + //header fields + size_t packet_count; + bool sob, eob; + + //optional fields + bool has_sid; boost::uint32_t sid; + bool has_cid; boost::uint64_t cid; + bool has_tsi; boost::uint32_t tsi; + bool has_tsf; boost::uint64_t tsf; + bool has_tlr; boost::uint32_t tlr; + }; + + /*! + * Pack a vrt header from metadata (big endian format). + * \param packet_buff memory to write the packed vrt header + * \param if_packet_info the if packet info (read/write) + */ + UHD_API void if_hdr_pack_be( + boost::uint32_t *packet_buff, + if_packet_info_t &if_packet_info + ); + + /*! + * Unpack a vrt header to metadata (big endian format). + * \param packet_buff memory to read the packed vrt header + * \param if_packet_info the if packet info (read/write) + */ + UHD_API void if_hdr_unpack_be( + const boost::uint32_t *packet_buff, + if_packet_info_t &if_packet_info + ); + + /*! + * Pack a vrt header from metadata (little endian format). + * \param packet_buff memory to write the packed vrt header + * \param if_packet_info the if packet info (read/write) + */ + UHD_API void if_hdr_pack_le( + boost::uint32_t *packet_buff, + if_packet_info_t &if_packet_info + ); + + /*! + * Unpack a vrt header to metadata (little endian format). + * \param packet_buff memory to read the packed vrt header + * \param if_packet_info the if packet info (read/write) + */ + UHD_API void if_hdr_unpack_le( + const boost::uint32_t *packet_buff, + if_packet_info_t &if_packet_info + ); + +} //namespace vrt + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_VRT_IF_PACKET_HPP */ diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt index 70cf6312d..bde2b72b9 100644 --- a/host/lib/transport/CMakeLists.txt +++ b/host/lib/transport/CMakeLists.txt @@ -50,8 +50,8 @@ ENDIF(HAVE_IFADDRS_H) # Append to the list of sources for lib uhd ######################################################################## LIBUHD_PYTHON_GEN_SOURCE( - ${CMAKE_SOURCE_DIR}/lib/transport/gen_vrt.py - ${CMAKE_BINARY_DIR}/lib/transport/vrt.cpp + ${CMAKE_SOURCE_DIR}/lib/transport/gen_vrt_if_packet.py + ${CMAKE_BINARY_DIR}/lib/transport/vrt_if_packet.cpp ) LIBUHD_PYTHON_GEN_SOURCE( diff --git a/host/lib/transport/gen_vrt.py b/host/lib/transport/gen_vrt.py deleted file mode 100755 index 06182bd39..000000000 --- a/host/lib/transport/gen_vrt.py +++ /dev/null @@ -1,233 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2010 Ettus Research LLC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# - -""" -The vrt packer/unpacker code generator: - -This script will generate the pack and unpack routines that convert -metatdata into vrt headers and vrt headers into metadata. - -The generated code infers jump tables to speed-up the parsing time. -""" - -TMPL_TEXT = """ -#import time -/*********************************************************************** - * This file was generated by $file on $time.strftime("%c") - **********************************************************************/ - -\#include -\#include -\#include -\#include - -//define the endian macros to convert integers -\#ifdef BOOST_BIG_ENDIAN - \#define BE_MACRO(x) (x) - \#define LE_MACRO(x) uhd::byteswap(x) -\#else - \#define BE_MACRO(x) uhd::byteswap(x) - \#define LE_MACRO(x) (x) -\#endif - -using namespace uhd; -using namespace uhd::transport; - -######################################################################## -#def gen_code($XE_MACRO, $suffix) -######################################################################## - -######################################################################## -## setup predicates -######################################################################## -#set $sid_p = 0b00001 -#set $cid_p = 0b00010 -#set $tsi_p = 0b00100 -#set $tsf_p = 0b01000 -#set $tlr_p = 0b10000 - -static UHD_INLINE void pack_uint64_$(suffix)(boost::uint64_t num, boost::uint32_t *mem){ - *(reinterpret_cast(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 (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) - case $pred: - #set $num_header_words = 1 - #set $flags = 0 - ########## Stream ID ########## - #if $pred & $sid_p - 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 - 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 - 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 - 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 - //packet_buff[$num_header_words+if_packet_info.num_payload_words32] = 0; - #set $num_trailer_words = 0; - #end if - ########## Variables ########## - 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 (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 - packet_buff[0] = $(XE_MACRO)(boost::uint32_t(0 - | vrt_hdr_flags - | ((if_packet_info.packet_count & 0xf) << 16) - | (if_packet_info.num_packet_words32 & 0xffff) - )); -} - -static UHD_INLINE void unpack_uint64_$(suffix)(boost::uint64_t &num, const boost::uint32_t *mem){ - num = $(XE_MACRO)(*reinterpret_cast(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)(packet_buff[0]); - size_t packet_words32 = vrt_hdr_word & 0xffff; - if_packet_info.packet_count = (vrt_hdr_word >> 16) & 0xf; - - //failure cases - 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"); - - boost::uint8_t pred = 0; - if(vrt_hdr_word & $hex(0x1 << 28)) pred |= $hex($sid_p); - if(vrt_hdr_word & $hex(0x1 << 27)) pred |= $hex($cid_p); - if(vrt_hdr_word & $hex(0x3 << 22)) pred |= $hex($tsi_p); - if(vrt_hdr_word & $hex(0x3 << 20)) pred |= $hex($tsf_p); - if(vrt_hdr_word & $hex(0x1 << 26)) pred |= $hex($tlr_p); - - switch(pred){ - #for $pred in range(2**5) - case $pred: - #set $has_time_spec = False - #set $num_header_words = 1 - ########## Stream ID ########## - #if $pred & $sid_p - 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 - 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 - 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 - 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 ########## - 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 - } -} - -######################################################################## -#end def -######################################################################## - -$gen_code("BE_MACRO", "be") -$gen_code("LE_MACRO", "le") -""" - -def parse_tmpl(_tmpl_text, **kwargs): - from Cheetah.Template import Template - return str(Template(_tmpl_text, kwargs)) - -if __name__ == '__main__': - import sys - open(sys.argv[1], 'w').write(parse_tmpl(TMPL_TEXT, file=__file__)) diff --git a/host/lib/transport/gen_vrt_if_packet.py b/host/lib/transport/gen_vrt_if_packet.py new file mode 100755 index 000000000..536409b2e --- /dev/null +++ b/host/lib/transport/gen_vrt_if_packet.py @@ -0,0 +1,233 @@ +#!/usr/bin/env python +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +""" +The vrt packer/unpacker code generator: + +This script will generate the pack and unpack routines that convert +metatdata into vrt headers and vrt headers into metadata. + +The generated code infers jump tables to speed-up the parsing time. +""" + +TMPL_TEXT = """ +#import time +/*********************************************************************** + * This file was generated by $file on $time.strftime("%c") + **********************************************************************/ + +\#include +\#include +\#include +\#include + +//define the endian macros to convert integers +\#ifdef BOOST_BIG_ENDIAN + \#define BE_MACRO(x) (x) + \#define LE_MACRO(x) uhd::byteswap(x) +\#else + \#define BE_MACRO(x) uhd::byteswap(x) + \#define LE_MACRO(x) (x) +\#endif + +using namespace uhd; +using namespace uhd::transport; + +######################################################################## +#def gen_code($XE_MACRO, $suffix) +######################################################################## + +######################################################################## +## setup predicates +######################################################################## +#set $sid_p = 0b00001 +#set $cid_p = 0b00010 +#set $tsi_p = 0b00100 +#set $tsf_p = 0b01000 +#set $tlr_p = 0b10000 + +static UHD_INLINE void pack_uint64_$(suffix)(boost::uint64_t num, boost::uint32_t *mem){ + *(reinterpret_cast(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 (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) + case $pred: + #set $num_header_words = 1 + #set $flags = 0 + ########## Stream ID ########## + #if $pred & $sid_p + 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 + 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 + 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 + 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 + //packet_buff[$num_header_words+if_packet_info.num_payload_words32] = 0; + #set $num_trailer_words = 0; + #end if + ########## Variables ########## + 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 (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 + packet_buff[0] = $(XE_MACRO)(boost::uint32_t(0 + | vrt_hdr_flags + | ((if_packet_info.packet_count & 0xf) << 16) + | (if_packet_info.num_packet_words32 & 0xffff) + )); +} + +static UHD_INLINE void unpack_uint64_$(suffix)(boost::uint64_t &num, const boost::uint32_t *mem){ + num = $(XE_MACRO)(*reinterpret_cast(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)(packet_buff[0]); + size_t packet_words32 = vrt_hdr_word & 0xffff; + if_packet_info.packet_count = (vrt_hdr_word >> 16) & 0xf; + + //failure cases + 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"); + + boost::uint8_t pred = 0; + if(vrt_hdr_word & $hex(0x1 << 28)) pred |= $hex($sid_p); + if(vrt_hdr_word & $hex(0x1 << 27)) pred |= $hex($cid_p); + if(vrt_hdr_word & $hex(0x3 << 22)) pred |= $hex($tsi_p); + if(vrt_hdr_word & $hex(0x3 << 20)) pred |= $hex($tsf_p); + if(vrt_hdr_word & $hex(0x1 << 26)) pred |= $hex($tlr_p); + + switch(pred){ + #for $pred in range(2**5) + case $pred: + #set $has_time_spec = False + #set $num_header_words = 1 + ########## Stream ID ########## + #if $pred & $sid_p + 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 + 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 + 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 + 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 ########## + 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 + } +} + +######################################################################## +#end def +######################################################################## + +$gen_code("BE_MACRO", "be") +$gen_code("LE_MACRO", "le") +""" + +def parse_tmpl(_tmpl_text, **kwargs): + from Cheetah.Template import Template + return str(Template(_tmpl_text, kwargs)) + +if __name__ == '__main__': + import sys + open(sys.argv[1], 'w').write(parse_tmpl(TMPL_TEXT, file=__file__)) diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp index 8cbc71008..31b7e6614 100644 --- a/host/lib/transport/vrt_packet_handler.hpp +++ b/host/lib/transport/vrt_packet_handler.hpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 719cf3f16..df1dba663 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include diff --git a/host/test/vrt_test.cpp b/host/test/vrt_test.cpp index 3f74a836e..b90b2fc15 100644 --- a/host/test/vrt_test.cpp +++ b/host/test/vrt_test.cpp @@ -16,7 +16,7 @@ // #include -#include +#include #include using namespace uhd::transport; -- cgit v1.2.3