Temporarily extract RDE encoders/decoders to rde-client

Eventually this code is to be upstreamed as encoders and
decoders exist in libpldm library (which is in C).

For the time being while this code is upstreamed and rebased,
extracting it to rde-client repo.

Google-Bug-Id: 319677028
Change-Id: I4768719e5f63f901f9a87b5c417ebf26067f5503
Signed-off-by: Harsh Tyagi <harshtya@google.com>
diff --git a/interface/pldm_rde.cpp b/interface/pldm_rde.cpp
new file mode 100644
index 0000000..a3b9de0
--- /dev/null
+++ b/interface/pldm_rde.cpp
@@ -0,0 +1,1030 @@
+/**
+ * @brief This file will be depricated soon. Currently it exists as a patch.
+ * This code is to be upstreamed in C, however to build it within this repo,
+ * this code is extracted as a cpp file here.
+ * There were some functionalities that were not working as a C file hence
+ * extracted to a cpp file
+ */
+#include "pldm_rde.hpp"
+
+#include "libpldm/base.h"
+
+#include <endian.h>
+
+#include <stdplus/print.hpp>
+
+#include <cstdlib>
+#include <cstring>
+
+int encode_negotiate_redfish_parameters_req(uint8_t instance_id,
+                                            uint8_t concurrency_support,
+                                            bitfield16_t* feature_support,
+                                            struct pldm_msg* msg)
+{
+    if ((msg == NULL) || (feature_support == NULL) ||
+        (concurrency_support == 0))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.msg_type = PLDM_REQUEST;
+    header.command = PLDM_NEGOTIATE_REDFISH_PARAMETERS;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_negotiate_redfish_parameters_req* req =
+        (struct pldm_rde_negotiate_redfish_parameters_req*)msg->payload;
+    req->mc_concurrency_support = concurrency_support;
+    req->mc_feature_support.value = htole16(feature_support->value);
+    return PLDM_SUCCESS;
+}
+
+int encode_negotiate_redfish_parameters_resp(
+    uint8_t instance_id, uint8_t completion_code,
+    uint8_t device_concurrency_support, bitfield8_t device_capabilities_flags,
+    bitfield16_t device_feature_support,
+    uint32_t device_configuration_signature, const char* device_provider_name,
+    enum pldm_rde_varstring_format name_format, struct pldm_msg* msg)
+{
+    if ((NULL == msg) || (NULL == device_provider_name))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.msg_type = PLDM_RESPONSE;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.command = PLDM_NEGOTIATE_REDFISH_PARAMETERS;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_negotiate_redfish_parameters_resp* response =
+        (struct pldm_rde_negotiate_redfish_parameters_resp*)msg->payload;
+    response->completion_code = completion_code;
+    if (response->completion_code != PLDM_SUCCESS)
+    {
+        return PLDM_SUCCESS;
+    }
+    response->device_concurrency_support = device_concurrency_support;
+    response->device_capabilities_flags.byte = device_capabilities_flags.byte;
+    response->device_feature_support.value =
+        htole16(device_feature_support.value);
+    response->device_configuration_signature =
+        htole32(device_configuration_signature);
+    response->device_provider_name.string_format = name_format;
+    // length should include NULL terminator.
+    response->device_provider_name.string_length_bytes =
+        strlen(device_provider_name) + 1;
+    // Copy including NULL terminator.
+    memcpy(response->device_provider_name.string_data, device_provider_name,
+           response->device_provider_name.string_length_bytes);
+    return PLDM_SUCCESS;
+}
+
+int decode_negotiate_redfish_parameters_req(const struct pldm_msg* msg,
+                                            size_t payload_length,
+                                            uint8_t* mc_concurrency_support,
+                                            bitfield16_t* mc_feature_support)
+{
+    if ((msg == NULL) || (mc_concurrency_support == NULL) ||
+        (mc_feature_support == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if (payload_length !=
+        sizeof(struct pldm_rde_negotiate_redfish_parameters_req))
+    {
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+    struct pldm_rde_negotiate_redfish_parameters_req* request =
+        (struct pldm_rde_negotiate_redfish_parameters_req*)msg->payload;
+    if (request->mc_concurrency_support == 0)
+    {
+        stdplus::print(stderr, "Concurrency support is 0\n");
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    *mc_concurrency_support = request->mc_concurrency_support;
+    mc_feature_support->value = le16toh(request->mc_feature_support.value);
+    return PLDM_SUCCESS;
+}
+
+int encode_negotiate_medium_parameters_resp(
+    uint8_t instance_id, uint8_t completion_code,
+    uint32_t device_maximum_transfer_bytes, struct pldm_msg* msg)
+{
+    if (NULL == msg)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.msg_type = PLDM_RESPONSE;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.command = PLDM_NEGOTIATE_MEDIUM_PARAMETERS;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_negotiate_medium_parameters_resp* response =
+        (struct pldm_rde_negotiate_medium_parameters_resp*)msg->payload;
+    response->completion_code = completion_code;
+    if (response->completion_code != PLDM_SUCCESS)
+    {
+        return PLDM_SUCCESS;
+    }
+    response->device_maximum_transfer_chunk_size_bytes =
+        htole32(device_maximum_transfer_bytes);
+    return PLDM_SUCCESS;
+}
+
+int decode_negotiate_redfish_parameters_resp(
+    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
+    struct pldm_rde_device_info* device)
+{
+    if ((msg == NULL) || (device == NULL) || (completion_code == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+
+    *completion_code = msg->payload[0];
+
+    if (PLDM_SUCCESS != *completion_code)
+    {
+        stdplus::print(
+            stderr,
+            "Unsuccessful completion code received in neg. params: {}\n",
+            static_cast<uint8_t>(*completion_code));
+        return PLDM_SUCCESS;
+    }
+
+    if (payload_length < RDE_NEGOTIATE_REDFISH_PARAMETERS_RESP_BYTES)
+    {
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+
+    struct pldm_rde_negotiate_redfish_parameters_resp* response =
+        (struct pldm_rde_negotiate_redfish_parameters_resp*)msg->payload;
+
+    device->device_concurrency = response->device_concurrency_support;
+    device->device_capabilities_flag = response->device_capabilities_flags;
+    device->device_configuration_signature =
+        le32toh(response->device_configuration_signature);
+    device->device_feature_support.value =
+        le16toh(response->device_feature_support.value);
+    device->device_provider_name = response->device_provider_name;
+    return PLDM_SUCCESS;
+}
+
+int decode_negotiate_medium_parameters_resp(
+    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
+    uint32_t* device_maximum_transfer_bytes)
+{
+    if ((msg == NULL) || (device_maximum_transfer_bytes == NULL) ||
+        (completion_code == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+
+    *completion_code = msg->payload[0];
+
+    if (PLDM_SUCCESS != *completion_code)
+    {
+        stdplus::print(
+            stderr,
+            "Unsuccessful completion code received in neg med params: {}\n",
+            static_cast<uint8_t>(*completion_code));
+        return PLDM_SUCCESS;
+    }
+
+    if (payload_length < RDE_NEGOTIATE_MEDIUM_PARAMETERS_RESP_BYTES)
+    {
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+
+    struct pldm_rde_negotiate_medium_parameters_resp* response =
+        (struct pldm_rde_negotiate_medium_parameters_resp*)msg->payload;
+
+    *device_maximum_transfer_bytes =
+        le32toh(response->device_maximum_transfer_chunk_size_bytes);
+
+    return PLDM_SUCCESS;
+}
+
+int encode_negotiate_medium_parameters_req(uint8_t instance_id,
+                                           uint32_t maximum_transfer_size,
+                                           struct pldm_msg* msg)
+{
+    if (msg == NULL)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.msg_type = PLDM_REQUEST;
+    header.command = PLDM_NEGOTIATE_MEDIUM_PARAMETERS;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_negotiate_medium_parameters_req* req =
+        (struct pldm_rde_negotiate_medium_parameters_req*)msg->payload;
+    req->mc_maximum_transfer_chunk_size_bytes = htole32(maximum_transfer_size);
+    return PLDM_SUCCESS;
+}
+
+int decode_negotiate_medium_parameters_req(const struct pldm_msg* msg,
+                                           size_t payload_length,
+                                           uint32_t* mc_maximum_transfer_size)
+{
+    if ((msg == NULL) || (mc_maximum_transfer_size == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if (payload_length !=
+        sizeof(struct pldm_rde_negotiate_medium_parameters_req))
+    {
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+    struct pldm_rde_negotiate_medium_parameters_req* request =
+        (struct pldm_rde_negotiate_medium_parameters_req*)msg->payload;
+    *mc_maximum_transfer_size =
+        le32toh(request->mc_maximum_transfer_chunk_size_bytes);
+    if (*mc_maximum_transfer_size < PLDM_RDE_MIN_TRANSFER_SIZE_BYTES)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    return PLDM_SUCCESS;
+}
+
+int encode_get_schema_dictionary_req(uint8_t instance_id, uint32_t resource_id,
+                                     uint8_t schema_class, struct pldm_msg* msg)
+{
+    if (msg == NULL)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.msg_type = PLDM_REQUEST;
+    header.command = PLDM_GET_SCHEMA_DICTIONARY;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_get_schema_dictionary_req* req =
+        (struct pldm_rde_get_schema_dictionary_req*)msg->payload;
+    req->resource_id = htole32(resource_id);
+    req->requested_schema_class = schema_class;
+    return PLDM_SUCCESS;
+}
+
+int decode_get_schema_dictionary_req(const struct pldm_msg* msg,
+                                     size_t payload_length,
+                                     uint32_t* resource_id,
+                                     uint8_t* requested_schema_class)
+{
+    if ((msg == NULL) || (resource_id == NULL) ||
+        (requested_schema_class == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if (payload_length != sizeof(struct pldm_rde_get_schema_dictionary_req))
+    {
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+    struct pldm_rde_get_schema_dictionary_req* request =
+        (struct pldm_rde_get_schema_dictionary_req*)msg->payload;
+    *resource_id = le32toh(request->resource_id);
+    *requested_schema_class = request->requested_schema_class;
+    if (*requested_schema_class > PLDM_RDE_SCHEMA_REGISTRY)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    return PLDM_SUCCESS;
+}
+
+int encode_get_schema_dictionary_resp(uint8_t instance_id,
+                                      uint8_t completion_code,
+                                      uint8_t dictionary_format,
+                                      uint32_t transfer_handle,
+                                      struct pldm_msg* msg)
+{
+    if (NULL == msg)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.msg_type = PLDM_RESPONSE;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.command = PLDM_GET_SCHEMA_DICTIONARY;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_get_schema_dictionary_resp* response =
+        (struct pldm_rde_get_schema_dictionary_resp*)msg->payload;
+    response->completion_code = completion_code;
+    if (response->completion_code != PLDM_SUCCESS)
+    {
+        return PLDM_SUCCESS;
+    }
+    response->dictionary_format = dictionary_format;
+    response->transfer_handle = htole32(transfer_handle);
+    return PLDM_SUCCESS;
+}
+
+int decode_get_schema_dictionary_resp(const struct pldm_msg* msg,
+                                      size_t payload_length,
+                                      uint8_t* completion_code,
+                                      uint8_t* dictionary_format,
+                                      uint32_t* transfer_handle)
+{
+    if ((msg == NULL) || (dictionary_format == NULL) ||
+        (completion_code == NULL) || (transfer_handle == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+
+    *completion_code = msg->payload[0];
+
+    if (PLDM_SUCCESS != *completion_code)
+    {
+        stdplus::print(stderr,
+                       "Unsuccessful completion code received in schema: {}\n",
+                       static_cast<uint8_t>(*completion_code));
+        return PLDM_SUCCESS;
+    }
+
+    if (payload_length < RDE_GET_DICTIONARY_SCHEMA_RESP_BYTES)
+    {
+        fprintf(stderr, "Unsuccessful completion code received %x",
+                (uint8_t)(*completion_code));
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+
+    struct pldm_rde_get_schema_dictionary_resp* response =
+        (struct pldm_rde_get_schema_dictionary_resp*)msg->payload;
+    *dictionary_format = response->dictionary_format;
+    *transfer_handle = le32toh(response->transfer_handle);
+    return PLDM_SUCCESS;
+}
+
+int encode_rde_multipart_receive_req(uint8_t instance_id,
+                                     uint32_t data_transfer_handle,
+                                     uint16_t operation_id,
+                                     uint8_t transfer_operation,
+                                     struct pldm_msg* msg)
+{
+    if (msg == NULL)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.msg_type = PLDM_REQUEST;
+    header.command = PLDM_RDE_MULTIPART_RECEIVE;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_multipart_receive_req* req =
+        (struct pldm_rde_multipart_receive_req*)msg->payload;
+    req->data_transfer_handle = htole32(data_transfer_handle);
+    req->operation_id = htole16(operation_id);
+    req->transfer_operation = transfer_operation;
+    return PLDM_SUCCESS;
+}
+
+int decode_rde_multipart_receive_req(const struct pldm_msg* msg,
+                                     size_t payload_length,
+                                     uint32_t* data_transfer_handle,
+                                     uint16_t* operation_id,
+                                     uint8_t* transfer_operation)
+{
+    if ((msg == NULL) || (data_transfer_handle == NULL) ||
+        (operation_id == NULL) || (transfer_operation == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if (payload_length != sizeof(struct pldm_rde_multipart_receive_req))
+    {
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+    struct pldm_rde_multipart_receive_req* request =
+        (struct pldm_rde_multipart_receive_req*)msg->payload;
+    *data_transfer_handle = le32toh(request->data_transfer_handle);
+    *operation_id = le16toh(request->operation_id);
+    *transfer_operation = request->transfer_operation;
+    if (*transfer_operation > PLDM_RDE_XFER_ABORT)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    return PLDM_SUCCESS;
+}
+
+int encode_rde_multipart_receive_resp(
+    uint8_t instance_id, uint8_t completion_code, uint8_t transfer_flag,
+    uint32_t next_data_transfer_handle, uint32_t data_length_bytes,
+    bool add_checksum, uint32_t checksum, const uint8_t* payload,
+    struct pldm_msg* msg)
+{
+    if (NULL == msg)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.msg_type = PLDM_RESPONSE;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.command = PLDM_RDE_MULTIPART_RECEIVE;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_multipart_receive_resp* response =
+        (struct pldm_rde_multipart_receive_resp*)msg->payload;
+    response->completion_code = completion_code;
+    if (response->completion_code != PLDM_SUCCESS)
+    {
+        return PLDM_SUCCESS;
+    }
+    response->transfer_flag = transfer_flag;
+    response->next_data_transfer_handle = htole32(next_data_transfer_handle);
+    memcpy(response->payload, (uint8_t*)payload, data_length_bytes);
+    uint32_t tot_length = data_length_bytes;
+    if (add_checksum)
+    {
+        tot_length += 4;
+        checksum = htole32(checksum);
+        memcpy(response->payload + data_length_bytes, &checksum,
+               sizeof(uint32_t));
+    }
+    response->data_length_bytes = htole32(tot_length);
+    return PLDM_SUCCESS;
+}
+
+int decode_rde_multipart_receive_resp(
+    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
+    uint8_t* ret_transfer_flag, uint32_t* ret_data_transfer_handle,
+    uint32_t* data_length_bytes, uint8_t** payload)
+{
+    if ((msg == NULL) || (completion_code == NULL) ||
+        (ret_transfer_flag == NULL) || (ret_data_transfer_handle == NULL) ||
+        (data_length_bytes == NULL) || (payload == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+
+    *completion_code = msg->payload[0];
+
+    if (PLDM_SUCCESS != *completion_code)
+    {
+        stdplus::print(
+            stderr, "Unsuccessful completion code received in multipart: {}\n",
+            static_cast<uint8_t>(*completion_code));
+        return PLDM_ERROR;
+    }
+
+    if (payload_length < RDE_MULTIPART_RECV_MINIMUM_RESP_BYTES)
+    {
+        stdplus::print(
+            stderr,
+            "Decoded successfully with failed payload length in multipart"
+            " with payload length: {} and expected: {}\n",
+            payload_length, RDE_MULTIPART_RECV_MINIMUM_RESP_BYTES);
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+
+    struct pldm_rde_multipart_receive_resp* response =
+        (struct pldm_rde_multipart_receive_resp*)msg->payload;
+    *ret_transfer_flag = response->transfer_flag;
+    *ret_data_transfer_handle = le32toh(response->next_data_transfer_handle);
+    *data_length_bytes = le32toh(response->data_length_bytes);
+    *payload = &response->payload[0];
+    return PLDM_SUCCESS;
+}
+
+int encode_rde_operation_init_req(
+    uint8_t instance_id, uint32_t resource_id, uint16_t operation_id,
+    uint8_t operation_type,
+    const union pldm_rde_operation_flags* operation_flags,
+    uint32_t send_data_transfer_handle, uint8_t operation_locator_length,
+    uint32_t request_payload_length, const uint8_t* operation_locator,
+    uint8_t* request_payload, struct pldm_msg* msg)
+{
+    if ((msg == NULL) || (operation_flags == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if ((operation_locator_length > 0) && (operation_locator == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if ((request_payload_length > 0) && (request_payload == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.msg_type = PLDM_REQUEST;
+    header.command = PLDM_RDE_OPERATION_INIT;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_operation_init_req* req =
+        (struct pldm_rde_operation_init_req*)msg->payload;
+    req->resource_id = htole32(resource_id);
+    req->operation_id = htole16(operation_id);
+    req->operation_type = operation_type;
+    req->operation_flags.byte = operation_flags->byte;
+    req->send_data_transfer_handle = htole32(send_data_transfer_handle);
+    req->operation_locator_length = operation_locator_length;
+    req->request_payload_length = htole32(request_payload_length);
+    if (operation_locator_length > 0)
+    {
+        memcpy(req->var_data, (uint8_t*)operation_locator,
+               operation_locator_length);
+    }
+    if (request_payload_length > 0)
+    {
+        memcpy(req->var_data + operation_locator_length,
+               (uint8_t*)request_payload, request_payload_length);
+        request_payload = NULL;
+    }
+    return PLDM_SUCCESS;
+}
+
+static bool pldm_rde_is_valid_mc_op_id(uint16_t operation_id)
+{
+    // Operation identifiers with the MSBit set are reserved for use by the
+    // MC. Operation identifiers with the MSBit clear are reserved for use
+    // by the RDE Device. The value 0x0000 is reserved to indicate no
+    // Operation.
+    if ((operation_id == 0) || ((operation_id >> 15) == 0))
+    {
+        return false;
+    }
+    return true;
+}
+
+int decode_rde_operation_init_req(
+    const struct pldm_msg* msg, size_t payload_length, uint32_t* resource_id,
+    uint16_t* operation_id, uint8_t* operation_type,
+    union pldm_rde_operation_flags* operation_flags,
+    uint32_t* send_data_transfer_handle, uint8_t* operation_locator_length,
+    uint32_t* request_payload_length, uint8_t** operation_locator,
+    uint8_t** request_payload)
+{
+    if ((msg == NULL) || (resource_id == NULL) || (operation_id == NULL) ||
+        (operation_type == NULL) || (operation_flags == NULL) ||
+        (send_data_transfer_handle == NULL) ||
+        (operation_locator_length == NULL) || (request_payload_length == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if (payload_length < PLDM_RDE_OPERATION_INIT_REQ_HDR_SIZE)
+    {
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+    struct pldm_rde_operation_init_req* request =
+        (struct pldm_rde_operation_init_req*)msg->payload;
+    *operation_id = le16toh(request->operation_id);
+    if (!pldm_rde_is_valid_mc_op_id(*operation_id))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    *resource_id = le32toh(request->resource_id);
+    *operation_type = request->operation_type;
+    operation_flags->byte = request->operation_flags.byte;
+    *send_data_transfer_handle = le32toh(request->send_data_transfer_handle);
+    *operation_locator_length = request->operation_locator_length;
+    *request_payload_length = le32toh(request->request_payload_length);
+    if (*operation_locator_length > 0)
+    {
+        *operation_locator = request->var_data;
+    }
+    else
+    {
+        *operation_locator = NULL;
+    }
+    if (*request_payload_length > 0)
+    {
+        *request_payload = request->var_data + *operation_locator_length;
+    }
+    else
+    {
+        *request_payload = NULL;
+    }
+    return PLDM_SUCCESS;
+}
+
+int encode_rde_operation_init_resp(
+    uint8_t instance_id, uint8_t completion_code, uint8_t operation_status,
+    uint8_t completion_percentage, uint32_t completion_time_seconds,
+    const union pldm_rde_op_execution_flags* operation_execution_flags,
+    uint32_t result_transfer_handle,
+    const union pldm_rde_permission_flags* permission_flags,
+    uint32_t response_payload_length,
+    enum pldm_rde_varstring_format etag_format, const char* etag,
+    const uint8_t* response_payload, struct pldm_msg* msg)
+{
+    if ((msg == NULL) || (operation_execution_flags == NULL) ||
+        (permission_flags == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if ((response_payload_length > 0) && (response_payload == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.msg_type = PLDM_RESPONSE;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.command = PLDM_RDE_OPERATION_INIT;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_operation_init_resp* response =
+        (struct pldm_rde_operation_init_resp*)msg->payload;
+    response->completion_code = completion_code;
+    if (response->completion_code != PLDM_SUCCESS)
+    {
+        return PLDM_SUCCESS;
+    }
+    response->operation_status = operation_status;
+    response->completion_percentage = completion_percentage;
+    response->completion_time_seconds = htole32(completion_time_seconds);
+    response->operation_execution_flags.byte = operation_execution_flags->byte;
+    response->result_transfer_handle = htole32(result_transfer_handle);
+    response->permission_flags.byte = permission_flags->byte;
+    response->response_payload_length = htole32(response_payload_length);
+    struct pldm_rde_varstring* resp_etag =
+        (struct pldm_rde_varstring*)response->var_data;
+    resp_etag->string_format = etag_format;
+    // length should include NULL terminator.
+    size_t etag_len_wo_null = strlen(etag);
+    resp_etag->string_length_bytes = etag_len_wo_null + 1;
+    // Copy including NULL terminator.
+    memcpy(resp_etag->string_data, etag, resp_etag->string_length_bytes);
+    // Copy the payload.
+    if (response_payload_length > 0)
+    {
+        memcpy(response->var_data + sizeof(struct pldm_rde_varstring) +
+                   etag_len_wo_null,
+               (uint8_t*)response_payload, response_payload_length);
+    }
+    return PLDM_SUCCESS;
+}
+
+int decode_rde_operation_init_resp(
+    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
+    uint8_t* completion_percentage, uint8_t* operation_status,
+    uint32_t* completion_time_seconds, uint32_t* result_transfer_handle,
+    uint32_t* response_payload_length,
+    union pldm_rde_permission_flags** permission_flags,
+    union pldm_rde_op_execution_flags** operation_execution_flags,
+    struct pldm_rde_varstring** resp_etag, uint8_t** response_payload)
+{
+    if (msg == NULL)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    *completion_code = msg->payload[0];
+    if (PLDM_SUCCESS != *completion_code)
+    {
+        fprintf(stderr,
+                "Unsuccessful completion code received in op init: %x\n",
+                (uint8_t)(*completion_code));
+        return PLDM_ERROR;
+    }
+
+    if (payload_length < RDE_READ_OPERATION_INIT_MIN_BYTES)
+    {
+        fprintf(stderr,
+                "Decoded successfully with failed payload length with payload "
+                "length: %zu and expected: %d\n",
+                payload_length, RDE_READ_OPERATION_INIT_MIN_BYTES);
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+
+    struct pldm_rde_operation_init_resp* response =
+        (struct pldm_rde_operation_init_resp*)msg->payload;
+
+    *operation_status = response->operation_status;
+    *completion_percentage = response->completion_percentage;
+    *completion_time_seconds = le32toh(response->completion_time_seconds);
+    (*operation_execution_flags)->byte =
+        response->operation_execution_flags.byte;
+    *result_transfer_handle = le32toh(response->result_transfer_handle);
+    (*permission_flags)->byte = response->permission_flags.byte;
+    *response_payload_length = le32toh(response->response_payload_length);
+
+    *resp_etag = (struct pldm_rde_varstring*)response->var_data;
+
+    if (*operation_status == PLDM_RDE_OPERATION_COMPLETED)
+    {
+        *response_payload =
+            &(*resp_etag)->string_data[0] + (*resp_etag)->string_length_bytes;
+    }
+    return 0;
+}
+
+int encode_rde_operation_complete_req(uint8_t instance_id, uint32_t resource_id,
+                                      uint16_t operation_id,
+                                      struct pldm_msg* msg)
+{
+    if (msg == NULL)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.msg_type = PLDM_REQUEST;
+    header.command = PLDM_RDE_OPERATION_COMPLETE;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_operation_complete_req* req =
+        (struct pldm_rde_operation_complete_req*)msg->payload;
+    req->resource_id = htole32(resource_id);
+    req->operation_id = htole16(operation_id);
+    return PLDM_SUCCESS;
+}
+
+int decode_rde_operation_complete_req(const struct pldm_msg* msg,
+                                      size_t payload_length,
+                                      uint32_t* resource_id,
+                                      uint16_t* operation_id)
+{
+    if ((msg == NULL) || (resource_id == NULL) || (operation_id == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if (payload_length < sizeof(struct pldm_rde_operation_complete_req))
+    {
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+    struct pldm_rde_operation_complete_req* request =
+        (struct pldm_rde_operation_complete_req*)msg->payload;
+    *resource_id = le32toh(request->resource_id);
+    *operation_id = le16toh(request->operation_id);
+    return PLDM_SUCCESS;
+}
+
+int encode_rde_operation_complete_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;
+    header.msg_type = PLDM_RESPONSE;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.command = PLDM_RDE_OPERATION_COMPLETE;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_operation_complete_resp* response =
+        (struct pldm_rde_operation_complete_resp*)msg->payload;
+    response->completion_code = completion_code;
+    return PLDM_SUCCESS;
+}
+
+int decode_rde_operation_complete_resp(const struct pldm_msg* msg,
+                                       size_t payload_length,
+                                       uint8_t* completion_code)
+{
+    if (msg == NULL)
+    {
+        fprintf(stderr, "Invalid message object\n");
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if (payload_length < 1)
+    {
+        fprintf(stderr, "Invalid payload length\n");
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+
+    *completion_code = msg->payload[0];
+
+    if (PLDM_SUCCESS != *completion_code)
+    {
+        fprintf(stderr,
+                "Unsuccessful completion code received in op complete: %x\n",
+                (uint8_t)(*completion_code));
+        return PLDM_SUCCESS;
+    }
+    return PLDM_SUCCESS;
+}
+
+int encode_rde_operation_status_req(uint8_t instance_id, uint32_t resource_id,
+                                    uint16_t operation_id, struct pldm_msg* msg)
+{
+    if (msg == NULL)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.msg_type = PLDM_REQUEST;
+    header.command = PLDM_RDE_OPERATION_STATUS;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_operation_status_req* req =
+        (struct pldm_rde_operation_status_req*)msg->payload;
+    req->resource_id = htole32(resource_id);
+    req->operation_id = htole16(operation_id);
+    return PLDM_SUCCESS;
+}
+
+int decode_rde_operation_status_req(const struct pldm_msg* msg,
+                                    size_t payload_length,
+                                    uint32_t* resource_id,
+                                    uint16_t* operation_id)
+{
+    if ((msg == NULL) || (resource_id == NULL) || (operation_id == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if (payload_length < sizeof(struct pldm_rde_operation_status_req))
+    {
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+    struct pldm_rde_operation_status_req* request =
+        (struct pldm_rde_operation_status_req*)msg->payload;
+    *resource_id = le32toh(request->resource_id);
+    *operation_id = le16toh(request->operation_id);
+    return PLDM_SUCCESS;
+}
+
+int encode_rde_operation_status_resp(
+    uint8_t instance_id, uint8_t completion_code, uint8_t operation_status,
+    uint8_t completion_percentage, uint32_t completion_time_seconds,
+    const union pldm_rde_op_execution_flags* operation_execution_flags,
+    uint32_t result_transfer_handle,
+    const union pldm_rde_permission_flags* permission_flags,
+    uint32_t response_payload_length,
+    enum pldm_rde_varstring_format etag_format, const char* etag,
+    const uint8_t* response_payload, struct pldm_msg* msg)
+{
+    if ((msg == NULL) || (operation_execution_flags == NULL) ||
+        (permission_flags == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    if ((response_payload_length > 0) && (response_payload == NULL))
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.msg_type = PLDM_RESPONSE;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.command = PLDM_RDE_OPERATION_STATUS;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_operation_status_resp* response =
+        (struct pldm_rde_operation_status_resp*)msg->payload;
+    response->completion_code = completion_code;
+    if (response->completion_code != PLDM_SUCCESS)
+    {
+        return PLDM_SUCCESS;
+    }
+    response->operation_status = operation_status;
+    response->completion_percentage = completion_percentage;
+    response->completion_time_seconds = htole32(completion_time_seconds);
+    response->operation_execution_flags.byte = operation_execution_flags->byte;
+    response->result_transfer_handle = htole32(result_transfer_handle);
+    response->permission_flags.byte = permission_flags->byte;
+    response->response_payload_length = htole32(response_payload_length);
+    struct pldm_rde_varstring* resp_etag =
+        (struct pldm_rde_varstring*)response->var_data;
+    resp_etag->string_format = etag_format;
+    // length should include NULL terminator.
+    size_t etag_len_wo_null = strlen(etag);
+    resp_etag->string_length_bytes = etag_len_wo_null + 1;
+    // Copy including NULL terminator.
+    memcpy(resp_etag->string_data, etag, resp_etag->string_length_bytes);
+    // Copy the payload.
+    if (response_payload_length > 0)
+    {
+        memcpy(response->var_data + sizeof(struct pldm_rde_varstring) +
+                   etag_len_wo_null,
+               (uint8_t*)response_payload, response_payload_length);
+    }
+    return PLDM_SUCCESS;
+}
+
+int decode_rde_operation_status_resp(
+    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
+    uint8_t* completion_percentage, uint8_t* operation_status,
+    uint32_t* completion_time_seconds, uint32_t* result_transfer_handle,
+    uint32_t* response_payload_length,
+    union pldm_rde_permission_flags** permission_flags,
+    union pldm_rde_op_execution_flags** operation_execution_flags,
+    struct pldm_rde_varstring** resp_etag, uint8_t** response_payload)
+{
+    if (msg == NULL)
+    {
+        stdplus::print(stderr, "Invalid msg object\n");
+        return PLDM_ERROR_INVALID_DATA;
+    }
+
+    *completion_code = msg->payload[0];
+    if (PLDM_SUCCESS != *completion_code)
+    {
+        stdplus::print(
+            stderr, "Unsuccessful completion code received in op status: {}\n",
+            static_cast<uint8_t>(*completion_code));
+        return PLDM_SUCCESS;
+    }
+
+    if (payload_length < RDE_READ_OPERATION_INIT_MIN_BYTES)
+    {
+        stdplus::print(stderr,
+                       "Decoded sucessfully with failed payload length\n");
+        return PLDM_ERROR_INVALID_LENGTH;
+    }
+
+    struct pldm_rde_operation_init_resp* response =
+        (struct pldm_rde_operation_init_resp*)msg->payload;
+
+    *operation_status = response->operation_status;
+    *completion_percentage = response->completion_percentage;
+    *completion_time_seconds = le32toh(response->completion_time_seconds);
+    (*operation_execution_flags)->byte =
+        response->operation_execution_flags.byte;
+    *result_transfer_handle = le32toh(response->result_transfer_handle);
+    (*permission_flags)->byte = response->permission_flags.byte;
+    *response_payload_length = le32toh(response->response_payload_length);
+
+    *resp_etag = (struct pldm_rde_varstring*)response->var_data;
+    if (*operation_status == PLDM_RDE_OPERATION_COMPLETED)
+    {
+        *response_payload =
+            &(*resp_etag)->string_data[0] + (*resp_etag)->string_length_bytes;
+    }
+    return 0;
+}
+
+int encode_rde_operation_kill_req(uint8_t instance_id, uint32_t resource_id,
+                                  uint16_t operation_id, struct pldm_msg* msg)
+{
+    if (msg == NULL)
+    {
+        return PLDM_ERROR_INVALID_DATA;
+    }
+    struct pldm_header_info header;
+    header.instance = instance_id;
+    header.pldm_type = PLDM_RDE;
+    header.msg_type = PLDM_REQUEST;
+    header.command = PLDM_RDE_OPERATION_KILL;
+    uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
+    if (rc != PLDM_SUCCESS)
+    {
+        return rc;
+    }
+    struct pldm_rde_operation_kill_req* req =
+        (struct pldm_rde_operation_kill_req*)msg->payload;
+    req->resource_id = htole32(resource_id);
+    req->operation_id = htole16(operation_id);
+    req->killflags.byte = 4;
+    return PLDM_SUCCESS;
+}
diff --git a/interface/pldm_rde.hpp b/interface/pldm_rde.hpp
new file mode 100644
index 0000000..5e3967b
--- /dev/null
+++ b/interface/pldm_rde.hpp
@@ -0,0 +1,928 @@
+/**
+ * @brief This file will be depricated soon. Currently it exists as a patch.
+ * This code is to be upstreamed in C, however to build it within this repo,
+ * this code is extracted as a cpp file here.
+ * There were some functionalities that were not working as a C file hence
+ * extracted to a cpp file
+ */
+#pragma once
+
+#ifndef PLDM_RDE_HPP
+#define PLDM_RDE_HPP
+
+#include "libpldm/base.h"
+#include "libpldm/pldm_types.h"
+
+#include <endian.h>
+
+#include <cstddef>
+#include <cstdint>
+
+// Minimum transfer size allowed is 64 bytes.
+#define PLDM_RDE_MIN_TRANSFER_SIZE_BYTES 64
+// Dictionary VersionTag for DSP0218 v1.0.0, v1.1.0, v1.1.1.
+#define PLDM_RDE_DICT_VERSION_TAG 0x00
+#define PLDM_RDE_NOT_A_OPERATION 0x00
+#define PLD_RDE_NULL_TRANSFER_HANDLE 0
+#define PLD_RDE_OP_PENDING_TRANSFER_HANDLE 0xFFFFFFFF
+#define PLDM_RDE_COMP_TIME_NOT_SUPPORTED 0xFFFFFFFF
+#define PLDM_RDE_COMP_PERCENTAGE_NOT_SUPPORTED 254
+// Variable struct header sizes
+#define PLDM_RDE_MULTIPART_RECEIVE_RESP_HDR_SIZE 10
+#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 0x06 /*Response should support PLDM_PLATFORM and PLDM_RDE*/
+#define RDE_NEGOTIATE_REDFISH_PARAMETERS_RESP_BYTES 12
+#define RDE_NEGOTIATE_MEDIUM_PARAMETERS_RESP_BYTES 5
+#define RDE_GET_DICTIONARY_SCHEMA_RESP_BYTES 6
+#define RDE_MULTIPART_RECV_MINIMUM_RESP_BYTES 6
+#define RDE_READ_OPERATION_INIT_MIN_BYTES 13
+#define RESOURCE_ID_ANY 0xFFFFFFFF
+#define IGNORE(x) (void)(x)
+
+/** @brief RDE Supported Commands
+ */
+enum pldm_rde_commands
+{
+    PLDM_NEGOTIATE_REDFISH_PARAMETERS = 0x01,
+    PLDM_NEGOTIATE_MEDIUM_PARAMETERS = 0x02,
+    PLDM_GET_SCHEMA_DICTIONARY = 0x03,
+    PLDM_GET_SCHEMA_FILE = 0x0C,
+    PLDM_RDE_OPERATION_INIT = 0x10,
+    PLDM_RDE_OPERATION_COMPLETE = 0x13,
+    PLDM_RDE_OPERATION_STATUS = 0x14,
+    PLDM_RDE_OPERATION_KILL = 0x15,
+    PLDM_RDE_MULTIPART_SEND = 0x30,
+    PLDM_RDE_MULTIPART_RECEIVE = 0x31,
+};
+
+typedef enum pldm_rde_varstring_format
+{
+    PLDM_RDE_VARSTRING_UNKNOWN = 0,
+    PLDM_RDE_VARSTRING_ASCII = 1,
+    PLDM_RDE_VARSTRING_UTF_8 = 2,
+    PLDM_RDE_VARSTRING_UTF_16 = 3,
+    PLDM_RDE_VARSTRING_UTF_16LE = 4,
+    PLDM_RDE_VARSTRING_UTF_16BE = 5,
+} pldm_rde_varstring_format;
+
+enum pldm_rde_schema_type
+{
+    PLDM_RDE_SCHEMA_MAJOR = 0,
+    PLDM_RDE_SCHEMA_EVENT = 1,
+    PLDM_RDE_SCHEMA_ANNOTATION = 2,
+    PLDM_RDE_SCHEMA_COLLECTION_MEMBER_TYPE = 3,
+    PLDM_RDE_SCHEMA_ERROR = 4,
+    PLDM_RDE_SCHEMA_REGISTRY = 5,
+};
+
+enum pldm_rde_completion_codes
+{
+    PLDM_RDE_ERROR_CANNOT_CREATE_OPERATION = 0x81,
+    PLDM_RDE_ERROR_NOT_ALLOWED = 0x82,
+    PLDM_RDE_ERROR_WRONG_LOCATION_TYPE = 0x83,
+    PLDM_RDE_ERROR_OPERATION_ABANDONED = 0x84,
+    PLDM_RDE_ERROR_OPERATION_EXISTS = 0x86,
+    PLDM_RDE_ERROR_OPERATION_FAILED = 0x87,
+    PLDM_RDE_ERROR_UNEXPECTED = 0x88,
+    PLDM_RDE_ERROR_UNSUPPORTED = 0x89,
+    PLDM_RDE_ERROR_NO_SUCH_RESOURCE = 0x92,
+};
+
+// TODO: Do we need this because base.h already has this
+/**
+ * @brief Transfer operation flags.
+ */
+enum pldm_rde_transfer_operation
+{
+    PLDM_RDE_XFER_FIRST_PART = 0,
+    PLDM_RDE_XFER_NEXT_PART = 1,
+    PLDM_RDE_XFER_ABORT = 2,
+};
+
+// TODO: Do we need this because base.h already has this
+enum pldm_rde_transfer_flag
+{
+    PLDM_RDE_START = 0,
+    PLDM_RDE_MIDDLE = 1,
+    PLDM_RDE_END = 2,
+    PLDM_RDE_START_AND_END = 3,
+};
+
+enum pldm_rde_operation_type
+{
+    PLDM_RDE_OPERATION_HEAD = 0,
+    PLDM_RDE_OPERATION_READ = 1,
+    PLDM_RDE_OPERATION_CREATE = 2,
+    PLDM_RDE_OPERATION_DELETE = 3,
+    PLDM_RDE_OPERATION_UPDATE = 4,
+    PLDM_RDE_OPERATION_REPLACE = 5,
+    PLDM_RDE_OPERATION_ACTION = 6,
+};
+
+enum pldm_rde_operation_status
+{
+    PLDM_RDE_OPERATION_INACTIVE = 0,
+    PLDM_RDE_OPERATION_NEEDS_INPUT = 1,
+    PLDM_RDE_OPERATION_TRIGGERED = 2,
+    PLDM_RDE_OPERATION_RUNNING = 3,
+    PLDM_RDE_OPERATION_HAVE_RESULTS = 4,
+    PLDM_RDE_OPERATION_COMPLETED = 5,
+    PLDM_RDE_OPERATION_FAILED = 6,
+    PLDM_RDE_OPERATION_ABANDONED = 7,
+};
+
+/**
+ * @brief MC feature support.
+ *
+ * The flags can be OR'd together to build the feature support for a MC.
+ */
+enum pldm_rde_mc_feature
+{
+    PLDM_RDE_MC_HEAD_SUPPORTED = 1,
+    PLDM_RDE_MC_READ_SUPPORTED = 2,
+    PLDM_RDE_MC_CREATE_SUPPORTED = 4,
+    PLDM_RDE_MC_DELETE_SUPPORTED = 8,
+    PLDM_RDE_MC_UPDATE_SUPPORTED = 16,
+    PLDM_RDE_MC_REPLACE_SUPPORTED = 32,
+    PLDM_RDE_MC_ACTION_SUPPORTED = 64,
+    PLDM_RDE_MC_EVENTS_SUPPORTED = 128,
+    PLDM_RDE_MC_BEJ_1_1_SUPPORTED = 256,
+};
+
+/**
+ * @brief Device capability flags.
+ *
+ * The flags can be OR'd together to build capabilities of a device.
+ */
+enum pldm_rde_device_capability
+{
+    PLDM_RDE_DEVICE_ATOMIC_RESOURCE_READ_SUPPORT = 1,
+    PLDM_RDE_DEVICE_EXPAND_SUPPORT = 2,
+    PLDM_RDE_DEVICE_BEJ_1_1_SUPPORT = 4,
+};
+
+/**
+ * @brief Device feature support.
+ *
+ * The flags can be OR'd together to build features of a RDE device.
+ */
+enum pldm_rde_device_feature
+{
+    PLDM_RDE_DEVICE_HEAD_SUPPORTED = 1,
+    PLDM_RDE_DEVICE_READ_SUPPORTED = 2,
+    PLDM_RDE_DEVICE_CREATE_SUPPORTED = 4,
+    PLDM_RDE_DEVICE_DELETE_SUPPORTED = 8,
+    PLDM_RDE_DEVICE_UPDATE_SUPPORTED = 16,
+    PLDM_RDE_DEVICE_REPLACE_SUPPORTED = 32,
+    PLDM_RDE_DEVICE_ACTION_SUPPORTED = 64,
+    PLDM_RDE_DEVICE_EVENTS_SUPPORTED = 128,
+};
+
+/**
+ * @brief RDEOperationKill request data structure
+ */
+struct pldm_rde_operation_kill_req
+{
+    uint32_t resource_id;
+    uint16_t operation_id;
+    bitfield8_t killflags;
+} __attribute__((packed));
+
+/**
+ * @brief NegotiateRedfishParameters request data structure.
+ */
+struct pldm_rde_negotiate_redfish_parameters_req
+{
+    uint8_t mc_concurrency_support;
+    bitfield16_t mc_feature_support;
+} __attribute__((packed));
+
+/**
+ * @brief varstring PLDM data type.
+ *
+ * sizeof(struct pldm_rde_varstring) will include the space for the NULL
+ * character.
+ */
+struct pldm_rde_varstring
+{
+    uint8_t string_format;
+    // Includes NULL terminator.
+    uint8_t string_length_bytes;
+    // String data should be NULL terminated.
+    uint8_t string_data[1];
+} __attribute__((packed));
+
+/**
+ * @brief NegotiateRedfishParameters response data structure.
+ */
+struct pldm_rde_negotiate_redfish_parameters_resp
+{
+    uint8_t completion_code;
+    uint8_t device_concurrency_support;
+    bitfield8_t device_capabilities_flags;
+    bitfield16_t device_feature_support;
+    uint32_t device_configuration_signature;
+    struct pldm_rde_varstring device_provider_name;
+} __attribute__((packed));
+
+/**
+ * @brief NegotiateMediumParameters request data structure.
+ */
+struct pldm_rde_negotiate_medium_parameters_req
+{
+    uint32_t mc_maximum_transfer_chunk_size_bytes;
+} __attribute__((packed));
+
+/**
+ * @brief NegotiateMediumParameters response data structure.
+ */
+struct pldm_rde_negotiate_medium_parameters_resp
+{
+    uint8_t completion_code;
+    uint32_t device_maximum_transfer_chunk_size_bytes;
+} __attribute__((packed));
+
+/**
+ * @brief GetSchemaDictionary request data structure.
+ */
+struct pldm_rde_get_schema_dictionary_req
+{
+    uint32_t resource_id;
+    uint8_t requested_schema_class;
+} __attribute__((packed));
+
+/**
+ * @brief GetSchemaDictionary response data structure.
+ */
+struct pldm_rde_get_schema_dictionary_resp
+{
+    uint8_t completion_code;
+    uint8_t dictionary_format;
+    uint32_t transfer_handle;
+} __attribute__((packed));
+
+/**
+ * @brief RDEMultipartReceive request data structure.
+ */
+struct pldm_rde_multipart_receive_req
+{
+    uint32_t data_transfer_handle;
+    uint16_t operation_id;
+    uint8_t transfer_operation;
+} __attribute__((packed));
+
+/**
+ * @brief RDEMultipartReceive response data structure.
+ */
+struct pldm_rde_multipart_receive_resp
+{
+    uint8_t completion_code;
+    uint8_t transfer_flag;
+    uint32_t next_data_transfer_handle;
+    uint32_t data_length_bytes;
+    uint8_t payload[1];
+} __attribute__((packed));
+
+/**
+ * @brief OperationFlags used in RDEOperationInit request data structure.
+ */
+union pldm_rde_operation_flags
+{
+    uint8_t byte;
+    struct
+    {
+        uint8_t locator_valid : 1;
+        uint8_t contains_request_payload : 1;
+        uint8_t contains_custom_request_parameters : 1;
+        uint8_t excerpt_flag : 1;
+        uint8_t reserved : 4;
+    } __attribute__((packed)) bits;
+};
+
+/**
+ * @brief RDEOperationInit request data structure.
+ */
+struct pldm_rde_operation_init_req
+{
+    uint32_t resource_id;
+    uint16_t operation_id;
+    uint8_t operation_type;
+    union pldm_rde_operation_flags operation_flags;
+    uint32_t send_data_transfer_handle;
+    uint8_t operation_locator_length;
+    uint32_t request_payload_length;
+    // Variable length data: bejLocator and the payload.
+    uint8_t var_data[1];
+} __attribute__((packed));
+
+/**
+ * @brief OperationExecutionFlags used in RDEOperationInit and
+ * RDEOperationStatus response data structures.
+ */
+union pldm_rde_op_execution_flags
+{
+    uint8_t byte;
+    struct
+    {
+        uint8_t task_spawned : 1;
+        uint8_t have_custom_response_parameters : 1;
+        uint8_t have_result_payload : 1;
+        uint8_t cache_allowed : 1;
+        uint8_t reserved : 4;
+    } __attribute__((packed)) bits;
+};
+
+/**
+ * @brief PermissionFlags used in RDEOperationInit and RDEOperationStatus
+ * response data structures.
+ */
+union pldm_rde_permission_flags
+{
+    uint8_t byte;
+    struct
+    {
+        uint8_t read_allowed : 1;
+        uint8_t update_allowed : 1;
+        uint8_t replace_allowed : 1;
+        uint8_t create_allowed : 1;
+        uint8_t delete_allowed : 1;
+        uint8_t head_allowed : 1;
+        uint8_t reserved : 2;
+    } __attribute__((packed)) bits;
+};
+
+/**
+ * @brief RDEOperationInit response data structure.
+ */
+struct pldm_rde_operation_init_resp
+{
+    uint8_t completion_code;
+    uint8_t operation_status;
+    uint8_t completion_percentage;
+    uint32_t completion_time_seconds;
+    union pldm_rde_op_execution_flags operation_execution_flags;
+    uint32_t result_transfer_handle;
+    union pldm_rde_permission_flags permission_flags;
+    uint32_t response_payload_length;
+    // Variable length data: varstring and the payload.
+    uint8_t var_data[1];
+} __attribute__((packed));
+
+/**
+ * @brief RDEOperationComplete request data structure.
+ */
+struct pldm_rde_operation_complete_req
+{
+    uint32_t resource_id;
+    uint16_t operation_id;
+} __attribute__((packed));
+
+/**
+ * @brief RDEOperationComplete response data structure.
+ */
+struct pldm_rde_operation_complete_resp
+{
+    uint8_t completion_code;
+} __attribute__((packed));
+
+/**
+ * @brief RDEOperationStatus request data structure.
+ */
+struct pldm_rde_operation_status_req
+{
+    uint32_t resource_id;
+    uint16_t operation_id;
+} __attribute__((packed));
+
+/**
+ * @brief RDEOperationStatus response data structure.
+ */
+struct pldm_rde_operation_status_resp
+{
+    uint8_t completion_code;
+    uint8_t operation_status;
+    uint8_t completion_percentage;
+    uint32_t completion_time_seconds;
+    union pldm_rde_op_execution_flags operation_execution_flags;
+    uint32_t result_transfer_handle;
+    union pldm_rde_permission_flags permission_flags;
+    uint32_t response_payload_length;
+    // Variable length data: varstring and the payload.
+    uint8_t var_data[1];
+} __attribute__((packed));
+
+struct pldm_rde_device_info
+{
+    uint8_t device_concurrency;
+    bitfield8_t device_capabilities_flag;
+    bitfield16_t device_feature_support;
+    uint32_t device_configuration_signature;
+    struct pldm_rde_varstring device_provider_name;
+    uint32_t device_maximum_transfer_chunk_size; // in bytes
+};
+
+/**
+ * @brief Encode NegotiateRedfishParameters request.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] concurrency_support - MC concurrency support.
+ * @param[in] feature_support - MC feature support flags.
+ * @param[out] msg - Request message.
+ * @return pldm_completion_codes.
+ */
+int encode_negotiate_redfish_parameters_req(uint8_t instance_id,
+                                            uint8_t concurrency_support,
+                                            bitfield16_t* feature_support,
+                                            struct pldm_msg* msg);
+
+/**
+ * @brief Decode NegotiateRedfishParameters request.
+ *
+ * @param[in] msg - Request message.
+ * @param[in] payload_length - Length of request message payload.
+ * @param[out] mc_concurrency_support - Pointer to a uint8_t variable.
+ * @param[out] mc_feature_support - Pointer to a bitfield16_t variable.
+ * @return pldm_completion_codes.
+ */
+int decode_negotiate_redfish_parameters_req(const struct pldm_msg* msg,
+                                            size_t payload_length,
+                                            uint8_t* mc_concurrency_support,
+                                            bitfield16_t* mc_feature_support);
+
+/**
+ * @brief Create a PLDM response message for NegotiateRedfishParameters.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] completion_code - PLDM completion code.
+ * @param[in] device_concurrency_support - Concurrency support.
+ * @param[in] device_capabilities_flags - Capabilities flags.
+ * @param[in] device_feature_support - Feature support flags.
+ * @param[in] device_configuration_signature - RDE device signature.
+ * @param[in] device_provider_name - Null terminated device provider name.
+ * @param[in] name_format - String format of the device_provider_name.
+ * @param[out] msg - Response message will be written to this.
+ * @return pldm_completion_codes.
+ */
+int encode_negotiate_redfish_parameters_resp(
+    uint8_t instance_id, uint8_t completion_code,
+    uint8_t device_concurrency_support, bitfield8_t device_capabilities_flags,
+    bitfield16_t device_feature_support,
+    uint32_t device_configuration_signature, const char* device_provider_name,
+    enum pldm_rde_varstring_format name_format, struct pldm_msg* msg);
+
+/**
+ * @brief Decode NegotiateRedfishParameters Response.
+ *
+ * @param[in] msg - Request message.
+ * @param[in] payload_length - Length of request message payload.
+ * @param[out] completion_code - Completion code as set by the responder.
+ * @param[out] device - Device Info as sent in the response (Memory to be
+ * manager by the caller).
+ * @return pldm_completion_codes.
+ */
+int decode_negotiate_redfish_parameters_resp(
+    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
+    struct pldm_rde_device_info* device);
+
+/**
+ * @brief Encode NegotiateMediumParameters request.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] maximum_transfer_size - Maximum amount of data the MC can
+ * support for a single message transfer.
+ * @param[out] msg - Request message.
+ * @return pldm_completion_codes.
+ */
+int encode_negotiate_medium_parameters_req(uint8_t instance_id,
+                                           uint32_t maximum_transfer_size,
+                                           struct pldm_msg* msg);
+
+/**
+ * @brief Decode NegotiateMediumParameters request.
+ *
+ * @param[in] msg - Request message.
+ * @param[in] payload_length - Length of request message payload.
+ * @param[out] mc_maximum_transfer_size - Pointer to a uint32_t variable.
+ * @return pldm_completion_codes.
+ */
+int decode_negotiate_medium_parameters_req(const struct pldm_msg* msg,
+                                           size_t payload_length,
+                                           uint32_t* mc_maximum_transfer_size);
+
+/**
+ * @brief Create a PLDM response message for NegotiateMediumParameters.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] completion_code - PLDM completion code.
+ * @param[in] device_maximum_transfer_bytes - Device maximum transfer byte
+ * support.
+ * @param[out] msg - Response message will be written to this.
+ * @return pldm_completion_codes.
+ */
+int encode_negotiate_medium_parameters_resp(
+    uint8_t instance_id, uint8_t completion_code,
+    uint32_t device_maximum_transfer_bytes, struct pldm_msg* msg);
+
+/**
+ * @brief Decode Negotiate Medium Parameters response
+ *
+ * @param[in] msg: PLDM Msg byte array received from the responder
+ * @param[in] payload_length: Length of the payload
+ * @param[out] completion_code: Completion code as set by the responder
+ * @param[out] device_maximum_transfer_bytes: Max bytes device can transfer
+ */
+int decode_negotiate_medium_parameters_resp(
+    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
+    uint32_t* device_maximum_transfer_bytes);
+
+/**
+ * @brief Encode GetSchemaDictionary request.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] resource_id - The ResourceID of any resource in the Redfish
+ * Resource PDR.
+ * @param[in] schema_class - The class of schema being requested.
+ * @param[out] msg - Request message.
+ * @return pldm_completion_codes.
+ */
+int encode_get_schema_dictionary_req(uint8_t instance_id, uint32_t resource_id,
+                                     uint8_t schema_class,
+                                     struct pldm_msg* msg);
+
+/**
+ * @brief Decode GetSchemaDictionary request.
+ *
+ * @param[in] msg - Request message.
+ * @param[in] payload_length - Length of request message payload.
+ * @param[out] resource_id - Pointer to a uint32_t variable.
+ * @param[out] requested_schema_class - Pointer to a uint8_t variable.
+ * @return pldm_completion_codes.
+ */
+int decode_get_schema_dictionary_req(const struct pldm_msg* msg,
+                                     size_t payload_length,
+                                     uint32_t* resource_id,
+                                     uint8_t* requested_schema_class);
+
+/**
+ * @brief Encode GetSchemaDictionary response.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] completion_code - PLDM completion code.
+ * @param[in] dictionary_format - The format of the dictionary.
+ * @param[in] transfer_handle - A data transfer handle that the MC shall
+ * use.
+ * @param[out] msg - Response message will be written to this.
+ * @return pldm_completion_codes.
+ */
+int encode_get_schema_dictionary_resp(uint8_t instance_id,
+                                      uint8_t completion_code,
+                                      uint8_t dictionary_format,
+                                      uint32_t transfer_handle,
+                                      struct pldm_msg* msg);
+
+/**
+ * @brief Decode Get Schema Dictionary Response
+ *
+ * @param[in] msg - Response Message
+ * @param[in] payload_length - Length of the payload
+ * @param[out] completion_code - Completion Code
+ * @param[out] dictionary_format - Dictionary Format for the particular
+ * resource id
+ * @param[out] transfer_handle - Transfer Handle to be used to get
+ * dictionary
+ */
+int decode_get_schema_dictionary_resp(const struct pldm_msg* msg,
+                                      size_t payload_length,
+                                      uint8_t* completion_code,
+                                      uint8_t* dictionary_format,
+                                      uint32_t* transfer_handle);
+
+/**
+ * @brief Encode RDEMultipartReceive request.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] data_transfer_handle - A handle to uniquely identify the chunk
+ * of data to be retrieved.
+ * @param[in] operation_id - Identification number for this operation.
+ * @param[in] transfer_operation - The portion of data requested for the
+ * transfer.
+ * @param[out] msg - Request will be written to this.
+ * @return pldm_completion_codes.
+ */
+int encode_rde_multipart_receive_req(uint8_t instance_id,
+                                     uint32_t data_transfer_handle,
+                                     uint16_t operation_id,
+                                     uint8_t transfer_operation,
+                                     struct pldm_msg* msg);
+
+/**
+ * @brief Decode RDEMultipartReceive request.
+ *
+ * @param[in] msg - Request message.
+ * @param[in] payload_length - Length of request message payload.
+ * @param[out] data_transfer_handle - A handle to uniquely identify the
+ * chunk of data to be retrieved.
+ * @param[out] operation_id - Identification number for this operation.
+ * @param[out] transfer_operation - The portion of data requested for the
+ * transfer.
+ * @return pldm_completion_codes.
+ */
+int decode_rde_multipart_receive_req(const struct pldm_msg* msg,
+                                     size_t payload_length,
+                                     uint32_t* data_transfer_handle,
+                                     uint16_t* operation_id,
+                                     uint8_t* transfer_operation);
+
+/**
+ * @brief Encode RDEMultipartReceive response.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] completion_code - PLDM completion code.
+ * @param[in] transfer_flag - The portion of data being sent to MC.
+ * @param[in] next_data_transfer_handle - A handle to uniquely identify the
+ * next chunk of data to be retrieved.
+ * @param[in] data_length_bytes - Length of the payload.
+ * @param[in] add_checksum - Indicate whether the payload needs to include
+ * the provided checksum.
+ * @param[in] checksum - Checksum.
+ * @param[in] payload - Pointer to the payload.
+ * @param[out] msg - Response message will be written to this.
+ * @return pldm_completion_codes.
+ */
+int encode_rde_multipart_receive_resp(
+    uint8_t instance_id, uint8_t completion_code, uint8_t transfer_flag,
+    uint32_t next_data_transfer_handle, uint32_t data_length_bytes,
+    bool add_checksum, uint32_t checksum, const uint8_t* payload,
+    struct pldm_msg* msg);
+
+/**
+ * @brief Decode RDE Multipart Receive Response
+ *
+ * @param[in] msg - Response message
+ * @param[in] payload_length - Expected length of the response, since the
+ * response could be equal to the negotiated transfer chunk size, the
+ * requester should usually set it to the negotiated transfer size
+ * @param[out] completion_code - Completion code of the response set by RDE
+ * @param[out] ret_transfer_flag - Transfer flag returned by RDE
+ * @param[out] ret_transfer_operation - Transfer operation returned by RDE
+ * @param[out] data_length_bytes - The length of the payload in response
+ * @param[out] payload - Pointer to the payload
+ */
+int decode_rde_multipart_receive_resp(
+    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
+    uint8_t* ret_transfer_flag, uint32_t* ret_data_transfer_handle,
+    uint32_t* data_length_bytes, uint8_t** payload);
+
+/**
+ * @brief Encode RDEOperationInit request.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] resource_id - The ResourceID.
+ * @param[in] operation_id - Identification number for this operation.
+ * @param[in] operation_type - The type of Redfish Operation being
+ * performed.
+ * @param[in] operation_flags - Flags associated with this Operation.
+ * @param[in] send_data_transfer_handle - Handle to be used with the first
+ * RDEMultipartSend command.
+ * @param[in] operation_locator_length - Length of the OperationLocator for
+ * this Operation.
+ * @param[in] request_payload_length - Length of the request payload in this
+ * message.
+ * @param[in] operation_locator - BEJ locator indicating where the new
+ * Operation is to take place within the resource.
+ * @param[in] request_payload - The request payload.
+ * @param[out] msg - Request will be written to this.
+ * @return pldm_completion_codes.
+ */
+int encode_rde_operation_init_req(
+    uint8_t instance_id, uint32_t resource_id, uint16_t operation_id,
+    uint8_t operation_type,
+    const union pldm_rde_operation_flags* operation_flags,
+    uint32_t send_data_transfer_handle, uint8_t operation_locator_length,
+    uint32_t request_payload_length, const uint8_t* operation_locator,
+    uint8_t* request_payload, struct pldm_msg* msg);
+
+/**
+ * @brief Decode RDEOperationInit request.
+ *
+ * @param[in] msg - Request message.
+ * @param[in] payload_length - Length of request message payload.
+ * @param[out] resource_id - The ResourceID.
+ * @param[out] operation_id - Identification number for this operation.
+ * @param[out] operation_type - The type of Redfish Operation being
+ * performed.
+ * @param[out] operation_flags  - Flags associated with this Operation.
+ * @param[out] send_data_transfer_handle - Handle to be used with the first
+ * RDEMultipartSend command.
+ * @param[out] operation_locator_length - Length of the OperationLocator for
+ * this Operation.
+ * @param[out] request_payload_length - Length of the request payload in
+ * this message.
+ * @param[out] operation_locator - BEJ locator indicating where the new
+ * Operation is to take place within the resource.
+ * @param[out] request_payload - The request payload.
+ * @return pldm_completion_codes.
+ */
+int decode_rde_operation_init_req(
+    const struct pldm_msg* msg, size_t payload_length, uint32_t* resource_id,
+    uint16_t* operation_id, uint8_t* operation_type,
+    union pldm_rde_operation_flags* operation_flags,
+    uint32_t* send_data_transfer_handle, uint8_t* operation_locator_length,
+    uint32_t* request_payload_length, uint8_t** operation_locator,
+    uint8_t** request_payload);
+
+/**
+ * @brief Encode RDEOperationInit response.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] completion_code - PLDM completion code.
+ * @param[in] operation_status - Status of the operation.
+ * @param[in] completion_percentage - Percentage complete.
+ * @param[in] completion_time_seconds - An estimate of the number of seconds
+ * remaining before the Operation is completed.
+ * @param[in] operation_execution_flags - Explains the result of operation.
+ * @param[in] result_transfer_handle - A data transfer handle that the MC
+ * may use to retrieve a larger response payload.
+ * @param[in] permission_flags - Indicates the access level granted to the
+ * resource targeted by the Operation.
+ * @param[in] response_payload_length - Length of the response payload.
+ * @param[in] etag_format - Format of the etag string.
+ * @param[in] etag - ETag.
+ * @param[in] response_payload - The response payload if the payload fits.
+ * @param[out] msg - Response message will be written to this.
+ * @return pldm_completion_codes.
+ */
+int encode_rde_operation_init_resp(
+    uint8_t instance_id, uint8_t completion_code, uint8_t operation_status,
+    uint8_t completion_percentage, uint32_t completion_time_seconds,
+    const union pldm_rde_op_execution_flags* operation_execution_flags,
+    uint32_t result_transfer_handle,
+    const union pldm_rde_permission_flags* permission_flags,
+    uint32_t response_payload_length,
+    enum pldm_rde_varstring_format etag_format, const char* etag,
+    const uint8_t* response_payload, struct pldm_msg* msg);
+
+/**
+ * @brief Decode RDEOperationInit Resp
+ */
+int decode_rde_operation_init_resp(
+    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
+    uint8_t* completion_percentage, uint8_t* operation_status,
+    uint32_t* completion_time_seconds, uint32_t* result_transfer_handle,
+    uint32_t* response_payload_length,
+    union pldm_rde_permission_flags** permission_flags,
+    union pldm_rde_op_execution_flags** operation_execution_flags,
+    struct pldm_rde_varstring** resp_etag, uint8_t** response_payload);
+
+/**
+ * @brief Encode RDEOperationComplete request.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] resource_id - The ResourceID.
+ * @param[in] operation_id - Identification number for this operation.
+ * @param[out] msg - Request will be written to this.
+ * @return pldm_completion_codes.
+ */
+int encode_rde_operation_complete_req(uint8_t instance_id, uint32_t resource_id,
+                                      uint16_t operation_id,
+                                      struct pldm_msg* msg);
+
+/**
+ * @brief Encode RDE Operation Kill request
+ * @param[in] instance_id - instance id of the requester
+ * @param[in] resource_id - resource id of the resource being requested
+ * @param[in] operation_id - operation id of the request
+ * @param[out] msg - Request will be written to this
+ */
+int encode_rde_operation_kill_req(uint8_t instance_id, uint32_t resource_id,
+                                  uint16_t operation_id, struct pldm_msg* msg);
+
+/**
+ * @brief Decode RDEOperationComplete request.
+ *
+ * @param[in] msg - Request message.
+ * @param[in] payload_length - Length of request message payload.
+ * @param[out] resource_id - The ResourceID.
+ * @param[out] operation_id - Identification number for this operation.
+ * @return pldm_completion_codes.
+ */
+int decode_rde_operation_complete_req(const struct pldm_msg* msg,
+                                      size_t payload_length,
+                                      uint32_t* resource_id,
+                                      uint16_t* operation_id);
+
+/**
+ * @brief Encode RDEOperationComplete 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_complete_resp(uint8_t instance_id,
+                                       uint8_t completion_code,
+                                       struct pldm_msg* msg);
+
+/**
+ * @brief Encode RDEOperationComplete 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 decode_rde_operation_complete_resp(const struct pldm_msg* msg,
+                                       size_t payload_length,
+                                       uint8_t* completion_code);
+
+/**
+ * @brief Encode RDEOperationStatus request.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] resource_id - The ResourceID.
+ * @param[in] operation_id - Identification number for this operation.
+ * @param[out] msg - Request will be written to this.
+ * @return pldm_completion_codes.
+ */
+int encode_rde_operation_status_req(uint8_t instance_id, uint32_t resource_id,
+                                    uint16_t operation_id,
+                                    struct pldm_msg* msg);
+
+/**
+ * @brief Decode RDEOperationStatus request.
+ *
+ * @param[in] msg - Request message.
+ * @param[in] payload_length - Length of request message payload.
+ * @param[out] resource_id - The ResourceID.
+ * @param[out] operation_id - Identification number for this operation.
+ * @return pldm_completion_codes.
+ */
+int decode_rde_operation_status_req(const struct pldm_msg* msg,
+                                    size_t payload_length,
+                                    uint32_t* resource_id,
+                                    uint16_t* operation_id);
+
+/**
+ * @brief Encode RDEOperationStatus response.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] completion_code - PLDM completion code.
+ * @param[in] operation_status - Status of the operation.
+ * @param[in] completion_percentage - Percentage complete.
+ * @param[in] completion_time_seconds - An estimate of the number of seconds
+ * remaining before the Operation is completed.
+ * @param[in] operation_execution_flags - Explains the result of operation.
+ * @param[in] result_transfer_handle - A data transfer handle that the MC
+ * may use to retrieve a larger response payload.
+ * @param[in] permission_flags - Indicates the access level granted to the
+ * resource targeted by the Operation.
+ * @param[in] response_payload_length - Length of the response payload.
+ * @param[in] etag_format - Format of the etag string.
+ * @param[in] etag - ETag.
+ * @param[in] response_payload - The response payload if the payload fits.
+ * @param[out] msg - Response message will be written to this.
+ * @return pldm_completion_codes.
+ */
+int encode_rde_operation_status_resp(
+    uint8_t instance_id, uint8_t completion_code, uint8_t operation_status,
+    uint8_t completion_percentage, uint32_t completion_time_seconds,
+    const union pldm_rde_op_execution_flags* operation_execution_flags,
+    uint32_t result_transfer_handle,
+    const union pldm_rde_permission_flags* permission_flags,
+    uint32_t response_payload_length,
+    enum pldm_rde_varstring_format etag_format, const char* etag,
+    const uint8_t* response_payload, struct pldm_msg* msg);
+
+/**
+ * @brief Encode RDEOperationStatus response.
+ *
+ * @param[in] instance_id - Message's instance id.
+ * @param[in] completion_code - PLDM completion code.
+ * @param[in] operation_status - Status of the operation.
+ * @param[in] completion_percentage - Percentage complete.
+ * @param[in] completion_time_seconds - An estimate of the number of seconds
+ * remaining before the Operation is completed.
+ * @param[in] operation_execution_flags - Explains the result of operation.
+ * @param[in] result_transfer_handle - A data transfer handle that the MC
+ * may use to retrieve a larger response payload.
+ * @param[in] permission_flags - Indicates the access level granted to the
+ * resource targeted by the Operation.
+ * @param[in] response_payload_length - Length of the response payload.
+ * @param[in] etag_format - Format of the etag string.
+ * @param[in] etag - ETag.
+ * @param[in] response_payload - The response payload if the payload fits.
+ * @param[out] msg - Response message will be written to this.
+ * @return pldm_completion_codes.
+ */
+int decode_rde_operation_status_resp(
+    const struct pldm_msg* msg, size_t payload_length, uint8_t* completion_code,
+    uint8_t* completion_percentage, uint8_t* operation_status,
+    uint32_t* completion_time_seconds, uint32_t* result_transfer_handle,
+    uint32_t* response_payload_length,
+    union pldm_rde_permission_flags** permission_flags,
+    union pldm_rde_op_execution_flags** operation_execution_flags,
+    struct pldm_rde_varstring** resp_etag, uint8_t** payload);
+#endif // PLDM_RDE_HPP
diff --git a/meson.build b/meson.build
index be7fb71..1fe2184 100644
--- a/meson.build
+++ b/meson.build
@@ -10,6 +10,7 @@
 sources = [
   'rded.cpp',
   'interface/pldm_interface.cpp',
+  'interface/pldm_rde.cpp',
   'util/matcher/rde_match_handler.cpp',
   'util/state_machine/discovery/base/base_disc_state_machine.cpp',
 ]