diff options
Diffstat (limited to 'host/lib/transport/vrt_packet_handler.hpp')
-rw-r--r-- | host/lib/transport/vrt_packet_handler.hpp | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp index bd76cbb8f..7e0588f03 100644 --- a/host/lib/transport/vrt_packet_handler.hpp +++ b/host/lib/transport/vrt_packet_handler.hpp @@ -35,14 +35,25 @@ namespace vrt_packet_handler{ +template <typename T> UHD_INLINE T get_context_code( + const boost::uint32_t *vrt_hdr, + const uhd::transport::vrt::if_packet_info_t &if_packet_info +){ + //extract the context word (we dont know the endianness so mirror the bytes) + boost::uint32_t word0 = vrt_hdr[if_packet_info.num_header_words32] | + uhd::byteswap(vrt_hdr[if_packet_info.num_header_words32]); + return T(word0 & 0xff); +} + /*********************************************************************** * vrt packet handler for recv **********************************************************************/ typedef std::vector<uhd::transport::managed_recv_buffer::sptr> managed_recv_buffs_t; typedef boost::function<bool(managed_recv_buffs_t &)> get_recv_buffs_t; - typedef boost::function<void(size_t /*which channel*/)> handle_overrun_t; + typedef boost::function<void(size_t /*which channel*/)> handle_overflow_t; + typedef boost::function<void(const boost::uint32_t *, uhd::transport::vrt::if_packet_info_t &)> vrt_unpacker_t; - static inline void handle_overrun_nop(size_t){} + static inline void handle_overflow_nop(size_t){} struct recv_state{ //width of the receiver in channels @@ -69,13 +80,12 @@ namespace vrt_packet_handler{ * Unpack a received vrt header and set the copy buffer. * - helper function for vrt_packet_handler::_recv1 ******************************************************************/ - template<typename vrt_unpacker_type> static UHD_INLINE void _recv1_helper( recv_state &state, uhd::rx_metadata_t &metadata, double tick_rate, - vrt_unpacker_type vrt_unpacker, - const handle_overrun_t &handle_overrun, + const vrt_unpacker_t &vrt_unpacker, + const handle_overflow_t &handle_overflow, size_t vrt_header_offset_words32 ){ //vrt unpack each managed buffer @@ -92,22 +102,19 @@ namespace vrt_packet_handler{ 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_header_offset_words32; vrt_unpacker(vrt_hdr, if_packet_info); - const boost::uint32_t *vrt_data = vrt_hdr + if_packet_info.num_header_words32; //handle the non-data packet case and parse its contents if (if_packet_info.packet_type != uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA){ - //extract the context word (we dont know the endianness so mirror the bytes) - boost::uint32_t word0 = vrt_data[0] | uhd::byteswap(vrt_data[0]); - if (word0 & uhd::rx_metadata_t::ERROR_CODE_OVERRUN) handle_overrun(i); - metadata.error_code = uhd::rx_metadata_t::error_code_t(word0 & 0xf); + metadata.error_code = get_context_code<uhd::rx_metadata_t::error_code_t>(vrt_hdr, if_packet_info); + if (metadata.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) handle_overflow(i); //break to exit loop and store metadata below state.size_of_copy_buffs = 0; break; } //setup the buffer to point to the data - state.copy_buffs[i] = reinterpret_cast<const boost::uint8_t *>(vrt_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); @@ -131,7 +138,6 @@ namespace vrt_packet_handler{ * Recv data, unpack a vrt header, and copy-convert the data. * - helper function for vrt_packet_handler::recv ******************************************************************/ - template<typename vrt_unpacker_type> static UHD_INLINE size_t _recv1( recv_state &state, const std::vector<void *> &buffs, @@ -141,9 +147,9 @@ namespace vrt_packet_handler{ const uhd::io_type_t &io_type, const uhd::otw_type_t &otw_type, double tick_rate, - vrt_unpacker_type vrt_unpacker, + const vrt_unpacker_t &vrt_unpacker, const get_recv_buffs_t &get_recv_buffs, - const handle_overrun_t &handle_overrun, + const handle_overflow_t &handle_overflow, size_t vrt_header_offset_words32 ){ metadata.error_code = uhd::rx_metadata_t::ERROR_CODE_NONE; @@ -158,7 +164,7 @@ namespace vrt_packet_handler{ try{ _recv1_helper( state, metadata, tick_rate, - vrt_unpacker, handle_overrun, + vrt_unpacker, handle_overflow, vrt_header_offset_words32 ); }catch(const std::exception &e){ @@ -206,7 +212,6 @@ namespace vrt_packet_handler{ /******************************************************************* * Recv vrt packets and copy convert the samples into the buffer. ******************************************************************/ - template<typename vrt_unpacker_type> static UHD_INLINE size_t recv( recv_state &state, const std::vector<void *> &buffs, @@ -216,9 +221,9 @@ namespace vrt_packet_handler{ const uhd::io_type_t &io_type, const uhd::otw_type_t &otw_type, double tick_rate, - vrt_unpacker_type vrt_unpacker, + const vrt_unpacker_t &vrt_unpacker, const get_recv_buffs_t &get_recv_buffs, - const handle_overrun_t &handle_overrun = &handle_overrun_nop, + const handle_overflow_t &handle_overflow = &handle_overflow_nop, size_t vrt_header_offset_words32 = 0 ){ switch(recv_mode){ @@ -235,7 +240,7 @@ namespace vrt_packet_handler{ tick_rate, vrt_unpacker, get_recv_buffs, - handle_overrun, + handle_overflow, vrt_header_offset_words32 ); } @@ -255,7 +260,7 @@ namespace vrt_packet_handler{ tick_rate, vrt_unpacker, get_recv_buffs, - handle_overrun, + handle_overflow, vrt_header_offset_words32 ); if (num_samps == 0) break; //had a recv timeout or error, break loop @@ -273,6 +278,7 @@ namespace vrt_packet_handler{ **********************************************************************/ typedef std::vector<uhd::transport::managed_send_buffer::sptr> managed_send_buffs_t; typedef boost::function<bool(managed_send_buffs_t &)> get_send_buffs_t; + typedef boost::function<void(boost::uint32_t *, uhd::transport::vrt::if_packet_info_t &)> vrt_packer_t; struct send_state{ //init the expected seq number @@ -287,7 +293,6 @@ namespace vrt_packet_handler{ * Pack a vrt header, copy-convert the data, and send it. * - helper function for vrt_packet_handler::send ******************************************************************/ - template<typename vrt_packer_type> static UHD_INLINE void _send1( send_state &state, const std::vector<const void *> &buffs, @@ -296,7 +301,7 @@ namespace vrt_packet_handler{ uhd::transport::vrt::if_packet_info_t &if_packet_info, const uhd::io_type_t &io_type, const uhd::otw_type_t &otw_type, - vrt_packer_type vrt_packer, + const vrt_packer_t &vrt_packer, const get_send_buffs_t &get_send_buffs, size_t vrt_header_offset_words32 ){ @@ -334,7 +339,6 @@ namespace vrt_packet_handler{ /******************************************************************* * Send vrt packets and copy convert the samples into the buffer. ******************************************************************/ - template<typename vrt_packer_type> static UHD_INLINE size_t send( send_state &state, const std::vector<const void *> &buffs, @@ -344,7 +348,7 @@ namespace vrt_packet_handler{ const uhd::io_type_t &io_type, const uhd::otw_type_t &otw_type, double tick_rate, - vrt_packer_type vrt_packer, + const vrt_packer_t &vrt_packer, const get_send_buffs_t &get_send_buffs, size_t max_samples_per_packet, size_t vrt_header_offset_words32 = 0 |