aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport/vrt.cpp
diff options
context:
space:
mode:
authorroot <root@usrp1-e.(none)>2010-03-23 13:35:36 +0000
committerroot <root@usrp1-e.(none)>2010-03-23 13:35:36 +0000
commitc329da8f953c3981e23791c688f350b27541554a (patch)
tree3447dd657bf7221e3b4b1a9147ce1bd2ffa430b9 /host/lib/transport/vrt.cpp
parentf6ec1e45117f5794facd1cd8e11cbfacabdeb166 (diff)
parent09a21dd6d4bc5b7f032e07cfabcba9f55d25b0f6 (diff)
downloaduhd-c329da8f953c3981e23791c688f350b27541554a.tar.gz
uhd-c329da8f953c3981e23791c688f350b27541554a.tar.bz2
uhd-c329da8f953c3981e23791c688f350b27541554a.zip
Merge branch 'u1e_uhd' of git@ettus.sourcerepo.com:ettus/uhd into u1e_uhd
Diffstat (limited to 'host/lib/transport/vrt.cpp')
-rw-r--r--host/lib/transport/vrt.cpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/host/lib/transport/vrt.cpp b/host/lib/transport/vrt.cpp
new file mode 100644
index 000000000..a06b5bf21
--- /dev/null
+++ b/host/lib/transport/vrt.cpp
@@ -0,0 +1,109 @@
+//
+// 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 <boost/asio.hpp> //endianness conversion
+#include <stdexcept>
+
+using namespace uhd;
+using namespace uhd::transport;
+
+void vrt::pack(
+ 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
+){
+ boost::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 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
+){
+ //clear the metadata
+ metadata = rx_metadata_t();
+
+ //extract vrt header
+ boost::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;
+}