[packages/uhd] - up to 4.7.0.0
baggins
baggins at pld-linux.org
Mon Dec 23 16:16:56 CET 2024
commit 07239a13bbdb3cd29cdbfc180aaaa77e62437bc7
Author: Jan Rękorajski <baggins at pld-linux.org>
Date: Mon Dec 23 16:39:20 2024 +0100
- up to 4.7.0.0
boost-1.87.patch | 931 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
uhd.spec | 16 +-
2 files changed, 940 insertions(+), 7 deletions(-)
---
diff --git a/uhd.spec b/uhd.spec
index f8450ea..4a3743c 100644
--- a/uhd.spec
+++ b/uhd.spec
@@ -7,16 +7,17 @@
Summary: Universal Hardware Driver for Ettus Research products
Summary(pl.UTF-8): Uniwersalny sterownik sprzętowy do produktów Ettus Research
Name: uhd
-Version: 4.4.0.0
-Release: 2
+Version: 4.7.0.0
+Release: 1
License: GPL v3+
Group: Applications/System
#Source0Download: https://github.com/EttusResearch/uhd/releases
Source0: https://github.com/EttusResearch/uhd/archive/v%{version}/%{name}-%{version}.tar.gz
-# Source0-md5: d91249b0114b2ac2fc36457f294ee55b
+# Source0-md5: 8bd35c962d47822e9e4fc8572e2d2845
Patch0: gcc13.patch
Patch1: %{name}-libdir.patch
Patch3: %{name}-mpm-build.patch
+Patch4: boost-1.87.patch
URL: https://www.ettus.com/sdr-software/uhd-usrp-hardware-driver/
BuildRequires: boost-devel >= 1.66
BuildRequires: cmake >= 3.8
@@ -171,9 +172,10 @@ Biblioteka USRP Module Peripheral Manager dla Pythona.
%prep
%setup -q
-%patch0 -p1
-%patch1 -p1
-%patch3 -p1
+%patch -P 0 -p1
+%patch -P 1 -p1
+%patch -P 3 -p1
+%patch -P 4 -p1
%{__sed} -i -e '1s,/usr/bin/env python$,%{__python},' host/examples/python/*.py
%{__sed} -i -e '1s,/usr/bin/env python$,%{__python},' host/utils/{converter_benchmark.py,usrp2_{card_burner,card_burner_gui,recovery}.py}
@@ -289,7 +291,7 @@ rm -rf $RPM_BUILD_ROOT
%files libs
%defattr(644,root,root,755)
-%attr(755,root,root) %{_libdir}/libuhd.so.4.4.0
+%attr(755,root,root) %{_libdir}/libuhd.so.4.7.0
%dir %{_libdir}/%{name}
%files devel
diff --git a/boost-1.87.patch b/boost-1.87.patch
new file mode 100644
index 0000000..5a97250
--- /dev/null
+++ b/boost-1.87.patch
@@ -0,0 +1,931 @@
+From adfe953d965e58b5931c1b1968899492c8087cf6 Mon Sep 17 00:00:00 2001
+From: Martin Braun <martin.braun at ettus.com>
+Date: Tue, 3 Dec 2024 12:05:50 +0100
+Subject: [PATCH] uhd: Update ASIO usage to modern style, compatible with Boost
+ 1.87
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Starting with Boost 1.66 and the corresponding ASIO version, there were
+some changes introduced based on the C++ Networking TS. This includes
+changes like replacing io_service with io_context, deprecating some
+functions, etc. Starting with Boost 1.87, the old style is no longer
+supported.
+
+This commit updates all usage of ASIO in a way that makes UHD compatible
+with future versions of ASIO. However, this makes UHD no longer
+compatible with Boost 1.65 and below.
+
+Summary of changes:
+- Replace asio::io_service with asio::io_context
+- Replace asio::io_service::strand with
+ asio::strand<asio::io_context::executor_type>
+ - This implies using asio::post() instead of asio::strand::post()
+- Replace asio::buffer_cast<T>(buf) with static_cast<T>(buf.data())
+- Update resolve(query) with new API
+- Replace references to endpoint_iterator with resolver::results_type
+- Replace ip::address::from_string() with ip::make_address()
+
+Co-authored-by: Jörg Hofrichter <joerg.hofrichter at emerson.com>
+---
+ host/examples/network_relay.cpp | 18 ++++-----
+ .../uhd/transport/nirio/rpc/rpc_client.hpp | 14 +++----
+ .../rpclib/include/rpc/detail/async_writer.h | 12 +++---
+ .../include/rpc/detail/server_session.h | 6 +--
+ host/lib/deps/rpclib/lib/rpc/client.cc | 24 +++++------
+ .../rpclib/lib/rpc/detail/server_session.cc | 23 +++++------
+ host/lib/deps/rpclib/lib/rpc/server.cc | 4 +-
+ .../uhdlib/transport/udp_boost_asio_link.hpp | 2 +-
+ .../include/uhdlib/transport/udp_common.hpp | 9 ++---
+ .../lib/include/uhdlib/utils/eeprom_utils.hpp | 12 +++---
+ host/lib/transport/dpdk_simple.cpp | 4 +-
+ host/lib/transport/if_addrs.cpp | 4 +-
+ host/lib/transport/nirio/rpc/rpc_client.cpp | 24 +++++------
+ host/lib/transport/udp_boost_asio_link.cpp | 2 +-
+ host/lib/transport/udp_simple.cpp | 19 ++++-----
+ host/lib/transport/udp_wsa_zero_copy.cpp | 8 ++--
+ host/lib/transport/udp_zero_copy.cpp | 4 +-
+ host/lib/usrp/cores/xport_adapter_ctrl.cpp | 9 ++---
+ host/lib/usrp/usrp1/mb_eeprom.cpp | 1 +
+ host/lib/usrp/usrp2/io_impl.cpp | 12 +++---
+ host/lib/usrp/usrp2/mb_eeprom.cpp | 9 ++---
+ host/lib/usrp/x300/x300_mb_eeprom.cpp | 32 ++++++++++-----
+ .../usrp_clock/octoclock/octoclock_eeprom.cpp | 6 +--
+ host/tests/eeprom_utils_test.cpp | 40 +++++++++++++++----
+ 24 files changed, 164 insertions(+), 134 deletions(-)
+
+diff --git a/host/examples/network_relay.cpp b/host/examples/network_relay.cpp
+index 9105844523..2387f3b2ab 100644
+--- a/host/examples/network_relay.cpp
++++ b/host/examples/network_relay.cpp
+@@ -78,21 +78,21 @@ class udp_relay_type
+ : _port(port)
+ {
+ {
+- asio::ip::udp::resolver resolver(_io_service);
+- asio::ip::udp::resolver::query query(asio::ip::udp::v4(), server_addr, port);
+- asio::ip::udp::endpoint endpoint = *resolver.resolve(query);
++ asio::ip::udp::resolver resolver(_io_context);
++ asio::ip::udp::endpoint endpoint =
++ *resolver.resolve(asio::ip::udp::v4(), server_addr, port).begin();
+
+ _server_socket = std::shared_ptr<asio::ip::udp::socket>(
+- new asio::ip::udp::socket(_io_service, endpoint));
++ new asio::ip::udp::socket(_io_context, endpoint));
+ resize_buffs(_server_socket, server_rx_size, server_tx_size);
+ }
+ {
+- asio::ip::udp::resolver resolver(_io_service);
+- asio::ip::udp::resolver::query query(asio::ip::udp::v4(), client_addr, port);
+- asio::ip::udp::endpoint endpoint = *resolver.resolve(query);
++ asio::ip::udp::resolver resolver(_io_context);
++ asio::ip::udp::endpoint endpoint =
++ *resolver.resolve(asio::ip::udp::v4(), client_addr, port).begin();
+
+ _client_socket = std::shared_ptr<asio::ip::udp::socket>(
+- new asio::ip::udp::socket(_io_service));
++ new asio::ip::udp::socket(_io_context));
+ _client_socket->open(asio::ip::udp::v4());
+ _client_socket->connect(endpoint);
+ resize_buffs(_client_socket, client_rx_size, client_tx_size);
+@@ -173,7 +173,7 @@ class udp_relay_type
+
+ const std::string _port;
+ boost::thread_group _thread_group;
+- asio::io_service _io_service;
++ asio::io_context _io_context;
+ asio::ip::udp::endpoint _endpoint;
+ std::mutex _endpoint_mutex;
+ socket_type _server_socket, _client_socket;
+diff --git a/host/include/uhd/transport/nirio/rpc/rpc_client.hpp b/host/include/uhd/transport/nirio/rpc/rpc_client.hpp
+index 844e36c763..98f1e2860d 100644
+--- a/host/include/uhd/transport/nirio/rpc/rpc_client.hpp
++++ b/host/include/uhd/transport/nirio/rpc/rpc_client.hpp
+@@ -56,20 +56,20 @@ class rpc_client : private uhd::noncopyable
+ const boost::system::error_code& err, size_t transferred, size_t expected);
+ void _wait_for_next_response_header();
+
+- inline void _stop_io_service()
++ inline void _stop_io_context()
+ {
+- if (_io_service_thread.get()) {
++ if (_io_context_thread.get()) {
+ UHD_LOG_DEBUG("NIRIO", "rpc_client stopping...");
+- _io_service.stop();
+- _io_service_thread->join();
+- _io_service_thread.reset();
++ _io_context.stop();
++ _io_context_thread->join();
++ _io_context_thread.reset();
+ UHD_LOG_DEBUG("NIRIO", "rpc_client stopped.");
+ }
+ }
+
+ // Services
+- boost::asio::io_service _io_service;
+- std::unique_ptr<boost::thread> _io_service_thread;
++ boost::asio::io_context _io_context;
++ std::unique_ptr<boost::thread> _io_context_thread;
+ boost::asio::ip::tcp::socket _socket;
+ // Handshake info
+ hshake_args_t _hshake_args_client;
+diff --git a/host/lib/deps/rpclib/include/rpc/detail/async_writer.h b/host/lib/deps/rpclib/include/rpc/detail/async_writer.h
+index 1e17f1292a..2b97361c86 100644
+--- a/host/lib/deps/rpclib/include/rpc/detail/async_writer.h
++++ b/host/lib/deps/rpclib/include/rpc/detail/async_writer.h
+@@ -19,9 +19,9 @@ namespace detail {
+ //! \brief Common logic for classes that have a write queue with async writing.
+ class async_writer : public std::enable_shared_from_this<async_writer> {
+ public:
+- async_writer(boost::asio::io_service *io,
++ async_writer(boost::asio::io_context* io,
+ boost::asio::ip::tcp::socket socket)
+- : socket_(std::move(socket)), write_strand_(*io), exit_(false) {}
++ : socket_(std::move(socket)), write_strand_(io->get_executor()), exit_(false) {}
+
+ void do_write() {
+ if (exit_) {
+@@ -31,9 +31,9 @@ class async_writer : public std::enable_shared_from_this<async_writer> {
+ auto &item = write_queue_.front();
+ // the data in item remains valid until the handler is called
+ // since it will still be in the queue physically until then.
+- boost::asio::async_write(
+- socket_, boost::asio::buffer(item.data(), item.size()),
+- write_strand_.wrap(
++ boost::asio::async_write(socket_,
++ boost::asio::buffer(item.data(), item.size()),
++ boost::asio::bind_executor(write_strand_,
+ [this, self](boost::system::error_code ec, std::size_t transferred) {
+ (void)transferred;
+ if (!ec) {
+@@ -69,7 +69,7 @@ class async_writer : public std::enable_shared_from_this<async_writer> {
+
+ protected:
+ boost::asio::ip::tcp::socket socket_;
+- boost::asio::io_service::strand write_strand_;
++ boost::asio::strand<boost::asio::io_context::executor_type> write_strand_;
+ std::atomic_bool exit_{false};
+ bool exited_ = false;
+ std::mutex m_exit_;
+diff --git a/host/lib/deps/rpclib/include/rpc/detail/server_session.h b/host/lib/deps/rpclib/include/rpc/detail/server_session.h
+index 754c0879cd..474e4b589b 100644
+--- a/host/lib/deps/rpclib/include/rpc/detail/server_session.h
++++ b/host/lib/deps/rpclib/include/rpc/detail/server_session.h
+@@ -22,7 +22,7 @@ namespace detail {
+
+ class server_session : public async_writer {
+ public:
+- server_session(server *srv, boost::asio::io_service *io,
++ server_session(server* srv, boost::asio::io_context* io,
+ boost::asio::ip::tcp::socket socket,
+ std::shared_ptr<dispatcher> disp, bool suppress_exceptions);
+ void start();
+@@ -34,8 +34,8 @@ class server_session : public async_writer {
+
+ private:
+ server* parent_;
+- boost::asio::io_service *io_;
+- boost::asio::io_service::strand read_strand_;
++ boost::asio::io_context* io_;
++ boost::asio::strand<boost::asio::io_context::executor_type> read_strand_;
+ std::shared_ptr<dispatcher> disp_;
+ RPCLIB_MSGPACK::unpacker pac_;
+ RPCLIB_MSGPACK::sbuffer output_buf_;
+diff --git a/host/lib/deps/rpclib/lib/rpc/client.cc b/host/lib/deps/rpclib/lib/rpc/client.cc
+index ed4a8e329f..b3d8579832 100644
+--- a/host/lib/deps/rpclib/lib/rpc/client.cc
++++ b/host/lib/deps/rpclib/lib/rpc/client.cc
+@@ -38,7 +38,7 @@ struct client::impl {
+ impl(client *parent, std::string const &addr, uint16_t port)
+ : parent_(parent),
+ io_(),
+- strand_(io_),
++ strand_(io_.get_executor()),
+ call_idx_(0),
+ addr_(addr),
+ port_(port),
+@@ -50,11 +50,11 @@ struct client::impl {
+ pac_.reserve_buffer(default_buffer_size);
+ }
+
+- void do_connect(tcp::resolver::iterator endpoint_iterator) {
++ void do_connect(const tcp::resolver::results_type& endpoints) {
+ LOG_INFO("Initiating connection.");
+ boost::asio::async_connect(
+- writer_->socket_, endpoint_iterator,
+- [this](boost::system::error_code ec, tcp::resolver::iterator) {
++ writer_->socket_, endpoints,
++ [this](boost::system::error_code ec, tcp::endpoint) {
+ std::unique_lock<std::mutex> lock(mut_connection_finished_);
+ if (!ec) {
+ LOG_INFO("Client connected to {}:{}", addr_, port_);
+@@ -101,7 +101,7 @@ struct client::impl {
+ std::get<1>(current_call)
+ .set_exception(std::current_exception());
+ }
+- strand_.post(
++ boost::asio::post(strand_,
+ [this, id]() { ongoing_calls_.erase(id); });
+ }
+
+@@ -144,8 +144,8 @@ struct client::impl {
+ std::pair<std::string, std::promise<RPCLIB_MSGPACK::object_handle>>;
+
+ client *parent_;
+- boost::asio::io_service io_;
+- boost::asio::io_service::strand strand_;
++ boost::asio::io_context io_;
++ boost::asio::strand<boost::asio::io_context::executor_type> strand_;
+ std::atomic<int> call_idx_; /// The index of the last call made
+ std::unordered_map<uint32_t, call_t> ongoing_calls_;
+ std::string addr_;
+@@ -164,9 +164,9 @@ struct client::impl {
+ client::client(std::string const &addr, uint16_t port)
+ : pimpl(new client::impl(this, addr, port)) {
+ tcp::resolver resolver(pimpl->io_);
+- auto endpoint_it =
+- resolver.resolve({pimpl->addr_, std::to_string(pimpl->port_)});
+- pimpl->do_connect(endpoint_it);
++ auto endpoints =
++ resolver.resolve(pimpl->addr_, std::to_string(pimpl->port_));
++ pimpl->do_connect(endpoints);
+ std::thread io_thread([this]() {
+ RPCLIB_CREATE_LOG_CHANNEL(client)
+ name_thread("client");
+@@ -190,7 +190,7 @@ int client::get_next_call_idx() {
+ void client::post(std::shared_ptr<RPCLIB_MSGPACK::sbuffer> buffer, int idx,
+ std::string const &func_name,
+ std::shared_ptr<rsp_promise> p) {
+- pimpl->strand_.post([=]() {
++ boost::asio::post(pimpl->strand_, [buffer, idx, func_name, p, this]() {
+ pimpl->ongoing_calls_.insert(
+ std::make_pair(idx, std::make_pair(func_name, std::move(*p))));
+ pimpl->write(std::move(*buffer));
+@@ -198,7 +198,7 @@ void client::post(std::shared_ptr<RPCLIB_MSGPACK::sbuffer> buffer, int idx,
+ }
+
+ void client::post(RPCLIB_MSGPACK::sbuffer *buffer) {
+- pimpl->strand_.post([=]() {
++ boost::asio::post(pimpl->strand_, [buffer, this]() {
+ pimpl->write(std::move(*buffer));
+ delete buffer;
+ });
+diff --git a/host/lib/deps/rpclib/lib/rpc/detail/server_session.cc b/host/lib/deps/rpclib/lib/rpc/detail/server_session.cc
+index d3e13c89fa..1468a62e5a 100644
+--- a/host/lib/deps/rpclib/lib/rpc/detail/server_session.cc
++++ b/host/lib/deps/rpclib/lib/rpc/detail/server_session.cc
+@@ -22,14 +22,14 @@ namespace detail {
+
+ static constexpr std::size_t default_buffer_size = rpc::constants::DEFAULT_BUFFER_SIZE;
+
+-server_session::server_session(server *srv, boost::asio::io_service *io,
++server_session::server_session(server *srv, boost::asio::io_context *io,
+ boost::asio::ip::tcp::socket socket,
+ std::shared_ptr<dispatcher> disp,
+ bool suppress_exceptions)
+ : async_writer(io, std::move(socket)),
+ parent_(srv),
+ io_(io),
+- read_strand_(*io),
++ read_strand_(io->get_executor()),
+ disp_(disp),
+ pac_(),
+ suppress_exceptions_(suppress_exceptions) {
+@@ -42,7 +42,7 @@ void server_session::start() { do_read(); }
+ void server_session::close() {
+ LOG_INFO("Closing session.");
+ exit_ = true;
+- write_strand_.post([this]() {
++ boost::asio::post(write_strand_, [this]() {
+ try {
+ socket_.close();
+ } catch (const boost::system::system_error&) {
+@@ -54,12 +54,11 @@ void server_session::close() {
+ void server_session::do_read() {
+ auto self(shared_from_this());
+ constexpr std::size_t max_read_bytes = default_buffer_size;
+- socket_.async_read_some(
+- boost::asio::buffer(pac_.buffer(), default_buffer_size),
++ socket_.async_read_some(boost::asio::buffer(pac_.buffer(), default_buffer_size),
+ // I don't think max_read_bytes needs to be captured explicitly
+ // (since it's constexpr), but MSVC insists.
+- read_strand_.wrap([this, self, max_read_bytes](boost::system::error_code ec,
+- std::size_t length) {
++ boost::asio::bind_executor(read_strand_, [this, self, max_read_bytes](boost::system::error_code ec,
++ std::size_t length) {
+ if (!ec) {
+ pac_.buffer_consumed(length);
+ RPCLIB_MSGPACK::unpacked result;
+@@ -69,7 +68,7 @@ void server_session::do_read() {
+
+ // any worker thread can take this call
+ auto z = std::shared_ptr<RPCLIB_MSGPACK::zone>(result.zone().release());
+- io_->post([
++ boost::asio::post(io_->get_executor(), [
+ this, msg, z
+ ]() {
+ this_handler().clear();
+@@ -102,10 +101,10 @@ void server_session::do_read() {
+ if (!resp.is_empty()) {
+ #ifdef _MSC_VER
+ // doesn't compile otherwise.
+- write_strand_.post(
++ boost::asio::post(write_strand_,
+ [=]() { write(resp.get_data()); });
+ #else
+- write_strand_.post(
++ boost::asio::post(write_strand_,
+ [this, resp, z]() { write(resp.get_data()); });
+ #endif
+ }
+@@ -114,14 +113,14 @@ void server_session::do_read() {
+ LOG_WARN("Session exit requested from a handler.");
+ // posting through the strand so this comes after
+ // the previous write
+- write_strand_.post([this]() { exit_ = true; });
++ boost::asio::post(write_strand_, [this]() { exit_ = true; });
+ }
+
+ if (this_server().stopping_) {
+ LOG_WARN("Server exit requested from a handler.");
+ // posting through the strand so this comes after
+ // the previous write
+- write_strand_.post(
++ boost::asio::post(write_strand_,
+ [this]() { parent_->close_sessions(); });
+ }
+ });
+diff --git a/host/lib/deps/rpclib/lib/rpc/server.cc b/host/lib/deps/rpclib/lib/rpc/server.cc
+index 4facb93a85..d0638cb8fc 100644
+--- a/host/lib/deps/rpclib/lib/rpc/server.cc
++++ b/host/lib/deps/rpclib/lib/rpc/server.cc
+@@ -25,7 +25,7 @@ struct server::impl {
+ : parent_(parent),
+ io_(),
+ acceptor_(io_,
+- tcp::endpoint(ip::address::from_string(address), port)),
++ tcp::endpoint(ip::make_address(address), port)),
+ socket_(io_),
+ suppress_exceptions_(false) {}
+
+@@ -66,7 +66,7 @@ struct server::impl {
+ }
+
+ server *parent_;
+- io_service io_;
++ io_context io_;
+ ip::tcp::acceptor acceptor_;
+ ip::tcp::socket socket_;
+ rpc::detail::thread_group loop_workers_;
+diff --git a/host/lib/include/uhdlib/transport/udp_boost_asio_link.hpp b/host/lib/include/uhdlib/transport/udp_boost_asio_link.hpp
+index 8944aa9991..80b585af73 100644
+--- a/host/lib/include/uhdlib/transport/udp_boost_asio_link.hpp
++++ b/host/lib/include/uhdlib/transport/udp_boost_asio_link.hpp
+@@ -146,7 +146,7 @@ class udp_boost_asio_link : public recv_link_base<udp_boost_asio_link>,
+ std::vector<udp_boost_asio_frame_buff> _recv_buffs;
+ std::vector<udp_boost_asio_frame_buff> _send_buffs;
+
+- boost::asio::io_service _io_service;
++ boost::asio::io_context _io_context;
+ std::shared_ptr<boost::asio::ip::udp::socket> _socket;
+ int _sock_fd;
+ adapter_id_t _adapter_id;
+diff --git a/host/lib/include/uhdlib/transport/udp_common.hpp b/host/lib/include/uhdlib/transport/udp_common.hpp
+index 96146a7017..b4b0ec309f 100644
+--- a/host/lib/include/uhdlib/transport/udp_common.hpp
++++ b/host/lib/include/uhdlib/transport/udp_common.hpp
+@@ -81,17 +81,16 @@ UHD_INLINE bool wait_for_recv_ready(int sock_fd, int32_t timeout_ms)
+ }
+
+ UHD_INLINE socket_sptr open_udp_socket(
+- const std::string& addr, const std::string& port, boost::asio::io_service& io_service)
++ const std::string& addr, const std::string& port, boost::asio::io_context& io_context)
+ {
+ using udp = boost::asio::ip::udp;
+
+ // resolve the address
+- udp::resolver resolver(io_service);
+- udp::resolver::query query(udp::v4(), addr, port);
+- udp::endpoint receiver_endpoint = *resolver.resolve(query);
++ udp::resolver resolver(io_context);
++ udp::endpoint receiver_endpoint = *resolver.resolve(udp::v4(), addr, port).begin();
+
+ // create, open, and connect the socket
+- socket_sptr socket = socket_sptr(new udp::socket(io_service));
++ socket_sptr socket = socket_sptr(new udp::socket(io_context));
+ socket->open(udp::v4());
+ socket->connect(receiver_endpoint);
+
+diff --git a/host/lib/include/uhdlib/utils/eeprom_utils.hpp b/host/lib/include/uhdlib/utils/eeprom_utils.hpp
+index d3be4c03c4..ea05136738 100644
+--- a/host/lib/include/uhdlib/utils/eeprom_utils.hpp
++++ b/host/lib/include/uhdlib/utils/eeprom_utils.hpp
+@@ -10,7 +10,6 @@
+ #include <uhd/types/dict.hpp>
+ #include <uhd/types/mac_addr.hpp>
+ #include <uhd/utils/log.hpp>
+-#include <boost/asio/ip/address_v4.hpp>
+ #include <string>
+ #include <vector>
+
+@@ -29,7 +28,7 @@ std::string uint16_bytes_to_string(const uhd::byte_vector_t& bytes);
+ * see if the resulting contents will contain duplicates. Useful error
+ * messages are logged describing any duplicates.
+ *
+- * <field_type> must provide to_string() and from_string() functions
++ * <field_type> must provide from_string() functions
+ *
+ * \param error_label Label to put on error messages
+ * \param new_eeprom New EEPROM contents
+@@ -38,12 +37,13 @@ std::string uint16_bytes_to_string(const uhd::byte_vector_t& bytes);
+ * \param keys Keys to examine for duplicate values
+ * \return true if duplicates are found, false if not
+ */
+-template <typename field_type>
++template <typename str_normalizer_type>
+ bool check_for_duplicates(const std::string& error_label,
+ const uhd::dict<std::string, std::string>& new_eeprom,
+ const uhd::dict<std::string, std::string>& curr_eeprom,
+ const std::string& category,
+- const std::vector<std::string>& keys)
++ const std::vector<std::string>& keys,
++ str_normalizer_type&& str_normalizer)
+ {
+ bool has_duplicates = false;
+ for (size_t i = 0; i < keys.size(); i++) {
+@@ -54,7 +54,7 @@ bool check_for_duplicates(const std::string& error_label,
+ continue;
+ }
+
+- auto value = field_type::from_string(new_eeprom[key]).to_string();
++ auto value = str_normalizer(new_eeprom[key]);
+
+ // Check other values in new_eeprom for duplicate
+ // Starting at key index i+1 so the same duplicate is not found twice
+@@ -63,7 +63,7 @@ bool check_for_duplicates(const std::string& error_label,
+ if (not new_eeprom.has_key(other_key)) {
+ continue;
+ }
+- auto other_value = field_type::from_string(new_eeprom[other_key]).to_string();
++ auto other_value = str_normalizer(new_eeprom[other_key]);
+ if (value == other_value) {
+ // Value is a duplicate of another supplied value
+ UHD_LOG_ERROR(error_label,
+diff --git a/host/lib/transport/dpdk_simple.cpp b/host/lib/transport/dpdk_simple.cpp
+index e258ddb2f8..f2787ba8c8 100644
+--- a/host/lib/transport/dpdk_simple.cpp
++++ b/host/lib/transport/dpdk_simple.cpp
+@@ -96,7 +96,7 @@ class dpdk_simple_impl : public dpdk_simple
+ // Extract buff and sanity check
+ const size_t nbytes = boost::asio::buffer_size(user_buff);
+ UHD_ASSERT_THROW(nbytes <= _link->get_send_frame_size())
+- const uint8_t* user_data = boost::asio::buffer_cast<const uint8_t*>(user_buff);
++ const uint8_t* user_data = static_cast<const uint8_t*>(user_buff.data());
+
+ // Get send buff
+ auto buff = _send_io->get_send_buff(SEND_TIMEOUT_MS);
+@@ -120,7 +120,7 @@ class dpdk_simple_impl : public dpdk_simple
+ size_t recv(const boost::asio::mutable_buffer& user_buff, double timeout) override
+ {
+ size_t user_buff_size = boost::asio::buffer_size(user_buff);
+- uint8_t* user_data = boost::asio::buffer_cast<uint8_t*>(user_buff);
++ uint8_t* user_data = static_cast<uint8_t*>(user_buff.data());
+
+ auto buff = _recv_io->get_recv_buff(static_cast<int32_t>(timeout * 1e3));
+ if (!buff) {
+diff --git a/host/lib/transport/if_addrs.cpp b/host/lib/transport/if_addrs.cpp
+index a1cb6909f0..4c43c95d57 100644
+--- a/host/lib/transport/if_addrs.cpp
++++ b/host/lib/transport/if_addrs.cpp
+@@ -50,8 +50,8 @@ std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void)
+ == boost::asio::ip::address_v4(0)) {
+ // manually calculate broadcast address
+ // https://svn.boost.org/trac/boost/ticket/5198
+- const uint32_t addr = sockaddr_to_ip_addr(iter->ifa_addr).to_ulong();
+- const uint32_t mask = sockaddr_to_ip_addr(iter->ifa_netmask).to_ulong();
++ const uint32_t addr = sockaddr_to_ip_addr(iter->ifa_addr).to_uint();
++ const uint32_t mask = sockaddr_to_ip_addr(iter->ifa_netmask).to_uint();
+ const uint32_t bcast = (addr & mask) | ~mask;
+ if_addr.bcast = boost::asio::ip::address_v4(bcast).to_string();
+ }
+diff --git a/host/lib/transport/nirio/rpc/rpc_client.cpp b/host/lib/transport/nirio/rpc/rpc_client.cpp
+index 16dd5aa823..aaa9753ee9 100644
+--- a/host/lib/transport/nirio/rpc/rpc_client.cpp
++++ b/host/lib/transport/nirio/rpc/rpc_client.cpp
+@@ -27,7 +27,7 @@ rpc_client::rpc_client(const std::string& server,
+ const std::string& port,
+ uint32_t process_id,
+ uint32_t host_id)
+- : _socket(_io_service), _hshake_args_server()
++ : _socket(_io_context), _hshake_args_server()
+ {
+ // Fill in handshake info
+ _hshake_args_client.version = CURRENT_VERSION;
+@@ -38,16 +38,14 @@ rpc_client::rpc_client(const std::string& server,
+
+ try {
+ // Synchronous resolve + connect
+- tcp::resolver resolver(_io_service);
+- // Create flags object with all special flags disabled. Especially the following:
++ tcp::resolver resolver(_io_context);
++ // All special flags disabled. Especially the following:
+ //- 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::passive);
+- tcp::resolver::query query(tcp::v4(), server, port, query_flags);
+- tcp::resolver::iterator iterator = resolver.resolve(query);
+- boost::asio::connect(_socket, iterator);
++ auto endpoints = resolver.resolve(server, port, tcp::resolver::passive);
++ boost::asio::connect(_socket, endpoints);
+
+ UHD_LOGGER_TRACE("NIRIO") << "rpc_client connected to server.";
+
+@@ -73,10 +71,10 @@ rpc_client::rpc_client(const std::string& server,
+ UHD_LOGGER_TRACE("NIRIO") << "rpc_client bound to server.";
+ _wait_for_next_response_header();
+
+- // Spawn a thread for the io_service callback handler. This thread will
++ // Spawn a thread for the io_context callback handler. This thread will
+ // run until rpc_client is destroyed.
+- _io_service_thread.reset(new boost::thread(
+- boost::bind(&boost::asio::io_service::run, &_io_service)));
++ _io_context_thread.reset(new boost::thread(
++ boost::bind(&boost::asio::io_context::run, &_io_context)));
+ } else {
+ UHD_LOGGER_DEBUG("NIRIO") << "rpc_client handshake failed.";
+ _exec_err.assign(boost::asio::error::connection_refused,
+@@ -100,7 +98,7 @@ rpc_client::rpc_client(const std::string& server,
+
+ rpc_client::~rpc_client()
+ {
+- _stop_io_service();
++ _stop_io_context();
+ }
+
+ const boost::system::error_code& rpc_client::call(func_id_t func_id,
+@@ -110,7 +108,7 @@ const boost::system::error_code& rpc_client::call(func_id_t func_id,
+ {
+ std::unique_lock<std::mutex> lock(_mutex);
+
+- if (_io_service_thread.get()) {
++ if (_io_context_thread.get()) {
+ _request.header.func_id = func_id;
+ in_args.store(_request.data);
+ _request.header.func_args_size = uhd::narrow_cast<uint32_t>(_request.data.size());
+@@ -147,7 +145,7 @@ const boost::system::error_code& rpc_client::call(func_id_t func_id,
+ UHD_LOGGER_DEBUG("NIRIO") << "rpc_client connection dropped.";
+ _exec_err.assign(boost::asio::error::connection_aborted,
+ boost::asio::error::get_system_category());
+- _stop_io_service();
++ _stop_io_context();
+ }
+
+ // Verify that we are talking to the correct endpoint
+diff --git a/host/lib/transport/udp_boost_asio_link.cpp b/host/lib/transport/udp_boost_asio_link.cpp
+index f91bad09e1..b6a6b550c1 100644
+--- a/host/lib/transport/udp_boost_asio_link.cpp
++++ b/host/lib/transport/udp_boost_asio_link.cpp
+@@ -37,7 +37,7 @@ udp_boost_asio_link::udp_boost_asio_link(
+ }
+
+ // create, open, and connect the socket
+- _socket = open_udp_socket(addr, port, _io_service);
++ _socket = open_udp_socket(addr, port, _io_context);
+ _sock_fd = _socket->native_handle();
+
+ auto info = udp_boost_asio_adapter_info(*_socket);
+diff --git a/host/lib/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp
+index c83e72d03b..2d031f2b00 100644
+--- a/host/lib/transport/udp_simple.cpp
++++ b/host/lib/transport/udp_simple.cpp
+@@ -8,7 +8,6 @@
+ #include <uhd/transport/udp_simple.hpp>
+ #include <uhd/utils/log.hpp>
+ #include <uhdlib/transport/udp_common.hpp>
+-#include <boost/format.hpp>
+
+ using namespace uhd::transport;
+ namespace asio = boost::asio;
+@@ -23,17 +22,19 @@ class udp_simple_impl : public udp_simple
+ const std::string& addr, const std::string& port, bool bcast, bool connect)
+ : _connected(connect)
+ {
+- UHD_LOGGER_TRACE("UDP")
+- << boost::format("Creating udp transport for %s %s") % addr % port;
++ UHD_LOG_TRACE("UDP", "Creating udp transport for " << addr << " " << port);
+
+ // resolve the address
+- asio::ip::udp::resolver resolver(_io_service);
+- asio::ip::udp::resolver::query query(
+- asio::ip::udp::v4(), addr, port, asio::ip::resolver_query_base::all_matching);
+- _send_endpoint = *resolver.resolve(query);
++ asio::ip::udp::resolver resolver(_io_context);
++ _send_endpoint = *resolver
++ .resolve(asio::ip::udp::v4(),
++ addr,
++ port,
++ asio::ip::resolver_query_base::all_matching)
++ .begin();
+
+ // create and open the socket
+- _socket = socket_sptr(new asio::ip::udp::socket(_io_service));
++ _socket = socket_sptr(new asio::ip::udp::socket(_io_context));
+ _socket->open(asio::ip::udp::v4());
+
+ // allow broadcasting
+@@ -72,7 +73,7 @@ class udp_simple_impl : public udp_simple
+
+ private:
+ bool _connected;
+- asio::io_service _io_service;
++ asio::io_context _io_context;
+ socket_sptr _socket;
+ asio::ip::udp::endpoint _send_endpoint;
+ asio::ip::udp::endpoint _recv_endpoint;
+diff --git a/host/lib/transport/udp_wsa_zero_copy.cpp b/host/lib/transport/udp_wsa_zero_copy.cpp
+index 55773296fe..f189396361 100644
+--- a/host/lib/transport/udp_wsa_zero_copy.cpp
++++ b/host/lib/transport/udp_wsa_zero_copy.cpp
+@@ -216,10 +216,10 @@ class udp_zero_copy_wsa_impl : public udp_zero_copy
+ UHD_ASSERT_THROW(_num_send_frames <= WSA_MAXIMUM_WAIT_EVENTS);
+
+ // resolve the address
+- asio::io_service io_service;
+- asio::ip::udp::resolver resolver(io_service);
+- asio::ip::udp::resolver::query query(asio::ip::udp::v4(), addr, port);
+- asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query);
++ asio::io_context io_context;
++ asio::ip::udp::resolver resolver(io_context);
++ asio::ip::udp::endpoint receiver_endpoint =
++ *resolver.resolve(asio::ip::udp::v4(), addr, port).begin();
+
+ // create the socket
+ _sock_fd =
+diff --git a/host/lib/transport/udp_zero_copy.cpp b/host/lib/transport/udp_zero_copy.cpp
+index be527be5cb..1a43f9d6be 100644
+--- a/host/lib/transport/udp_zero_copy.cpp
++++ b/host/lib/transport/udp_zero_copy.cpp
+@@ -161,7 +161,7 @@ class udp_zero_copy_asio_impl : public udp_zero_copy
+ check_registry_for_fast_send_threshold(this->get_send_frame_size());
+ #endif /*CHECK_REG_SEND_THRESH*/
+
+- _socket = open_udp_socket(addr, port, _io_service);
++ _socket = open_udp_socket(addr, port, _io_context);
+ _sock_fd = _socket->native_handle();
+
+ UHD_LOGGER_TRACE("UDP") << boost::format("Local UDP socket endpoint: %s:%s")
+@@ -252,7 +252,7 @@ class udp_zero_copy_asio_impl : public udp_zero_copy
+ size_t _next_recv_buff_index, _next_send_buff_index;
+
+ // asio guts -> socket and service
+- asio::io_service _io_service;
++ asio::io_context _io_context;
+ socket_sptr _socket;
+ int _sock_fd;
+ };
+diff --git a/host/lib/usrp/cores/xport_adapter_ctrl.cpp b/host/lib/usrp/cores/xport_adapter_ctrl.cpp
+index 224f51ba22..9b3556ad3a 100644
+--- a/host/lib/usrp/cores/xport_adapter_ctrl.cpp
++++ b/host/lib/usrp/cores/xport_adapter_ctrl.cpp
+@@ -28,13 +28,12 @@ std::pair<uint32_t, uint32_t> cast_ipv4_and_port(
+ const std::string& ipv4, const std::string& port)
+ {
+ using namespace boost::asio;
+- io_service io_service;
+- ip::udp::resolver resolver(io_service);
++ io_context io_context;
++ ip::udp::resolver resolver(io_context);
+ try {
+- ip::udp::resolver::query query(ip::udp::v4(), ipv4, port);
+- ip::udp::endpoint endpoint = *resolver.resolve(query);
++ ip::udp::endpoint endpoint = *(resolver.resolve(ipv4, port).begin());
+ return {
+- uint32_t(endpoint.address().to_v4().to_ulong()), uint32_t(endpoint.port())};
++ uint32_t(endpoint.address().to_v4().to_uint()), uint32_t(endpoint.port())};
+ } catch (const std::exception&) {
+ throw uhd::value_error("Invalid UDP address: " + ipv4 + ":" + port);
+ }
+diff --git a/host/lib/usrp/usrp1/mb_eeprom.cpp b/host/lib/usrp/usrp1/mb_eeprom.cpp
+index 756a103953..e5648dd34d 100644
+--- a/host/lib/usrp/usrp1/mb_eeprom.cpp
++++ b/host/lib/usrp/usrp1/mb_eeprom.cpp
+@@ -8,6 +8,7 @@
+ #include <uhd/types/byte_vector.hpp>
+ #include <uhd/usrp/mboard_eeprom.hpp>
+ #include <uhdlib/utils/eeprom_utils.hpp>
++#include <boost/asio.hpp>
+
+ namespace {
+ const uint8_t USRP1_EEPROM_ADDR = 0x50;
+diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
+index c58787e3e5..48ab7b5f0e 100644
+--- a/host/lib/usrp/usrp2/io_impl.cpp
++++ b/host/lib/usrp/usrp2/io_impl.cpp
+@@ -415,12 +415,12 @@ void usrp2_impl::program_stream_dest(
+ "IPv4 Address: %s, UDP Port: %s")
+ % args.args["addr"] % args.args["port"];
+
+- asio::io_service io_service;
+- asio::ip::udp::resolver resolver(io_service);
+- asio::ip::udp::resolver::query query(
+- asio::ip::udp::v4(), args.args["addr"], args.args["port"]);
+- asio::ip::udp::endpoint endpoint = *resolver.resolve(query);
+- stream_ctrl.ip_addr = uhd::htonx(uint32_t(endpoint.address().to_v4().to_ulong()));
++ asio::io_context io_context;
++ asio::ip::udp::resolver resolver(io_context);
++ asio::ip::udp::endpoint endpoint =
++ *resolver.resolve(asio::ip::udp::v4(), args.args["addr"], args.args["port"])
++ .begin();
++ stream_ctrl.ip_addr = uhd::htonx(uint32_t(endpoint.address().to_v4().to_uint()));
+ stream_ctrl.udp_port = uhd::htonx(uint32_t(endpoint.port()));
+
+ for (size_t i = 0; i < 3; i++) {
+diff --git a/host/lib/usrp/usrp2/mb_eeprom.cpp b/host/lib/usrp/usrp2/mb_eeprom.cpp
+index 7bfe6159d0..2b01c0bf40 100644
+--- a/host/lib/usrp/usrp2/mb_eeprom.cpp
++++ b/host/lib/usrp/usrp2/mb_eeprom.cpp
+@@ -141,8 +141,7 @@ void usrp2_impl::set_mb_eeprom(const std::string& mb, const mboard_eeprom_t& mb_
+
+ if (mb_eeprom.has_key("ip-addr")) {
+ byte_vector_t ip_addr_bytes(4);
+- byte_copy(
+- boost::asio::ip::address_v4::from_string(mb_eeprom["ip-addr"]).to_bytes(),
++ byte_copy(boost::asio::ip::make_address_v4(mb_eeprom["ip-addr"]).to_bytes(),
+ ip_addr_bytes);
+ iface->write_eeprom(
+ N200_EEPROM_ADDR, offsetof(n200_eeprom_map, ip_addr), ip_addr_bytes);
+@@ -150,8 +149,7 @@ void usrp2_impl::set_mb_eeprom(const std::string& mb, const mboard_eeprom_t& mb_
+
+ if (mb_eeprom.has_key("subnet")) {
+ byte_vector_t ip_addr_bytes(4);
+- byte_copy(
+- boost::asio::ip::address_v4::from_string(mb_eeprom["subnet"]).to_bytes(),
++ byte_copy(boost::asio::ip::make_address_v4(mb_eeprom["subnet"]).to_bytes(),
+ ip_addr_bytes);
+ iface->write_eeprom(
+ N200_EEPROM_ADDR, offsetof(n200_eeprom_map, subnet), ip_addr_bytes);
+@@ -159,8 +157,7 @@ void usrp2_impl::set_mb_eeprom(const std::string& mb, const mboard_eeprom_t& mb_
+
+ if (mb_eeprom.has_key("gateway")) {
+ byte_vector_t ip_addr_bytes(4);
+- byte_copy(
+- boost::asio::ip::address_v4::from_string(mb_eeprom["gateway"]).to_bytes(),
++ byte_copy(boost::asio::ip::make_address_v4(mb_eeprom["gateway"]).to_bytes(),
+ ip_addr_bytes);
+ iface->write_eeprom(
+ N200_EEPROM_ADDR, offsetof(n200_eeprom_map, gateway), ip_addr_bytes);
+diff --git a/host/lib/usrp/x300/x300_mb_eeprom.cpp b/host/lib/usrp/x300/x300_mb_eeprom.cpp
+index e0e6072aa1..273ad2b1ed 100644
+--- a/host/lib/usrp/x300/x300_mb_eeprom.cpp
++++ b/host/lib/usrp/x300/x300_mb_eeprom.cpp
+@@ -9,6 +9,7 @@
+ #include <uhd/types/serial.hpp>
+ #include <uhd/usrp/mboard_eeprom.hpp>
+ #include <uhdlib/utils/eeprom_utils.hpp>
++#include <boost/asio.hpp>
+
+ namespace {
+ const uint8_t X300_EEPROM_ADDR = 0x50;
+@@ -122,10 +123,22 @@ void uhd::usrp::x300::set_mb_eeprom(
+ "ip-addr0", "ip-addr1", "ip-addr2", "ip-addr3"};
+
+ // make sure there are no duplicate values
+- if (check_for_duplicates<uhd::mac_addr_t>(
+- "X300", mb_eeprom, curr_eeprom, "MAC address", mac_keys)
+- or check_for_duplicates<boost::asio::ip::address_v4>(
+- "X300", mb_eeprom, curr_eeprom, "IP address", ip_keys)) {
++ if (check_for_duplicates("X300",
++ mb_eeprom,
++ curr_eeprom,
++ "MAC address",
++ mac_keys,
++ [](const std::string& str) {
++ return mac_addr_t::from_string(str).to_string();
++ })
++ or check_for_duplicates("X300",
++ mb_eeprom,
++ curr_eeprom,
++ "IP address",
++ ip_keys,
++ [](const std::string& str) {
++ return boost::asio::ip::make_address(str).to_string();
++ })) {
+ throw uhd::value_error(
+ "Duplicate values not permitted - write to EEPROM aborted");
+ }
+@@ -161,8 +174,7 @@ void uhd::usrp::x300::set_mb_eeprom(
+ // store the ip addresses
+ byte_vector_t ip_addr_bytes(4);
+ if (mb_eeprom.has_key("gateway")) {
+- byte_copy(
+- boost::asio::ip::address_v4::from_string(mb_eeprom["gateway"]).to_bytes(),
++ byte_copy(boost::asio::ip::make_address_v4(mb_eeprom["gateway"]).to_bytes(),
+ ip_addr_bytes);
+ iface->write_eeprom(
+ X300_EEPROM_ADDR, offsetof(x300_eeprom_map, gateway), ip_addr_bytes);
+@@ -170,8 +182,8 @@ void uhd::usrp::x300::set_mb_eeprom(
+ for (size_t i = 0; i < 4; i++) {
+ const std::string n(1, char(i) + '0');
+ if (mb_eeprom.has_key("ip-addr" + n)) {
+- byte_copy(boost::asio::ip::address_v4::from_string(mb_eeprom["ip-addr" + n])
+- .to_bytes(),
++ byte_copy(
++ boost::asio::ip::make_address_v4(mb_eeprom["ip-addr" + n]).to_bytes(),
+ ip_addr_bytes);
+ iface->write_eeprom(X300_EEPROM_ADDR,
+ offsetof(x300_eeprom_map, ip_addr) + (i * 4),
+@@ -179,8 +191,8 @@ void uhd::usrp::x300::set_mb_eeprom(
+ }
+
+ if (mb_eeprom.has_key("subnet" + n)) {
+- byte_copy(boost::asio::ip::address_v4::from_string(mb_eeprom["subnet" + n])
+- .to_bytes(),
++ byte_copy(
++ boost::asio::ip::make_address_v4(mb_eeprom["subnet" + n]).to_bytes(),
+ ip_addr_bytes);
+ iface->write_eeprom(X300_EEPROM_ADDR,
+ offsetof(x300_eeprom_map, subnet) + (i * 4),
+diff --git a/host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp b/host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp
+index 9023c6607a..adddb23f3e 100644
+--- a/host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp
++++ b/host/lib/usrp_clock/octoclock/octoclock_eeprom.cpp
+@@ -99,7 +99,7 @@ void octoclock_eeprom_t::_store() const
+ // IP address
+ if ((*this).has_key("ip-addr")) {
+ ip_v4::bytes_type ip_addr_bytes =
+- ip_v4::from_string((*this)["ip-addr"]).to_bytes();
++ boost::asio::ip::make_address_v4((*this)["ip-addr"]).to_bytes();
+ memcpy(&eeprom_out->ip_addr, &ip_addr_bytes, 4);
+ eeprom_out->ip_addr = uhd::htonx<uint32_t>(eeprom_out->ip_addr);
+ }
+@@ -107,7 +107,7 @@ void octoclock_eeprom_t::_store() const
+ // Default router
+ if ((*this).has_key("gateway")) {
+ ip_v4::bytes_type dr_addr_bytes =
+- ip_v4::from_string((*this)["gateway"]).to_bytes();
++ boost::asio::ip::make_address_v4((*this)["gateway"]).to_bytes();
+ memcpy(&eeprom_out->dr_addr, &dr_addr_bytes, 4);
+ eeprom_out->dr_addr = uhd::htonx<uint32_t>(eeprom_out->dr_addr);
+ }
+@@ -115,7 +115,7 @@ void octoclock_eeprom_t::_store() const
+ // Netmask
+ if ((*this).has_key("netmask")) {
+ ip_v4::bytes_type netmask_bytes =
+- ip_v4::from_string((*this)["netmask"]).to_bytes();
++ boost::asio::ip::make_address_v4((*this)["netmask"]).to_bytes();
+ memcpy(&eeprom_out->netmask, &netmask_bytes, 4);
+ eeprom_out->netmask = uhd::htonx<uint32_t>(eeprom_out->netmask);
+ }
+diff --git a/host/tests/eeprom_utils_test.cpp b/host/tests/eeprom_utils_test.cpp
+index 728b4b8b67..57d107a177 100644
+--- a/host/tests/eeprom_utils_test.cpp
++++ b/host/tests/eeprom_utils_test.cpp
+@@ -44,13 +44,37 @@ BOOST_AUTO_TEST_CASE(test_eeprom_duplicate_check)
+ map_list_of("0", "b")("1", "B");
+ const std::vector<std::string> keys = {"0", "1", "2"};
+
+- BOOST_CHECK_EQUAL(check_for_duplicates<upper_case_char>(
+- "TEST", new_eeprom_no_dups, curr_eeprom, "Test Value", keys),
++ BOOST_CHECK_EQUAL(check_for_duplicates("TEST",
++ new_eeprom_no_dups,
++ curr_eeprom,
++ "Test Value",
++ keys,
++ [](const std::string& str) {
++ return upper_case_char::from_string(str).to_string();
++ }),
+ false);
+- BOOST_CHECK(check_for_duplicates<upper_case_char>(
+- "TEST", new_eeprom_dups_in_curr, curr_eeprom, "Test Value", keys));
+- BOOST_CHECK(check_for_duplicates<upper_case_char>(
+- "TEST", new_eeprom_dups_in_new, curr_eeprom, "Test Value", keys));
+- BOOST_CHECK(check_for_duplicates<upper_case_char>(
+- "TEST", new_eeprom_dups_in_both, curr_eeprom, "Test Value", keys));
++ BOOST_CHECK(check_for_duplicates("TEST",
++ new_eeprom_dups_in_curr,
++ curr_eeprom,
++ "Test Value",
++ keys,
++ [](const std::string& str) {
++ return upper_case_char::from_string(str).to_string();
++ }));
++ BOOST_CHECK(check_for_duplicates("TEST",
++ new_eeprom_dups_in_new,
++ curr_eeprom,
++ "Test Value",
++ keys,
++ [](const std::string& str) {
++ return upper_case_char::from_string(str).to_string();
++ }));
++ BOOST_CHECK(check_for_duplicates("TEST",
++ new_eeprom_dups_in_both,
++ curr_eeprom,
++ "Test Value",
++ keys,
++ [](const std::string& str) {
++ return upper_case_char::from_string(str).to_string();
++ }));
+ }
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/uhd.git/commitdiff/07239a13bbdb3cd29cdbfc180aaaa77e62437bc7
More information about the pld-cvs-commit
mailing list