mpm: Add rpc_version key in device find routine

This adds a new key to the discovery information coming from MPM
devices (rpc_version). The purpose of this is to smooth a transition to
alternative RPC subsystems other than mprpc.

If a device reports a different RPC version than supported by UHD, it
can still be found, but cannot be used for UHD sessions.
This commit is contained in:
Martin Braun 2026-03-26 22:14:10 +01:00
parent a95c20357f
commit 2d430f98c3
4 changed files with 38 additions and 3 deletions

View File

@ -17,7 +17,9 @@
#include <uhdlib/utils/prefs.hpp>
#include <uhdlib/utils/serial_number.hpp>
#include <boost/algorithm/string.hpp>
#include <algorithm>
#include <future>
#include <iterator>
#ifdef HAVE_DPDK
# include <uhdlib/transport/dpdk/common.hpp>
#endif
@ -113,6 +115,7 @@ device_addrs_t mpmd_find_with_addr(
new_addr[value[0]] = value[1];
}
}
new_addr[RPC_VERSION_KEY] = new_addr.get(RPC_VERSION_KEY, DEFAULT_RPC_VERSION);
addrs.push_back(new_addr);
}
return addrs;
@ -258,8 +261,15 @@ device_addrs_t mpmd_find(const device_addr_t& hint_)
if (check_reachability) {
std::vector<std::future<boost::optional<device_addr_t>>> reachability_tasks;
for (const auto& mpm_dev : bcast_mpm_devs) {
reachability_tasks.emplace_back(std::async(std::launch::async,
[mpm_dev]() { return mpmd_mboard_impl::is_device_reachable(mpm_dev); }));
if (mpm_dev.get(RPC_VERSION_KEY, DEFAULT_RPC_VERSION) == RPC_VERSION) {
reachability_tasks.emplace_back(
std::async(std::launch::async, [mpm_dev]() {
return mpmd_mboard_impl::is_device_reachable(mpm_dev);
}));
} else {
reachability_tasks.emplace_back(std::async(std::launch::async,
[]() { return boost::optional<device_addr_t>{}; }));
}
}
// Variable i is used to index reachability_tasks as well as bcast_mpm_devs (both
// of same size by construction), therefore using iterators here is less elegant.
@ -272,8 +282,15 @@ device_addrs_t mpmd_find(const device_addr_t& hint_)
flag_dev_as_unreachable(bcast_mpm_devs[i]));
}
}
} else {
} else if (find_all) {
filtered_mpm_devs = bcast_mpm_devs;
} else {
std::copy_if(bcast_mpm_devs.cbegin(),
bcast_mpm_devs.cend(),
std::back_inserter(filtered_mpm_devs),
[](const device_addr_t& dev) {
return dev.get(RPC_VERSION_KEY, DEFAULT_RPC_VERSION) == RPC_VERSION;
});
}
if (filtered_mpm_devs.empty() and not bcast_mpm_devs.empty()) {

View File

@ -149,6 +149,15 @@ const std::string mpmd_impl::MPM_ECHO_CMD = "MPM-ECHO";
mpmd_impl::mpmd_impl(const device_addr_t& device_args)
: rfnoc_device(), _device_args(device_args)
{
UHD_ASSERT_THROW(device_args.has_key(RPC_VERSION_KEY));
if (device_args.get(RPC_VERSION_KEY, DEFAULT_RPC_VERSION) != RPC_VERSION) {
UHD_LOG_THROW(uhd::runtime_error,
"MPMD",
"RPC version mismatch. Expected: "
<< RPC_VERSION
<< " Actual: " << device_args.get(RPC_VERSION_KEY, DEFAULT_RPC_VERSION)
<< ". Please update the version of MPM on your USRP device.");
}
const device_addrs_t mb_args_without_prefs = separate_device_addr(device_args);
device_addrs_t mb_args;
for (size_t i = 0; i < mb_args_without_prefs.size(); ++i) {

View File

@ -38,6 +38,12 @@ static constexpr size_t MPMD_SHORT_RPC_TIMEOUT = 2000;
static constexpr size_t MPMD_CLAIMER_RPC_TIMEOUT = 10000;
//! Ethernet address for management and RPC communication
static const std::string MGMT_ADDR_KEY = "mgmt_addr";
//! RPC version
static const std::string RPC_VERSION_KEY = "rpc_version";
static const std::string RPC_VERSION = "1";
// Older devices did not provide an RPC version, but they were all using
// mprpc, aka version 1.
static const std::string DEFAULT_RPC_VERSION = "1";
namespace uhd { namespace mpmd {

View File

@ -15,6 +15,8 @@ from usrp_mpm.mpmutils import set_proc_title, to_binary_str
RESPONSE_PREAMBLE = b"USRP-MPM"
RESPONSE_SEP = b";"
RESPONSE_CLAIMED_KEY = b"claimed"
# 1: mprpc
RPC_VERSION = b"1"
# A buffer size large enough to capture any UDP packet we receive on the
# discovery socket
MAX_SOCK_BUFSIZ = 9000
@ -57,6 +59,7 @@ def _discovery_process(state, discovery_addr):
+ [b"serial=" + state.dev_serial.value]
+ [b"name=" + state.dev_name.value]
+ [b"fpga=" + state.dev_fpga_type.value]
+ [b"rpc_version=" + RPC_VERSION]
+ [RESPONSE_CLAIMED_KEY + to_binary_str("={}".format(state.claim_status.value))]
)