base: Provide pldm_msg_hdr_correlate_response()
Users of the asynchronous pldm_transport_send_msg() and
pldm_transport_recv_msg() APIs likely need some way to correlate a
received message as a response to a sent request.
Change-Id: I232400aebf06845e3eabf24205e31aa5668de9ba
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 484009e..408645a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,7 @@
### Added
1. state-set: Add new enum for Operational Fault Status enum
+2. base: Provide pldm_msg_hdr_correlate_response()
### Changed
diff --git a/include/libpldm/base.h b/include/libpldm/base.h
index c3d1ac9..9264d29 100644
--- a/include/libpldm/base.h
+++ b/include/libpldm/base.h
@@ -6,6 +6,7 @@
#endif
#include <asm/byteorder.h>
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
@@ -152,6 +153,22 @@
uint8_t payload[1]; //!< &payload[0] is the beginning of the payload
} __attribute__((packed));
+/**
+ * @brief Compare the headers from two PLDM messages to determine if the latter
+ * is a message representing a response to the former, where the former must be
+ * a request.
+ *
+ * @param[in] req - A pointer to a PLDM header object, which must represent a
+ * request
+ * @param[in] resp - A pointer to a PLDM header object, which may represent a
+ * response to the provided request.
+ *
+ * @return true if the header pointed to by resp represents a message that is a
+ * response to the header pointed to by req, otherwise false.
+ */
+bool pldm_msg_hdr_correlate_response(const struct pldm_msg_hdr *req,
+ const struct pldm_msg_hdr *resp);
+
/** @struct pldm_header_info
*
* The information needed to prepare PLDM header and this is passed to the
diff --git a/src/base.c b/src/base.c
index 02dca1a..39dcd65 100644
--- a/src/base.c
+++ b/src/base.c
@@ -65,6 +65,15 @@
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_TESTING
+bool pldm_msg_hdr_correlate_response(const struct pldm_msg_hdr *req,
+ const struct pldm_msg_hdr *resp)
+{
+ return req->instance_id == resp->instance_id && req->request &&
+ !resp->request && req->type == resp->type &&
+ req->command == resp->command;
+}
+
LIBPLDM_ABI_STABLE
int encode_get_types_req(uint8_t instance_id, struct pldm_msg *msg)
{
diff --git a/tests/libpldm_base_test.cpp b/tests/libpldm_base_test.cpp
index 7d67009..20289fc 100644
--- a/tests/libpldm_base_test.cpp
+++ b/tests/libpldm_base_test.cpp
@@ -792,3 +792,159 @@
rc = encode_set_tid_req(0, 0xff, request);
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PldmMsgHdr, correlateSuccess)
+{
+ static const struct pldm_msg_hdr req = {
+ .instance_id = 0,
+ .reserved = 0,
+ .datagram = 0,
+ .request = 1,
+ .type = 0,
+ .header_ver = 1,
+ .command = 0x01,
+ };
+ static const struct pldm_msg_hdr resp = {
+ .instance_id = 0,
+ .reserved = 0,
+ .datagram = 0,
+ .request = 0,
+ .type = 0,
+ .header_ver = 1,
+ .command = 0x01,
+ };
+
+ ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), true);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PldmMsgHdr, correlateFailInstanceID)
+{
+ static const struct pldm_msg_hdr req = {
+ .instance_id = 0,
+ .reserved = 0,
+ .datagram = 0,
+ .request = 1,
+ .type = 0,
+ .header_ver = 1,
+ .command = 0x01,
+ };
+ static const struct pldm_msg_hdr resp = {
+ .instance_id = 1,
+ .reserved = 0,
+ .datagram = 0,
+ .request = 0,
+ .type = 0,
+ .header_ver = 1,
+ .command = 0x01,
+ };
+
+ ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PldmMsgHdr, correlateFailRequest)
+{
+ static const struct pldm_msg_hdr req = {
+ .instance_id = 0,
+ .reserved = 0,
+ .datagram = 0,
+ .request = 1,
+ .type = 0,
+ .header_ver = 1,
+ .command = 0x01,
+ };
+ static const struct pldm_msg_hdr resp = {
+ .instance_id = 0,
+ .reserved = 0,
+ .datagram = 0,
+ .request = 1,
+ .type = 0,
+ .header_ver = 1,
+ .command = 0x01,
+ };
+
+ ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PldmMsgHdr, correlateFailType)
+{
+ static const struct pldm_msg_hdr req = {
+ .instance_id = 0,
+ .reserved = 0,
+ .datagram = 0,
+ .request = 1,
+ .type = 0,
+ .header_ver = 1,
+ .command = 0x01,
+ };
+ static const struct pldm_msg_hdr resp = {
+ .instance_id = 0,
+ .reserved = 0,
+ .datagram = 0,
+ .request = 0,
+ .type = 1,
+ .header_ver = 1,
+ .command = 0x01,
+ };
+
+ ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PldmMsgHdr, correlateFailCommand)
+{
+ static const struct pldm_msg_hdr req = {
+ .instance_id = 0,
+ .reserved = 0,
+ .datagram = 0,
+ .request = 1,
+ .type = 0,
+ .header_ver = 1,
+ .command = 0x01,
+ };
+ static const struct pldm_msg_hdr resp = {
+ .instance_id = 0,
+ .reserved = 0,
+ .datagram = 0,
+ .request = 0,
+ .type = 0,
+ .header_ver = 1,
+ .command = 0x02,
+ };
+
+ ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(PldmMsgHdr, correlateFailRequestIsResponse)
+{
+ static const struct pldm_msg_hdr req = {
+ .instance_id = 0,
+ .reserved = 0,
+ .datagram = 0,
+ .request = 0,
+ .type = 0,
+ .header_ver = 1,
+ .command = 0x01,
+ };
+ static const struct pldm_msg_hdr resp = {
+ .instance_id = 0,
+ .reserved = 0,
+ .datagram = 0,
+ .request = 0,
+ .type = 0,
+ .header_ver = 1,
+ .command = 0x02,
+ };
+
+ ASSERT_EQ(pldm_msg_hdr_correlate_response(&req, &resp), false);
+}
+#endif