diff options
Diffstat (limited to 'host/lib/transport/udp_boost_asio_link.cpp')
-rw-r--r-- | host/lib/transport/udp_boost_asio_link.cpp | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/host/lib/transport/udp_boost_asio_link.cpp b/host/lib/transport/udp_boost_asio_link.cpp new file mode 100644 index 000000000..95d68ba91 --- /dev/null +++ b/host/lib/transport/udp_boost_asio_link.cpp @@ -0,0 +1,126 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include <uhd/utils/log.hpp> +#include <uhdlib/transport/udp_boost_asio_link.hpp> +#include <boost/format.hpp> + +using namespace uhd::transport; + +namespace asio = boost::asio; + +udp_boost_asio_link::udp_boost_asio_link( + const std::string& addr, const std::string& port, const link_params_t& params) + : recv_link_base_t(params.num_recv_frames, params.recv_frame_size) + , send_link_base_t(params.num_send_frames, params.send_frame_size) + , _recv_memory_pool(buffer_pool::make(params.num_recv_frames, params.recv_frame_size)) + , _send_memory_pool(buffer_pool::make(params.num_send_frames, params.send_frame_size)) +{ + for (size_t i = 0; i < params.num_recv_frames; i++) { + _recv_buffs.push_back(udp_boost_asio_frame_buff(_recv_memory_pool->at(i))); + } + + for (size_t i = 0; i < params.num_send_frames; i++) { + _send_buffs.push_back(udp_boost_asio_frame_buff(_send_memory_pool->at(i))); + } + + for (auto& buff : _recv_buffs) { + recv_link_base_t::preload_free_buff(&buff); + } + + for (auto& buff : _send_buffs) { + send_link_base_t::preload_free_buff(&buff); + } + + // create, open, and connect the socket + _socket = open_udp_socket(addr, port, _io_service); + _sock_fd = _socket->native_handle(); + + UHD_LOGGER_TRACE("UDP") + << boost::format("Created UDP link to %s:%s") % addr % port; + UHD_LOGGER_TRACE("UDP") << boost::format("Local UDP socket endpoint: %s:%s") + % get_local_addr() % get_local_port(); +} + +uint16_t udp_boost_asio_link::get_local_port() const +{ + return _socket->local_endpoint().port(); +} + +std::string udp_boost_asio_link::get_local_addr() const +{ + return _socket->local_endpoint().address().to_string(); +} + +size_t udp_boost_asio_link::resize_recv_socket_buffer(size_t num_bytes) +{ + return resize_udp_socket_buffer<asio::socket_base::receive_buffer_size>( + _socket, num_bytes); +} + +size_t udp_boost_asio_link::resize_send_socket_buffer(size_t num_bytes) +{ + return resize_udp_socket_buffer<asio::socket_base::send_buffer_size>( + _socket, num_bytes); +} + +udp_boost_asio_link::sptr udp_boost_asio_link::make(const std::string& addr, + const std::string& port, + const link_params_t& params, + size_t& recv_socket_buff_size, + size_t& send_socket_buff_size) +{ + UHD_ASSERT_THROW(params.num_recv_frames != 0); + UHD_ASSERT_THROW(params.num_send_frames != 0); + UHD_ASSERT_THROW(params.recv_frame_size != 0); + UHD_ASSERT_THROW(params.send_frame_size != 0); + UHD_ASSERT_THROW(params.recv_buff_size != 0); + UHD_ASSERT_THROW(params.send_buff_size != 0); + +#if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) + // limit buffer size on macos to avoid the warning issued by + // resize_buff_helper + if (params.recv_buff_size > MAX_BUFF_SIZE_ETH_MACOS) { + params.recv_buff_size = MAX_BUFF_SIZE_ETH_MACOS; + } + if (params.send_buff_size > MAX_BUFF_SIZE_ETH_MACOS) { + params.send_buff_size = MAX_BUFF_SIZE_ETH_MACOS; + } +#endif + + udp_boost_asio_link::sptr link( + new udp_boost_asio_link(addr, port, params)); + + // call the helper to resize send and recv buffers + + recv_socket_buff_size = resize_udp_socket_buffer_with_warning( + [link](size_t size) { return link->resize_recv_socket_buffer(size); }, + params.recv_buff_size, + "recv"); + send_socket_buff_size = resize_udp_socket_buffer_with_warning( + [link](size_t size) { return link->resize_send_socket_buffer(size); }, + params.send_buff_size, + "send"); + + if (recv_socket_buff_size < params.num_recv_frames * MAX_ETHERNET_MTU) { + UHD_LOG_WARNING("UDP", + "The current recv_buff_size of " + << params.recv_buff_size + << " is less than the minimum recommended size of " + << params.num_recv_frames * MAX_ETHERNET_MTU + << " and may result in dropped packets on some NICs"); + } + if (send_socket_buff_size < params.num_send_frames * MAX_ETHERNET_MTU) { + UHD_LOG_WARNING("UDP", + "The current send_buff_size of " + << params.send_buff_size + << " is less than the minimum recommended size of " + << params.num_send_frames * MAX_ETHERNET_MTU + << " and may result in dropped packets on some NICs"); + } + + return link; +} |