blob: 1035fd71efe662da3e5bd1896f2d661ab5d732e2 [file]
From 016f55dfaf07c3b90bdc8ef0318629751f1a3b6e Mon Sep 17 00:00:00 2001
From: Nikhil Namjoshi <nikhilnamjoshi@google.com>
Date: Thu, 7 Dec 2023 00:05:33 +0000
Subject: [PATCH] Adding RDEOperationEnumerate support
Add encoders and decoders for RDEOperationEnumerate.
Additionlly added code hooks to serve RDEOperationEnumerate
requests from the client. Also added test for the encoders
and decoders.
Tested:
Unit tested the encoders and decoders
Additionally tested the fix through libmctp app by sending
RdeOperationEnumerate requested in the middle of the
RdeOperationComplete request
```
0xc0000
Reading 0xc0000
Received. EID: 9 tag_owner: 0 msg_tag: 6 len:265
cc: 0
operation_status: 5
completion_percentage: 100
Has paylaod: Yes
response_payload_length: 242
etag len: 1
etag:
{"@odata.id":"/redfish/v1/Chassis/Tray/Controls","@odata.type":"#ControlCollection.ControlCollection","Name":"Control Collection","Members":[{"@odata.id":"/redfish/v1/Chassis/Tray/Controls/HDD_pid"},{"@odata.id":"/redfish/v1/Chassis/Tray/Controls/fans"}],"Members@odata.count":2}
{
"@odata.id": "/redfish/v1/Chassis/Tray/Controls",
"@odata.type": "#ControlCollection.ControlCollection",
"Members": [
{
"@odata.id": "/redfish/v1/Chassis/Tray/Controls/HDD_pid"
},
{
"@odata.id": "/redfish/v1/Chassis/Tray/Controls/fans"
}
],
"Members@odata.count": 2,
"Name": "Control Collection"
}
Received. EID: 9 tag_owner: 0 msg_tag: 6 len:13
cc: 0
operation count : 1
Resource Id : 786432
Operation Id: 65451
Operation Type : 1
Resource id verified
Received. EID: 9 tag_owner: 0 msg_tag: 6 len:4
cc: 0
operation completed!!!
```
Patch Tracking Bug: b/323193207
Upstream info / review: NA
Upstream-Status: Pending
Justification:
There is dependency on upstreaming rded first, followed
by other libpldm command support like OperationInit,
Operation,Status, OperationComplete and OperationKill
Change-Id: Ifda68fc89837d746a360bc7e56e932c79db6a9e8
Signed-off-by: Nikhil Namjoshi <nikhilnamjoshi@google.com>
---
include/libpldm/pldm_rde.h | 92 ++++++++++++-
src/pldm_rde.c | 150 ++++++++++++++++++++
tests/libpldm_rde_test.cpp | 271 +++++++++++++++++++++++++++++++++++++
3 files changed, 512 insertions(+), 1 deletion(-)
diff --git a/include/libpldm/pldm_rde.h b/include/libpldm/pldm_rde.h
index 3b8c1e8..5b2a3dc 100644
--- a/include/libpldm/pldm_rde.h
+++ b/include/libpldm/pldm_rde.h
@@ -25,6 +25,7 @@ extern "C" {
#define PLDM_RDE_OPERATION_INIT_REQ_HDR_SIZE 17
#define PLDM_RDE_OPERATION_INIT_RESP_HDR_SIZE 17
#define PLDM_RDE_OPERATION_STATUS_RESP_HDR_SIZE 17
+#define PLDM_RDE_OPERATION_ENUMERATE_RESP_HDR_SIZE 3
#define PLDM_RDE 0x06 /*Response should support PLDM_PLATFORM and PLDM_RDE*/
#define RDE_NEGOTIATE_REDFISH_PARAMETERS_RESP_BYTES 12
@@ -46,6 +47,7 @@ enum pldm_rde_commands {
PLDM_RDE_OPERATION_COMPLETE = 0x13,
PLDM_RDE_OPERATION_STATUS = 0x14,
PLDM_RDE_OPERATION_KILL = 0x15,
+ PLDM_RDE_OPERATION_ENUMERATE = 0x16,
PLDM_RDE_MULTIPART_SEND = 0x30,
PLDM_RDE_MULTIPART_RECEIVE = 0x31,
};
@@ -331,6 +333,26 @@ struct pldm_rde_operation_complete_req {
struct pldm_rde_operation_complete_resp {
uint8_t completion_code;
} __attribute__((packed));
+
+/**
+ * @brief RDEOperationEnumerate response operation data structure.
+ */
+struct pldm_rde_operation_enumerate_operation_data {
+ uint32_t resource_id;
+ uint16_t operation_id;
+ uint8_t operation_type;
+} __attribute__((packed));
+
+/**
+ * @brief RDEOperationEnumerate response data structure.
+ */
+struct pldm_rde_operation_enumerate_resp {
+ uint8_t completion_code;
+ uint16_t operation_count;
+ // Variable length data.
+ uint8_t var_data[1];
+} __attribute__((packed));
+
/**
* @brief RDEOperationStatus request data structure.
*/
@@ -754,6 +776,74 @@ int encode_rde_operation_complete_resp(uint8_t instance_id,
int decode_rde_operation_complete_resp(const struct pldm_msg *msg,
size_t payload_length,
uint8_t *completion_code);
+
+/**
+ * @brief Encode RDEOperationEnumerate request.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[out] msg - Request will be written to this.
+ * @return pldm_completion_codes.
+ */
+int encode_rde_operation_enumerate_req(uint8_t instance_id,
+ struct pldm_msg *msg);
+
+/**
+ * @brief Decode RDEOperationEnumerate request.
+ *
+ * @param[in] msg - Request message.
+ * @param[in] payload_length - Length of request message payload.
+ * @return pldm_completion_codes.
+ */
+int decode_rde_operation_enumerate_req(const struct pldm_msg *msg,
+ size_t payload_length);
+
+/**
+ * @brief Encodes RDEOperationEnumerate response.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] completion_code - PLDM completion code.
+ * @param[out] msg - Response message will be written to this.
+ * @return pldm_completion_codes.
+ */
+int encode_rde_operation_enumerate_resp(uint8_t instance_id,
+ uint8_t completion_code,
+ struct pldm_msg *msg);
+
+/**
+ * @brief Updates encoded RDEOperationEnumerate response by appending operation
+ * data to the response.
+ *
+ * @param[in] resource_id - Resource id
+ * @param[in] operation_id - Operation Id
+ * @param[in] operation_type - Operation type
+ * @param[out] msg - Response message will be written to this.
+ * @return pldm_completion_codes.
+ */
+int update_encoded_rde_operation_enumerate_resp(const uint32_t resource_id,
+ const uint16_t operation_id,
+ const uint8_t operation_type,
+ struct pldm_msg *msg);
+
+/**
+ * @brief Decode RDEOperationEnumerate response.
+ * NOTE: The operation_count and operation_data will have
+ * valid data only when then completion_code is PLDM_SUCCESS
+ *
+ * @param[in] msg - Response message will be written to this.
+ * @param[out] completion_code - PLDM completion code.
+ * @param[out] operation_count - Number of active operations in RDE device.
+ * @param[out] operation_data - An array of struct
+ * pldm_rde_operation_enumerate_operation_data to store the operation data
+ * @param[in] operation_data_array_size - Size of the input array of struct
+ * pldm_rde_operation_enumerate_operation_data
+ * @return pldm_completion_codes.
+ */
+int decode_rde_operation_enumerate_resp(
+ const struct pldm_msg *msg, uint8_t *completion_code,
+ uint16_t *operation_count,
+ struct pldm_rde_operation_enumerate_operation_data *operation_data,
+ uint16_t operation_data_array_size);
+
/**
* @brief Encode RDEOperationStatus request.
*
@@ -844,4 +934,4 @@ int decode_rde_operation_status_resp(
}
#endif
-#endif /* PLDM_RDE_H */
\ No newline at end of file
+#endif /* PLDM_RDE_H */
diff --git a/src/pldm_rde.c b/src/pldm_rde.c
index 2c87f8e..7116827 100644
--- a/src/pldm_rde.c
+++ b/src/pldm_rde.c
@@ -785,6 +785,156 @@ int decode_rde_operation_complete_resp(const struct pldm_msg *msg,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
+int encode_rde_operation_enumerate_req(uint8_t instance_id,
+ struct pldm_msg *msg)
+{
+ if (msg == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+ struct pldm_header_info header = {0};
+ header.instance = instance_id;
+ header.pldm_type = PLDM_RDE;
+ header.msg_type = PLDM_REQUEST;
+ header.command = PLDM_RDE_OPERATION_ENUMERATE;
+ uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+ if (rc != PLDM_SUCCESS) {
+ return rc;
+ }
+
+ return PLDM_SUCCESS;
+}
+
+LIBPLDM_ABI_STABLE
+int decode_rde_operation_enumerate_req(const struct pldm_msg *msg,
+ size_t payload_length)
+{
+ if (msg == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ // Enumerate operation should not have any request payload
+ if (payload_length != 0) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+
+ return PLDM_SUCCESS;
+}
+
+LIBPLDM_ABI_STABLE
+int encode_rde_operation_enumerate_resp(uint8_t instance_id,
+ uint8_t completion_code,
+ struct pldm_msg *msg)
+{
+ if (msg == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ struct pldm_header_info header = {0};
+ header.msg_type = PLDM_RESPONSE;
+ header.instance = instance_id;
+ header.pldm_type = PLDM_RDE;
+ header.command = PLDM_RDE_OPERATION_ENUMERATE;
+ uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+ if (rc != PLDM_SUCCESS) {
+ return rc;
+ }
+ struct pldm_rde_operation_enumerate_resp *response =
+ (struct pldm_rde_operation_enumerate_resp *)msg->payload;
+ response->completion_code = completion_code;
+
+ // Initially set the operation count to 0. Operation data can be added
+ // by calling update_encoded_rde_operation_enumerate_resp API
+ response->operation_count = 0;
+ return PLDM_SUCCESS;
+}
+
+LIBPLDM_ABI_STABLE
+int update_encoded_rde_operation_enumerate_resp(const uint32_t resource_id,
+ const uint16_t operation_id,
+ const uint8_t operation_type,
+ struct pldm_msg *msg)
+{
+ if (msg == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ struct pldm_rde_operation_enumerate_operation_data operation_data = {0};
+ operation_data.resource_id = htole32(resource_id);
+ operation_data.operation_id = htole16(operation_id);
+ operation_data.operation_type = operation_type;
+
+ struct pldm_rde_operation_enumerate_resp *response =
+ (struct pldm_rde_operation_enumerate_resp *)msg->payload;
+
+ uint16_t operation_count = le16toh(response->operation_count);
+ memcpy(response->var_data +
+ (sizeof(struct pldm_rde_operation_enumerate_operation_data) *
+ operation_count),
+ (void *)&operation_data,
+ sizeof(struct pldm_rde_operation_enumerate_operation_data));
+
+ response->operation_count = htole16(operation_count + 1);
+ return PLDM_SUCCESS;
+}
+
+LIBPLDM_ABI_STABLE
+int decode_rde_operation_enumerate_resp(
+ const struct pldm_msg *msg, uint8_t *completion_code,
+ uint16_t *operation_count,
+ struct pldm_rde_operation_enumerate_operation_data *operation_data,
+ uint16_t operation_data_array_size)
+{
+ if (msg == NULL) {
+ fprintf(stderr, "Invalid msg object\n");
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ if ((completion_code == NULL) || (operation_count == NULL) ||
+ (operation_data == NULL)) {
+ fprintf(stderr, "Invalid input pointers\n");
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ struct pldm_rde_operation_enumerate_resp *response =
+ (struct pldm_rde_operation_enumerate_resp *)msg->payload;
+
+ *completion_code = response->completion_code;
+ if (*completion_code != PLDM_SUCCESS) {
+ fprintf(
+ stderr,
+ "Unsuccessful completion code received in op status: %x\n",
+ (uint8_t)(*completion_code));
+ return PLDM_SUCCESS;
+ }
+
+ *operation_count = le16toh(response->operation_count);
+ if (operation_data_array_size < *operation_count) {
+ fprintf(stderr,
+ "Input operation_data struct array too small\n");
+ return PLDM_ERROR_INVALID_DATA;
+ }
+
+ for (uint16_t i = 0; i < *operation_count; i++) {
+ struct pldm_rde_operation_enumerate_operation_data
+ native_operation_data;
+ memcpy(
+ (void *)&native_operation_data,
+ response->var_data +
+ i * sizeof(struct
+ pldm_rde_operation_enumerate_operation_data),
+ sizeof(struct pldm_rde_operation_enumerate_operation_data));
+ operation_data[i].resource_id =
+ le32toh(native_operation_data.resource_id);
+ operation_data[i].operation_id =
+ le16toh(native_operation_data.operation_id);
+ operation_data[i].operation_type =
+ native_operation_data.operation_type;
+ }
+
+ return PLDM_SUCCESS;
+}
+
LIBPLDM_ABI_STABLE
int encode_rde_operation_status_req(uint8_t instance_id, uint32_t resource_id,
uint16_t operation_id, struct pldm_msg *msg)
diff --git a/tests/libpldm_rde_test.cpp b/tests/libpldm_rde_test.cpp
index 56e322b..ed4625e 100644
--- a/tests/libpldm_rde_test.cpp
+++ b/tests/libpldm_rde_test.cpp
@@ -887,3 +887,274 @@ TEST(RDEOperationStatus, DecodeResponseSuccess)
EXPECT_EQ(returnEtag->string_length_bytes,
std::end(etag) - std::begin(etag));
}
+
+TEST(RDEOperationEnumerate, EncodeRequest)
+{
+ uint8_t instanceId = 23;
+
+ constexpr size_t requestSize = sizeof(struct pldm_msg_hdr);
+ std::array<uint8_t, requestSize> requestMsg{};
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+ // When input msg of type struct pldm_msg * is NULL
+ EXPECT_EQ(encode_rde_operation_enumerate_req(instanceId, NULL),
+ PLDM_ERROR_INVALID_DATA);
+
+ // When all inputs are valid
+ EXPECT_EQ(encode_rde_operation_enumerate_req(instanceId, request),
+ PLDM_SUCCESS);
+
+ // Test Header values
+ EXPECT_EQ(request->hdr.instance_id, instanceId);
+ EXPECT_EQ(request->hdr.request, PLDM_REQUEST);
+ EXPECT_EQ(request->hdr.type, PLDM_RDE);
+ EXPECT_EQ(request->hdr.command, PLDM_RDE_OPERATION_ENUMERATE);
+}
+
+TEST(RDEOperationEnumerate, DecodeRequest)
+{
+ uint8_t instanceId = 25;
+
+ constexpr size_t requestSize = sizeof(struct pldm_msg_hdr);
+ std::array<uint8_t, requestSize> requestMsg{};
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+ encode_rde_operation_enumerate_req(instanceId, request);
+
+ // When input msg of type struct pldm_msg * is NULL
+ EXPECT_EQ(decode_rde_operation_enumerate_req(
+ NULL, requestSize - sizeof(struct pldm_msg_hdr)),
+ PLDM_ERROR_INVALID_DATA);
+
+ // When when the request size in non-zero indicating a request payload is
+ // present
+ EXPECT_EQ(decode_rde_operation_enumerate_req(request, 10),
+ PLDM_ERROR_INVALID_LENGTH);
+
+ // When all inputs are valid
+ EXPECT_EQ(decode_rde_operation_enumerate_req(
+ request, requestSize - sizeof(struct pldm_msg_hdr)),
+ PLDM_SUCCESS);
+}
+
+TEST(RDEOperationEnumerate, EncodeResponse)
+{
+ uint8_t instanceId = 29;
+ uint8_t completionCode = 0;
+
+ constexpr size_t responsePayloadLength =
+ sizeof(struct pldm_msg_hdr) +
+ PLDM_RDE_OPERATION_ENUMERATE_RESP_HDR_SIZE;
+ std::array<uint8_t, responsePayloadLength> responseMsg{};
+ auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+ // When input msg of type struct pldm_msg* is NULL
+ EXPECT_EQ(
+ encode_rde_operation_enumerate_resp(instanceId, completionCode, NULL),
+ PLDM_ERROR_INVALID_DATA);
+
+ // When all the inputs are valid
+ EXPECT_EQ(encode_rde_operation_enumerate_resp(instanceId, completionCode,
+ response),
+ PLDM_SUCCESS);
+
+ // verify header.
+ EXPECT_EQ(response->hdr.instance_id, instanceId);
+ EXPECT_EQ(response->hdr.request, 0);
+ EXPECT_EQ(response->hdr.type, PLDM_RDE);
+ EXPECT_EQ(response->hdr.command, PLDM_RDE_OPERATION_ENUMERATE);
+
+ // verify payload.
+ auto respPayload =
+ reinterpret_cast<pldm_rde_operation_enumerate_resp*>(response->payload);
+ EXPECT_EQ(respPayload->completion_code, completionCode);
+ EXPECT_EQ(respPayload->operation_count, 0);
+}
+
+TEST(RDEOperationEnumerate, UpdateEncodedResponse)
+{
+ uint8_t instanceId = 29;
+ uint8_t completionCode = 0;
+ const uint16_t operationCount = 3;
+
+ constexpr size_t responsePayloadLength =
+ sizeof(struct pldm_msg_hdr) +
+ PLDM_RDE_OPERATION_ENUMERATE_RESP_HDR_SIZE +
+ (operationCount *
+ sizeof(struct pldm_rde_operation_enumerate_operation_data));
+ std::array<uint8_t, responsePayloadLength> responseMsg{};
+ auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+ EXPECT_EQ(encode_rde_operation_enumerate_resp(instanceId, completionCode,
+ response),
+ PLDM_SUCCESS);
+
+ struct pldm_rde_operation_enumerate_operation_data
+ enumerateData[operationCount] = {
+ {.resource_id = 54314,
+ .operation_id = 2,
+ .operation_type = PLDM_RDE_OPERATION_READ},
+ {.resource_id = 32456,
+ .operation_id = 1,
+ .operation_type = PLDM_RDE_OPERATION_UPDATE},
+ {.resource_id = 76543,
+ .operation_id = 6,
+ .operation_type = PLDM_RDE_OPERATION_ACTION}};
+
+ // When input msg of type struct pldm_msg* is NULL
+ EXPECT_EQ(update_encoded_rde_operation_enumerate_resp(
+ enumerateData[0].resource_id, enumerateData[0].operation_id,
+ enumerateData[0].operation_type, NULL),
+ PLDM_ERROR_INVALID_DATA);
+
+ // Update the encoded payload with enumerate_data one by one and verify that
+ // response payload metadata gets updated accordingly
+ for (int i = 0; i < operationCount; i++)
+ {
+
+ EXPECT_EQ(update_encoded_rde_operation_enumerate_resp(
+ enumerateData[i].resource_id,
+ enumerateData[i].operation_id,
+ enumerateData[i].operation_type, response),
+ PLDM_SUCCESS);
+ auto respPayload2 =
+ reinterpret_cast<pldm_rde_operation_enumerate_resp*>(
+ response->payload);
+ EXPECT_EQ(respPayload2->completion_code, completionCode);
+ EXPECT_EQ(respPayload2->operation_count, i + 1);
+ }
+
+ // verify payload.
+ auto respPayload3 =
+ reinterpret_cast<pldm_rde_operation_enumerate_resp*>(response->payload);
+ EXPECT_EQ(respPayload3->completion_code, completionCode);
+ EXPECT_EQ(respPayload3->operation_count, operationCount);
+
+ struct pldm_rde_operation_enumerate_operation_data* enumerateRespData =
+ (struct pldm_rde_operation_enumerate_operation_data*)
+ respPayload3->var_data;
+
+ // Verify that the enumerate_data in the response is updated
+ for (int i = 0; i < operationCount; i++)
+ {
+ EXPECT_EQ(enumerateRespData[i].resource_id,
+ enumerateData[i].resource_id);
+ EXPECT_EQ(enumerateRespData[i].operation_id,
+ enumerateData[i].operation_id);
+ EXPECT_EQ(enumerateRespData[i].operation_type,
+ enumerateData[i].operation_type);
+ }
+}
+
+TEST(RDEOperationEnumerate, DecodeResponse)
+{
+ uint8_t instanceId = 29;
+ uint8_t completionCodeInput = 0;
+ const uint16_t operationCountInput = 3;
+
+ uint8_t completionCodeOutput = 0;
+ uint16_t operationCountOutput = 0;
+
+ struct pldm_rde_operation_enumerate_operation_data
+ enumerateRespData[operationCountInput];
+
+ struct pldm_rde_operation_enumerate_operation_data
+ enumerateData[operationCountInput] = {
+ {.resource_id = 54314,
+ .operation_id = 2,
+ .operation_type = PLDM_RDE_OPERATION_READ},
+ {.resource_id = 32456,
+ .operation_id = 1,
+ .operation_type = PLDM_RDE_OPERATION_UPDATE},
+ {.resource_id = 76543,
+ .operation_id = 6,
+ .operation_type = PLDM_RDE_OPERATION_ACTION}};
+
+ constexpr size_t responsePayloadLength =
+ sizeof(struct pldm_msg_hdr) +
+ PLDM_RDE_OPERATION_ENUMERATE_RESP_HDR_SIZE +
+ (operationCountInput *
+ sizeof(struct pldm_rde_operation_enumerate_operation_data));
+ std::array<uint8_t, responsePayloadLength> responseMsg{};
+ auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
+
+ // When input msg of type struct pldm_msg* is NULL
+ EXPECT_EQ(decode_rde_operation_enumerate_resp(
+ NULL, &completionCodeOutput, &operationCountOutput,
+ enumerateRespData, operationCountInput),
+ PLDM_ERROR_INVALID_DATA);
+
+ // When input completion_code is NULL
+ EXPECT_EQ(decode_rde_operation_enumerate_resp(
+ response, NULL, &operationCountOutput, enumerateRespData,
+ operationCountInput),
+ PLDM_ERROR_INVALID_DATA);
+
+ // When input operation_count is NULL
+ EXPECT_EQ(decode_rde_operation_enumerate_resp(
+ response, &completionCodeOutput, NULL, enumerateRespData,
+ operationCountInput),
+ PLDM_ERROR_INVALID_DATA);
+
+ // When input operation_data is NULL
+ EXPECT_EQ(decode_rde_operation_enumerate_resp(
+ response, &completionCodeOutput, &operationCountOutput, NULL,
+ operationCountInput),
+ PLDM_ERROR_INVALID_DATA);
+
+ // When input array size is smaller that the actual operation count
+ EXPECT_EQ(decode_rde_operation_enumerate_resp(
+ response, &completionCodeOutput, &operationCountOutput,
+ enumerateRespData, operationCountInput - 1),
+ PLDM_SUCCESS);
+
+ // When all the inputs are valid
+ EXPECT_EQ(encode_rde_operation_enumerate_resp(
+ instanceId, completionCodeInput, response),
+ PLDM_SUCCESS);
+
+ // Update the encoded payload with enumerate_data one by one
+ for (int i = 0; i < operationCountInput; i++)
+ {
+ EXPECT_EQ(update_encoded_rde_operation_enumerate_resp(
+ enumerateData[i].resource_id,
+ enumerateData[i].operation_id,
+ enumerateData[i].operation_type, response),
+ PLDM_SUCCESS);
+ }
+
+ EXPECT_EQ(decode_rde_operation_enumerate_resp(
+ response, &completionCodeOutput, &operationCountOutput,
+ enumerateRespData, operationCountInput),
+ PLDM_SUCCESS);
+
+ auto respPayload1 =
+ reinterpret_cast<pldm_rde_operation_enumerate_resp*>(response->payload);
+ EXPECT_EQ(respPayload1->completion_code, completionCodeInput);
+ EXPECT_EQ(respPayload1->operation_count, operationCountInput);
+
+ // Verify that the enumerate_data in the response is updated
+ for (int i = 0; i < operationCountInput; i++)
+ {
+ EXPECT_EQ(enumerateRespData[i].resource_id,
+ enumerateData[i].resource_id);
+ EXPECT_EQ(enumerateRespData[i].operation_id,
+ enumerateData[i].operation_id);
+ EXPECT_EQ(enumerateRespData[i].operation_type,
+ enumerateData[i].operation_type);
+ }
+
+ // When encoder encounters error and sets error completion code
+ EXPECT_EQ(
+ encode_rde_operation_enumerate_resp(instanceId, PLDM_ERROR, response),
+ PLDM_SUCCESS);
+ EXPECT_EQ(decode_rde_operation_enumerate_resp(
+ response, &completionCodeOutput, &operationCountOutput,
+ enumerateRespData, operationCountInput),
+ PLDM_SUCCESS);
+
+ auto respPayload2 =
+ reinterpret_cast<pldm_rde_operation_enumerate_resp*>(response->payload);
+ EXPECT_EQ(respPayload2->completion_code, PLDM_ERROR);
+ EXPECT_EQ(respPayload2->operation_count, 0);
+}
--
2.43.0.594.gd9cf4e227d-goog