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; +} | 
