aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport
diff options
context:
space:
mode:
authorPhilip Balister <philip@opensdr.com>2010-04-01 12:44:19 +0000
committerPhilip Balister <philip@opensdr.com>2010-04-01 12:44:19 +0000
commit93572731923e43bbb34a12db41170e56376ab03b (patch)
treea46c53d1695a211dac39e46abf60a8f517e8d287 /host/lib/transport
parent930755fce1e5d22a5ede0459dccd6c9501fc642c (diff)
parent03be4d0673c5e0f597db7d27f535956a591bbeb7 (diff)
downloaduhd-93572731923e43bbb34a12db41170e56376ab03b.tar.gz
uhd-93572731923e43bbb34a12db41170e56376ab03b.tar.bz2
uhd-93572731923e43bbb34a12db41170e56376ab03b.zip
Merge branch 'usrp_e' of git@ettus.sourcerepo.com:ettus/uhd into usrp_e
Diffstat (limited to 'host/lib/transport')
-rwxr-xr-xhost/lib/transport/gen_vrt.py206
-rw-r--r--host/lib/transport/if_addrs.cpp109
-rw-r--r--host/lib/transport/udp_simple.cpp1
-rw-r--r--host/lib/transport/udp_zero_copy_asio.cpp3
-rw-r--r--host/lib/transport/vrt.cpp550
5 files changed, 812 insertions, 57 deletions
diff --git a/host/lib/transport/gen_vrt.py b/host/lib/transport/gen_vrt.py
new file mode 100755
index 000000000..918de3ad7
--- /dev/null
+++ b/host/lib/transport/gen_vrt.py
@@ -0,0 +1,206 @@
+#!/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 <http://www.gnu.org/licenses/>.
+#
+
+"""
+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
+
+########################################################################
+## setup predicates
+########################################################################
+#set $sid_p = 0b00001
+#set $cid_p = 0b00010
+#set $tsi_p = 0b00100
+#set $tsf_p = 0b01000
+#set $tlr_p = 0b10000
+
+/***********************************************************************
+ * This file was generated by $file on $time.strftime("%c")
+ **********************************************************************/
+
+\#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;
+
+ 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);
+
+ switch(pred){
+ #for $pred in range(2**5)
+ case $pred:
+ #set $num_header_words = 1
+ #set $flags = 0
+ ########## Stream ID ##########
+ #if $pred & $sid_p
+ header_buff[$num_header_words] = htonl(metadata.stream_id);
+ #set $num_header_words += 1
+ #set $flags |= (0x1 << 28);
+ #end if
+ ########## Class ID ##########
+ #if $pred & $cid_p
+ header_buff[$num_header_words] = htonl(0);
+ #set $num_header_words += 1
+ header_buff[$num_header_words] = htonl(0);
+ #set $num_header_words += 1
+ #set $flags |= (0x1 << 27);
+ #end if
+ ########## Integer Time ##########
+ #if $pred & $tsi_p
+ header_buff[$num_header_words] = htonl(metadata.time_spec.secs);
+ #set $num_header_words += 1
+ #set $flags |= (0x3 << 22);
+ #end if
+ ########## Fractional Time ##########
+ #if $pred & $tsf_p
+ header_buff[$num_header_words] = htonl(0);
+ #set $num_header_words += 1
+ header_buff[$num_header_words] = htonl(metadata.time_spec.ticks);
+ #set $num_header_words += 1
+ #set $flags |= (0x1 << 20);
+ #end if
+ ########## Trailer ##########
+ #if $pred & $tlr_p
+ #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;
+ 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);
+
+ //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");
+
+ 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 $set_has_time_spec = False
+ #set $num_header_words = 1
+ ########## Stream ID ##########
+ #if $pred & $sid_p
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[$num_header_words]);
+ #set $num_header_words += 1
+ #end if
+ ########## Class ID ##########
+ #if $pred & $cid_p
+ #set $num_header_words += 1
+ #set $num_header_words += 1
+ #end if
+ ########## Integer Time ##########
+ #if $pred & $tsi_p
+ metadata.has_time_spec = true;
+ #set $set_has_time_spec = True
+ metadata.time_spec.secs = ntohl(header_buff[$num_header_words]);
+ #set $num_header_words += 1
+ #end if
+ ########## Fractional Time ##########
+ #if $pred & $tsf_p
+ #if not $set_has_time_spec
+ metadata.has_time_spec = true;
+ #set $set_has_time_spec = True
+ #end if
+ #set $num_header_words += 1
+ metadata.time_spec.ticks = ntohl(header_buff[$num_header_words]);
+ #set $num_header_words += 1
+ #end if
+ ########## Trailer ##########
+ #if $pred & $tlr_p
+ #set $num_trailer_words = 1;
+ #else
+ #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);
+ break;
+ #end for
+ }
+}
+"""
+
+from Cheetah import Template
+def parse_str(_tmpl_text, **kwargs): return str(Template.Template(_tmpl_text, kwargs))
+
+if __name__ == '__main__':
+ from Cheetah import Template
+ print parse_str(TMPL_TEXT, file=__file__)
diff --git a/host/lib/transport/if_addrs.cpp b/host/lib/transport/if_addrs.cpp
new file mode 100644
index 000000000..5c8c8a176
--- /dev/null
+++ b/host/lib/transport/if_addrs.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/if_addrs.hpp>
+#include <boost/asio/ip/address_v4.hpp>
+#include <boost/cstdint.hpp>
+#include <iostream>
+
+uhd::transport::if_addrs_t::if_addrs_t(void){
+ /* NOP */
+}
+
+/***********************************************************************
+ * Interface address discovery through ifaddrs api
+ **********************************************************************/
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+
+static boost::asio::ip::address_v4 sockaddr_to_ip_addr(sockaddr *addr){
+ return boost::asio::ip::address_v4(ntohl(
+ reinterpret_cast<sockaddr_in*>(addr)->sin_addr.s_addr
+ ));
+}
+
+std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void){
+ std::vector<if_addrs_t> if_addrs;
+ struct ifaddrs *ifap;
+ if (getifaddrs(&ifap) == 0){
+ for (struct ifaddrs *iter = ifap; iter != NULL; iter = iter->ifa_next){
+ //ensure that the entries are valid
+ if (iter->ifa_addr->sa_family != AF_INET) continue;
+ if (iter->ifa_netmask->sa_family != AF_INET) continue;
+ if (iter->ifa_broadaddr->sa_family != AF_INET) continue;
+
+ //append a new set of interface addresses
+ if_addrs_t if_addr;
+ if_addr.inet = sockaddr_to_ip_addr(iter->ifa_addr).to_string();
+ if_addr.mask = sockaddr_to_ip_addr(iter->ifa_netmask).to_string();
+ if_addr.bcast = sockaddr_to_ip_addr(iter->ifa_broadaddr).to_string();
+ if_addrs.push_back(if_addr);
+ }
+ freeifaddrs(ifap);
+ }
+ return if_addrs;
+}
+
+/***********************************************************************
+ * Interface address discovery through windows api (TODO)
+ **********************************************************************/
+#elif HAVE_WINSOCK2_H
+#include <winsock2.h>
+
+std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void){
+ std::vector<if_addrs_t> if_addrs;
+ SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
+ if (sd == SOCKET_ERROR) {
+ std::cerr << "Failed to get a socket. Error " << WSAGetLastError() <<
+ std::endl; return if_addrs;
+ }
+
+ INTERFACE_INFO InterfaceList[20];
+ unsigned long nBytesReturned;
+ if (WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList,
+ sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR) {
+ std::cerr << "Failed calling WSAIoctl: error " << WSAGetLastError() <<
+ std::endl;
+ return if_addrs;
+ }
+
+ int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
+ for (int i = 0; i < nNumInterfaces; ++i) {
+ boost::uint32_t iiAddress = ntohl(reinterpret_cast<sockaddr_in&>(InterfaceList[i].iiAddress).sin_addr.s_addr);
+ boost::uint32_t iiNetmask = ntohl(reinterpret_cast<sockaddr_in&>(InterfaceList[i].iiNetmask).sin_addr.s_addr);
+ boost::uint32_t iiBroadcastAddress = (iiAddress & iiNetmask) | ~iiNetmask;
+
+ if_addrs_t if_addr;
+ if_addr.inet = boost::asio::ip::address_v4(iiAddress).to_string();
+ if_addr.mask = boost::asio::ip::address_v4(iiNetmask).to_string();
+ if_addr.bcast = boost::asio::ip::address_v4(iiBroadcastAddress).to_string();
+ if_addrs.push_back(if_addr);
+ }
+
+ return if_addrs;
+}
+
+/***********************************************************************
+ * Interface address discovery not included
+ **********************************************************************/
+#else /* HAVE_IFADDRS_H */
+
+std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void){
+ return std::vector<if_addrs_t>();
+}
+
+#endif /* HAVE_IFADDRS_H */
diff --git a/host/lib/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp
index 3c8ecb70d..f339127ad 100644
--- a/host/lib/transport/udp_simple.cpp
+++ b/host/lib/transport/udp_simple.cpp
@@ -16,6 +16,7 @@
//
#include <uhd/transport/udp_simple.hpp>
+#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/format.hpp>
#include <iostream>
diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp
index 219ae8720..1fc8ce14a 100644
--- a/host/lib/transport/udp_zero_copy_asio.cpp
+++ b/host/lib/transport/udp_zero_copy_asio.cpp
@@ -17,6 +17,7 @@
#include <uhd/transport/udp_zero_copy.hpp>
#include <boost/cstdint.hpp>
+#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/format.hpp>
#include <iostream>
@@ -115,7 +116,7 @@ smart_buffer::sptr udp_zero_copy_impl::recv(void){
//implement timeout through polling and sleeping
boost::asio::deadline_timer timer(_socket->get_io_service());
- timer.expires_from_now(boost::posix_time::milliseconds(50));
+ timer.expires_from_now(boost::posix_time::milliseconds(100));
while (not ((available = _socket->available()) or timer.expires_from_now().is_negative())){
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
}
diff --git a/host/lib/transport/vrt.cpp b/host/lib/transport/vrt.cpp
index a06b5bf21..bebca5db9 100644
--- a/host/lib/transport/vrt.cpp
+++ b/host/lib/transport/vrt.cpp
@@ -1,19 +1,9 @@
-//
-// 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/>.
-//
+
+
+
+/***********************************************************************
+ * This file was generated by ./gen_vrt.py on Fri Mar 26 15:33:00 2010
+ **********************************************************************/
#include <uhd/transport/vrt.hpp>
#include <boost/asio.hpp> //endianness conversion
@@ -30,26 +20,274 @@ void vrt::pack(
size_t &num_packet_words32, //output
size_t packet_count //input
){
- boost::uint32_t vrt_hdr_flags = 0;
- num_header_words32 = 1;
+ boost::uint32_t vrt_hdr_flags;
- //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);
- }
+ boost::uint8_t pred = 0;
+ if (metadata.has_stream_id) pred |= 0x1;
+ if (metadata.has_time_spec) pred |= 0xc;
- 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
+ switch(pred){
+ case 0:
+ num_header_words32 = 1;
+ num_packet_words32 = 1 + num_payload_words32;
+ vrt_hdr_flags = 0x0;
+ break;
+ case 1:
+ header_buff[1] = htonl(metadata.stream_id);
+ num_header_words32 = 2;
+ num_packet_words32 = 2 + num_payload_words32;
+ vrt_hdr_flags = 0x10000000;
+ break;
+ case 2:
+ header_buff[1] = htonl(0);
+ header_buff[2] = htonl(0);
+ num_header_words32 = 3;
+ num_packet_words32 = 3 + num_payload_words32;
+ vrt_hdr_flags = 0x8000000;
+ break;
+ case 3:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(0);
+ num_header_words32 = 4;
+ num_packet_words32 = 4 + num_payload_words32;
+ vrt_hdr_flags = 0x18000000;
+ break;
+ case 4:
+ header_buff[1] = htonl(metadata.time_spec.secs);
+ num_header_words32 = 2;
+ num_packet_words32 = 2 + num_payload_words32;
+ vrt_hdr_flags = 0xc00000;
+ break;
+ case 5:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(metadata.time_spec.secs);
+ num_header_words32 = 3;
+ num_packet_words32 = 3 + num_payload_words32;
+ vrt_hdr_flags = 0x10c00000;
+ break;
+ case 6:
+ header_buff[1] = htonl(0);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(metadata.time_spec.secs);
+ num_header_words32 = 4;
+ num_packet_words32 = 4 + num_payload_words32;
+ vrt_hdr_flags = 0x8c00000;
+ break;
+ case 7:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(0);
+ header_buff[4] = htonl(metadata.time_spec.secs);
+ num_header_words32 = 5;
+ num_packet_words32 = 5 + num_payload_words32;
+ vrt_hdr_flags = 0x18c00000;
+ break;
+ case 8:
+ header_buff[1] = htonl(0);
+ header_buff[2] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 3;
+ num_packet_words32 = 3 + num_payload_words32;
+ vrt_hdr_flags = 0x100000;
+ break;
+ case 9:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 4;
+ num_packet_words32 = 4 + num_payload_words32;
+ vrt_hdr_flags = 0x10100000;
+ break;
+ case 10:
+ header_buff[1] = htonl(0);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(0);
+ header_buff[4] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 5;
+ num_packet_words32 = 5 + num_payload_words32;
+ vrt_hdr_flags = 0x8100000;
+ break;
+ case 11:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(0);
+ header_buff[4] = htonl(0);
+ header_buff[5] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 6;
+ num_packet_words32 = 6 + num_payload_words32;
+ vrt_hdr_flags = 0x18100000;
+ break;
+ case 12:
+ header_buff[1] = htonl(metadata.time_spec.secs);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 4;
+ num_packet_words32 = 4 + num_payload_words32;
+ vrt_hdr_flags = 0xd00000;
+ break;
+ case 13:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(metadata.time_spec.secs);
+ header_buff[3] = htonl(0);
+ header_buff[4] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 5;
+ num_packet_words32 = 5 + num_payload_words32;
+ vrt_hdr_flags = 0x10d00000;
+ break;
+ case 14:
+ header_buff[1] = htonl(0);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(metadata.time_spec.secs);
+ header_buff[4] = htonl(0);
+ header_buff[5] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 6;
+ num_packet_words32 = 6 + num_payload_words32;
+ vrt_hdr_flags = 0x8d00000;
+ break;
+ case 15:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(0);
+ header_buff[4] = htonl(metadata.time_spec.secs);
+ header_buff[5] = htonl(0);
+ header_buff[6] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 7;
+ num_packet_words32 = 7 + num_payload_words32;
+ vrt_hdr_flags = 0x18d00000;
+ break;
+ case 16:
+ num_header_words32 = 1;
+ num_packet_words32 = 2 + num_payload_words32;
+ vrt_hdr_flags = 0x4000000;
+ break;
+ case 17:
+ header_buff[1] = htonl(metadata.stream_id);
+ num_header_words32 = 2;
+ num_packet_words32 = 3 + num_payload_words32;
+ vrt_hdr_flags = 0x14000000;
+ break;
+ case 18:
+ header_buff[1] = htonl(0);
+ header_buff[2] = htonl(0);
+ num_header_words32 = 3;
+ num_packet_words32 = 4 + num_payload_words32;
+ vrt_hdr_flags = 0xc000000;
+ break;
+ case 19:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(0);
+ num_header_words32 = 4;
+ num_packet_words32 = 5 + num_payload_words32;
+ vrt_hdr_flags = 0x1c000000;
+ break;
+ case 20:
+ header_buff[1] = htonl(metadata.time_spec.secs);
+ num_header_words32 = 2;
+ num_packet_words32 = 3 + num_payload_words32;
+ vrt_hdr_flags = 0x4c00000;
+ break;
+ case 21:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(metadata.time_spec.secs);
+ num_header_words32 = 3;
+ num_packet_words32 = 4 + num_payload_words32;
+ vrt_hdr_flags = 0x14c00000;
+ break;
+ case 22:
+ header_buff[1] = htonl(0);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(metadata.time_spec.secs);
+ num_header_words32 = 4;
+ num_packet_words32 = 5 + num_payload_words32;
+ vrt_hdr_flags = 0xcc00000;
+ break;
+ case 23:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(0);
+ header_buff[4] = htonl(metadata.time_spec.secs);
+ num_header_words32 = 5;
+ num_packet_words32 = 6 + num_payload_words32;
+ vrt_hdr_flags = 0x1cc00000;
+ break;
+ case 24:
+ header_buff[1] = htonl(0);
+ header_buff[2] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 3;
+ num_packet_words32 = 4 + num_payload_words32;
+ vrt_hdr_flags = 0x4100000;
+ break;
+ case 25:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 4;
+ num_packet_words32 = 5 + num_payload_words32;
+ vrt_hdr_flags = 0x14100000;
+ break;
+ case 26:
+ header_buff[1] = htonl(0);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(0);
+ header_buff[4] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 5;
+ num_packet_words32 = 6 + num_payload_words32;
+ vrt_hdr_flags = 0xc100000;
+ break;
+ case 27:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(0);
+ header_buff[4] = htonl(0);
+ header_buff[5] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 6;
+ num_packet_words32 = 7 + num_payload_words32;
+ vrt_hdr_flags = 0x1c100000;
+ break;
+ case 28:
+ header_buff[1] = htonl(metadata.time_spec.secs);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 4;
+ num_packet_words32 = 5 + num_payload_words32;
+ vrt_hdr_flags = 0x4d00000;
+ break;
+ case 29:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(metadata.time_spec.secs);
+ header_buff[3] = htonl(0);
+ header_buff[4] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 5;
+ num_packet_words32 = 6 + num_payload_words32;
+ vrt_hdr_flags = 0x14d00000;
+ break;
+ case 30:
+ header_buff[1] = htonl(0);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(metadata.time_spec.secs);
+ header_buff[4] = htonl(0);
+ header_buff[5] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 6;
+ num_packet_words32 = 7 + num_payload_words32;
+ vrt_hdr_flags = 0xcd00000;
+ break;
+ case 31:
+ header_buff[1] = htonl(metadata.stream_id);
+ header_buff[2] = htonl(0);
+ header_buff[3] = htonl(0);
+ header_buff[4] = htonl(metadata.time_spec.secs);
+ header_buff[5] = htonl(0);
+ header_buff[6] = htonl(metadata.time_spec.ticks);
+ num_header_words32 = 7;
+ num_packet_words32 = 8 + num_payload_words32;
+ vrt_hdr_flags = 0x1cd00000;
+ break;
}
- 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;
+ //set the burst flags
+ if (metadata.start_of_burst) vrt_hdr_flags |= 0x2000000;
+ if (metadata.end_of_burst) vrt_hdr_flags |= 0x1000000;
//fill in complete header word
header_buff[0] = htonl(vrt_hdr_flags |
@@ -80,30 +318,230 @@ void vrt::unpack(
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++]);
- }
+ boost::uint8_t pred = 0;
+ if(vrt_hdr_word & 0x10000000) pred |= 0x1;
+ if(vrt_hdr_word & 0x8000000) pred |= 0x2;
+ if(vrt_hdr_word & 0xc00000) pred |= 0x4;
+ if(vrt_hdr_word & 0x300000) pred |= 0x8;
+ if(vrt_hdr_word & 0x4000000) pred |= 0x10;
- 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
+ switch(pred){
+ case 0:
+ num_header_words32 = 1;
+ num_payload_words32 = packet_words32 - 1;
+ break;
+ case 1:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ num_header_words32 = 2;
+ num_payload_words32 = packet_words32 - 2;
+ break;
+ case 2:
+ num_header_words32 = 3;
+ num_payload_words32 = packet_words32 - 3;
+ break;
+ case 3:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ num_header_words32 = 4;
+ num_payload_words32 = packet_words32 - 4;
+ break;
+ case 4:
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[1]);
+ num_header_words32 = 2;
+ num_payload_words32 = packet_words32 - 2;
+ break;
+ case 5:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[2]);
+ num_header_words32 = 3;
+ num_payload_words32 = packet_words32 - 3;
+ break;
+ case 6:
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[3]);
+ num_header_words32 = 4;
+ num_payload_words32 = packet_words32 - 4;
+ break;
+ case 7:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[4]);
+ num_header_words32 = 5;
+ num_payload_words32 = packet_words32 - 5;
+ break;
+ case 8:
+ metadata.has_time_spec = true;
+ metadata.time_spec.ticks = ntohl(header_buff[2]);
+ num_header_words32 = 3;
+ num_payload_words32 = packet_words32 - 3;
+ break;
+ case 9:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ metadata.has_time_spec = true;
+ metadata.time_spec.ticks = ntohl(header_buff[3]);
+ num_header_words32 = 4;
+ num_payload_words32 = packet_words32 - 4;
+ break;
+ case 10:
+ metadata.has_time_spec = true;
+ metadata.time_spec.ticks = ntohl(header_buff[4]);
+ num_header_words32 = 5;
+ num_payload_words32 = packet_words32 - 5;
+ break;
+ case 11:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ metadata.has_time_spec = true;
+ metadata.time_spec.ticks = ntohl(header_buff[5]);
+ num_header_words32 = 6;
+ num_payload_words32 = packet_words32 - 6;
+ break;
+ case 12:
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[1]);
+ metadata.time_spec.ticks = ntohl(header_buff[3]);
+ num_header_words32 = 4;
+ num_payload_words32 = packet_words32 - 4;
+ break;
+ case 13:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[2]);
+ metadata.time_spec.ticks = ntohl(header_buff[4]);
+ num_header_words32 = 5;
+ num_payload_words32 = packet_words32 - 5;
+ break;
+ case 14:
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[3]);
+ metadata.time_spec.ticks = ntohl(header_buff[5]);
+ num_header_words32 = 6;
+ num_payload_words32 = packet_words32 - 6;
+ break;
+ case 15:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[4]);
+ metadata.time_spec.ticks = ntohl(header_buff[6]);
+ num_header_words32 = 7;
+ num_payload_words32 = packet_words32 - 7;
+ break;
+ case 16:
+ num_header_words32 = 1;
+ num_payload_words32 = packet_words32 - 2;
+ break;
+ case 17:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ num_header_words32 = 2;
+ num_payload_words32 = packet_words32 - 3;
+ break;
+ case 18:
+ num_header_words32 = 3;
+ num_payload_words32 = packet_words32 - 4;
+ break;
+ case 19:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ num_header_words32 = 4;
+ num_payload_words32 = packet_words32 - 5;
+ break;
+ case 20:
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[1]);
+ num_header_words32 = 2;
+ num_payload_words32 = packet_words32 - 3;
+ break;
+ case 21:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[2]);
+ num_header_words32 = 3;
+ num_payload_words32 = packet_words32 - 4;
+ break;
+ case 22:
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[3]);
+ num_header_words32 = 4;
+ num_payload_words32 = packet_words32 - 5;
+ break;
+ case 23:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[4]);
+ num_header_words32 = 5;
+ num_payload_words32 = packet_words32 - 6;
+ break;
+ case 24:
+ metadata.has_time_spec = true;
+ metadata.time_spec.ticks = ntohl(header_buff[2]);
+ num_header_words32 = 3;
+ num_payload_words32 = packet_words32 - 4;
+ break;
+ case 25:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ metadata.has_time_spec = true;
+ metadata.time_spec.ticks = ntohl(header_buff[3]);
+ num_header_words32 = 4;
+ num_payload_words32 = packet_words32 - 5;
+ break;
+ case 26:
+ metadata.has_time_spec = true;
+ metadata.time_spec.ticks = ntohl(header_buff[4]);
+ num_header_words32 = 5;
+ num_payload_words32 = packet_words32 - 6;
+ break;
+ case 27:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ metadata.has_time_spec = true;
+ metadata.time_spec.ticks = ntohl(header_buff[5]);
+ num_header_words32 = 6;
+ num_payload_words32 = packet_words32 - 7;
+ break;
+ case 28:
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[1]);
+ metadata.time_spec.ticks = ntohl(header_buff[3]);
+ num_header_words32 = 4;
+ num_payload_words32 = packet_words32 - 5;
+ break;
+ case 29:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[2]);
+ metadata.time_spec.ticks = ntohl(header_buff[4]);
+ num_header_words32 = 5;
+ num_payload_words32 = packet_words32 - 6;
+ break;
+ case 30:
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[3]);
+ metadata.time_spec.ticks = ntohl(header_buff[5]);
+ num_header_words32 = 6;
+ num_payload_words32 = packet_words32 - 7;
+ break;
+ case 31:
+ metadata.has_stream_id = true;
+ metadata.stream_id = ntohl(header_buff[1]);
+ metadata.has_time_spec = true;
+ metadata.time_spec.secs = ntohl(header_buff[4]);
+ metadata.time_spec.ticks = ntohl(header_buff[6]);
+ num_header_words32 = 7;
+ num_payload_words32 = packet_words32 - 8;
+ break;
}
-
- size_t num_trailer_words32 = (vrt_hdr_word & (0x1 << 26))? 1 : 0;
-
- num_payload_words32 = packet_words32 - num_header_words32 - num_trailer_words32;
}
+