diff options
author | Josh Blum <josh@joshknows.com> | 2010-03-15 17:00:04 +0000 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2010-03-15 17:00:04 +0000 |
commit | 1bfb556262d12740c71e68a2a071e6e67ed2b3e7 (patch) | |
tree | a081bfd3a61ccb42372a627be7b57ce19a3baa0d /host/lib/transport/vrt.cpp | |
parent | 1b965831ae7588c7879d84de4e5fbd78ca614761 (diff) | |
parent | fc40ff2f1327d01c72c4d7dbc07a14e473251981 (diff) | |
download | uhd-1bfb556262d12740c71e68a2a071e6e67ed2b3e7.tar.gz uhd-1bfb556262d12740c71e68a2a071e6e67ed2b3e7.tar.bz2 uhd-1bfb556262d12740c71e68a2a071e6e67ed2b3e7.zip |
Merge branch 'master' of git@ettus.sourcerepo.com:ettus/uhd into u1e_uhd
Conflicts:
host/apps/CMakeLists.txt
host/lib/usrp/usrp2/usrp2_impl.cpp
Diffstat (limited to 'host/lib/transport/vrt.cpp')
-rw-r--r-- | host/lib/transport/vrt.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/host/lib/transport/vrt.cpp b/host/lib/transport/vrt.cpp new file mode 100644 index 000000000..5029df217 --- /dev/null +++ b/host/lib/transport/vrt.cpp @@ -0,0 +1,108 @@ +// +// 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 <http://www.gnu.org/licenses/>. +// + +#include <uhd/transport/vrt.hpp> +#include <netinet/in.h> +#include <stdexcept> + +using namespace uhd::transport; + +void vrt::pack( + const tx_metadata_t &metadata, //input + 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 +){ + uint32_t vrt_hdr_flags = 0; + num_header_words32 = 1; + + //load the vrt header and flags + if(metadata.has_stream_id){ + vrt_hdr_flags |= (0x1 << 28); //IF Data packet with Stream Identifier + header_buff[num_header_words32++] = htonl(metadata.stream_id); + } + + if(metadata.has_time_spec){ + vrt_hdr_flags |= (0x3 << 22) | (0x1 << 20); //TSI: Other, TSF: Sample Count Timestamp + header_buff[num_header_words32++] = htonl(metadata.time_spec.secs); + header_buff[num_header_words32++] = htonl(metadata.time_spec.ticks); + header_buff[num_header_words32++] = 0; //unused part of fractional seconds + } + + vrt_hdr_flags |= (metadata.start_of_burst)? (0x1 << 25) : 0; + vrt_hdr_flags |= (metadata.end_of_burst)? (0x1 << 24) : 0; + + num_packet_words32 = num_header_words32 + num_payload_words32; + + //fill in complete header word + header_buff[0] = htonl(vrt_hdr_flags | + ((packet_count & 0xf) << 16) | + (num_packet_words32 & 0xffff) + ); +} + +void vrt::unpack( + rx_metadata_t &metadata, //output + const 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 +){ + //clear the metadata + metadata = rx_metadata_t(); + + //extract vrt header + uint32_t vrt_hdr_word = ntohl(header_buff[0]); + size_t packet_words32 = vrt_hdr_word & 0xffff; + packet_count = (vrt_hdr_word >> 16) & 0xf; + + //failure cases + if (packet_words32 == 0 or 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"); + + //parse the header flags + num_header_words32 = 1; + + if (vrt_hdr_word & (0x1 << 28)){ //stream id + metadata.has_stream_id = true; + metadata.stream_id = ntohl(header_buff[num_header_words32++]); + } + + if (vrt_hdr_word & (0x1 << 27)){ //class id (we dont use) + num_header_words32 += 2; + } + + if (vrt_hdr_word & (0x3 << 22)){ //integer time + metadata.has_time_spec = true; + metadata.time_spec.secs = ntohl(header_buff[num_header_words32++]); + } + + if (vrt_hdr_word & (0x3 << 20)){ //fractional time + metadata.has_time_spec = true; + metadata.time_spec.ticks = ntohl(header_buff[num_header_words32++]); + num_header_words32++; //unused part of fractional seconds + } + + size_t num_trailer_words32 = (vrt_hdr_word & (0x1 << 26))? 1 : 0; + + num_payload_words32 = packet_words32 - num_header_words32 - num_trailer_words32; +} |