aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/transport
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/transport')
-rw-r--r--host/lib/transport/CMakeLists.txt1
-rw-r--r--host/lib/transport/chdr.cpp182
-rw-r--r--host/lib/transport/libusb1_base.cpp20
-rw-r--r--host/lib/transport/nirio/rpc/rpc_client.cpp2
-rw-r--r--host/lib/transport/super_recv_packet_handler.hpp2
5 files changed, 198 insertions, 9 deletions
diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt
index 5920f3d78..9ec8a5c0b 100644
--- a/host/lib/transport/CMakeLists.txt
+++ b/host/lib/transport/CMakeLists.txt
@@ -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/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp
index ae33cc036..0baf8dc76 100644
--- a/host/lib/transport/libusb1_base.cpp
+++ b/host/lib/transport/libusb1_base.cpp
@@ -345,15 +345,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/nirio/rpc/rpc_client.cpp b/host/lib/transport/nirio/rpc/rpc_client.cpp
index cf8e9c1a9..48f47cfae 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..c3c2b8e97 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;
}