aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/rfnoc
diff options
context:
space:
mode:
authorSamuel O'Brien <sam.obrien@ni.com>2020-06-23 15:09:55 -0500
committerAaron Rossetto <aaron.rossetto@ni.com>2020-07-13 15:21:52 -0500
commit297d5855ca3ac2e3fea329bd938cf4763fac583b (patch)
treee302783f5efcadbd451d8d24463baece7d85a47c /host/lib/rfnoc
parent22837edfe20feb57c24f2a55edbb65757b3fab6a (diff)
downloaduhd-297d5855ca3ac2e3fea329bd938cf4763fac583b.tar.gz
uhd-297d5855ca3ac2e3fea329bd938cf4763fac583b.tar.bz2
uhd-297d5855ca3ac2e3fea329bd938cf4763fac583b.zip
utils: Expose CHDR Parsing API
This commit introduces a new public api in uhd::utils which allows serializing and deserializing chdr packets. As far as testing, this commit adds the chdr_parse_test test. It uses a wireshark trace located in rfnoc_packets_*.cpp as well as hand coded packets from hardcoded_packets.cpp to test the serialization and deserialization process Signed-off-by: Samuel O'Brien <sam.obrien@ni.com>
Diffstat (limited to 'host/lib/rfnoc')
-rw-r--r--host/lib/rfnoc/chdr_types.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/host/lib/rfnoc/chdr_types.cpp b/host/lib/rfnoc/chdr_types.cpp
index 3cb68ff9a..3978c8694 100644
--- a/host/lib/rfnoc/chdr_types.cpp
+++ b/host/lib/rfnoc/chdr_types.cpp
@@ -9,6 +9,7 @@
#include <uhd/types/endianness.hpp>
#include <boost/format.hpp>
#include <cassert>
+#include <sstream>
using namespace uhd;
using namespace uhd::rfnoc::chdr;
@@ -141,6 +142,17 @@ void ctrl_payload::deserialize(const uint64_t* buff,
UHD_ASSERT_THROW(ptr <= max_size_bytes);
}
+size_t ctrl_payload::get_length() const
+{
+ size_t length = 1;
+ if (this->has_timestamp()) {
+ length += 1;
+ }
+ size_t operations = 1 + this->data_vtr.size();
+ length += operations / 2 + operations % 2;
+ return length;
+}
+
bool ctrl_payload::operator==(const ctrl_payload& rhs) const
{
return (dst_port == rhs.dst_port) && (src_port == rhs.src_port)
@@ -241,6 +253,11 @@ void strs_payload::deserialize(const uint64_t* buff,
status_info = get_field_u64<uint64_t>(word3, STATUS_INFO_OFFSET, STATUS_INFO_WIDTH);
}
+size_t strs_payload::get_length() const
+{
+ return 4;
+}
+
bool strs_payload::operator==(const strs_payload& rhs) const
{
return (src_epid == rhs.src_epid) && (status == rhs.status)
@@ -310,6 +327,11 @@ void strc_payload::deserialize(const uint64_t* buff,
num_bytes = conv_byte_order(buff[1]);
}
+size_t strc_payload::get_length() const
+{
+ return 2;
+}
+
bool strc_payload::operator==(const strc_payload& rhs) const
{
return (src_epid == rhs.src_epid) && (op_code == rhs.op_code)
@@ -328,6 +350,74 @@ const std::string strc_payload::to_string() const
// CHDR Management Payload
//----------------------------------------------------
+const std::string mgmt_op_t::to_string() const
+{
+ std::stringstream stream;
+ switch (get_op_code()) {
+ case mgmt_op_t::MGMT_OP_NOP:
+ stream << "NOP";
+ break;
+ case mgmt_op_t::MGMT_OP_ADVERTISE:
+ stream << "ADVERTISE";
+ break;
+ case mgmt_op_t::MGMT_OP_SEL_DEST:
+ stream << "SEL_DEST";
+ break;
+ case mgmt_op_t::MGMT_OP_RETURN:
+ stream << "RETURN";
+ break;
+ case mgmt_op_t::MGMT_OP_INFO_REQ:
+ stream << "INFO_REQ";
+ break;
+ case mgmt_op_t::MGMT_OP_INFO_RESP:
+ stream << "INFO_RESP";
+ break;
+ case mgmt_op_t::MGMT_OP_CFG_WR_REQ:
+ stream << "CFG_WR_REQ";
+ break;
+ case mgmt_op_t::MGMT_OP_CFG_RD_REQ:
+ stream << "CFG_RD_REQ";
+ break;
+ case mgmt_op_t::MGMT_OP_CFG_RD_RESP:
+ stream << "CFG_RD_RESP";
+ break;
+ default:
+ UHD_THROW_INVALID_CODE_PATH();
+ }
+ stream << ": ";
+ switch (get_op_code()) {
+ case mgmt_op_t::MGMT_OP_SEL_DEST: {
+ mgmt_op_t::sel_dest_payload payload = static_cast<uint64_t>(get_op_payload());
+ stream << "dest:" << payload.dest;
+ break;
+ }
+ case mgmt_op_t::MGMT_OP_CFG_WR_REQ:
+ case mgmt_op_t::MGMT_OP_CFG_RD_REQ:
+ case mgmt_op_t::MGMT_OP_CFG_RD_RESP: {
+ mgmt_op_t::cfg_payload payload = static_cast<uint64_t>(get_op_payload());
+ stream << str(
+ boost::format("addr:0x%08x, data:0x%08x") % payload.addr % payload.data);
+ break;
+ }
+ case mgmt_op_t::MGMT_OP_INFO_REQ:
+ case mgmt_op_t::MGMT_OP_INFO_RESP: {
+ mgmt_op_t::node_info_payload payload =
+ static_cast<uint64_t>(get_op_payload());
+ stream << "device_id:" << payload.device_id
+ << ", node_type:" << payload.node_type
+ << ", node_inst:" << payload.node_inst
+ << ", ext_info:" << payload.ext_info;
+ break;
+ }
+ default: {
+ stream << "-";
+ break;
+ }
+ }
+ stream << "\n";
+ return stream.str();
+}
+
//! Serialize this hop into a list of 64-bit words
size_t mgmt_hop_t::serialize(std::vector<uint64_t>& target,
const std::function<uint64_t(uint64_t)>& conv_byte_order,
@@ -369,6 +459,21 @@ void mgmt_hop_t::deserialize(std::list<uint64_t>& src,
} while (ops_remaining > 0);
}
+const std::string mgmt_hop_t::to_string() const
+{
+ std::stringstream stream;
+ for (size_t op_index = 0; op_index < get_num_ops(); op_index++) {
+ if (op_index == 0) {
+ stream << " -> ";
+ } else {
+ stream << " ";
+ }
+ const mgmt_op_t& op = get_op(op_index);
+ stream << op.to_string();
+ }
+ return stream.str();
+}
+
void mgmt_payload::populate_header(chdr_header& header) const
{
header.set_pkt_type(PKT_TYPE_MGMT);
@@ -440,6 +545,15 @@ void mgmt_payload::deserialize(const uint64_t* buff,
}
}
+size_t mgmt_payload::get_length() const
+{
+ size_t length = 1 + _padding_size; /* header */
+ for (const auto& hop : this->_hops) {
+ length += hop.get_num_ops() + _padding_size;
+ }
+ return length;
+}
+
const std::string mgmt_payload::to_string() const
{
return str(boost::format(
@@ -447,6 +561,16 @@ const std::string mgmt_payload::to_string() const
% _src_epid % int(_chdr_w) % _protover % _hops.size());
}
+const std::string mgmt_payload::hops_to_string() const
+{
+ std::stringstream stream;
+ for (size_t hop_index = 0; hop_index < get_num_hops(); hop_index++) {
+ const mgmt_hop_t& hop = get_hop(hop_index);
+ stream << hop.to_string();
+ }
+ return stream.str();
+}
+
bool mgmt_payload::operator==(const mgmt_payload& rhs) const
{