dsp: platform: Add encode req & decode resp for GetEventReceiver command
Add encode and decode API for the Get Event Receiver command
This command is defined in DSP0248 as a conditional command.
The GetEventReceiver command is used to verify the values that were set
into an Event Generator using the SetEventReceiver command.
Change-Id: I411cc939d00bc69867507fe58911c813d0c1e2ae
Signed-off-by: Roger G. Coscojuela <roger.gili-coscojuela@sipearl.com>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 23a058e..cef81ea 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@
- utils: Introduce `pldm_edac_crc8()`
- pdr: Add pldm_pdr_delete_by_effecter_id() API
- platform: Add encode req for GetPDRRepositoryInfo
+- platform: Add encode req & decode resp for GetEventReceiver
- pdr: Add pldm_pdr_delete_by_sensor_id() API
- pdr: Add pldm_entity_association_tree_delete_node() API
diff --git a/include/libpldm/platform.h b/include/libpldm/platform.h
index 89af565..4cce891 100644
--- a/include/libpldm/platform.h
+++ b/include/libpldm/platform.h
@@ -16,6 +16,7 @@
#include <libpldm/compiler.h>
#include <libpldm/pdr.h>
#include <libpldm/pldm_types.h>
+#include <libpldm/utils.h>
/**
* @brief PLDM response transfer flag for the Platform and control commands
@@ -47,7 +48,8 @@
#define PLDM_GET_PDR_REQ_BYTES 13
-#define PLDM_SET_EVENT_RECEIVER_RESP_BYTES 1
+#define PLDM_SET_EVENT_RECEIVER_RESP_BYTES 1
+#define PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES 2
/* Platform event supported request */
#define PLDM_EVENT_MESSAGE_BUFFER_SIZE_REQ_BYTES 2
@@ -1081,6 +1083,19 @@
uint16_t heartbeat_timer;
} __attribute__((packed));
+/** @struct pldm_get_event_receiver_resp
+ *
+ * Structure representing GetEventReceiver command.
+ */
+struct pldm_get_event_receiver_resp {
+ uint8_t completion_code;
+ uint8_t transport_protocol_type;
+ union {
+ uint8_t mctp_eid;
+ struct variable_field vendor_specific;
+ } event_receiver_address;
+};
+
/** @struct pldm_event_message_buffer_size_req
*
* Structure representing EventMessageBufferSizes command request data
@@ -2437,6 +2452,60 @@
uint8_t *present_state, uint8_t *previous_state, uint8_t *event_state,
uint8_t *present_reading);
+/** @brief Encode the GetEventReceiver request message
+ *
+ * @param[in] instance_id - Message's instance id
+ * @param[out] msg - Argument to capture the Message
+ * @param[in] payload_length - length of request message payload
+ * @return 0 on success
+ * -EINVAL if the input parameters' memory are not allocated,
+ * or message type or instance in request header is invalid
+ * -ENOMSG if the PLDM type in the request header is invalid
+ * -EOVERFLOW if the input message length is invalid
+ */
+int encode_get_event_receiver_req(uint8_t instance_id, struct pldm_msg *msg,
+ size_t payload_length);
+
+/** @brief Decode the GetEventReceiver response message
+ *
+ * @param[in] msg - Request message
+ * @param[in] payload_length - Length of response message payload
+ * @param[out] resp - Structure to store decoded response
+ * @return 0 on success
+ * -EINVAL if the input parameters' memory are not allocated,
+ * or message type or instance in request header is invalid
+ * -ENOMSG if the PLDM type in the request header is invalid
+ * -EOVERFLOW if the input message length is invalid
+ * -ENOTSUP if the transport protocol is not supported
+ */
+int decode_get_event_receiver_resp(const struct pldm_msg *msg,
+ size_t payload_length,
+ struct pldm_get_event_receiver_resp *resp);
+
+/** @brief Encode the GetEventReceiver response message
+ *
+ * @param[in] instance_id - Message's instance id
+ * @param[in] event_receiver_info - Structure to encode. All members,
+ * except those mentioned in the @note below, should be initialized by
+ * the caller.
+ * @param[out] msg - Argument to capture the Message
+ * @param[in/out] payload_lenght - The lenght of the supplied buffer for
+ payload
+ * @return 0 on success
+ * -EINVAL if the input parameters' memory are not allocated,
+ * or message type or instance in request header is invalid
+ * -ENOMSG if the PLDM type in the request header is invalid
+ * -EOVERFLOW if the input message length is invalid
+ *
+ * @note Caller is responsible for the allocation of the event_receiver_address_info
+ * parameter. For MCTP transport event_receiver_info.mctp_eid should be set. For other
+ * protocol types event_receiver_info.vendor_specific should be used.
+ */
+int encode_get_event_receiver_resp(
+ uint8_t instance_id,
+ struct pldm_get_event_receiver_resp *event_receiver_info,
+ struct pldm_msg *msg, size_t *payload_length);
+
/** @brief Encode the SetEventReceiver request message
*
* @param[in] instance_id - Message's instance id
diff --git a/src/dsp/platform.c b/src/dsp/platform.c
index 7ad8e2f..21ada82 100644
--- a/src/dsp/platform.c
+++ b/src/dsp/platform.c
@@ -2503,6 +2503,100 @@
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_TESTING
+int encode_get_event_receiver_req(uint8_t instance_id, struct pldm_msg *msg,
+ size_t payload_length LIBPLDM_CC_UNUSED)
+{
+ struct pldm_header_info header;
+ header.msg_type = PLDM_REQUEST;
+ header.instance = instance_id;
+ header.pldm_type = PLDM_PLATFORM;
+ header.command = PLDM_GET_EVENT_RECEIVER;
+
+ if (!msg) {
+ return -EINVAL;
+ }
+
+ return pack_pldm_header_errno(&header, &(msg->hdr));
+}
+
+LIBPLDM_ABI_TESTING
+int encode_get_event_receiver_resp(
+ uint8_t instance_id,
+ struct pldm_get_event_receiver_resp *event_receiver_info,
+ struct pldm_msg *msg, size_t *payload_length)
+{
+ PLDM_MSGBUF_DEFINE_P(buf);
+ int rc;
+ if (!msg || !event_receiver_info) {
+ return -EINVAL;
+ }
+
+ /* See Table 2, DSP0245 v1.4.0 */
+ if (event_receiver_info->transport_protocol_type !=
+ PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
+ return -ENOTSUP;
+ }
+
+ struct pldm_header_info header = { 0 };
+ header.msg_type = PLDM_RESPONSE;
+ header.instance = instance_id;
+ header.pldm_type = PLDM_PLATFORM;
+ header.command = PLDM_GET_EVENT_RECEIVER;
+
+ rc = pack_pldm_header_errno(&header, &(msg->hdr));
+ if (rc) {
+ return rc;
+ }
+ rc = pldm_msgbuf_init_errno(buf, PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES,
+ msg->payload, *payload_length);
+ if (rc) {
+ return rc;
+ }
+
+ pldm_msgbuf_insert(buf, event_receiver_info->completion_code);
+ pldm_msgbuf_insert(buf, event_receiver_info->transport_protocol_type);
+ pldm_msgbuf_insert(
+ buf, event_receiver_info->event_receiver_address.mctp_eid);
+ return pldm_msgbuf_complete_used(buf, *payload_length, payload_length);
+}
+
+LIBPLDM_ABI_TESTING
+int decode_get_event_receiver_resp(const struct pldm_msg *msg,
+ size_t payload_length,
+ struct pldm_get_event_receiver_resp *resp)
+{
+ PLDM_MSGBUF_DEFINE_P(buf);
+ int rc;
+ if (!msg) {
+ return -EINVAL;
+ }
+
+ rc = pldm_msg_has_error(msg, payload_length);
+ if (rc) {
+ resp->completion_code = rc;
+ return 0;
+ }
+
+ rc = pldm_msgbuf_init_errno(buf, PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES,
+ msg->payload, payload_length);
+ if (rc) {
+ return rc;
+ }
+ pldm_msgbuf_extract(buf, resp->completion_code);
+ rc = pldm_msgbuf_extract(buf, resp->transport_protocol_type);
+ if (rc) {
+ return pldm_msgbuf_discard(buf, rc);
+ }
+ if (resp->transport_protocol_type ==
+ PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP) {
+ pldm_msgbuf_extract(buf, resp->event_receiver_address.mctp_eid);
+ } else {
+ return pldm_msgbuf_discard(buf, -ENOTSUP);
+ }
+ return pldm_msgbuf_complete_consumed(buf);
+}
+
LIBPLDM_ABI_STABLE
int encode_set_event_receiver_req(uint8_t instance_id,
uint8_t event_message_global_enable,
diff --git a/tests/dsp/platform.cpp b/tests/dsp/platform.cpp
index 0586c2e..1cfdb0a 100644
--- a/tests/dsp/platform.cpp
+++ b/tests/dsp/platform.cpp
@@ -6,6 +6,7 @@
#include <array>
#include <cerrno>
+#include <cstddef>
#include <cstdint>
#include <cstring>
#include <vector>
@@ -3592,6 +3593,129 @@
EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
}
+#ifdef LIBPLDM_API_TESTING
+TEST(GetEventReceiver, testGoodEncodeRequest)
+{
+ std::array<uint8_t, hdrSize> requestMsg{};
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ auto request = new (requestMsg.data()) pldm_msg;
+ auto rc =
+ encode_get_event_receiver_req(0, request, sizeof(struct pldm_msg));
+ ASSERT_EQ(rc, 0);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetEventReceiver, testBadEncodeRequest)
+{
+ auto rc =
+ encode_get_event_receiver_req(0, nullptr, sizeof(struct pldm_msg));
+ EXPECT_EQ(rc, -EINVAL);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetEventReceiver, testGoodEncodeResponse)
+{
+ struct pldm_get_event_receiver_resp request_event_receiver_values;
+ request_event_receiver_values.completion_code = 0;
+ request_event_receiver_values.transport_protocol_type =
+ PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP;
+ request_event_receiver_values.event_receiver_address.mctp_eid = 84;
+ size_t payload_lenght = PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES + 1;
+ std::array<uint8_t, hdrSize + sizeof(pldm_get_event_receiver_resp)>
+ responseMsg{};
+ auto response = new (responseMsg.data()) pldm_msg;
+ auto rc = encode_get_event_receiver_resp(0, &request_event_receiver_values,
+ response, &payload_lenght);
+ EXPECT_EQ(rc, 0);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetEventReceiver, testBadEncodeResponse)
+{
+ std::array<uint8_t, hdrSize + sizeof(pldm_get_event_receiver_resp)>
+ responseMsg{};
+ auto response = new (responseMsg.data()) pldm_msg;
+ struct pldm_get_event_receiver_resp request_event_receiver_values;
+ request_event_receiver_values.completion_code = 0;
+ request_event_receiver_values.transport_protocol_type =
+ PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP;
+ request_event_receiver_values.event_receiver_address.mctp_eid = 64;
+ size_t payload_lenght = PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES;
+ // msg can not be null
+ auto rc = encode_get_event_receiver_resp(0, &request_event_receiver_values,
+ nullptr, &payload_lenght);
+ EXPECT_EQ(rc, -EINVAL);
+ // unsupported protocol
+ request_event_receiver_values.transport_protocol_type = 1;
+ rc = encode_get_event_receiver_resp(0, &request_event_receiver_values,
+ response, &payload_lenght);
+ EXPECT_EQ(rc, -ENOTSUP);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetEventReceiver, testGoodDecodeResponse)
+{
+ struct pldm_get_event_receiver_resp request_event_receiver_values;
+ request_event_receiver_values.completion_code = 0;
+ request_event_receiver_values.transport_protocol_type =
+ PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP;
+ request_event_receiver_values.event_receiver_address.mctp_eid = 34;
+ size_t payload_lenght = PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES + 1;
+ struct pldm_get_event_receiver_resp decoded_resp;
+ std::array<uint8_t, hdrSize + sizeof(pldm_get_event_receiver_resp)>
+ responseMsg{};
+ auto response = new (responseMsg.data()) pldm_msg;
+ auto rc = encode_get_event_receiver_resp(0, &request_event_receiver_values,
+ response, &payload_lenght);
+ EXPECT_EQ(rc, 0);
+ rc = decode_get_event_receiver_resp(
+ response, PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES + 1, &decoded_resp);
+ EXPECT_EQ(rc, 0);
+ EXPECT_EQ(decoded_resp.completion_code, PLDM_SUCCESS);
+ EXPECT_EQ(decoded_resp.transport_protocol_type,
+ request_event_receiver_values.transport_protocol_type);
+ EXPECT_EQ(decoded_resp.event_receiver_address.mctp_eid,
+ request_event_receiver_values.event_receiver_address.mctp_eid);
+}
+#endif
+
+#ifdef LIBPLDM_API_TESTING
+TEST(GetEventReceiver, testBadDecodeResponse)
+{
+ struct pldm_get_event_receiver_resp decoded_resp;
+ struct pldm_get_event_receiver_resp expected_resp;
+ expected_resp.completion_code = 0;
+ expected_resp.transport_protocol_type = PLDM_TRANSPORT_PROTOCOL_TYPE_MCTP;
+ expected_resp.event_receiver_address.mctp_eid = 34;
+ std::array<uint8_t, hdrSize + sizeof(pldm_get_event_receiver_resp)>
+ responseMsg{};
+ auto response = new (responseMsg.data()) pldm_msg;
+ size_t payload_lenght = PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES + 1;
+ auto rc = encode_get_event_receiver_resp(0, &expected_resp, response,
+ &payload_lenght);
+ EXPECT_EQ(rc, 0);
+ // message can not be null
+ rc = decode_get_event_receiver_resp(
+ nullptr, responseMsg.size() - sizeof(pldm_msg_hdr), &decoded_resp);
+ EXPECT_EQ(rc, -EINVAL);
+ // Allocated less than expected
+ rc = decode_get_event_receiver_resp(
+ response, PLDM_GET_EVENT_RECEIVER_MIN_RESP_BYTES - 1, &decoded_resp);
+ EXPECT_EQ(rc, -EOVERFLOW);
+ // Not supported protocol
+ size_t transport_protocol_type_offset = hdrSize + 1;
+ // Manually modify the transport_protocol_type to a not supported one
+ responseMsg[transport_protocol_type_offset] = 1;
+ rc = decode_get_event_receiver_resp(
+ response, responseMsg.size() - sizeof(pldm_msg_hdr), &decoded_resp);
+ EXPECT_EQ(rc, -ENOTSUP);
+}
+#endif
+
TEST(SetEventReceiver, testGoodEncodeRequest)
{
uint8_t eventMessageGlobalEnable =