aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/rfnoc
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2019-08-01 14:49:12 -0700
committerMartin Braun <martin.braun@ettus.com>2019-11-26 11:49:34 -0800
commitb89c53c0691c6d70fb24561243a930bbcc32363b (patch)
treef98c821b5a86daff0addd79eaf9bc6c812f38946 /host/lib/rfnoc
parent595fba47d534634432d4e114d31bbfa42cc00812 (diff)
downloaduhd-b89c53c0691c6d70fb24561243a930bbcc32363b.tar.gz
uhd-b89c53c0691c6d70fb24561243a930bbcc32363b.tar.bz2
uhd-b89c53c0691c6d70fb24561243a930bbcc32363b.zip
rfnoc: ctrlport: Separately validate and handle async messages
This introduces the concept of an async message validator, an optional callback for functions to check if an async message has a valid payload. After validation, the async message is ack'd. Then, the async message handler is executed. This makes sure that an async message is ack'd as soon as possible, rather than after the async message handling, which can itself have all sorts of communication going on to the device.
Diffstat (limited to 'host/lib/rfnoc')
-rw-r--r--host/lib/rfnoc/ctrlport_endpoint.cpp33
-rw-r--r--host/lib/rfnoc/register_iface_holder.cpp5
2 files changed, 33 insertions, 5 deletions
diff --git a/host/lib/rfnoc/ctrlport_endpoint.cpp b/host/lib/rfnoc/ctrlport_endpoint.cpp
index 5c0deca1d..3374a707b 100644
--- a/host/lib/rfnoc/ctrlport_endpoint.cpp
+++ b/host/lib/rfnoc/ctrlport_endpoint.cpp
@@ -191,6 +191,12 @@ public:
}
}
+ virtual void register_async_msg_validator(async_msg_validator_t callback_f)
+ {
+ std::unique_lock<std::mutex> lock(_mutex);
+ _validate_async_msg = callback_f;
+ }
+
virtual void register_async_msg_handler(async_msg_callback_t callback_f)
{
std::unique_lock<std::mutex> lock(_mutex);
@@ -274,12 +280,12 @@ public:
UHD_LOG_ERROR(
"CTRLEP", "Malformed async message request: Invalid num_data");
} else {
- try {
- _handle_async_msg(
- rx_ctrl.address, rx_ctrl.data_vtr, rx_ctrl.timestamp);
+ if (!_validate_async_msg(rx_ctrl.address, rx_ctrl.data_vtr)) {
+ UHD_LOG_ERROR("CTRLEP",
+ "Malformed async message request: Async message was not "
+ "validated by block controller!");
+ } else {
status = CMD_OKAY;
- } catch (...) {
- UHD_LOG_ERROR("CTRLEP", "Async message handler threw an exception");
}
}
try {
@@ -298,6 +304,19 @@ public:
} catch (...) {
UHD_LOG_ERROR("CTRLEP",
"Encountered an error sending a response for an async message");
+ return;
+ }
+ if (status == CMD_OKAY) {
+ try {
+ _handle_async_msg(
+ rx_ctrl.address, rx_ctrl.data_vtr, rx_ctrl.timestamp);
+ } catch (const std::exception& ex) {
+ UHD_LOG_ERROR("CTRLEP",
+ "Caught exception during async message handling: " << ex.what());
+ } catch (...) {
+ UHD_LOG_ERROR("CTRLEP",
+ "Caught unknown exception during async message handling!");
+ }
}
}
}
@@ -463,6 +482,10 @@ private:
//! The clock that drives the timing logic for the ctrlport endpoint
const clock_iface& _timebase_clk;
+ //! The function to call to validate an async message (by default, all async
+ // messages are considered valid)
+ async_msg_validator_t _validate_async_msg =
+ [](uint32_t, const std::vector<uint32_t>&) { return true; };
//! The function to call to handle an async message
async_msg_callback_t _handle_async_msg = async_msg_callback_t();
//! The current control sequence number of outgoing packets
diff --git a/host/lib/rfnoc/register_iface_holder.cpp b/host/lib/rfnoc/register_iface_holder.cpp
index ea5bf0149..d3a0e82e5 100644
--- a/host/lib/rfnoc/register_iface_holder.cpp
+++ b/host/lib/rfnoc/register_iface_holder.cpp
@@ -64,6 +64,11 @@ public:
UHD_LOG_ERROR("REGS", "Attempting to use invalidated register interface!");
}
+ void register_async_msg_validator(async_msg_validator_t)
+ {
+ UHD_LOG_ERROR("REGS", "Attempting to use invalidated register interface!");
+ }
+
void set_policy(const std::string&, const uhd::device_addr_t&)
{
UHD_LOG_ERROR("REGS", "Attempting to use invalidated register interface!");