aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/transport')
-rw-r--r--host/lib/transport/CMakeLists.txt5
-rw-r--r--host/lib/transport/chdr.cpp182
-rw-r--r--host/lib/transport/gen_vrt_if_packet.py269
-rw-r--r--host/lib/transport/libusb1_base.cpp48
-rw-r--r--host/lib/transport/libusb1_base.hpp27
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp73
-rwxr-xr-xhost/lib/transport/nirio/lvbitx/process-lvbitx.py16
-rw-r--r--host/lib/transport/nirio/nirio_driver_iface_linux.cpp10
-rw-r--r--host/lib/transport/nirio/niriok_proxy_impl_v1.cpp421
-rw-r--r--host/lib/transport/nirio/niriok_proxy_impl_v2.cpp270
-rw-r--r--host/lib/transport/nirio/rpc/rpc_client.cpp2
-rw-r--r--host/lib/transport/super_recv_packet_handler.hpp7
-rw-r--r--host/lib/transport/udp_zero_copy.cpp9
13 files changed, 1088 insertions, 251 deletions
diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt
index 5920f3d78..6abc399b4 100644
--- a/host/lib/transport/CMakeLists.txt
+++ b/host/lib/transport/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright 2010-2013 Ettus Research LLC
+# Copyright 2010-2013,2015 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
@@ -30,7 +30,7 @@ INCLUDE_SUBDIRECTORY(nirio)
MESSAGE(STATUS "")
FIND_PACKAGE(USB1)
-LIBUHD_REGISTER_COMPONENT("USB" ENABLE_USB ON "ENABLE_LIBUHD;LIBUSB_FOUND" OFF)
+LIBUHD_REGISTER_COMPONENT("USB" ENABLE_USB ON "ENABLE_LIBUHD;LIBUSB_FOUND" OFF OFF)
IF(ENABLE_USB)
MESSAGE(STATUS "USB support enabled via libusb.")
@@ -129,6 +129,7 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/if_addrs.cpp
${CMAKE_CURRENT_SOURCE_DIR}/udp_simple.cpp
${CMAKE_CURRENT_SOURCE_DIR}/nirio_zero_copy.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/chdr.cpp
)
# Verbose Debug output for send/recv
diff --git a/host/lib/transport/chdr.cpp b/host/lib/transport/chdr.cpp
new file mode 100644
index 000000000..632887e56
--- /dev/null
+++ b/host/lib/transport/chdr.cpp
@@ -0,0 +1,182 @@
+//
+// Copyright 2014 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/chdr.hpp>
+#include <uhd/utils/byteswap.hpp>
+#include <uhd/exception.hpp>
+
+//define the endian macros to convert integers
+#ifdef BOOST_BIG_ENDIAN
+ #define BE_MACRO(x) (x)
+ #define LE_MACRO(x) uhd::byteswap(x)
+#else
+ #define BE_MACRO(x) uhd::byteswap(x)
+ #define LE_MACRO(x) (x)
+#endif
+
+using namespace uhd::transport::vrt;
+
+static const boost::uint32_t HDR_FLAG_TSF = (1 << 29);
+static const boost::uint32_t HDR_FLAG_EOB = (1 << 28);
+static const boost::uint32_t HDR_FLAG_ERROR = (1 << 28);
+
+/***************************************************************************/
+/* Packing */
+/***************************************************************************/
+/*! Translate the contents of \p if_packet_info into a 32-Bit word and return it.
+ */
+UHD_INLINE boost::uint32_t _hdr_pack_chdr(
+ if_packet_info_t &if_packet_info
+) {
+ // Set fields in if_packet_info
+ if_packet_info.num_header_words32 = 2 + (if_packet_info.has_tsf ? 2 : 0);
+ if_packet_info.num_packet_words32 =
+ if_packet_info.num_header_words32 +
+ if_packet_info.num_payload_words32;
+
+ boost::uint16_t pkt_length =
+ if_packet_info.num_payload_bytes + (4 * if_packet_info.num_header_words32);
+ boost::uint32_t chdr = 0
+ // 2 Bits: Packet type
+ | (if_packet_info.packet_type << 30)
+ // 1 Bit: Has time
+ | (if_packet_info.has_tsf ? HDR_FLAG_TSF : 0)
+ // 1 Bit: EOB or Error
+ | ((if_packet_info.eob or if_packet_info.error) ? HDR_FLAG_EOB : 0)
+ // 12 Bits: Sequence number
+ | ((if_packet_info.packet_count & 0xFFF) << 16)
+ // 16 Bits: Total packet length
+ | pkt_length;
+ return chdr;
+}
+
+void chdr::if_hdr_pack_be(
+ boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
+) {
+ // Write header and update if_packet_info
+ packet_buff[0] = BE_MACRO(_hdr_pack_chdr(if_packet_info));
+
+ // Write SID
+ packet_buff[1] = BE_MACRO(if_packet_info.sid);
+
+ // Write time
+ if (if_packet_info.has_tsf) {
+ packet_buff[2] = BE_MACRO(boost::uint32_t(if_packet_info.tsf >> 32));
+ packet_buff[3] = BE_MACRO(boost::uint32_t(if_packet_info.tsf >> 0));
+ }
+}
+
+void chdr::if_hdr_pack_le(
+ boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
+) {
+ // Write header and update if_packet_info
+ packet_buff[0] = LE_MACRO(_hdr_pack_chdr(if_packet_info));
+
+ // Write SID
+ packet_buff[1] = LE_MACRO(if_packet_info.sid);
+
+ // Write time
+ if (if_packet_info.has_tsf) {
+ packet_buff[2] = LE_MACRO(boost::uint32_t(if_packet_info.tsf >> 32));
+ packet_buff[3] = LE_MACRO(boost::uint32_t(if_packet_info.tsf >> 0));
+ }
+}
+
+
+/***************************************************************************/
+/* Unpacking */
+/***************************************************************************/
+UHD_INLINE void _hdr_unpack_chdr(
+ const boost::uint32_t chdr,
+ if_packet_info_t &if_packet_info
+) {
+ // Set constant members
+ if_packet_info.link_type = if_packet_info_t::LINK_TYPE_CHDR;
+ if_packet_info.has_cid = false;
+ if_packet_info.has_sid = true;
+ if_packet_info.has_tsi = false;
+ if_packet_info.has_tlr = false;
+ if_packet_info.sob = false;
+
+ // Set configurable members
+ if_packet_info.has_tsf = (chdr & HDR_FLAG_TSF) > 0;
+ if_packet_info.packet_type = if_packet_info_t::packet_type_t((chdr >> 30) & 0x3);
+ if_packet_info.eob = (if_packet_info.packet_type == if_packet_info_t::PACKET_TYPE_DATA)
+ && ((chdr & HDR_FLAG_EOB) > 0);
+ if_packet_info.error = (if_packet_info.packet_type == if_packet_info_t::PACKET_TYPE_RESP)
+ && ((chdr & HDR_FLAG_ERROR) > 0);
+ if_packet_info.packet_count = (chdr >> 16) & 0xFFF;
+
+ // Set packet length variables
+ if (if_packet_info.has_tsf) {
+ if_packet_info.num_header_words32 = 4;
+ } else {
+ if_packet_info.num_header_words32 = 2;
+ }
+ size_t pkt_size_bytes = (chdr & 0xFFFF);
+ size_t pkt_size_word32 = (pkt_size_bytes / 4) + ((pkt_size_bytes % 4) ? 1 : 0);
+ // Check lengths match:
+ if (pkt_size_word32 < if_packet_info.num_header_words32) {
+ throw uhd::value_error("Bad CHDR or invalid packet length");
+ }
+ if (if_packet_info.num_packet_words32 < pkt_size_word32) {
+ throw uhd::value_error("Bad CHDR or packet fragment");
+ }
+ if_packet_info.num_payload_bytes = pkt_size_bytes - (4 * if_packet_info.num_header_words32);
+ if_packet_info.num_payload_words32 = pkt_size_word32 - if_packet_info.num_header_words32;
+}
+
+void chdr::if_hdr_unpack_be(
+ const boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
+) {
+ // Read header and update if_packet_info
+ boost::uint32_t chdr = BE_MACRO(packet_buff[0]);
+ _hdr_unpack_chdr(chdr, if_packet_info);
+
+ // Read SID
+ if_packet_info.sid = BE_MACRO(packet_buff[1]);
+
+ // Read time (has_tsf was updated earlier)
+ if (if_packet_info.has_tsf) {
+ if_packet_info.tsf = 0
+ | boost::uint64_t(BE_MACRO(packet_buff[2])) << 32
+ | BE_MACRO(packet_buff[3]);
+ }
+}
+
+void chdr::if_hdr_unpack_le(
+ const boost::uint32_t *packet_buff,
+ if_packet_info_t &if_packet_info
+) {
+ // Read header and update if_packet_info
+ boost::uint32_t chdr = LE_MACRO(packet_buff[0]);
+ _hdr_unpack_chdr(chdr, if_packet_info);
+
+ // Read SID
+ if_packet_info.sid = LE_MACRO(packet_buff[1]);
+
+ // Read time (has_tsf was updated earlier)
+ if (if_packet_info.has_tsf) {
+ if_packet_info.tsf = 0
+ | boost::uint64_t(LE_MACRO(packet_buff[2])) << 32
+ | LE_MACRO(packet_buff[3]);
+ }
+}
+
diff --git a/host/lib/transport/gen_vrt_if_packet.py b/host/lib/transport/gen_vrt_if_packet.py
index 98f6804ae..6723e3a4b 100644
--- a/host/lib/transport/gen_vrt_if_packet.py
+++ b/host/lib/transport/gen_vrt_if_packet.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2010-2013 Ettus Research LLC
+# Copyright 2010-2013,2015 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
@@ -25,26 +25,25 @@ 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
+TMPL_TEXT = """<% import time %>
/***********************************************************************
- * This file was generated by $file on $time.strftime("%c")
+ * This file was generated by ${file} on ${time.strftime("%c")}
**********************************************************************/
-\#include <uhd/exception.hpp>
-\#include <uhd/transport/vrt_if_packet.hpp>
-\#include <uhd/utils/byteswap.hpp>
-\#include <boost/detail/endian.hpp>
-\#include <vector>
+#include <uhd/exception.hpp>
+#include <uhd/transport/vrt_if_packet.hpp>
+#include <uhd/utils/byteswap.hpp>
+#include <boost/detail/endian.hpp>
+#include <vector>
//define the endian macros to convert integers
-\#ifdef BOOST_BIG_ENDIAN
- \#define BE_MACRO(x) (x)
- \#define LE_MACRO(x) uhd::byteswap(x)
-\#else
- \#define BE_MACRO(x) uhd::byteswap(x)
- \#define LE_MACRO(x) (x)
-\#endif
+#ifdef BOOST_BIG_ENDIAN
+ #define BE_MACRO(x) (x)
+ #define LE_MACRO(x) uhd::byteswap(x)
+#else
+ #define BE_MACRO(x) uhd::byteswap(x)
+ #define LE_MACRO(x) (x)
+#endif
using namespace uhd;
using namespace uhd::transport;
@@ -59,13 +58,13 @@ static pred_table_type get_pred_unpack_table(void)
pred_table_type table(1 << 9, 0); //only 9 bits useful here (20-28)
for (size_t i = 0; i < table.size(); i++){
boost::uint32_t vrt_hdr_word = i << 20;
- if(vrt_hdr_word & $hex(0x1 << 28)) table[i] |= $hex($sid_p);
- if(vrt_hdr_word & $hex(0x1 << 27)) table[i] |= $hex($cid_p);
- if(vrt_hdr_word & $hex(0x3 << 22)) table[i] |= $hex($tsi_p);
- if(vrt_hdr_word & $hex(0x3 << 20)) table[i] |= $hex($tsf_p);
- if(vrt_hdr_word & $hex(0x1 << 26)) table[i] |= $hex($tlr_p);
- if(vrt_hdr_word & $hex(0x1 << 24)) table[i] |= $hex($eob_p);
- if(vrt_hdr_word & $hex(0x1 << 25)) table[i] |= $hex($sob_p);
+ if(vrt_hdr_word & ${hex(0x1 << 28)}) table[i] |= ${hex(sid_p)};
+ if(vrt_hdr_word & ${hex(0x1 << 27)}) table[i] |= ${hex(cid_p)};
+ if(vrt_hdr_word & ${hex(0x3 << 22)}) table[i] |= ${hex(tsi_p)};
+ if(vrt_hdr_word & ${hex(0x3 << 20)}) table[i] |= ${hex(tsf_p)};
+ if(vrt_hdr_word & ${hex(0x1 << 26)}) table[i] |= ${hex(tlr_p)};
+ if(vrt_hdr_word & ${hex(0x1 << 24)}) table[i] |= ${hex(eob_p)};
+ if(vrt_hdr_word & ${hex(0x1 << 25)}) table[i] |= ${hex(sob_p)};
}
return table;
}
@@ -105,13 +104,12 @@ UHD_INLINE static boost::uint32_t vrt_to_chdr(const boost::uint32_t vrt, const i
}
########################################################################
-#def gen_code($XE_MACRO, $suffix)
+<%def name="gen_code(XE_MACRO, suffix)">
########################################################################
-
/***********************************************************************
- * interal impl of packing VRT IF header only
+ * internal impl of packing VRT IF header only
**********************************************************************/
-UHD_INLINE void __if_hdr_pack_$(suffix)(
+UHD_INLINE void __if_hdr_pack_${suffix}(
boost::uint32_t *packet_buff,
if_packet_info_t &if_packet_info,
boost::uint32_t &vrt_hdr_word32
@@ -119,72 +117,53 @@ UHD_INLINE void __if_hdr_pack_$(suffix)(
boost::uint32_t vrt_hdr_flags = 0;
pred_type pred = 0;
- if (if_packet_info.has_sid) pred |= $hex($sid_p);
- if (if_packet_info.has_cid) pred |= $hex($cid_p);
- if (if_packet_info.has_tsi) pred |= $hex($tsi_p);
- if (if_packet_info.has_tsf) pred |= $hex($tsf_p);
- if (if_packet_info.has_tlr) pred |= $hex($tlr_p);
- if (if_packet_info.eob) pred |= $hex($eob_p);
- if (if_packet_info.sob) pred |= $hex($sob_p);
+ if (if_packet_info.has_sid) pred |= ${hex(sid_p)};
+ if (if_packet_info.has_cid) pred |= ${hex(cid_p)};
+ if (if_packet_info.has_tsi) pred |= ${hex(tsi_p)};
+ if (if_packet_info.has_tsf) pred |= ${hex(tsf_p)};
+ if (if_packet_info.has_tlr) pred |= ${hex(tlr_p)};
+ if (if_packet_info.eob) pred |= ${hex(eob_p)};
+ if (if_packet_info.sob) pred |= ${hex(sob_p)};
switch(pred){
- #for $pred in range(2**7)
- case $pred:
- #set $num_header_words = 1
- #set $flags = 0
+ % for pred in range(2**7):
+ case ${pred}:<% num_header_words = 1 %><% flags = 0 %>
########## Stream ID ##########
- #if $pred & $sid_p
- packet_buff[$num_header_words] = $(XE_MACRO)(if_packet_info.sid);
- #set $num_header_words += 1
- #set $flags |= (0x1 << 28);
- #end if
+ % if pred & sid_p:
+ packet_buff[${num_header_words}] = ${XE_MACRO}(if_packet_info.sid);<% num_header_words += 1 %><% flags |= (0x1 << 28) %>
+ % endif
########## Class ID ##########
- #if $pred & $cid_p
- packet_buff[$num_header_words] = 0; //not implemented
- #set $num_header_words += 1
- packet_buff[$num_header_words] = 0; //not implemented
- #set $num_header_words += 1
- #set $flags |= (0x1 << 27);
- #end if
+ % if pred & cid_p:
+ packet_buff[${num_header_words}] = 0; //not implemented<% num_header_words += 1 %>
+ packet_buff[${num_header_words}] = 0; //not implemented<% num_header_words += 1 %><% flags |= (0x1 << 27) %>
+ % endif
########## Integer Time ##########
- #if $pred & $tsi_p
- packet_buff[$num_header_words] = $(XE_MACRO)(if_packet_info.tsi);
- #set $num_header_words += 1
- #set $flags |= (0x3 << 22);
- #end if
+ % if pred & tsi_p:
+ packet_buff[${num_header_words}] = ${XE_MACRO}(if_packet_info.tsi);<% num_header_words += 1 %><% flags |= (0x3 << 22) %>
+ % endif
########## Fractional Time ##########
- #if $pred & $tsf_p
- packet_buff[$num_header_words] = $(XE_MACRO)(boost::uint32_t(if_packet_info.tsf >> 32));
- #set $num_header_words += 1
- packet_buff[$num_header_words] = $(XE_MACRO)(boost::uint32_t(if_packet_info.tsf >> 0));
- #set $num_header_words += 1
- #set $flags |= (0x1 << 20);
- #end if
+ % if pred & tsf_p:
+ packet_buff[${num_header_words}] = ${XE_MACRO}(boost::uint32_t(if_packet_info.tsf >> 32));<% num_header_words += 1 %>
+ packet_buff[${num_header_words}] = ${XE_MACRO}(boost::uint32_t(if_packet_info.tsf >> 0));<% num_header_words += 1 %><% flags |= (0x1 << 20) %>
+ % endif
########## Burst Flags ##########
- #if $pred & $eob_p
- #set $flags |= (0x1 << 24);
- #end if
- #if $pred & $sob_p
- #set $flags |= (0x1 << 25);
- #end if
+<% if pred & eob_p: flags |= (0x1 << 24) %><% if pred & sob_p: flags |= (0x1 << 25) %>
########## Trailer ##########
- #if $pred & $tlr_p
+ % if pred & tlr_p:
{
const size_t empty_bytes = if_packet_info.num_payload_words32*sizeof(boost::uint32_t) - if_packet_info.num_payload_bytes;
if_packet_info.tlr = (0x3 << 22) | (occ_table[empty_bytes & 0x3] << 10);
}
- packet_buff[$num_header_words+if_packet_info.num_payload_words32] = $(XE_MACRO)(if_packet_info.tlr);
- #set $flags |= (0x1 << 26);
- #set $num_trailer_words = 1;
- #else
- #set $num_trailer_words = 0;
- #end if
+ packet_buff[${num_header_words}+if_packet_info.num_payload_words32] = ${XE_MACRO}(if_packet_info.tlr);<% flags |= (0x1 << 26) %><% num_trailer_words = 1 %>
+ % else:
+<% num_trailer_words = 0 %>
+ % endif
########## Variables ##########
- if_packet_info.num_header_words32 = $num_header_words;
- if_packet_info.num_packet_words32 = $($num_header_words + $num_trailer_words) + if_packet_info.num_payload_words32;
- vrt_hdr_flags = $hex($flags);
+ if_packet_info.num_header_words32 = ${num_header_words};
+ if_packet_info.num_packet_words32 = ${num_header_words + num_trailer_words} + if_packet_info.num_payload_words32;
+ vrt_hdr_flags = ${hex(flags)};
break;
- #end for
+ % endfor
}
//fill in complete header word
@@ -197,9 +176,9 @@ UHD_INLINE void __if_hdr_pack_$(suffix)(
}
/***********************************************************************
- * interal impl of unpacking VRT IF header only
+ * internal impl of unpacking VRT IF header only
**********************************************************************/
-UHD_INLINE void __if_hdr_unpack_$(suffix)(
+UHD_INLINE void __if_hdr_unpack_${suffix}(
const boost::uint32_t *packet_buff,
if_packet_info_t &if_packet_info,
const boost::uint32_t vrt_hdr_word32
@@ -219,86 +198,78 @@ UHD_INLINE void __if_hdr_unpack_$(suffix)(
size_t empty_bytes = 0;
switch(pred){
- #for $pred in range(2**7)
- case $pred:
- #set $has_time_spec = False
- #set $num_header_words = 1
+ % for pred in range(2**7):
+ case ${pred}:<% has_time_spec = False %><% num_header_words = 1 %>
########## Stream ID ##########
- #if $pred & $sid_p
+ % if pred & sid_p:
if_packet_info.has_sid = true;
- if_packet_info.sid = $(XE_MACRO)(packet_buff[$num_header_words]);
- #set $num_header_words += 1
- #else
+ if_packet_info.sid = ${XE_MACRO}(packet_buff[${num_header_words}]);<% num_header_words += 1 %>
+ % else:
if_packet_info.has_sid = false;
- #end if
+ % endif
########## Class ID ##########
- #if $pred & $cid_p
+ % if pred & cid_p:
if_packet_info.has_cid = true;
- if_packet_info.cid = 0; //not implemented
- #set $num_header_words += 2
- #else
+ if_packet_info.cid = 0; //not implemented<% num_header_words += 2 %>
+ % else:
if_packet_info.has_cid = false;
- #end if
+ % endif
########## Integer Time ##########
- #if $pred & $tsi_p
+ % if pred & tsi_p:
if_packet_info.has_tsi = true;
- if_packet_info.tsi = $(XE_MACRO)(packet_buff[$num_header_words]);
- #set $num_header_words += 1
- #else
+ if_packet_info.tsi = ${XE_MACRO}(packet_buff[${num_header_words}]);
+<% num_header_words += 1 %>
+ % else:
if_packet_info.has_tsi = false;
- #end if
+ % endif
########## Fractional Time ##########
- #if $pred & $tsf_p
+ % if pred & tsf_p:
if_packet_info.has_tsf = true;
- if_packet_info.tsf = boost::uint64_t($(XE_MACRO)(packet_buff[$num_header_words])) << 32;
- #set $num_header_words += 1
- if_packet_info.tsf |= $(XE_MACRO)(packet_buff[$num_header_words]);
- #set $num_header_words += 1
- #else
+ if_packet_info.tsf = boost::uint64_t(${XE_MACRO}(packet_buff[${num_header_words}])) << 32;<% num_header_words += 1 %>
+ if_packet_info.tsf |= ${XE_MACRO}(packet_buff[${num_header_words}]);<% num_header_words += 1 %>
+ % else:
if_packet_info.has_tsf = false;
- #end if
+ % endif
########## Burst Flags ##########
- #if $pred & $eob_p
+ % if pred & eob_p:
if_packet_info.eob = true;
- #else
+ % else:
if_packet_info.eob = false;
- #end if
- #if $pred & $sob_p
+ % endif
+ % if pred & sob_p:
if_packet_info.sob = true;
- #else
+ % else:
if_packet_info.sob = false;
- #end if
+ % endif
########## Trailer ##########
- #if $pred & $tlr_p
+ % if pred & tlr_p:
if_packet_info.has_tlr = true;
- if_packet_info.tlr = $(XE_MACRO)(packet_buff[packet_words32-1]);
- #set $num_trailer_words = 1;
+ if_packet_info.tlr = ${XE_MACRO}(packet_buff[packet_words32-1]);<% num_trailer_words = 1 %>
{
const int indicators = (if_packet_info.tlr >> 20) & (if_packet_info.tlr >> 8);
if ((indicators & (1 << 0)) != 0) if_packet_info.eob = true;
if ((indicators & (1 << 1)) != 0) if_packet_info.sob = true;
empty_bytes = occ_table[(indicators >> 2) & 0x3];
}
- #else
- if_packet_info.has_tlr = false;
- #set $num_trailer_words = 0;
- #end if
+ % else:
+ if_packet_info.has_tlr = false;<% num_trailer_words = 0 %>
+ % endif
########## Variables ##########
//another failure case
- if (packet_words32 < $($num_header_words + $num_trailer_words))
+ if (packet_words32 < ${num_header_words + num_trailer_words})
throw uhd::value_error("bad vrt header or invalid packet length");
- if_packet_info.num_header_words32 = $num_header_words;
- if_packet_info.num_payload_words32 = packet_words32 - $($num_header_words + $num_trailer_words);
+ if_packet_info.num_header_words32 = ${num_header_words};
+ if_packet_info.num_payload_words32 = packet_words32 - ${num_header_words + num_trailer_words};
if_packet_info.num_payload_bytes = if_packet_info.num_payload_words32*sizeof(boost::uint32_t) - empty_bytes;
break;
- #end for
+ % endfor
}
}
/***********************************************************************
* link layer + VRT IF packing
**********************************************************************/
-void vrt::if_hdr_pack_$(suffix)(
+void vrt::if_hdr_pack_${suffix}(
boost::uint32_t *packet_buff,
if_packet_info_t &if_packet_info
){
@@ -306,29 +277,29 @@ void vrt::if_hdr_pack_$(suffix)(
switch (if_packet_info.link_type)
{
case if_packet_info_t::LINK_TYPE_NONE:
- __if_hdr_pack_$(suffix)(packet_buff, if_packet_info, vrt_hdr_word32);
- packet_buff[0] = $(XE_MACRO)(vrt_hdr_word32);
+ __if_hdr_pack_${suffix}(packet_buff, if_packet_info, vrt_hdr_word32);
+ packet_buff[0] = ${XE_MACRO}(vrt_hdr_word32);
break;
case if_packet_info_t::LINK_TYPE_CHDR:
{
- __if_hdr_pack_$(suffix)(packet_buff, if_packet_info, vrt_hdr_word32);
+ __if_hdr_pack_${suffix}(packet_buff, if_packet_info, vrt_hdr_word32);
const boost::uint32_t chdr = vrt_to_chdr(vrt_hdr_word32, if_packet_info);
- packet_buff[0] = $(XE_MACRO)(chdr);
+ packet_buff[0] = ${XE_MACRO}(chdr);
break;
}
case if_packet_info_t::LINK_TYPE_VRLP:
- __if_hdr_pack_$(suffix)(packet_buff+2, if_packet_info, vrt_hdr_word32);
+ __if_hdr_pack_${suffix}(packet_buff+2, if_packet_info, vrt_hdr_word32);
if_packet_info.num_header_words32 += 2;
if_packet_info.num_packet_words32 += 3;
- packet_buff[0] = $(XE_MACRO)(VRLP);
- packet_buff[1] = $(XE_MACRO)(boost::uint32_t(
+ packet_buff[0] = ${XE_MACRO}(VRLP);
+ packet_buff[1] = ${XE_MACRO}(boost::uint32_t(
(if_packet_info.num_packet_words32 & 0xfffff) |
((if_packet_info.packet_count & 0xfff) << 20)
));
- packet_buff[2] = $(XE_MACRO)(vrt_hdr_word32);
- packet_buff[if_packet_info.num_packet_words32-1] = $(XE_MACRO)(VEND);
+ packet_buff[2] = ${XE_MACRO}(vrt_hdr_word32);
+ packet_buff[if_packet_info.num_packet_words32-1] = ${XE_MACRO}(VEND);
break;
}
}
@@ -336,7 +307,7 @@ void vrt::if_hdr_pack_$(suffix)(
/***********************************************************************
* link layer + VRT IF unpacking
**********************************************************************/
-void vrt::if_hdr_unpack_$(suffix)(
+void vrt::if_hdr_unpack_${suffix}(
const boost::uint32_t *packet_buff,
if_packet_info_t &if_packet_info
){
@@ -344,16 +315,16 @@ void vrt::if_hdr_unpack_$(suffix)(
switch (if_packet_info.link_type)
{
case if_packet_info_t::LINK_TYPE_NONE:
- vrt_hdr_word32 = $(XE_MACRO)(packet_buff[0]);
- __if_hdr_unpack_$(suffix)(packet_buff, if_packet_info, vrt_hdr_word32);
+ vrt_hdr_word32 = ${XE_MACRO}(packet_buff[0]);
+ __if_hdr_unpack_${suffix}(packet_buff, if_packet_info, vrt_hdr_word32);
break;
case if_packet_info_t::LINK_TYPE_CHDR:
{
- const boost::uint32_t chdr = $(XE_MACRO)(packet_buff[0]);
+ const boost::uint32_t chdr = ${XE_MACRO}(packet_buff[0]);
vrt_hdr_word32 = chdr_to_vrt(chdr, if_packet_info);
size_t packet_count = if_packet_info.packet_count;
- __if_hdr_unpack_$(suffix)(packet_buff, if_packet_info, vrt_hdr_word32);
+ __if_hdr_unpack_${suffix}(packet_buff, if_packet_info, vrt_hdr_word32);
if_packet_info.num_payload_bytes -= (~chdr + 1) & 0x3;
if_packet_info.packet_count = packet_count;
break;
@@ -361,12 +332,12 @@ void vrt::if_hdr_unpack_$(suffix)(
case if_packet_info_t::LINK_TYPE_VRLP:
{
- if ($(XE_MACRO)(packet_buff[0]) != VRLP) throw uhd::value_error("bad vrl header VRLP");
- const boost::uint32_t vrl_hdr = $(XE_MACRO)(packet_buff[1]);
- vrt_hdr_word32 = $(XE_MACRO)(packet_buff[2]);
+ if (${XE_MACRO}(packet_buff[0]) != VRLP) throw uhd::value_error("bad vrl header VRLP");
+ const boost::uint32_t vrl_hdr = ${XE_MACRO}(packet_buff[1]);
+ vrt_hdr_word32 = ${XE_MACRO}(packet_buff[2]);
if (if_packet_info.num_packet_words32 < (vrl_hdr & 0xfffff)) throw uhd::value_error("bad vrl header or packet fragment");
- if ($(XE_MACRO)(packet_buff[(vrl_hdr & 0xfffff)-1]) != VEND) throw uhd::value_error("bad vrl trailer VEND");
- __if_hdr_unpack_$(suffix)(packet_buff+2, if_packet_info, vrt_hdr_word32);
+ if (${XE_MACRO}(packet_buff[(vrl_hdr & 0xfffff)-1]) != VEND) throw uhd::value_error("bad vrl trailer VEND");
+ __if_hdr_unpack_${suffix}(packet_buff+2, if_packet_info, vrt_hdr_word32);
if_packet_info.num_header_words32 += 2; //add vrl header
if_packet_info.packet_count = (vrl_hdr >> 20) & 0xfff;
break;
@@ -375,16 +346,16 @@ void vrt::if_hdr_unpack_$(suffix)(
}
########################################################################
-#end def
+</%def>
########################################################################
-$gen_code("BE_MACRO", "be")
-$gen_code("LE_MACRO", "le")
+${gen_code("BE_MACRO", "be")}
+${gen_code("LE_MACRO", "le")}
"""
def parse_tmpl(_tmpl_text, **kwargs):
- from Cheetah.Template import Template
- return str(Template(_tmpl_text, kwargs))
+ from mako.template import Template
+ return Template(_tmpl_text).render(**kwargs)
if __name__ == '__main__':
import sys
diff --git a/host/lib/transport/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp
index ae33cc036..f92117a9e 100644
--- a/host/lib/transport/libusb1_base.cpp
+++ b/host/lib/transport/libusb1_base.cpp
@@ -71,7 +71,18 @@ private:
timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 100000;
- libusb_handle_events_timeout(context, &tv);
+ int ret = libusb_handle_events_timeout(context, &tv);
+ switch (ret)
+ {
+ case LIBUSB_SUCCESS:
+ case LIBUSB_ERROR_TIMEOUT:
+ break;
+ case LIBUSB_ERROR_NO_DEVICE:
+ throw uhd::io_error(libusb_strerror(LIBUSB_ERROR_NO_DEVICE));
+ default:
+ UHD_MSG(error) << __FUNCTION__ << ": " << libusb_strerror((libusb_error)ret) << std::endl;
+ break;
+ }
}
};
@@ -251,6 +262,21 @@ public:
_claimed.push_back(interface);
}
+ void clear_endpoints(unsigned char recv_endpoint, unsigned char send_endpoint)
+ {
+ int ret;
+ ret = libusb_clear_halt(this->get(), recv_endpoint | 0x80);
+ UHD_LOG << "usb device handle: recv endpoint clear: " << libusb_error_name(ret) << std::endl;
+ ret = libusb_clear_halt(this->get(), send_endpoint | 0x00);
+ UHD_LOG << "usb device handle: send endpoint clear: " << libusb_error_name(ret) << std::endl;
+ }
+
+ void reset_device(void)
+ {
+ int ret = libusb_reset_device(this->get());
+ UHD_LOG << "usb device handle: dev Reset: " << libusb_error_name(ret) << std::endl;
+ }
+
private:
libusb::device::sptr _dev; //always keep a reference to device
libusb_device_handle *_handle;
@@ -345,15 +371,21 @@ libusb::special_handle::sptr libusb::special_handle::make(device::sptr dev){
std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(
boost::uint16_t vid, boost::uint16_t pid
){
- std::vector<usb_device_handle::sptr> handles;
+ return usb_device_handle::get_device_list(std::vector<usb_device_handle::vid_pid_pair_t>(1,usb_device_handle::vid_pid_pair_t(vid,pid)));
+}
+std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(const std::vector<usb_device_handle::vid_pid_pair_t>& vid_pid_pair_list)
+{
+ std::vector<usb_device_handle::sptr> handles;
libusb::device_list::sptr dev_list = libusb::device_list::make();
- for (size_t i = 0; i < dev_list->size(); i++){
- usb_device_handle::sptr handle = libusb::special_handle::make(dev_list->at(i));
- if (handle->get_vendor_id() == vid and handle->get_product_id() == pid){
- handles.push_back(handle);
- }
+ for(size_t iter = 0; iter < vid_pid_pair_list.size(); ++iter)
+ {
+ for (size_t i = 0; i < dev_list->size(); i++){
+ usb_device_handle::sptr handle = libusb::special_handle::make(dev_list->at(i));
+ if (handle->get_vendor_id() == vid_pid_pair_list[iter].first and handle->get_product_id() == vid_pid_pair_list[iter].second){
+ handles.push_back(handle);
+ }
+ }
}
-
return handles;
}
diff --git a/host/lib/transport/libusb1_base.hpp b/host/lib/transport/libusb1_base.hpp
index b00946614..2ff1291d9 100644
--- a/host/lib/transport/libusb1_base.hpp
+++ b/host/lib/transport/libusb1_base.hpp
@@ -24,6 +24,29 @@
#include <uhd/transport/usb_device_handle.hpp>
#include <libusb.h>
+//! Define LIBUSB_CALL when its missing (non-windows)
+#ifndef LIBUSB_CALL
+ #define LIBUSB_CALL
+#endif /*LIBUSB_CALL*/
+
+//! libusb_handle_events_timeout_completed is only in newer API
+#ifndef HAVE_LIBUSB_HANDLE_EVENTS_TIMEOUT_COMPLETED
+ #define libusb_handle_events_timeout_completed(ctx, tx, completed) \
+ libusb_handle_events_timeout(ctx, tx)
+#endif /* HAVE_LIBUSB_HANDLE_EVENTS_TIMEOUT_COMPLETED */
+
+//! libusb_error_name is only in newer API
+#ifndef HAVE_LIBUSB_ERROR_NAME
+ #define libusb_error_name(code) \
+ str(boost::format("LIBUSB_ERROR_CODE %d") % code)
+#endif /* HAVE_LIBUSB_ERROR_NAME */
+
+//! libusb_strerror is only in newer API
+#ifndef HAVE_LIBUSB_STRERROR
+ #define libusb_strerror(code) \
+ libusb_error_name(code)
+#endif /* HAVE_LIBUSB_STRERROR */
+
/***********************************************************************
* Libusb object oriented smart pointer wrappers:
* The following wrappers provide allocation and automatic deallocation
@@ -135,6 +158,10 @@ namespace libusb {
* Control interface: 0
*/
virtual void claim_interface(int) = 0;
+
+ virtual void clear_endpoints(unsigned char recv_endpoint, unsigned char send_endpoint) = 0;
+
+ virtual void reset_device(void) = 0;
};
/*!
diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp
index 1ac02d16f..b67b36d0a 100644
--- a/host/lib/transport/libusb1_zero_copy.cpp
+++ b/host/lib/transport/libusb1_zero_copy.cpp
@@ -43,23 +43,6 @@ using namespace uhd::transport;
static const size_t DEFAULT_NUM_XFERS = 16; //num xfers
static const size_t DEFAULT_XFER_SIZE = 32*512; //bytes
-//! Define LIBUSB_CALL when its missing (non-windows)
-#ifndef LIBUSB_CALL
- #define LIBUSB_CALL
-#endif /*LIBUSB_CALL*/
-
-//! libusb_handle_events_timeout_completed is only in newer API
-#ifndef HAVE_LIBUSB_HANDLE_EVENTS_TIMEOUT_COMPLETED
- #define libusb_handle_events_timeout_completed(ctx, tx, completed) \
- libusb_handle_events_timeout(ctx, tx)
-#endif
-
-//! libusb_error_name is only in newer API
-#ifndef HAVE_LIBUSB_ERROR_NAME
- #define libusb_error_name(code) \
- str(boost::format("LIBUSB_ERROR_CODE %d") % code)
-#endif
-
//! type for sharing the release queue with managed buffers
class libusb_zero_copy_mb;
typedef boost::shared_ptr<bounded_buffer<libusb_zero_copy_mb *> > mb_queue_sptr;
@@ -155,7 +138,8 @@ public:
result.is_recv = _is_recv;
#endif
const int ret = libusb_submit_transfer(_lut);
- if (ret != 0) throw uhd::runtime_error(str(boost::format(
+ if (ret != LIBUSB_SUCCESS)
+ throw uhd::usb_error(ret, str(boost::format(
"usb %s submit failed: %s") % _name % libusb_error_name(ret)));
}
@@ -164,8 +148,9 @@ public:
{
if (wait_for_completion(timeout))
{
- if (result.status != LIBUSB_TRANSFER_COMPLETED) throw uhd::runtime_error(str(boost::format(
- "usb %s transfer status: %d") % _name % int(result.status)));
+ if (result.status != LIBUSB_TRANSFER_COMPLETED)
+ throw uhd::runtime_error(str(boost::format("usb %s transfer status: %d")
+ % _name % libusb_error_name(result.status)));
result.completed = 0;
return make(reinterpret_cast<buffer_type *>(this), _lut->buffer, (_is_recv)? result.actual_length : _frame_size);
}
@@ -219,7 +204,8 @@ public:
_num_frames(num_frames),
_frame_size(frame_size),
_buffer_pool(buffer_pool::make(_num_frames, _frame_size)),
- _enqueued(_num_frames), _released(_num_frames)
+ _enqueued(_num_frames), _released(_num_frames),
+ _status(STATUS_RUNNING)
{
const bool is_recv = (endpoint & 0x80) != 0;
const std::string name = str(boost::format("%s%d") % ((is_recv)? "rx" : "tx") % int(endpoint & 0x7f));
@@ -304,18 +290,24 @@ public:
UHD_INLINE typename buffer_type::sptr get_buff(double timeout)
{
typename buffer_type::sptr buff;
- libusb_zero_copy_mb *front = NULL;
- boost::mutex::scoped_lock lock(_mutex);
+
+ if (_status == STATUS_ERROR)
+ return buff;
+
+ // Serialize access to buffers
+ boost::mutex::scoped_lock get_buff_lock(_get_buff_mutex);
+
+ boost::mutex::scoped_lock queue_lock(_queue_mutex);
if (_enqueued.empty())
{
- _cond.timed_wait(lock, boost::posix_time::microseconds(long(timeout*1e6)));
+ _buff_ready_cond.timed_wait(queue_lock, boost::posix_time::microseconds(long(timeout*1e6)));
}
if (_enqueued.empty()) return buff;
- front = _enqueued.front();
+ libusb_zero_copy_mb *front = _enqueued.front();
- lock.unlock();
+ queue_lock.unlock();
buff = front->get_new<buffer_type>(timeout);
- lock.lock();
+ queue_lock.lock();
if (buff) _enqueued.pop_front();
this->submit_what_we_can();
@@ -333,28 +325,39 @@ private:
buffer_pool::sptr _buffer_pool;
std::vector<boost::shared_ptr<libusb_zero_copy_mb> > _mb_pool;
- boost::mutex _mutex;
- boost::condition_variable _cond;
+ boost::mutex _queue_mutex;
+ boost::condition_variable _buff_ready_cond;
+ boost::mutex _get_buff_mutex;
//! why 2 queues? there is room in the future to have > N buffers but only N in flight
boost::circular_buffer<libusb_zero_copy_mb *> _enqueued, _released;
+ enum {STATUS_RUNNING, STATUS_ERROR} _status;
+
void enqueue_buffer(libusb_zero_copy_mb *mb)
{
- boost::mutex::scoped_lock l(_mutex);
+ boost::mutex::scoped_lock l(_queue_mutex);
_released.push_back(mb);
this->submit_what_we_can();
- l.unlock();
- _cond.notify_one();
+ _buff_ready_cond.notify_one();
}
void submit_what_we_can(void)
{
+ if (_status == STATUS_ERROR)
+ return;
while (not _released.empty() and not _enqueued.full())
{
- _released.front()->submit();
- _enqueued.push_back(_released.front());
- _released.pop_front();
+ try {
+ _released.front()->submit();
+ _enqueued.push_back(_released.front());
+ _released.pop_front();
+ }
+ catch (uhd::usb_error& e)
+ {
+ _status = STATUS_ERROR;
+ throw e;
+ }
}
}
diff --git a/host/lib/transport/nirio/lvbitx/process-lvbitx.py b/host/lib/transport/nirio/lvbitx/process-lvbitx.py
index ab9625608..7887c3997 100755
--- a/host/lib/transport/nirio/lvbitx/process-lvbitx.py
+++ b/host/lib/transport/nirio/lvbitx/process-lvbitx.py
@@ -1,6 +1,6 @@
#!/usr/bin/python
#
-# Copyright 2013-2014 Ettus Research LLC
+# Copyright 2013-2015 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
@@ -35,7 +35,7 @@ parser.add_option("--output-src-path", type="string", dest="output_src_path", he
# Args
if (len(args) < 1):
- print 'ERROR: Please specify the input LVBITX file name'
+ print('ERROR: Please specify the input LVBITX file name')
sys.exit(1)
lvbitx_filename = args[0]
@@ -44,16 +44,16 @@ autogen_src_path = os.path.abspath(options.output_src_path) if (options.output_s
class_name = os.path.splitext(os.path.basename(input_filename))[0]
if (not os.path.isfile(input_filename)):
- print 'ERROR: FPGA File ' + input_filename + ' could not be accessed or is not a file.'
+ print('ERROR: FPGA File ' + input_filename + ' could not be accessed or is not a file.')
sys.exit(1)
if (options.merge_bin is not None and not os.path.isfile(os.path.abspath(options.merge_bin))):
- print 'ERROR: FPGA Bin File ' + options.merge_bin + ' could not be accessed or is not a file.'
+ print('ERROR: FPGA Bin File ' + options.merge_bin + ' could not be accessed or is not a file.')
sys.exit(1)
if (not os.path.exists(autogen_src_path)):
- print 'ERROR: Output path ' + autogen_src_path + ' could not be accessed.'
+ print('ERROR: Output path ' + autogen_src_path + ' could not be accessed.')
sys.exit(1)
if (options.output_lvbitx_path is not None and input_filename == os.path.join(autogen_src_path, class_name + '.lvbitx')):
- print 'ERROR: Input and output LVBITX files were the same. Choose a difference input file or output path.'
+ print('ERROR: Input and output LVBITX files were the same. Choose a difference input file or output path.')
sys.exit(1)
# Get XML Tree Node
@@ -122,7 +122,7 @@ def map_SubType_to_ScalarType(SubType):
elif SubType == 'U64':
ScalarType = 'RIO_SCALAR_TYPE_UQ'
else:
- print 'ERROR: No corresponding nirio_scalar_type_t value for SubType ' + SubType + ' .'
+ print('ERROR: No corresponding nirio_scalar_type_t value for SubType ' + SubType + ' .')
sys.exit(1)
return ScalarType;
@@ -187,7 +187,7 @@ codegen_transform['lvbitx_signature'] = str.upper(root.find('SignatureRegister')
# Write BIN file
bitstream = base64.b64decode(root.find('Bitstream').text)
if (options.output_lvbitx_path is not None and hashlib.md5(bitstream).hexdigest() != root.find('BitstreamMD5').text):
- print 'ERROR: The MD5 sum for the output LVBITX was incorrect. Make sure that the bitstream in the input LVBITX or BIN file is valid.'
+ print('ERROR: The MD5 sum for the output LVBITX was incorrect. Make sure that the bitstream in the input LVBITX or BIN file is valid.')
sys.exit(1)
if (options.output_bin):
fpga_bin_file = open(os.path.join(options.output_lvbitx_path, class_name + '.bin'), 'w')
diff --git a/host/lib/transport/nirio/nirio_driver_iface_linux.cpp b/host/lib/transport/nirio/nirio_driver_iface_linux.cpp
index 4afc1579f..4d983de17 100644
--- a/host/lib/transport/nirio/nirio_driver_iface_linux.cpp
+++ b/host/lib/transport/nirio/nirio_driver_iface_linux.cpp
@@ -25,16 +25,6 @@
namespace nirio_driver_iface {
-struct nirio_ioctl_block_t
-{
- uint64_t in_buf;
- uint64_t out_buf;
- uint32_t in_buf_len;
- uint32_t out_buf_len;
- uint32_t bytes_returned;
- uint32_t padding;
-};
-
nirio_status rio_open(
const std::string& device_path,
rio_dev_handle_t& device_handle)
diff --git a/host/lib/transport/nirio/niriok_proxy_impl_v1.cpp b/host/lib/transport/nirio/niriok_proxy_impl_v1.cpp
index f0ffe2ffc..444e98f1b 100644
--- a/host/lib/transport/nirio/niriok_proxy_impl_v1.cpp
+++ b/host/lib/transport/nirio/niriok_proxy_impl_v1.cpp
@@ -26,8 +26,397 @@
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif
+// CTL_CODE macro for non-win OSes
+#ifndef UHD_PLATFORM_WIN32
+ #define CTL_CODE(a,controlCode,b,c) (controlCode)
+#endif
+
+const uint32_t NIRIO_IOCTL_BASE = 0x800;
+
+const uint32_t NIRIO_IOCTL_SYNCOP =
+ CTL_CODE(FILE_DEVICE_UNKNOWN,
+ NIRIO_IOCTL_BASE + 4,
+ METHOD_OUT_DIRECT,
+ FILE_READ_DATA | FILE_WRITE_DATA);
+ ///< The synchronous operation code. Note: We
+ /// must use METHOD_OUT_DIRECT on the syncOp()
+ /// IOCTL to ensure the contents of the output
+ /// block are available in the kernel.
+
+const uint32_t NIRIO_IOCTL_GET_IFACE_NUM =
+ CTL_CODE(FILE_DEVICE_UNKNOWN,
+ NIRIO_IOCTL_BASE + 6,
+ METHOD_BUFFERED,
+ FILE_READ_DATA); ///< Get the interface number for a device
+
+const uint32_t NIRIO_IOCTL_GET_SESSION =
+ CTL_CODE(FILE_DEVICE_UNKNOWN,
+ NIRIO_IOCTL_BASE + 8,
+ METHOD_BUFFERED,
+ FILE_READ_ACCESS); ///< Gets a previously opened session to a device
+
+const uint32_t NIRIO_IOCTL_POST_OPEN =
+ CTL_CODE(FILE_DEVICE_UNKNOWN,
+ NIRIO_IOCTL_BASE + 9,
+ METHOD_BUFFERED,
+ FILE_READ_ACCESS); ///< Called after opening a session
+
+const uint32_t NIRIO_IOCTL_PRE_CLOSE =
+ CTL_CODE(FILE_DEVICE_UNKNOWN,
+ NIRIO_IOCTL_BASE + 10,
+ METHOD_BUFFERED,
+ FILE_READ_ACCESS); ///< Called before closing a session
+
namespace uhd { namespace niusrprio
{
+ // -------------------------------
+ // Function Codes: defined as integers rather than enums because they
+ // are going to be carried accross boundaries so size matters
+
+ struct NIRIO_FUNC
+ {
+ static const uint32_t GET32 = 0x00000001;
+ static const uint32_t SET32 = 0x00000002;
+ static const uint32_t SET_DRIVER_CONFIG = 0x00000007;
+ static const uint32_t FIFO = 0x00000008;
+ static const uint32_t IO = 0x0000000A;
+ static const uint32_t FIFO_STOP_ALL = 0x0000000C;
+ static const uint32_t ADD_RESOURCE = 0x0000000D;
+ static const uint32_t GET_STRING = 0x0000000E;
+ static const uint32_t SET_STRING = 0x0000000F;
+ static const uint32_t DOWNLOAD = 0x00000013;
+ static const uint32_t RESET = 0x00000014;
+ };
+
+ struct NIRIO_RESOURCE
+ {
+ static const uint32_t INPUT_FIFO = 0xD0000001;
+ static const uint32_t OUTPUT_FIFO = 0xD0000002;
+ };
+
+ struct NIRIO_FIFO
+ {
+ static const uint32_t CONFIGURE = 0x80000001;
+ static const uint32_t START = 0x80000002;
+ static const uint32_t STOP = 0x80000003;
+ static const uint32_t READ = 0x80000004;
+ static const uint32_t WRITE = 0x80000005;
+ static const uint32_t WAIT = 0x80000006;
+ static const uint32_t GRANT = 0x80000007;
+ };
+
+ struct NIRIO_IO
+ {
+ static const uint32_t POKE64 = 0xA0000005;
+ static const uint32_t POKE32 = 0xA0000006;
+ static const uint32_t POKE16 = 0xA0000007;
+ static const uint32_t POKE8 = 0xA0000008;
+ static const uint32_t PEEK64 = 0xA0000009;
+ static const uint32_t PEEK32 = 0xA000000A;
+ static const uint32_t PEEK16 = 0xA000000B;
+ static const uint32_t PEEK8 = 0xA000000C;
+ static const uint32_t READ_BLOCK = 0xA000000D;
+ static const uint32_t WRITE_BLOCK = 0xA000000E;
+ static const uint32_t GET_IO_WINDOW = 0xA000000F;
+ static const uint32_t GET_IO_WINDOW_SIZE = 0xA0000010;
+ };
+
+ struct nirio_ioctl_packet_t {
+ nirio_ioctl_packet_t(void* const _outBuf, const uint32_t _outSize, const int32_t _statusCode)
+ {
+ outBuf._64BitField = 0;
+ outBuf.pointer = _outBuf;
+ outSize = _outSize;
+ statusCode = _statusCode;
+ };
+
+ union {
+ void* pointer;
+ uint64_t _64BitField;
+ } outBuf;
+
+ uint32_t outSize;
+ int32_t statusCode;
+ };
+
+ struct nirio_syncop_in_params_t
+ {
+ uint32_t function;
+ uint32_t subfunction;
+
+ union
+ {
+ struct
+ {
+ uint32_t attribute;
+ uint32_t value;
+ } attribute32;
+
+ struct
+ {
+ uint32_t attribute;
+ uint64_t value;
+ } attribute64;
+
+ struct
+ {
+ uint32_t attribute;
+ } attributeStr;
+
+ struct
+ {
+ uint32_t attribute;
+ } download;
+
+ union
+ {
+ struct
+ {
+ uint32_t reserved_field_0_0_0;
+ } reserved_field_0_0;
+ struct
+ {
+ uint32_t reserved_field_0_1_0;
+ uint32_t reserved_field_0_1_1;
+ } reserved_field_0_1;
+ struct
+ {
+ uint32_t reserved_field_0_2_0;
+ } reserved_field_0_2;
+ } reserved_field_0;
+
+ union
+ {
+ struct
+ {
+ uint32_t channel;
+ uint32_t baseAddress;
+ uint32_t depthInSamples;
+ uint32_t version;
+ } fifo;
+ struct
+ {
+ uint32_t channel;
+ uint32_t baseAddress;
+ uint32_t depthInSamples;
+ uint32_t version;
+ uint32_t scalarType;
+ uint32_t bitWidth;
+ } fifoWithDataType;
+ struct
+ {
+ uint64_t rangeBaseAddress;
+ uint32_t rangeSizeInBytes;
+ uint32_t rangeAttribute;
+ } atomic; // obsolete
+ } add;
+
+ struct
+ {
+ uint32_t channel;
+
+ union
+ {
+ struct
+ {
+ uint32_t requestedDepth;
+ uint8_t requiresActuals;
+ } config;
+ struct
+ {
+ uint32_t timeout;
+ } read;
+ struct
+ {
+ uint32_t timeout;
+ uint32_t scalarType;
+ uint32_t bitWidth;
+ } readWithDataType;
+ struct
+ {
+ uint32_t timeout;
+ } write;
+ struct
+ {
+ uint32_t timeout;
+ uint32_t scalarType;
+ uint32_t bitWidth;
+ } writeWithDataType;
+ struct
+ {
+ uint32_t elementsRequested;
+ uint32_t scalarType;
+ uint32_t bitWidth;
+ uint32_t timeout;
+ uint8_t output;
+ } wait;
+ struct
+ {
+ uint32_t elements;
+ } grant;
+ } op;
+ } fifo;
+
+ struct
+ {
+ uint64_t reserved_field_1_0;
+ uint32_t reserved_field_1_1;
+ uint32_t reserved_field_1_2;
+ } reserved_field_1; // Obsolete
+
+ struct
+ {
+ uint32_t offset;
+ union
+ {
+ uint64_t value64;
+ uint32_t value32;
+ uint16_t value16;
+ uint8_t value8;
+ } value;
+ union
+ {
+ uint32_t sizeToMap;
+ } memoryMappedIoWindow;
+ } io;
+
+ struct
+ {
+ uint32_t reserved_field_2_0;
+ uint32_t reserved_field_2_1;
+ } reserved_field_2;
+
+ struct
+ {
+ uint32_t reserved_field_3_0;
+ } reserved_field_3;
+
+ union
+ {
+ struct
+ {
+ uint32_t reserved_field_4_0;
+ int32_t reserved_field_4_1;
+ } wait;
+ } reserved_field_4;
+
+ } params;
+
+ uint32_t inbufByteLen;
+
+ union
+ {
+ const void* pointer;
+ uint64_t _64BitField;
+ } inbuf;
+ };
+
+ static inline void init_syncop_in_params(nirio_syncop_in_params_t& param, const void* const buf, const uint32_t len)
+ {
+ param.inbuf._64BitField = 0;
+ param.inbuf.pointer = buf;
+ param.inbufByteLen = len;
+ }
+
+ struct nirio_syncop_out_params_t
+ {
+ union
+ {
+ struct
+ {
+ uint32_t value;
+ } attribute32;
+
+ struct
+ {
+ uint64_t value;
+ } attribute64;
+
+ union
+ {
+ struct
+ {
+ uint32_t reserved_field_0_0;
+ } enable;
+ } reserved_field_0;
+
+ struct
+ {
+ union
+ {
+ struct
+ {
+ uint32_t actualDepth;
+ uint32_t actualSize;
+ } config;
+ struct
+ {
+ uint32_t numberRead;
+ uint32_t numberRemaining;
+ } read;
+ struct
+ {
+ uint32_t numberRemaining;
+ } write;
+ struct
+ {
+ union
+ {
+ void* pointer;
+ uint64_t _64BitField;
+ } elements;
+ } wait;
+ } op;
+ } fifo;
+
+ struct
+ {
+ union
+ {
+ union
+ {
+ uint64_t value64;
+ uint32_t value32;
+ uint16_t value16;
+ uint8_t value8;
+ } value;
+ union
+ {
+ void* memoryMappedAddress;
+ uint64_t _64BitField;
+ } memoryMappedIoWindow;
+ union
+ {
+ uint32_t size;
+ } memoryMappedIoWindowSize;
+ };
+ } io;
+
+ uint32_t stringLength;
+
+ struct
+ {
+ uint32_t reserved_field_1_0;
+ } reserved_field_1;
+
+ } params;
+
+ uint32_t outbufByteLen;
+
+ union
+ {
+ void* pointer;
+ uint64_t _64BitField;
+ } outbuf;
+ };
+
+ static inline void init_syncop_out_params(nirio_syncop_out_params_t& param, void* buf, uint32_t len)
+ {
+ param.outbuf._64BitField = 0;
+ param.outbuf.pointer = buf;
+ param.outbufByteLen = len;
+ }
+
//-------------------------------------------------------
// niriok_proxy_impl_v1
//-------------------------------------------------------
@@ -55,11 +444,11 @@ namespace uhd { namespace niusrprio
interface_path, _device_handle), status);
if (nirio_status_not_fatal(status)) {
nirio_status_chain(nirio_driver_iface::rio_ioctl(_device_handle,
- nirio_driver_iface::NIRIO_IOCTL_POST_OPEN,
+ NIRIO_IOCTL_POST_OPEN,
NULL, 0, NULL, 0), status);
nirio_ioctl_packet_t out(&_interface_num, sizeof(_interface_num), 0);
nirio_status_chain(nirio_driver_iface::rio_ioctl(_device_handle,
- nirio_driver_iface::NIRIO_IOCTL_GET_IFACE_NUM,
+ NIRIO_IOCTL_GET_IFACE_NUM,
NULL, 0,
&out, sizeof(out)), status);
@@ -83,7 +472,7 @@ namespace uhd { namespace niusrprio
if(nirio_driver_iface::rio_isopen(_device_handle))
{
nirio_driver_iface::rio_ioctl(
- _device_handle, nirio_driver_iface::NIRIO_IOCTL_PRE_CLOSE, NULL, 0, NULL, 0);
+ _device_handle, NIRIO_IOCTL_PRE_CLOSE, NULL, 0, NULL, 0);
nirio_driver_iface::rio_close(_device_handle);
}
}
@@ -100,18 +489,6 @@ namespace uhd { namespace niusrprio
return sync_operation(&in, sizeof(in), &out, sizeof(out));
}
- nirio_status niriok_proxy_impl_v1::get_cached_session(
- uint32_t& session)
- {
- READER_LOCK
-
- nirio_ioctl_packet_t out(&session, sizeof(session), 0);
- return nirio_driver_iface::rio_ioctl(_device_handle,
- nirio_driver_iface::NIRIO_IOCTL_GET_SESSION,
- NULL, 0,
- &out, sizeof(out));
- }
-
nirio_status niriok_proxy_impl_v1::get_version(
nirio_version_t type,
uint32_t& major,
@@ -150,7 +527,7 @@ namespace uhd { namespace niusrprio
nirio_ioctl_packet_t out(readBuffer, readBufferLength, 0);
nirio_status ioctl_status = nirio_driver_iface::rio_ioctl(_device_handle,
- nirio_driver_iface::NIRIO_IOCTL_SYNCOP,
+ NIRIO_IOCTL_SYNCOP,
writeBuffer, writeBufferLength,
&out, sizeof(out));
if (nirio_status_fatal(ioctl_status)) return ioctl_status;
@@ -282,14 +659,14 @@ namespace uhd { namespace niusrprio
nirio_status niriok_proxy_impl_v1::add_fifo_resource(const nirio_fifo_info_t& fifo_info)
{
- niriok_proxy_impl_v1::nirio_syncop_in_params_t in = {};
- niriok_proxy_impl_v1::nirio_syncop_out_params_t out = {};
+ nirio_syncop_in_params_t in = {};
+ nirio_syncop_out_params_t out = {};
- in.function = niriok_proxy_impl_v1::NIRIO_FUNC::ADD_RESOURCE;
+ in.function = NIRIO_FUNC::ADD_RESOURCE;
if (fifo_info.direction == OUTPUT_FIFO)
- in.subfunction = niriok_proxy_impl_v1::NIRIO_RESOURCE::OUTPUT_FIFO;
+ in.subfunction = NIRIO_RESOURCE::OUTPUT_FIFO;
else
- in.subfunction = niriok_proxy_impl_v1::NIRIO_RESOURCE::INPUT_FIFO;
+ in.subfunction = NIRIO_RESOURCE::INPUT_FIFO;
in.params.add.fifoWithDataType.channel = fifo_info.channel;
in.params.add.fifoWithDataType.baseAddress = fifo_info.base_addr;
@@ -307,7 +684,7 @@ namespace uhd { namespace niusrprio
nirio_syncop_in_params_t in = {};
nirio_syncop_out_params_t out = {};
- in.function = niriok_proxy_impl_v1::NIRIO_FUNC::SET_DRIVER_CONFIG;
+ in.function = NIRIO_FUNC::SET_DRIVER_CONFIG;
in.subfunction = 0;
return sync_operation(&in, sizeof(in), &out, sizeof(out));
diff --git a/host/lib/transport/nirio/niriok_proxy_impl_v2.cpp b/host/lib/transport/nirio/niriok_proxy_impl_v2.cpp
index 748db5cf8..f75de01e1 100644
--- a/host/lib/transport/nirio/niriok_proxy_impl_v2.cpp
+++ b/host/lib/transport/nirio/niriok_proxy_impl_v2.cpp
@@ -27,9 +27,263 @@
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif
+#define IOCTL_TRANSPORT_GET32 IOCTL(0, 0, IOCTL_ACCESS_READ)
+#define IOCTL_TRANSPORT_SET32 IOCTL(0, 1, IOCTL_ACCESS_WRITE)
+#define IOCTL_TRANSPORT_GET_STRING IOCTL(0, 2, IOCTL_ACCESS_READ)
+#define IOCTL_TRANSPORT_SET_STRING IOCTL(0, 3, IOCTL_ACCESS_WRITE)
+#define IOCTL_TRANSPORT_RESET IOCTL(1, 1, IOCTL_ACCESS_WRITE)
+#define IOCTL_TRANSPORT_ADD_INPUT_FIFO_RESOURCE IOCTL(2, 0, IOCTL_ACCESS_ANY)
+#define IOCTL_TRANSPORT_ADD_OUTPUT_FIFO_RESOURCE IOCTL(2, 1, IOCTL_ACCESS_ANY)
+#define IOCTL_TRANSPORT_SET_DEVICE_CONFIG IOCTL(2, 3, IOCTL_ACCESS_WRITE)
+#define IOCTL_TRANSPORT_FIFO_CONFIG IOCTL(4, 0, IOCTL_ACCESS_ANY)
+#define IOCTL_TRANSPORT_FIFO_START IOCTL(4, 1, IOCTL_ACCESS_ANY)
+#define IOCTL_TRANSPORT_FIFO_STOP IOCTL(4, 2, IOCTL_ACCESS_ANY)
+#define IOCTL_TRANSPORT_FIFO_READ IOCTL(4, 3, IOCTL_ACCESS_READ)
+#define IOCTL_TRANSPORT_FIFO_WRITE IOCTL(4, 4, IOCTL_ACCESS_WRITE)
+#define IOCTL_TRANSPORT_FIFO_WAIT IOCTL(4, 5, IOCTL_ACCESS_ANY)
+#define IOCTL_TRANSPORT_FIFO_GRANT IOCTL(4, 6, IOCTL_ACCESS_ANY)
+#define IOCTL_TRANSPORT_FIFO_STOP_ALL IOCTL(4, 7, IOCTL_ACCESS_ANY)
+#define IOCTL_TRANSPORT_PEEK64 IOCTL(5, 2, IOCTL_ACCESS_READ)
+#define IOCTL_TRANSPORT_PEEK32 IOCTL(5, 3, IOCTL_ACCESS_READ)
+#define IOCTL_TRANSPORT_POKE64 IOCTL(5, 6, IOCTL_ACCESS_WRITE)
+#define IOCTL_TRANSPORT_POKE32 IOCTL(5, 7, IOCTL_ACCESS_WRITE)
+#define IOCTL_TRANSPORT_POST_OPEN IOCTL(8, 0, IOCTL_ACCESS_ANY)
+#define IOCTL_TRANSPORT_PRE_CLOSE IOCTL(8, 1, IOCTL_ACCESS_ANY)
+
namespace uhd { namespace niusrprio
{
//-------------------------------------------------------
+ // ioctl param typedefs
+ //-------------------------------------------------------
+ typedef struct {
+ nirio_scalar_type_t scalarType;
+ nirio_u32_t bitWidth;
+ nirio_i32_t integerWordLength;
+ } nirio_fifo_data_type_t;
+
+ typedef struct in_transport_get32
+ {
+ nirio_device_attribute32_t attribute;
+ int32_t status;
+ } in_transport_get32_t;
+ typedef struct out_transport_get32
+ {
+ uint32_t retVal__;
+ int32_t status;
+ } out_transport_get32_t;
+ typedef struct in_transport_set32
+ {
+ nirio_device_attribute32_t attribute;
+ uint32_t value;
+ int32_t status;
+ } in_transport_set32_t;
+ typedef struct out_transport_set32
+ {
+ int32_t status;
+ } out_transport_set32_t;
+ typedef struct out_transport_get_string
+ {
+ uint32_t stringLen;
+ int32_t status;
+ } out_transport_get_string_t;
+ typedef struct out_transport_set_string
+ {
+ int32_t status;
+ } out_transport_set_string_t;
+ typedef struct in_transport_reset
+ {
+ int32_t status;
+ } in_transport_reset_t;
+ typedef struct out_transport_reset
+ {
+ int32_t status;
+ } out_transport_reset_t;
+ typedef struct in_transport_add_input_fifo_resource
+ {
+ uint32_t channel;
+ uint32_t baseAddress;
+ uint32_t depthInSamples;
+ nirio_fifo_data_type_t dataType;
+ uint32_t version;
+ int32_t status;
+ } in_transport_add_input_fifo_resource_t;
+ typedef struct out_transport_addInputFifo_resource
+ {
+ int32_t status;
+ } out_transport_add_input_fifo_resource_t;
+ typedef struct in_transport_addOutputFifo_resource
+ {
+ uint32_t channel;
+ uint32_t baseAddress;
+ uint32_t depthInSamples;
+ nirio_fifo_data_type_t dataType;
+ uint32_t version;
+ int32_t status;
+ } in_transport_add_output_fifo_resource_t;
+ typedef struct out_transport_addOutputFifo_resource
+ {
+ int32_t status;
+ } out_transport_add_output_fifo_resource_t;
+ typedef struct in_transport_setDevice_config
+ {
+ uint32_t attribute;
+ int32_t status;
+ } in_transport_set_device_config_t;
+ typedef struct out_transport_setDevice_config
+ {
+ int32_t status;
+ } out_transport_set_device_config_t;
+ typedef struct in_transport_fifo_config
+ {
+ uint32_t channel;
+ aligned_uint64_t requestedDepth;
+ int32_t status;
+ } in_transport_fifo_config_t;
+ typedef struct out_transport_fifo_config
+ {
+ aligned_uint64_t actualDepth;
+ aligned_uint64_t actualSize;
+ int32_t status;
+ } out_transport_fifo_config_t;
+ typedef struct in_transport_fifo_start
+ {
+ uint32_t channel;
+ int32_t status;
+ } in_transport_fifo_start_t;
+ typedef struct out_transport_fifo_start
+ {
+ int32_t status;
+ } out_transport_fifo_start_t;
+ typedef struct in_transport_fifo_stop
+ {
+ uint32_t channel;
+ int32_t status;
+ } in_transport_fifo_stop_t;
+ typedef struct out_transport_fifo_stop
+ {
+ int32_t status;
+ } out_transport_fifo_stop_t;
+ typedef struct in_transport_fifo_read
+ {
+ uint32_t channel;
+ aligned_uint64_t buf;
+ uint32_t numberElements;
+ nirio_fifo_data_type_t dataType;
+ uint32_t timeout;
+ int32_t status;
+ } in_transport_fifo_read_t;
+ typedef struct out_transport_fifo_read
+ {
+ uint32_t read;
+ uint32_t remaining;
+ int32_t status;
+ } out_transport_fifo_read_t;
+ typedef struct in_transport_fifo_write
+ {
+ uint32_t channel;
+ aligned_uint64_t buf;
+ uint32_t numberElements;
+ nirio_fifo_data_type_t dataType;
+ uint32_t timeout;
+ int32_t status;
+ } in_transport_fifo_write_t;
+ typedef struct out_transport_fifo_write
+ {
+ uint32_t remaining;
+ int32_t status;
+ } out_transport_fifo_write_t;
+ typedef struct in_transport_fifo_wait
+ {
+ uint32_t channel;
+ aligned_uint64_t elementsRequested;
+ nirio_fifo_data_type_t dataType;
+ bool output;
+ uint32_t timeout;
+ int32_t status;
+ } in_transport_fifo_wait_t;
+ typedef struct out_transport_fifo_wait
+ {
+ aligned_uint64_t elements;
+ aligned_uint64_t elementsAcquired;
+ aligned_uint64_t elementsRemaining;
+ int32_t status;
+ } out_transport_fifo_wait_t;
+ typedef struct in_transport_fifo_grant
+ {
+ uint32_t channel;
+ aligned_uint64_t elements;
+ int32_t status;
+ } in_transport_fifo_grant_t;
+ typedef struct out_transport_fifo_grant
+ {
+ int32_t status;
+ } out_transport_fifo_grant_t;
+ typedef struct in_transport_fifoStop_all
+ {
+ int32_t status;
+ } in_transport_fifo_stop_all_t;
+ typedef struct out_transport_fifoStop_all
+ {
+ int32_t status;
+ } out_transport_fifo_stop_all_t;
+ typedef struct in_transport_peek64
+ {
+ uint32_t offset;
+ int32_t status;
+ } in_transport_peek64_t;
+ typedef struct out_transport_peek64
+ {
+ aligned_uint64_t retVal__;
+ int32_t status;
+ } out_transport_peek64_t;
+ typedef struct in_transport_peek32
+ {
+ uint32_t offset;
+ int32_t status;
+ } in_transport_peek32_t;
+ typedef struct out_transport_peek32
+ {
+ uint32_t retVal__;
+ int32_t status;
+ } out_transport_peek32_t;
+ typedef struct in_transport_poke64
+ {
+ uint32_t offset;
+ aligned_uint64_t value;
+ int32_t status;
+ } in_transport_poke64_t;
+ typedef struct out_transport_poke64
+ {
+ int32_t status;
+ } out_transport_poke64_t;
+ typedef struct in_transport_poke32
+ {
+ uint32_t offset;
+ uint32_t value;
+ int32_t status;
+ } in_transport_poke32_t;
+ typedef struct out_transport_poke32
+ {
+ int32_t status;
+ } out_transport_poke32_t;
+ typedef struct in_transport_post_open
+ {
+ int32_t status;
+ } in_transport_post_open_t;
+ typedef struct out_transport_post_open
+ {
+ int32_t status;
+ } out_transport_post_open_t;
+ typedef struct in_transport_pre_close
+ {
+ int32_t status;
+ } in_transport_pre_close_t;
+ typedef struct out_transport_pre_close
+ {
+ int32_t status;
+ } out_transport_pre_close_t;
+
+ //-------------------------------------------------------
// niriok_proxy_impl_v2
//-------------------------------------------------------
niriok_proxy_impl_v2::niriok_proxy_impl_v2()
@@ -110,18 +364,6 @@ namespace uhd { namespace niusrprio
return out.status;
}
- nirio_status niriok_proxy_impl_v2::get_cached_session(
- uint32_t& session)
- {
- READER_LOCK
-
- nirio_ioctl_packet_t out(&session, sizeof(session), 0);
- return nirio_driver_iface::rio_ioctl(_device_handle,
- nirio_driver_iface::NIRIO_IOCTL_GET_SESSION,
- NULL, 0,
- &out, sizeof(out));
- }
-
nirio_status niriok_proxy_impl_v2::get_version(
nirio_version_t type,
uint32_t& major,
@@ -580,7 +822,7 @@ namespace uhd { namespace niusrprio
out_transport_fifo_read_t out = {};
in.channel = channel;
- in.buf = reinterpret_cast<tAlignedU64>(buffer);
+ in.buf = reinterpret_cast<aligned_uint64_t>(buffer);
in.numberElements = elements_to_read;
in.dataType.scalarType = map_int_to_scalar_type(scalar_type);
in.dataType.bitWidth = bit_width;
@@ -620,7 +862,7 @@ namespace uhd { namespace niusrprio
out_transport_fifo_write_t out = {};
in.channel = channel;
- in.buf = reinterpret_cast<tAlignedU64>(buffer);
+ in.buf = reinterpret_cast<aligned_uint64_t>(buffer);
in.numberElements = elements_to_write;
in.dataType.scalarType = map_int_to_scalar_type(scalar_type);
in.dataType.bitWidth = bit_width;
diff --git a/host/lib/transport/nirio/rpc/rpc_client.cpp b/host/lib/transport/nirio/rpc/rpc_client.cpp
index cf8e9c1a9..bbaf9f235 100644
--- a/host/lib/transport/nirio/rpc/rpc_client.cpp
+++ b/host/lib/transport/nirio/rpc/rpc_client.cpp
@@ -52,7 +52,7 @@ rpc_client::rpc_client (
//- address_configured: Only return addresses if a non-loopback address is configured for the system.
//- numeric_host: No name resolution should be attempted for host
//- numeric_service: No name resolution should be attempted for service
- tcp::resolver::query::flags query_flags;
+ tcp::resolver::query::flags query_flags(tcp::resolver::query::passive);
tcp::resolver::query query(tcp::v4(), server, port, query_flags);
tcp::resolver::iterator iterator = resolver.resolve(query);
diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp
index 5c84327a4..0f1f7ff3a 100644
--- a/host/lib/transport/super_recv_packet_handler.hpp
+++ b/host/lib/transport/super_recv_packet_handler.hpp
@@ -147,7 +147,7 @@ public:
*/
void set_xport_chan_get_buff(const size_t xport_chan, const get_buff_type &get_buff, const bool flush = false){
if (flush){
- while (get_buff(0.0));
+ while (get_buff(0.0)) {};
}
_props.at(xport_chan).get_buff = get_buff;
}
@@ -560,6 +560,11 @@ private:
_props[index].handle_overflow();
curr_info.metadata = metadata;
UHD_MSG(fastpath) << "O";
+
+ // Not sending flow control would cause timeouts due to source flow control locking up
+ if(_props[index].handle_flowctrl) {
+ _props[index].handle_flowctrl(next_info[index].ifpi.packet_count);
+ }
}
return;
diff --git a/host/lib/transport/udp_zero_copy.cpp b/host/lib/transport/udp_zero_copy.cpp
index adc7d5585..70fb5b552 100644
--- a/host/lib/transport/udp_zero_copy.cpp
+++ b/host/lib/transport/udp_zero_copy.cpp
@@ -87,7 +87,10 @@ public:
if (wait_for_recv_ready(_sock_fd, timeout)){
_len = ::recv(_sock_fd, (char *)_mem, _frame_size, 0);
- UHD_ASSERT_THROW(_len > 0); // TODO: Handle case of recv error
+ if (_len == 0)
+ throw uhd::io_error("socket closed");
+ if (_len < 0)
+ throw uhd::io_error(str(boost::format("recv error on socket: %s") % strerror(errno)));
index++; //advances the caller's buffer
return make(this, _mem, size_t(_len));
}
@@ -126,6 +129,10 @@ public:
boost::this_thread::sleep(boost::posix_time::microseconds(1));
continue; //try to send again
}
+ if (ret == -1)
+ {
+ throw uhd::io_error(str(boost::format("send error on socket: %s") % strerror(errno)));
+ }
UHD_ASSERT_THROW(ret == ssize_t(size()));
}
_claimer.release();