blob: 2cb45383f1dd0f23da0fadd1df96c89de886e698 [file]
From fc86526273db3d1b7ebe271bbdf648c8c07878e3 Mon Sep 17 00:00:00 2001
From: Harsh Tyagi <harshtya@google.com>
Date: Wed, 16 Aug 2023 18:21:48 +0000
Subject: [PATCH] Add support for dictionary extraction for resources and RDE
Operation
Tested:
Testing done on dev machine for extracting dictionaries
Patch Tracking Bug: 293472370
Upstream-Status: Pending
Upstream info / review: https://gerrit.openbmc.org/c/openbmc/libpldm/+/65474
Justification: (Design under review)
https://gerrit.openbmc.org/c/openbmc/docs/+/61256
---
include/libpldm/pldm_rde.h | 20 +
.../libpldm/requester/pldm_rde_requester.h | 182 +++++
src/pldm_rde.c | 89 ++-
src/requester/pldm.c | 10 +-
src/requester/pldm_rde_requester.c | 528 ++++++++++++++
tests/requester/rde_requester_test.cpp | 650 ++++++++++++++----
6 files changed, 1318 insertions(+), 161 deletions(-)
diff --git a/include/libpldm/pldm_rde.h b/include/libpldm/pldm_rde.h
index 462c395..3b8c1e8 100644
--- a/include/libpldm/pldm_rde.h
+++ b/include/libpldm/pldm_rde.h
@@ -45,6 +45,7 @@ enum pldm_rde_commands {
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,
};
@@ -159,6 +160,15 @@ enum pldm_rde_device_feature {
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.
*/
@@ -698,6 +708,16 @@ int decode_rde_operation_init_resp(
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.
*
diff --git a/include/libpldm/requester/pldm_rde_requester.h b/include/libpldm/requester/pldm_rde_requester.h
index 09b2de7..358cfab 100644
--- a/include/libpldm/requester/pldm_rde_requester.h
+++ b/include/libpldm/requester/pldm_rde_requester.h
@@ -119,6 +119,42 @@ struct rde_read_operation {
uint8_t completion_code;
};
+/**
+ * @brief RDE operation
+ */
+struct rde_operation {
+ uint8_t request_id;
+ uint32_t resource_id;
+ uint16_t operation_id;
+ uint8_t operation_type;
+ uint8_t operation_status;
+ uint8_t percentage_complete;
+ uint32_t completion_time;
+ uint32_t result_transfer_handle;
+
+ // Request Data
+ union pldm_rde_operation_flags operation_flags;
+ uint32_t send_data_transfer_handle;
+ uint8_t operation_locator_length;
+ uint8_t *operation_locator;
+ uint32_t request_payload_length;
+ uint8_t *request_payload;
+
+ // Response Data
+ uint32_t resp_payload_length;
+ uint8_t *response_data;
+ union pldm_rde_op_execution_flags *resp_operation_flags;
+ union pldm_rde_permission_flags *resp_permission_flags;
+ struct pldm_rde_varstring *resp_etag;
+
+ // For multipart receive
+ uint32_t transfer_handle;
+ uint8_t transfer_operation;
+
+ // op complete
+ uint8_t completion_code;
+};
+
/**
* @brief RDE Requester context
*/
@@ -252,6 +288,152 @@ pldm_rde_requester_rc_t pldm_rde_get_next_discovery_command(
pldm_rde_requester_rc_t
pldm_rde_create_context(struct pldm_rde_requester_context *current_ctx);
+/**
+ * @brief Initializes the context to trigger dictionary schema RDE ops
+ *
+ * @param[in] ctx - RDE Requester context to be initialized and set the state to
+ * trigger Dictionary Operations over RDE/PLDM
+ *
+ * @return pldm_requester_rc_t (errno may be set)
+ */
+pldm_rde_requester_rc_t
+pldm_rde_init_get_dictionary_schema(struct pldm_rde_requester_context *ctx);
+
+/**
+ * @brief Gets the next command in sequence required to extract dictionaries
+ * from the RDE Device for the given resources
+ *
+ * @param[in] instance_id - Instance ID corresponding to the request
+ * @param[in] manager - Context Manager
+ * @param[in] current_ctx - RDE Request Context
+ * @param[out] request - Request object that would hold the encoded request
+ * message for the requester to send
+ *
+ * @return pldm_requester_rc_t (errno may be set)
+ */
+pldm_rde_requester_rc_t pldm_rde_get_next_dictionary_schema_command(
+ uint8_t instance_id, struct pldm_rde_requester_manager *manager,
+ struct pldm_rde_requester_context *current_ctx, struct pldm_msg *request);
+
+/**
+ * @brief Pushes the response received into current context, updates the state
+ * of the context and/or returns the response payload back to the requester
+ *
+ * @param[in] manager - Context Manager
+ * @param[in] ctx - RDE Request Context
+ * @param[in] resp_msg - Response received from the RDE Device
+ * @param[in] resp_size - Size of the response message
+ * @param[in] callback - Pointer to a function that would be executed over the
+ * response payload as per requester's requirement
+ *
+ * @return pldm_requester_rc_t (errno may be set)
+ */
+pldm_rde_requester_rc_t pldm_rde_push_get_dictionary_response(
+ struct pldm_rde_requester_manager *manager,
+ struct pldm_rde_requester_context *ctx, void *resp_msg, size_t resp_size,
+ callback_funct callback);
+
+/**
+ * @brief Initialize RDE operation context for performing any RDE operation
+ * More about the terms in the spec:
+ * https://www.dmtf.org/sites/default/files/standards/documents/DSP0218_1.1.0.pdf
+ *
+ * @param[in] ctx - Current context to be initialized
+ * @param[in] request_id - Unique request ID for the request
+ * @param[in] resource_id - Resource id of the PDR resource RDE operation is to
+ * be performed on
+ * @param[in] operation_id - Each RDE operation has an operation ID
+ * @param[in] operation_type - Operation type (READ, UPDATE, etc)
+ * @param[in] operation_flags - Operation flags required by the RDE operation
+ * @param[in] send_data_transfer_handle - Transfer handle (usually required if
+ * there is a large request payload)
+ * @param[in] operation_locator_length - Operation Locator length
+ * @param[in] request_payload_length - Request payload length
+ * @param[in] operation_locator - operation locator
+ * @param[in] request_payload - pointer Request payload buffer
+ *
+ * @return pldm_requester_rc_t (errno may be set)
+ */
+pldm_rde_requester_rc_t pldm_rde_init_rde_operation_context(
+ struct pldm_rde_requester_context *ctx, uint8_t request_id,
+ uint32_t resource_id, uint16_t operation_id, uint8_t operation_type,
+ uint8_t op_flags_byte, 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 Get next RDE operation in sequence to cater to a RDE request
+ *
+ * @param[in] instance_id - Instance id corresponding to the request
+ * @param[in] manager - Context Manager to perform RDE operation on the device
+ * @param[in] current_ctx - Current context to perform RDE operation
+ * @param[out] request - Pointer to request message where the encoded pldm msg
+ * would be stored
+ *
+ * @return pldm_requester_rc_t (errno may be set)
+ */
+pldm_rde_requester_rc_t
+pldm_rde_get_next_rde_operation(uint8_t instance_id,
+ struct pldm_rde_requester_manager *manager,
+ struct pldm_rde_requester_context *current_ctx,
+ struct pldm_msg *request);
+
+/**
+ * @brief Pushes the RDE response received back to the requester via callback
+ * function and also updates the context with the required state to complete the
+ * RDE operation
+ *
+ * @param[in] manager - Context Manager
+ * @param[in] ctx - Context for performing RDE operation
+ * @param[in] resp_msg - Response received after performing RDE operation
+ * @param[in] resp_size - Size of the response received
+ * @param[in] callback - Callback function to be executed on the response
+ *
+ * @return pldm_requester_rc_t (errno may be set)
+ */
+pldm_rde_requester_rc_t pldm_rde_push_read_operation_response(
+ struct pldm_rde_requester_manager *manager,
+ struct pldm_rde_requester_context *ctx, void *resp_msg,
+ size_t resp_size, callback_funct callback);
+
+/**
+ * @brief Cleanup memory after RDE Operation completes (Succeeds/Fails)
+ * Needs to be called after every rde_operation_init once RDE Operation init is
+ * completed
+ *
+ * @param[in] ctx - Requester context holds RDE operation context to be cleared
+ *
+ * @return pldm_requester_rc_t (errno may be set)
+*/
+pldm_rde_requester_rc_t
+free_rde_op_init_context(struct pldm_rde_requester_context *ctx);
+
+/**
+ * @brief Cleanup PDR memory after dictioanry extraction
+*/
+pldm_rde_requester_rc_t free_op_context_after_dictionary_extraction(
+ struct pldm_rde_requester_context *ctx);
+
+/**
+ * =============== Workaround begins for b/293742455 ===================
+ */
+/**
+ * @brief Provides the RDE Op complete request encoded
+ */
+pldm_rde_requester_rc_t get_pldm_rde_operation_complete_request(
+ uint8_t instance_id, struct pldm_rde_requester_context *current_ctx,
+ struct pldm_msg *request);
+
+/**
+ * @brief Provides the RDE Op Kill request encoded
+ */
+pldm_rde_requester_rc_t get_pldm_rde_operation_kill_request(
+ uint8_t instance_id, struct pldm_rde_requester_context *current_ctx,
+ struct pldm_msg *request);
+/**
+ * =============== Workaround ends for b/293742455 ===================
+ */
+
#ifdef __cplusplus
}
#endif
diff --git a/src/pldm_rde.c b/src/pldm_rde.c
index 90d31cc..4d1e3de 100644
--- a/src/pldm_rde.c
+++ b/src/pldm_rde.c
@@ -5,6 +5,7 @@
#include <stdlib.h>
#include <string.h>
+LIBPLDM_ABI_STABLE
int encode_negotiate_redfish_parameters_resp(
uint8_t instance_id, uint8_t completion_code,
uint8_t device_concurrency_support, bitfield8_t device_capabilities_flags,
@@ -47,6 +48,7 @@ int encode_negotiate_redfish_parameters_resp(
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int encode_negotiate_redfish_parameters_req(uint8_t instance_id,
uint8_t concurrency_support,
bitfield16_t *feature_support,
@@ -72,6 +74,7 @@ int encode_negotiate_redfish_parameters_req(uint8_t instance_id,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int decode_negotiate_redfish_parameters_req(const struct pldm_msg *msg,
size_t payload_length,
uint8_t *mc_concurrency_support,
@@ -96,6 +99,7 @@ int decode_negotiate_redfish_parameters_req(const struct pldm_msg *msg,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int encode_negotiate_medium_parameters_resp(
uint8_t instance_id, uint8_t completion_code,
uint32_t device_maximum_transfer_bytes, struct pldm_msg *msg)
@@ -123,6 +127,7 @@ int encode_negotiate_medium_parameters_resp(
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
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)
@@ -134,6 +139,9 @@ int decode_negotiate_redfish_parameters_resp(
*completion_code = msg->payload[0];
if (PLDM_SUCCESS != *completion_code) {
+ fprintf(stderr,
+ "Unsuccessful completion code received in neg. params: %x\n",
+ (uint8_t)(*completion_code));
return PLDM_SUCCESS;
}
@@ -154,6 +162,7 @@ int decode_negotiate_redfish_parameters_resp(
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
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)
@@ -166,6 +175,9 @@ int decode_negotiate_medium_parameters_resp(
*completion_code = msg->payload[0];
if (PLDM_SUCCESS != *completion_code) {
+ fprintf(stderr,
+ "Unsuccessful completion code received in neg med params: %x\n",
+ (uint8_t)(*completion_code));
return PLDM_SUCCESS;
}
@@ -182,6 +194,7 @@ int decode_negotiate_medium_parameters_resp(
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int encode_negotiate_medium_parameters_req(uint8_t instance_id,
uint32_t maximum_transfer_size,
struct pldm_msg *msg)
@@ -205,6 +218,7 @@ int encode_negotiate_medium_parameters_req(uint8_t instance_id,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int decode_negotiate_medium_parameters_req(const struct pldm_msg *msg,
size_t payload_length,
uint32_t *mc_maximum_transfer_size)
@@ -226,6 +240,7 @@ int decode_negotiate_medium_parameters_req(const struct pldm_msg *msg,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int encode_get_schema_dictionary_req(uint8_t instance_id, uint32_t resource_id,
uint8_t schema_class, struct pldm_msg *msg)
{
@@ -248,6 +263,7 @@ int encode_get_schema_dictionary_req(uint8_t instance_id, uint32_t resource_id,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int decode_get_schema_dictionary_req(const struct pldm_msg *msg,
size_t payload_length,
uint32_t *resource_id,
@@ -271,6 +287,7 @@ int decode_get_schema_dictionary_req(const struct pldm_msg *msg,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int encode_get_schema_dictionary_resp(uint8_t instance_id,
uint8_t completion_code,
uint8_t dictionary_format,
@@ -300,6 +317,7 @@ int encode_get_schema_dictionary_resp(uint8_t instance_id,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int decode_get_schema_dictionary_resp(const struct pldm_msg *msg,
size_t payload_length,
uint8_t *completion_code,
@@ -314,12 +332,14 @@ int decode_get_schema_dictionary_resp(const struct pldm_msg *msg,
*completion_code = msg->payload[0];
if (PLDM_SUCCESS != *completion_code) {
- fprintf(stderr, "COMPLETION CODE ERROR\n");
+ fprintf(stderr, "Unsuccessful completion code received in schema: %x\n",
+ (uint8_t)(*completion_code));
return PLDM_SUCCESS;
}
if (payload_length < RDE_GET_DICTIONARY_SCHEMA_RESP_BYTES) {
- fprintf(stderr, "RESPONSE INVALID LEN CODE ERROR\n");
+ fprintf(stderr, "Unsuccessful completion code received %x",
+ (uint8_t)(*completion_code));
return PLDM_ERROR_INVALID_LENGTH;
}
@@ -330,6 +350,7 @@ int decode_get_schema_dictionary_resp(const struct pldm_msg *msg,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int encode_rde_multipart_receive_req(uint8_t instance_id,
uint32_t data_transfer_handle,
uint16_t operation_id,
@@ -356,6 +377,7 @@ int encode_rde_multipart_receive_req(uint8_t instance_id,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int decode_rde_multipart_receive_req(const struct pldm_msg *msg,
size_t payload_length,
uint32_t *data_transfer_handle,
@@ -380,6 +402,7 @@ int decode_rde_multipart_receive_req(const struct pldm_msg *msg,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
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,
@@ -419,6 +442,7 @@ int encode_rde_multipart_receive_resp(
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
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,
@@ -433,14 +457,17 @@ int decode_rde_multipart_receive_resp(
*completion_code = msg->payload[0];
if (PLDM_SUCCESS != *completion_code) {
- fprintf(stderr, "Decoded successfully with failed completion "
- "code in multipart\n");
+ fprintf(stderr,
+ "Unsuccessful completion code received in multipart: %x\n",
+ (uint8_t)(*completion_code));
return PLDM_ERROR;
}
if (payload_length < RDE_MULTIPART_RECV_MINIMUM_RESP_BYTES) {
- fprintf(stderr, "Decoded successfully with invalid payload "
- "length in multipart\n");
+ fprintf(stderr,
+ "Decoded successfully with failed payload length in multipart"
+ " with payload length: %zu and expected: %d\n",
+ payload_length, RDE_MULTIPART_RECV_MINIMUM_RESP_BYTES);
return PLDM_ERROR_INVALID_LENGTH;
}
@@ -454,6 +481,7 @@ int decode_rde_multipart_receive_resp(
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int encode_rde_operation_init_req(
uint8_t instance_id, uint32_t resource_id, uint16_t operation_id,
uint8_t operation_type,
@@ -513,6 +541,7 @@ static bool pldm_rde_is_valid_mc_op_id(uint16_t operation_id)
return true;
}
+LIBPLDM_ABI_STABLE
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,
@@ -558,6 +587,7 @@ int decode_rde_operation_init_req(
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
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,
@@ -615,6 +645,7 @@ int encode_rde_operation_init_resp(
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
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,
@@ -629,14 +660,16 @@ int decode_rde_operation_init_resp(
}
*completion_code = msg->payload[0];
if (PLDM_SUCCESS != *completion_code) {
- fprintf(stderr,
- "Decoded successfully with failed completion code\n");
+ fprintf(stderr, "Unsuccessful completion code received in op init: %x\n",
+ (uint8_t)(*completion_code));
return PLDM_SUCCESS;
}
if (payload_length < RDE_READ_OPERATION_INIT_MIN_BYTES) {
fprintf(stderr,
- "Decoded successfully with failed payload length\n");
+ "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;
}
@@ -661,6 +694,7 @@ int decode_rde_operation_init_resp(
return 0;
}
+LIBPLDM_ABI_STABLE
int encode_rde_operation_complete_req(uint8_t instance_id, uint32_t resource_id,
uint16_t operation_id,
struct pldm_msg *msg)
@@ -684,6 +718,7 @@ int encode_rde_operation_complete_req(uint8_t instance_id, uint32_t resource_id,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int decode_rde_operation_complete_req(const struct pldm_msg *msg,
size_t payload_length,
uint32_t *resource_id,
@@ -702,6 +737,7 @@ int decode_rde_operation_complete_req(const struct pldm_msg *msg,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int encode_rde_operation_complete_resp(uint8_t instance_id,
uint8_t completion_code,
struct pldm_msg *msg)
@@ -724,6 +760,7 @@ int encode_rde_operation_complete_resp(uint8_t instance_id,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int decode_rde_operation_complete_resp(const struct pldm_msg *msg,
size_t payload_length,
uint8_t *completion_code)
@@ -741,12 +778,14 @@ int decode_rde_operation_complete_resp(const struct pldm_msg *msg,
if (PLDM_SUCCESS != *completion_code) {
fprintf(stderr,
- "Decoded successfully with failed completion code\n");
+ "Unsuccessful completion code received in op complete: %x\n",
+ (uint8_t)(*completion_code));
return PLDM_SUCCESS;
}
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)
{
@@ -769,6 +808,7 @@ int encode_rde_operation_status_req(uint8_t instance_id, uint32_t resource_id,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
int decode_rde_operation_status_req(const struct pldm_msg *msg,
size_t payload_length,
uint32_t *resource_id,
@@ -787,6 +827,7 @@ int decode_rde_operation_status_req(const struct pldm_msg *msg,
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
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,
@@ -844,6 +885,7 @@ int encode_rde_operation_status_resp(
return PLDM_SUCCESS;
}
+LIBPLDM_ABI_STABLE
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,
@@ -861,7 +903,8 @@ int decode_rde_operation_status_resp(
*completion_code = msg->payload[0];
if (PLDM_SUCCESS != *completion_code) {
fprintf(stderr,
- "Decoded successfully with failed completion code\n");
+ "Unsuccessful completion code received in op status: %x\n",
+ (uint8_t)(*completion_code));
return PLDM_SUCCESS;
}
@@ -890,3 +933,27 @@ int decode_rde_operation_status_resp(
}
return 0;
}
+
+LIBPLDM_ABI_STABLE
+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 = { 0 };
+ 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/src/requester/pldm.c b/src/requester/pldm.c
index 4bbb13c..0c5858e 100644
--- a/src/requester/pldm.c
+++ b/src/requester/pldm.c
@@ -14,6 +14,7 @@
#include <unistd.h>
#include <stdio.h>
#include "mctp-defines.h"
+#include <errno.h>
/* Temporary for old api */
#include <libpldm/transport/mctp-demux.h>
@@ -265,6 +266,7 @@ static pldm_requester_rc_t mctp_recv_at_network(mctp_eid_t eid, int mctp_fd,
(struct sockaddr*)&addr, &addrlen);
if (length <= 0)
{
+ fprintf(stderr, "No length received at MCTP socket, errno: %d\n", errno);
return PLDM_REQUESTER_RECV_FAIL;
}
else if (length < min_len)
@@ -280,7 +282,7 @@ static pldm_requester_rc_t mctp_recv_at_network(mctp_eid_t eid, int mctp_fd,
(struct sockaddr*)&addr, &addrlen);
if (length != bytes)
{
- free(*pldm_resp_msg);
+ fprintf(stderr, "Recevie from socket failed with errno: %d\n", errno);
return PLDM_REQUESTER_INVALID_RECV_LEN;
}
*resp_msg_len = length;
@@ -305,14 +307,14 @@ pldm_requester_rc_t recv_at_network(mctp_eid_t eid, int mctp_fd,
struct pldm_msg_hdr* hdr = (struct pldm_msg_hdr*)(*pldm_resp_msg);
if (hdr->request != PLDM_RESPONSE)
{
- free(*pldm_resp_msg);
+ fprintf(stderr, "MCTP Receive failed - Header is not a response\n");
return PLDM_REQUESTER_NOT_RESP_MSG;
}
uint8_t pldm_rc = 0;
if (*resp_msg_len < (sizeof(struct pldm_msg_hdr) + sizeof(pldm_rc)))
{
- free(*pldm_resp_msg);
+ fprintf(stderr, "MCTP Receive failed - Receive message is too small\n");
return PLDM_REQUESTER_RESP_MSG_TOO_SMALL;
}
@@ -336,7 +338,7 @@ pldm_requester_rc_t pldm_recv_at_network(mctp_eid_t eid, int mctp_fd,
struct pldm_msg_hdr* hdr = (struct pldm_msg_hdr*)(*pldm_resp_msg);
if (hdr->instance_id != instance_id)
{
- free(*pldm_resp_msg);
+ fprintf(stderr, "MCTP Receive failed - Instance Id mismatch\n");
return PLDM_REQUESTER_INSTANCE_ID_MISMATCH;
}
diff --git a/src/requester/pldm_rde_requester.c b/src/requester/pldm_rde_requester.c
index bf55c20..e4d0070 100644
--- a/src/requester/pldm_rde_requester.c
+++ b/src/requester/pldm_rde_requester.c
@@ -7,6 +7,20 @@
#include <stdlib.h>
#include <string.h>
+LIBPLDM_ABI_STABLE
+pldm_rde_requester_rc_t
+free_op_context_after_dictionary_extraction(struct pldm_rde_requester_context *ctx)
+{
+ struct pdr_resource *current_pdr_resource = ctx->current_pdr_resource;
+
+ if (current_pdr_resource != NULL)
+ {
+ fprintf(stderr, "Cleaning Dictionary PDR Object\n");
+ free(current_pdr_resource);
+ }
+ return PLDM_RDE_REQUESTER_SUCCESS;
+}
+
LIBPLDM_ABI_STABLE
pldm_rde_requester_rc_t
pldm_rde_init_context(const char *device_id, int net_id,
@@ -170,3 +184,517 @@ pldm_rde_discovery_push_response(struct pldm_rde_requester_manager *manager,
return PLDM_RDE_REQUESTER_NO_NEXT_COMMAND_FOUND;
}
}
+
+LIBPLDM_ABI_STABLE
+pldm_rde_requester_rc_t
+pldm_rde_init_get_dictionary_schema(struct pldm_rde_requester_context *ctx)
+{
+ if (ctx->context_status == CONTEXT_BUSY) {
+ return PLDM_RDE_CONTEXT_INITIALIZATION_ERROR;
+ }
+ ctx->next_command = PLDM_GET_SCHEMA_DICTIONARY;
+ struct pdr_resource *current_pdr_resource =
+ (struct pdr_resource *)malloc(sizeof(struct pdr_resource));
+ ctx->current_pdr_resource = current_pdr_resource;
+ // start with 0th index of resource id array
+ current_pdr_resource->resource_id_index = 0;
+ current_pdr_resource->schema_class = PLDM_RDE_SCHEMA_MAJOR;
+ ctx->requester_status = PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ return PLDM_RDE_REQUESTER_SUCCESS;
+}
+
+LIBPLDM_ABI_STABLE
+pldm_rde_requester_rc_t pldm_rde_get_next_dictionary_schema_command(
+ uint8_t instance_id, struct pldm_rde_requester_manager *manager,
+ struct pldm_rde_requester_context *current_ctx, struct pldm_msg *request)
+{
+ if (manager->number_of_resources == 0) {
+ return PLDM_RDE_NO_PDR_RESOURCES_FOUND;
+ }
+ if (!manager->initialized) {
+ return PLDM_RDE_CONTEXT_INITIALIZATION_ERROR;
+ }
+
+ if (current_ctx->context_status == CONTEXT_BUSY) {
+ return PLDM_RDE_CONTEXT_NOT_READY;
+ }
+
+ int rc = 0;
+ switch (current_ctx->next_command) {
+ case PLDM_GET_SCHEMA_DICTIONARY: {
+ uint32_t resource_id =
+ current_ctx->current_pdr_resource->resource_id_index;
+ rc = encode_get_schema_dictionary_req(
+ instance_id, manager->resource_ids[resource_id],
+ PLDM_RDE_SCHEMA_MAJOR, request);
+ break;
+ }
+ case PLDM_RDE_MULTIPART_RECEIVE:
+ rc = encode_rde_multipart_receive_req(
+ instance_id,
+ current_ctx->current_pdr_resource->transfer_handle, 0x00,
+ current_ctx->current_pdr_resource->transfer_operation,
+ request);
+ break;
+ default:
+ rc = PLDM_RDE_REQUESTER_NO_NEXT_COMMAND_FOUND;
+ break;
+ }
+ if (rc) {
+ fprintf(stderr, "Unable to encode request with rc: %d\n", rc);
+ return PLDM_RDE_REQUESTER_ENCODING_REQUEST_FAILURE;
+ }
+ return rc;
+}
+
+int set_next_dictionary_index(struct pldm_rde_requester_manager *manager,
+ struct pldm_rde_requester_context *ctx)
+{
+ uint8_t new_rid_idx = ctx->current_pdr_resource->resource_id_index + 1;
+
+ if (new_rid_idx == manager->number_of_resources) {
+ fprintf(stdout,
+ "Processed all resources for dictionaries: %x \n",
+ (uint8_t)new_rid_idx);
+ ctx->next_command =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ ctx->current_pdr_resource->transfer_operation =
+ PLDM_XFER_COMPLETE;
+ ctx->requester_status = PLDM_RDE_REQUESTER_NO_PENDING_ACTION;
+ ctx->context_status = CONTEXT_FREE;
+ free_op_context_after_dictionary_extraction(ctx);
+ } else {
+ ctx->next_command = PLDM_GET_SCHEMA_DICTIONARY;
+ ctx->current_pdr_resource->resource_id_index = new_rid_idx;
+ ctx->current_pdr_resource->schema_class = PLDM_RDE_SCHEMA_MAJOR;
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ }
+ return PLDM_RDE_REQUESTER_SUCCESS;
+}
+
+LIBPLDM_ABI_STABLE
+pldm_rde_requester_rc_t pldm_rde_push_get_dictionary_response(
+ struct pldm_rde_requester_manager *manager,
+ struct pldm_rde_requester_context *ctx, void *resp_msg, size_t resp_size,
+ callback_funct callback)
+{
+ int rc = 0;
+ switch (ctx->next_command) {
+ case PLDM_GET_SCHEMA_DICTIONARY: {
+ uint8_t completion_code = DEFAULT_INIT;
+ rc = decode_get_schema_dictionary_resp(
+ resp_msg, resp_size - sizeof(struct pldm_msg_hdr),
+ &completion_code,
+ &(ctx->current_pdr_resource->dictionary_format),
+ &(ctx->current_pdr_resource->transfer_handle));
+ if (rc || completion_code) {
+ ctx->context_status = CONTEXT_FREE;
+ set_next_dictionary_index(manager, ctx);
+ break;
+ }
+
+ ctx->next_command = PLDM_RDE_MULTIPART_RECEIVE;
+ ctx->current_pdr_resource->transfer_operation =
+ PLDM_XFER_FIRST_PART;
+ ctx->context_status = CONTEXT_FREE;
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ return PLDM_RDE_REQUESTER_SUCCESS;
+ }
+ case PLDM_RDE_MULTIPART_RECEIVE: {
+ uint8_t completion_code = DEFAULT_INIT;
+ uint8_t ret_transfer_flag = DEFAULT_INIT;
+ uint8_t *payload = NULL;
+ uint32_t ret_data_transfer_handle = DEFAULT_INIT;
+ uint32_t data_length_bytes = DEFAULT_INIT;
+
+ rc = decode_rde_multipart_receive_resp(
+ resp_msg, resp_size - sizeof(struct pldm_msg_hdr),
+ &completion_code, &ret_transfer_flag,
+ &ret_data_transfer_handle, &data_length_bytes, &payload);
+
+ if (rc || completion_code) {
+ ctx->context_status = CONTEXT_FREE;
+ set_next_dictionary_index(manager, ctx);
+ break;
+ }
+ if ((ret_transfer_flag == PLDM_RDE_START) ||
+ (ret_transfer_flag == PLDM_RDE_MIDDLE)) {
+ // Call the callback method to send back response
+ // payload to requester
+ callback(manager, ctx, &payload, data_length_bytes,
+ false);
+ ctx->next_command = PLDM_RDE_MULTIPART_RECEIVE;
+ ctx->current_pdr_resource->transfer_operation =
+ PLDM_XFER_NEXT_PART;
+ ctx->current_pdr_resource->transfer_handle =
+ ret_data_transfer_handle;
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ } else if ((ret_transfer_flag == PLDM_RDE_START_AND_END) ||
+ (ret_transfer_flag == PLDM_RDE_END)) {
+ callback(manager, ctx, &payload, data_length_bytes,
+ true);
+ // find the next resource id from the resource id array
+ // if exists
+ set_next_dictionary_index(manager, ctx);
+ }
+ ctx->context_status = CONTEXT_FREE;
+ return PLDM_RDE_REQUESTER_SUCCESS;
+ }
+ }
+ return rc;
+}
+
+LIBPLDM_ABI_STABLE
+pldm_rde_requester_rc_t pldm_rde_init_rde_operation_context(
+ struct pldm_rde_requester_context *ctx, uint8_t request_id,
+ uint32_t resource_id, uint16_t operation_id, uint8_t operation_type,
+ uint8_t op_flags_byte, 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 (ctx == NULL || ctx->context_status == CONTEXT_BUSY) {
+ return PLDM_RDE_CONTEXT_INITIALIZATION_ERROR;
+ }
+ ctx->next_command = PLDM_RDE_OPERATION_INIT;
+
+ struct rde_operation *operation =
+ (struct rde_operation *)malloc(sizeof(struct rde_operation));
+ operation->request_id = request_id;
+ operation->resource_id = resource_id;
+ operation->operation_id = operation_id;
+ operation->operation_type = operation_type;
+ union pldm_rde_operation_flags opflags;
+ opflags.byte = op_flags_byte;
+ operation->operation_flags = opflags;
+
+ if (operation_locator != NULL) {
+ operation->operation_locator = operation_locator;
+ }
+ operation->operation_locator_length = operation_locator_length;
+ operation->request_payload_length = request_payload_length;
+ operation->send_data_transfer_handle = send_data_transfer_handle;
+ operation->resp_permission_flags =
+ (union pldm_rde_permission_flags *)malloc(
+ sizeof(union pldm_rde_permission_flags));
+ operation->resp_operation_flags =
+ (union pldm_rde_op_execution_flags *)malloc(
+ sizeof(union pldm_rde_op_execution_flags));
+ if (request_payload != NULL) {
+ operation->request_payload = request_payload;
+ }
+ ctx->operation_ctx = operation;
+ ctx->requester_status = PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ return PLDM_RDE_REQUESTER_SUCCESS;
+}
+
+LIBPLDM_ABI_STABLE
+pldm_rde_requester_rc_t
+pldm_rde_get_next_rde_operation(uint8_t instance_id,
+ struct pldm_rde_requester_manager *manager,
+ struct pldm_rde_requester_context *current_ctx,
+ struct pldm_msg *request)
+{
+ if (!manager->initialized) {
+ return PLDM_RDE_CONTEXT_INITIALIZATION_ERROR;
+ }
+ if (manager->number_of_resources == 0) {
+ return PLDM_RDE_NO_PDR_RESOURCES_FOUND;
+ }
+
+ if (current_ctx->context_status == CONTEXT_BUSY) {
+ return PLDM_RDE_CONTEXT_NOT_READY;
+ }
+
+ int rc = 0;
+ struct rde_operation *operation_ctx =
+ (struct rde_operation *)current_ctx->operation_ctx;
+ switch (current_ctx->next_command) {
+ case PLDM_RDE_OPERATION_INIT: {
+ rc = encode_rde_operation_init_req(
+ instance_id, operation_ctx->resource_id,
+ operation_ctx->operation_id,
+ operation_ctx->operation_type,
+ &(operation_ctx->operation_flags),
+ operation_ctx->send_data_transfer_handle,
+ operation_ctx->operation_locator_length,
+ operation_ctx->request_payload_length,
+ operation_ctx->operation_locator,
+ operation_ctx->request_payload, request);
+ break;
+ }
+ case PLDM_RDE_OPERATION_STATUS: {
+ rc = encode_rde_operation_status_req(
+ instance_id, operation_ctx->resource_id,
+ operation_ctx->operation_id, request);
+ break;
+ }
+
+ case PLDM_RDE_OPERATION_COMPLETE: {
+ rc = encode_rde_operation_complete_req(
+ instance_id, operation_ctx->resource_id,
+ operation_ctx->operation_id, request);
+ break;
+ }
+ case PLDM_RDE_MULTIPART_RECEIVE: {
+ rc = encode_rde_multipart_receive_req(
+ instance_id, operation_ctx->result_transfer_handle,
+ operation_ctx->operation_id,
+ operation_ctx->transfer_operation, request);
+ break;
+ }
+ }
+ return rc;
+}
+
+int set_next_rde_operation(struct pldm_rde_requester_manager **manager,
+ struct pldm_rde_requester_context *ctx,
+ callback_funct callback)
+{
+ struct rde_operation *operation_ctx =
+ (struct rde_operation *)ctx->operation_ctx;
+
+ int rc = PLDM_RDE_REQUESTER_SUCCESS;
+ switch (operation_ctx->operation_status) {
+ case PLDM_RDE_OPERATION_RUNNING: {
+ ctx->next_command = PLDM_RDE_OPERATION_STATUS;
+ ctx->context_status = CONTEXT_CONTINUE;
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ break;
+ }
+ case PLDM_RDE_OPERATION_TRIGGERED: {
+ ctx->next_command = PLDM_RDE_OPERATION_STATUS;
+ ctx->context_status = CONTEXT_CONTINUE;
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ break;
+ }
+ case PLDM_RDE_OPERATION_HAVE_RESULTS: {
+ ctx->next_command = PLDM_RDE_MULTIPART_RECEIVE;
+ ctx->context_status = CONTEXT_CONTINUE;
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ operation_ctx->transfer_operation = PLDM_XFER_FIRST_PART;
+ break;
+ }
+ case PLDM_RDE_OPERATION_COMPLETED: {
+ // skip the etag bytes and then call callback on the payloads
+ callback(*manager, ctx, &(operation_ctx->response_data),
+ operation_ctx->resp_payload_length, false);
+ ctx->next_command = PLDM_RDE_OPERATION_COMPLETE;
+ ctx->context_status = CONTEXT_FREE;
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ break;
+ }
+ case PLDM_RDE_OPERATION_ABANDONED: {
+ ctx->next_command = PLDM_RDE_OPERATION_COMPLETE;
+ ctx->context_status = CONTEXT_CONTINUE;
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ break;
+ }
+ case PLDM_RDE_OPERATION_FAILED: {
+ ctx->next_command = PLDM_RDE_OPERATION_COMPLETE;
+ ctx->context_status = CONTEXT_CONTINUE;
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ break;
+ }
+ default: {
+ rc = PLDM_RDE_OPERATION_FAILED;
+ fprintf(stderr, "Received default operation_status : %u\n",
+ operation_ctx->operation_status);
+ }
+ }
+ return rc;
+}
+
+
+LIBPLDM_ABI_STABLE
+pldm_rde_requester_rc_t pldm_rde_push_read_operation_response(
+ struct pldm_rde_requester_manager *manager,
+ struct pldm_rde_requester_context *ctx, void *resp_msg,
+ size_t resp_size, callback_funct callback)
+{
+ int rc = 0;
+ struct rde_operation *operation_ctx =
+ (struct rde_operation *)ctx->operation_ctx;
+ IGNORE(operation_ctx);
+ switch (ctx->next_command) {
+ case PLDM_RDE_OPERATION_INIT: {
+ uint8_t completion_code;
+ rc = decode_rde_operation_init_resp(
+ resp_msg, resp_size - sizeof(struct pldm_msg_hdr),
+ &completion_code, &(operation_ctx->percentage_complete),
+ &(operation_ctx->operation_status),
+ &(operation_ctx->completion_time),
+ &(operation_ctx->result_transfer_handle),
+ &(operation_ctx->resp_payload_length),
+ &(operation_ctx->resp_permission_flags),
+ &(operation_ctx->resp_operation_flags),
+ &(operation_ctx->resp_etag),
+ &(operation_ctx->response_data));
+
+ if (rc || completion_code) {
+ // If operation init failed, then there is not need to
+ // send the rest of the requests for the resource.
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_REQUEST_FAILED;
+ ctx->next_command =
+ PLDM_RDE_REQUESTER_NO_NEXT_COMMAND_FOUND;
+ ctx->context_status = CONTEXT_FREE;
+ break;
+ }
+
+ rc = set_next_rde_operation(&manager, ctx, callback);
+
+ if (rc) {
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_REQUEST_FAILED;
+ ctx->next_command = PLDM_RDE_OPERATION_COMPLETE;
+ }
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ return PLDM_RDE_REQUESTER_SUCCESS;
+ }
+ case PLDM_RDE_OPERATION_STATUS: {
+ // Same as operation init
+ uint8_t completion_code;
+ rc = decode_rde_operation_status_resp(
+ resp_msg, resp_size - sizeof(struct pldm_msg_hdr),
+ &completion_code, &(operation_ctx->percentage_complete),
+ &(operation_ctx->operation_status),
+ &(operation_ctx->completion_time),
+ &(operation_ctx->result_transfer_handle),
+ &(operation_ctx->resp_payload_length),
+ &(operation_ctx->resp_permission_flags),
+ &(operation_ctx->resp_operation_flags),
+ &(operation_ctx->resp_etag),
+ &(operation_ctx->response_data));
+
+ if (rc || completion_code) {
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_REQUEST_FAILED;
+ ctx->next_command = PLDM_RDE_OPERATION_COMPLETE;
+ ctx->context_status = CONTEXT_FREE;
+ break;
+ }
+
+ rc = set_next_rde_operation(&manager, ctx, callback);
+ if (rc) {
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_REQUEST_FAILED;
+ ctx->next_command = PLDM_RDE_OPERATION_COMPLETE;
+ }
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ return PLDM_RDE_REQUESTER_SUCCESS;
+ }
+
+ case PLDM_RDE_OPERATION_COMPLETE: {
+ rc = decode_rde_operation_complete_resp(
+ resp_msg, resp_size - sizeof(struct pldm_msg_hdr),
+ &(operation_ctx->completion_code));
+ ctx->next_command = PLDM_RDE_REQUESTER_NO_NEXT_COMMAND_FOUND;
+ ctx->context_status = CONTEXT_FREE;
+ ctx->requester_status = PLDM_RDE_REQUESTER_NO_PENDING_ACTION;
+
+ break;
+ }
+ case PLDM_RDE_MULTIPART_RECEIVE: {
+ uint8_t completion_code, ret_transfer_flag;
+ uint8_t *payload = malloc(sizeof(uint8_t));
+ uint32_t ret_data_transfer_handle, data_length_bytes;
+
+ rc = decode_rde_multipart_receive_resp(
+ resp_msg, resp_size - sizeof(struct pldm_msg_hdr),
+ &completion_code, &ret_transfer_flag,
+ &ret_data_transfer_handle, &data_length_bytes,
+ &payload);
+ if (rc || completion_code) {
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_REQUEST_FAILED;
+ ctx->next_command = PLDM_RDE_OPERATION_COMPLETE;
+ ctx->context_status = CONTEXT_FREE;
+ break;
+ }
+
+ if (ret_transfer_flag == PLDM_RDE_START ||
+ ret_transfer_flag == PLDM_RDE_MIDDLE) {
+ // next command is MULTIPART
+ callback(manager, ctx, &payload, data_length_bytes,
+ false);
+ ctx->next_command = PLDM_RDE_MULTIPART_RECEIVE;
+ operation_ctx->transfer_operation = PLDM_XFER_NEXT_PART;
+ operation_ctx->result_transfer_handle =
+ ret_data_transfer_handle;
+ } else if (ret_transfer_flag == PLDM_RDE_START_AND_END ||
+ ret_transfer_flag == PLDM_RDE_END) {
+ // next command is Opertaion Complete
+ callback(manager, ctx, &payload, data_length_bytes,
+ true);
+ ctx->next_command = PLDM_RDE_OPERATION_COMPLETE;
+ }
+ ctx->context_status = CONTEXT_CONTINUE;
+ ctx->requester_status =
+ PLDM_RDE_REQUESTER_READY_TO_PICK_NEXT_REQUEST;
+ break;
+ }
+ }
+
+ return rc;
+}
+
+LIBPLDM_ABI_STABLE
+pldm_rde_requester_rc_t
+free_rde_op_init_context(struct pldm_rde_requester_context *ctx)
+{
+ struct rde_operation *operation =
+ (struct rde_operation *)ctx->operation_ctx;
+
+ if (operation != NULL) {
+ if (operation->resp_permission_flags != NULL) {
+ free(operation->resp_permission_flags);
+ }
+
+ if (operation->resp_operation_flags != NULL) {
+ free(operation->resp_operation_flags);
+ }
+ }
+ return PLDM_RDE_REQUESTER_SUCCESS;
+}
+
+/**
+ * =============== Workaround begins for b/293742455 ===================
+ */
+LIBPLDM_ABI_STABLE
+pldm_rde_requester_rc_t get_pldm_rde_operation_complete_request(
+ uint8_t instance_id, struct pldm_rde_requester_context *current_ctx,
+ struct pldm_msg *request)
+{
+ struct rde_operation *operation_ctx =
+ (struct rde_operation *)current_ctx->operation_ctx;
+ return encode_rde_operation_complete_req(
+ instance_id, operation_ctx->resource_id,
+ operation_ctx->operation_id, request);
+}
+
+LIBPLDM_ABI_STABLE
+pldm_rde_requester_rc_t get_pldm_rde_operation_kill_request(
+ uint8_t instance_id, struct pldm_rde_requester_context *current_ctx,
+ struct pldm_msg *request)
+{
+ struct rde_operation *operation_ctx =
+ (struct rde_operation *)current_ctx->operation_ctx;
+
+ return encode_rde_operation_kill_req(
+ instance_id, operation_ctx->resource_id,
+ operation_ctx->operation_id, request);
+}
+/**
+ * =============== Workaround ends ===================
+ */
diff --git a/tests/requester/rde_requester_test.cpp b/tests/requester/rde_requester_test.cpp
index efa4113..4a26ca0 100644
--- a/tests/requester/rde_requester_test.cpp
+++ b/tests/requester/rde_requester_test.cpp
@@ -10,40 +10,71 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
struct pldm_rde_requester_context rde_contexts[256];
-std::vector<uint32_t> resource_ids;
int rde_context_counter = 0;
-uint8_t TEST_MC_CONCURRENCY;
-uint32_t TEST_MC_TRANSFER_SIZE;
-bitfield8_t* TEST_DEV_CAPABILITES;
-bitfield16_t* TEST_MC_FEATURES;
-uint8_t TEST_NUMBER_OF_RESOURCES;
-std::string TEST_DEV_ID;
-int TEST_NET_ID;
-int TEST_INSTANCE_ID;
-
std::map<uint8_t, int> rde_command_request_size = {
{PLDM_NEGOTIATE_REDFISH_PARAMETERS, 3},
{PLDM_NEGOTIATE_MEDIUM_PARAMETERS, 4},
{PLDM_GET_SCHEMA_DICTIONARY, 5},
{PLDM_RDE_MULTIPART_RECEIVE, 7}};
-void initial_setup()
+std::map<uint8_t, int> rde_op_command_request_size = {
+ {PLDM_RDE_OPERATION_INIT, 18},
+ {PLDM_RDE_OPERATION_STATUS, 18},
+ {PLDM_RDE_OPERATION_COMPLETE, 6},
+ {PLDM_RDE_MULTIPART_RECEIVE, 7}};
+
+class TestRdeRequester : public ::testing::Test
{
- TEST_INSTANCE_ID = 1;
- TEST_MC_CONCURRENCY = uint8_t(3);
- TEST_MC_TRANSFER_SIZE = uint32_t(2056);
- TEST_MC_FEATURES = (bitfield16_t*)malloc(sizeof(bitfield16_t));
- TEST_DEV_CAPABILITES = (bitfield8_t*)malloc(sizeof(bitfield8_t));
- TEST_MC_FEATURES->value = (uint16_t)102;
-
- TEST_NUMBER_OF_RESOURCES = 2;
- resource_ids.emplace_back(0x00000000);
- resource_ids.emplace_back(0x00010000);
-
- TEST_NET_ID = 9;
- TEST_DEV_ID = "rde_dev";
-}
+ public:
+ TestRdeRequester()
+ {
+ instanceId = 1;
+ mcConcurrency = 3;
+ mcTransferSize = 2056;
+ mcFeatures.value = 102;
+
+ numberOfResources = 2;
+ resourceIds.emplace_back(0x00000000);
+ resourceIds.emplace_back(0x00010000);
+
+ netId = 9;
+ devId = "rde_dev";
+
+ // RDE operation test values
+ requestId = 0x01;
+ resourceId = 0x0001000;
+ sendTransferHandle = 0x0001000;
+ opId = 0x00;
+ opLocLength = 0x00;
+ payloadLength = 0x00;
+ opLoc = 0x00;
+ reqPtr = 0x00;
+ flags = 0x00;
+ }
+
+ uint8_t mcConcurrency;
+ uint32_t mcTransferSize;
+ bitfield8_t devCapabilities_;
+ bitfield16_t mcFeatures;
+ uint8_t numberOfResources;
+ std::string devId;
+ int netId;
+ int instanceId;
+
+ // RDE Operation Test values
+ uint8_t requestId;
+ uint32_t resourceId;
+ uint32_t sendTransferHandle;
+ uint16_t opId;
+ uint8_t opLocLength;
+ uint32_t payloadLength;
+ uint8_t opLoc;
+ uint8_t reqPtr;
+ uint8_t flags;
+
+ std::vector<uint32_t> resourceIds;
+};
void free_memory(void* context)
{
@@ -72,97 +103,90 @@ struct pldm_rde_requester_context*
return &rde_contexts[0];
}
-TEST(ContextManagerInitializationSuccess, RDERequesterTest)
+TEST_F(TestRdeRequester, ContextManagerInitializationSuccess)
{
- initial_setup();
struct pldm_rde_requester_manager* manager =
new pldm_rde_requester_manager();
- int rc = pldm_rde_init_context(
- TEST_DEV_ID.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
- EXPECT_EQ(manager->mc_concurrency, TEST_MC_CONCURRENCY);
- EXPECT_EQ(manager->mc_transfer_size, TEST_MC_TRANSFER_SIZE);
- EXPECT_EQ(manager->mc_feature_support, TEST_MC_FEATURES);
- EXPECT_EQ(manager->device_name, TEST_DEV_ID);
- EXPECT_EQ(manager->net_id, TEST_NET_ID);
- EXPECT_EQ(manager->number_of_resources, TEST_NUMBER_OF_RESOURCES);
+ EXPECT_EQ(manager->mc_concurrency, mcConcurrency);
+ EXPECT_EQ(manager->mc_transfer_size, mcTransferSize);
+ EXPECT_EQ(manager->mc_feature_support, &mcFeatures);
+ EXPECT_EQ(manager->device_name, devId);
+ EXPECT_EQ(manager->net_id, netId);
+ EXPECT_EQ(manager->number_of_resources, numberOfResources);
EXPECT_EQ(manager->resource_ids[0], 0x00000000);
EXPECT_EQ(manager->resource_ids[1], 0x00010000);
}
-TEST(ContextManagerInitializationFailureDueToNullManager, RDERequesterTest)
+TEST_F(TestRdeRequester, ContextManagerInitializationFailureDueToNullManager)
{
- initial_setup();
-
struct pldm_rde_requester_manager* manager = NULL;
- int rc = pldm_rde_init_context(
- TEST_DEV_ID.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
EXPECT_EQ(rc, PLDM_RDE_CONTEXT_INITIALIZATION_ERROR);
}
-TEST(ContextManagerInitializationFailureDueToWrongDevId, RDERequesterTest)
+TEST_F(TestRdeRequester, ContextManagerInitializationFailureDueToWrongDevId)
{
- initial_setup();
std::string incorrect_dev_id;
struct pldm_rde_requester_manager* manager =
new pldm_rde_requester_manager();
- int rc = pldm_rde_init_context(
- incorrect_dev_id.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ int rc = pldm_rde_init_context(incorrect_dev_id.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
EXPECT_EQ(rc, PLDM_RDE_CONTEXT_INITIALIZATION_ERROR);
incorrect_dev_id = "";
- rc = pldm_rde_init_context(
- incorrect_dev_id.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ rc = pldm_rde_init_context(incorrect_dev_id.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
EXPECT_EQ(rc, PLDM_RDE_CONTEXT_INITIALIZATION_ERROR);
incorrect_dev_id = "VERY_LONG_DEV_ID";
- rc = pldm_rde_init_context(
- incorrect_dev_id.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ rc = pldm_rde_init_context(incorrect_dev_id.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
EXPECT_EQ(rc, PLDM_RDE_CONTEXT_INITIALIZATION_ERROR);
}
-TEST(ContextManagerInitializationFailureDueToNullAllocatorFunctions,
- RDERequesterTest)
+TEST_F(TestRdeRequester,
+ ContextManagerInitializationFailureDueToNullAllocatorFunctions)
{
- initial_setup();
-
struct pldm_rde_requester_manager* manager =
new pldm_rde_requester_manager();
- int rc = pldm_rde_init_context(TEST_DEV_ID.c_str(), TEST_NET_ID, manager,
- TEST_MC_CONCURRENCY, TEST_MC_TRANSFER_SIZE,
- TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), NULL, free_memory);
+ int rc =
+ pldm_rde_init_context(devId.c_str(), netId, manager, mcConcurrency,
+ mcTransferSize, &mcFeatures, numberOfResources,
+ &resourceIds.front(), NULL, free_memory);
EXPECT_EQ(rc, PLDM_RDE_CONTEXT_INITIALIZATION_ERROR);
- rc = pldm_rde_init_context(
- TEST_DEV_ID.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, NULL);
+ rc = pldm_rde_init_context(devId.c_str(), netId, manager, mcConcurrency,
+ mcTransferSize, &mcFeatures, numberOfResources,
+ &resourceIds.front(),
+ allocate_memory_to_contexts, NULL);
EXPECT_EQ(rc, PLDM_RDE_CONTEXT_INITIALIZATION_ERROR);
}
-TEST(StartRDEDiscoverySuccess, RDEDiscoveryTest)
+TEST_F(TestRdeRequester, StartRDEDiscoverySuccess)
{
- initial_setup();
struct pldm_rde_requester_manager* manager =
new pldm_rde_requester_manager();
- int rc = pldm_rde_init_context(
- TEST_DEV_ID.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
struct pldm_rde_requester_context base_context = rde_contexts[0];
@@ -172,16 +196,15 @@ TEST(StartRDEDiscoverySuccess, RDEDiscoveryTest)
EXPECT_EQ(base_context.next_command, PLDM_NEGOTIATE_REDFISH_PARAMETERS);
}
-TEST(StartRDEDiscoveryFailure, RDEDiscoveryTest)
+TEST_F(TestRdeRequester, StartRDEDiscoveryFailure)
{
- initial_setup();
struct pldm_rde_requester_manager* manager =
new pldm_rde_requester_manager();
- int rc = pldm_rde_init_context(
- TEST_DEV_ID.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
struct pldm_rde_requester_context base_context = rde_contexts[0];
@@ -190,16 +213,15 @@ TEST(StartRDEDiscoveryFailure, RDEDiscoveryTest)
EXPECT_EQ(rc, PLDM_RDE_CONTEXT_NOT_READY);
}
-TEST(CreateRequesterContextSuccess, RDEDiscoveryTest)
+TEST_F(TestRdeRequester, CreateRequesterContextSuccess)
{
- initial_setup();
struct pldm_rde_requester_manager* manager =
new pldm_rde_requester_manager();
- int rc = pldm_rde_init_context(
- TEST_DEV_ID.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
struct pldm_rde_requester_context* current_ctx =
new pldm_rde_requester_context();
@@ -213,16 +235,15 @@ TEST(CreateRequesterContextSuccess, RDEDiscoveryTest)
PLDM_RDE_REQUESTER_NO_NEXT_COMMAND_FOUND);
}
-TEST(CreateRequesterContextFailure, RDEDiscoveryTest)
+TEST_F(TestRdeRequester, CreateRequesterContextFailure)
{
- initial_setup();
struct pldm_rde_requester_manager* manager =
new pldm_rde_requester_manager();
- int rc = pldm_rde_init_context(
- TEST_DEV_ID.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
struct pldm_rde_requester_context* current_ctx = NULL;
rc = pldm_rde_create_context(current_ctx);
@@ -232,7 +253,7 @@ TEST(CreateRequesterContextFailure, RDEDiscoveryTest)
int test_get_next_request_seq(pldm_rde_requester_manager** manager,
struct pldm_rde_requester_context** ctx,
- uint8_t next_command)
+ uint8_t next_command, int instanceId)
{
(*ctx)->next_command = next_command;
int requestBytes = 0;
@@ -243,63 +264,63 @@ int test_get_next_request_seq(pldm_rde_requester_manager** manager,
}
std::vector<uint8_t> msg(sizeof(pldm_msg_hdr) + requestBytes);
auto request = reinterpret_cast<pldm_msg*>(msg.data());
- return pldm_rde_get_next_discovery_command(TEST_INSTANCE_ID, *manager, *ctx,
+ return pldm_rde_get_next_discovery_command(instanceId, *manager, *ctx,
request);
}
-TEST(GetNextRequestInSequenceSuccess, PLDMRDEDiscovery)
-{
- initial_setup();
+TEST_F(TestRdeRequester, GetNextRequestInSequenceSuccess)
+{
struct pldm_rde_requester_manager* manager =
new pldm_rde_requester_manager();
- int rc = pldm_rde_init_context(
- TEST_DEV_ID.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
struct pldm_rde_requester_context* base_context =
new pldm_rde_requester_context();
rc = pldm_rde_create_context(base_context);
rc = test_get_next_request_seq(&manager, &base_context,
- PLDM_NEGOTIATE_REDFISH_PARAMETERS);
+ PLDM_NEGOTIATE_REDFISH_PARAMETERS,
+ instanceId);
EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
rc = test_get_next_request_seq(&manager, &base_context,
- PLDM_NEGOTIATE_MEDIUM_PARAMETERS);
+ PLDM_NEGOTIATE_MEDIUM_PARAMETERS,
+ instanceId);
EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
}
-TEST(GetNextRequestInSequenceFailure, PLDMRDEDiscovery)
+TEST_F(TestRdeRequester, GetNextRequestInSequenceFailure)
{
- initial_setup();
struct pldm_rde_requester_manager* manager =
new pldm_rde_requester_manager();
- int rc = pldm_rde_init_context(
- TEST_DEV_ID.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
struct pldm_rde_requester_context* base_context =
new pldm_rde_requester_context();
rc = pldm_rde_create_context(base_context);
- rc = test_get_next_request_seq(&manager, &base_context,
- 0x0023); // Unknown request code to encode
+ rc = test_get_next_request_seq(
+ &manager, &base_context, 0x0023,
+ instanceId); // Unknown request code to encode
EXPECT_EQ(rc, PLDM_RDE_REQUESTER_ENCODING_REQUEST_FAILURE);
}
-TEST(PushDiscoveryResponseRedfishParamSuccess, PLDMRDEDiscovery)
+TEST_F(TestRdeRequester, PushDiscoveryResponseRedfishParamSuccess)
{
- initial_setup();
struct pldm_rde_requester_manager* manager =
new pldm_rde_requester_manager();
- int rc = pldm_rde_init_context(
- TEST_DEV_ID.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
struct pldm_rde_requester_context* base_context =
new pldm_rde_requester_context();
@@ -311,14 +332,15 @@ TEST(PushDiscoveryResponseRedfishParamSuccess, PLDMRDEDiscovery)
auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg);
rc = test_get_next_request_seq(&manager, &base_context,
- PLDM_NEGOTIATE_REDFISH_PARAMETERS);
+ PLDM_NEGOTIATE_REDFISH_PARAMETERS,
+ instanceId);
EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
rc = encode_negotiate_redfish_parameters_resp(
- TEST_INSTANCE_ID, /*completion_code=*/0,
- /*device_concurrency=*/TEST_MC_CONCURRENCY, *TEST_DEV_CAPABILITES,
- /*device_capabilities_flags=*/*TEST_MC_FEATURES,
+ instanceId, /*completion_code=*/0,
+ /*device_concurrency=*/mcConcurrency, devCapabilities_,
+ /*device_capabilities_flags=*/mcFeatures,
/*dev provider name*/ 0x00f,
- /*Example*/ TEST_DEV_ID.c_str(),
+ /*Example*/ devId.c_str(),
/*device_configuration_signature*/ PLDM_RDE_VARSTRING_UTF_16,
responsePtr);
EXPECT_EQ(rc, 0);
@@ -328,33 +350,32 @@ TEST(PushDiscoveryResponseRedfishParamSuccess, PLDMRDEDiscovery)
struct pldm_rde_device_info* deviceInfo = manager->device;
EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
- EXPECT_EQ(deviceInfo->device_concurrency, TEST_MC_CONCURRENCY);
+ EXPECT_EQ(deviceInfo->device_concurrency, mcConcurrency);
EXPECT_EQ(deviceInfo->device_capabilities_flag.byte,
- TEST_DEV_CAPABILITES->byte);
+ devCapabilities_.byte);
EXPECT_EQ(deviceInfo->device_feature_support.value,
- TEST_MC_FEATURES->value);
+ mcFeatures.value);
EXPECT_EQ(base_context->next_command, PLDM_NEGOTIATE_MEDIUM_PARAMETERS);
- rc = test_get_next_request_seq(&manager, &base_context,
- PLDM_NEGOTIATE_MEDIUM_PARAMETERS);
+ rc = test_get_next_request_seq(
+ &manager, &base_context, PLDM_NEGOTIATE_MEDIUM_PARAMETERS, instanceId);
EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
rc = encode_negotiate_medium_parameters_resp(
- TEST_INSTANCE_ID, /*completion_code=*/0,
+ instanceId, /*completion_code=*/0,
/*device_maximum_transfer_bytes*/ 256, responsePtr);
EXPECT_EQ(rc, 0);
}
-TEST(PushDiscoveryResponseRedfishMediumParamSuccess, PLDMRDEDiscovery)
+TEST_F(TestRdeRequester, PushDiscoveryResponseRedfishMediumParamSuccess)
{
- initial_setup();
struct pldm_rde_requester_manager* manager =
new pldm_rde_requester_manager();
- int rc = pldm_rde_init_context(
- TEST_DEV_ID.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
struct pldm_rde_requester_context* base_context =
new pldm_rde_requester_context();
@@ -365,12 +386,12 @@ TEST(PushDiscoveryResponseRedfishMediumParamSuccess, PLDMRDEDiscovery)
size_t responseMsgSize = sizeof(pldm_msg_hdr) + 6;
auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg);
- rc = test_get_next_request_seq(&manager, &base_context,
- PLDM_NEGOTIATE_MEDIUM_PARAMETERS);
+ rc = test_get_next_request_seq(
+ &manager, &base_context, PLDM_NEGOTIATE_MEDIUM_PARAMETERS, instanceId);
EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
rc = encode_negotiate_medium_parameters_resp(
- TEST_INSTANCE_ID, /*completion_code=*/0,
+ instanceId, /*completion_code=*/0,
/*device_maximum_transfer_bytes*/ 256, responsePtr);
EXPECT_EQ(rc, 0);
@@ -385,16 +406,15 @@ TEST(PushDiscoveryResponseRedfishMediumParamSuccess, PLDMRDEDiscovery)
EXPECT_EQ(manager->negotiated_transfer_size, 256);
}
-TEST(PushDiscoveryResponseFailure, PLDMRDEDiscovery)
+TEST_F(TestRdeRequester, PushDiscoveryResponseFailure)
{
- initial_setup();
struct pldm_rde_requester_manager* manager =
new pldm_rde_requester_manager();
-
- int rc = pldm_rde_init_context(
- TEST_DEV_ID.c_str(), TEST_NET_ID, manager, TEST_MC_CONCURRENCY,
- TEST_MC_TRANSFER_SIZE, TEST_MC_FEATURES, TEST_NUMBER_OF_RESOURCES,
- &resource_ids.front(), allocate_memory_to_contexts, free_memory);
+
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
struct pldm_rde_requester_context* base_context =
new pldm_rde_requester_context();
@@ -408,3 +428,341 @@ TEST(PushDiscoveryResponseFailure, PLDMRDEDiscovery)
EXPECT_EQ(rc, PLDM_RDE_REQUESTER_NO_NEXT_COMMAND_FOUND);
}
+
+TEST_F(TestRdeRequester, InitDictionarySchemaSuccess)
+{
+ struct pldm_rde_requester_manager* manager =
+ new pldm_rde_requester_manager();
+
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
+ EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
+ struct pldm_rde_requester_context* base_context =
+ new pldm_rde_requester_context();
+ rc = pldm_rde_create_context(base_context);
+
+ rc = pldm_rde_init_get_dictionary_schema(base_context);
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+ EXPECT_EQ(base_context->current_pdr_resource->schema_class,
+ PLDM_RDE_SCHEMA_MAJOR);
+}
+
+TEST_F(TestRdeRequester, InitDictionarySchemaFailure)
+{
+ struct pldm_rde_requester_manager* manager =
+ new pldm_rde_requester_manager();
+
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
+ EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
+ struct pldm_rde_requester_context* base_context =
+ new pldm_rde_requester_context();
+ base_context->context_status = CONTEXT_BUSY;
+
+ rc = pldm_rde_init_get_dictionary_schema(base_context);
+ EXPECT_EQ(rc, PLDM_RDE_CONTEXT_INITIALIZATION_ERROR);
+}
+
+TEST_F(TestRdeRequester, GetNextDictionarySchemaSuccess)
+{
+ struct pldm_rde_requester_manager* manager =
+ new pldm_rde_requester_manager();
+
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
+ EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
+ struct pldm_rde_requester_context* base_context =
+ new pldm_rde_requester_context();
+ rc = pldm_rde_create_context(base_context);
+
+ rc = pldm_rde_init_get_dictionary_schema(base_context);
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+
+ int requestBytes = 0;
+ if (rde_command_request_size.find(base_context->next_command) !=
+ rde_command_request_size.end())
+ {
+ requestBytes = rde_command_request_size[base_context->next_command];
+ }
+ std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + requestBytes);
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+ rc = pldm_rde_get_next_dictionary_schema_command(instanceId, manager,
+ base_context, request);
+
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+}
+
+TEST_F(TestRdeRequester, GetNextDictionarySchemaFailure)
+{
+ struct pldm_rde_requester_manager* manager =
+ new pldm_rde_requester_manager();
+
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
+ EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
+ struct pldm_rde_requester_context* base_context =
+ new pldm_rde_requester_context();
+ rc = pldm_rde_create_context(base_context);
+
+ base_context->next_command = 0x23;
+
+ std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr));
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+ rc = pldm_rde_get_next_dictionary_schema_command(instanceId, manager,
+ base_context, request);
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_ENCODING_REQUEST_FAILURE);
+}
+
+TEST_F(TestRdeRequester, MultipartReceiveSuccess)
+{
+ struct pldm_rde_requester_manager* manager =
+ new pldm_rde_requester_manager();
+
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
+ EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
+ struct pldm_rde_requester_context* base_context =
+ new pldm_rde_requester_context();
+ rc = pldm_rde_create_context(base_context);
+
+ rc = pldm_rde_init_get_dictionary_schema(base_context);
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+
+ base_context->next_command = PLDM_RDE_MULTIPART_RECEIVE;
+ base_context->current_pdr_resource->transfer_handle = 0x00;
+
+ int requestBytes = 0;
+ if (rde_command_request_size.find(base_context->next_command) !=
+ rde_command_request_size.end())
+ {
+ requestBytes = rde_command_request_size[base_context->next_command];
+ }
+ std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + requestBytes);
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+
+ rc = pldm_rde_get_next_dictionary_schema_command(instanceId, manager,
+ base_context, request);
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+}
+
+void dummy_callback(struct pldm_rde_requester_manager* manager,
+ struct pldm_rde_requester_context* ctx, uint8_t** payload,
+ uint32_t payload_length, bool has_checksum)
+{
+ IGNORE(manager);
+ IGNORE(ctx);
+ IGNORE(payload);
+ IGNORE(payload_length);
+ IGNORE(has_checksum);
+}
+
+TEST_F(TestRdeRequester, PushResponseForGetDictionarySchema)
+{
+ struct pldm_rde_requester_manager* manager =
+ new pldm_rde_requester_manager();
+
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
+ EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
+ struct pldm_rde_requester_context* base_context =
+ new pldm_rde_requester_context();
+ rc = pldm_rde_create_context(base_context);
+
+ rc = pldm_rde_init_get_dictionary_schema(base_context);
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+
+ std::vector<uint8_t> response(sizeof(pldm_msg_hdr) + 6, 0);
+ uint8_t* responseMsg = response.data();
+ size_t responseMsgSize = sizeof(pldm_msg_hdr) + 6;
+ auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg);
+
+ rc = encode_get_schema_dictionary_resp(instanceId,
+ /*cc*/ 0,
+ /* dictionary_format*/ 0x00,
+ /*transfer_handle*/ 0x00,
+ responsePtr);
+
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+ rc = pldm_rde_push_get_dictionary_response(
+ manager, base_context, responsePtr, responseMsgSize, dummy_callback);
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+}
+
+TEST_F(TestRdeRequester, PushResponseForMultipartReceive)
+{
+ struct pldm_rde_requester_manager* manager =
+ new pldm_rde_requester_manager();
+
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
+ EXPECT_EQ(rc, PLDM_BASE_REQUESTER_SUCCESS);
+ struct pldm_rde_requester_context* base_context =
+ new pldm_rde_requester_context();
+ rc = pldm_rde_create_context(base_context);
+
+ rc = pldm_rde_init_get_dictionary_schema(base_context);
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+
+ base_context->next_command = PLDM_RDE_MULTIPART_RECEIVE;
+ std::vector<uint8_t> response(sizeof(pldm_msg_hdr) + 20, 0);
+ uint8_t* responseMsg = response.data();
+ size_t responseMsgSize = sizeof(pldm_msg_hdr) + 20;
+ auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg);
+
+ uint8_t payload[] = {2, 3, 4};
+ rc = encode_rde_multipart_receive_resp(
+ instanceId, /*completion_code*/ 0, /*transfer_flag*/ 0x00,
+ /*next_data_transfer_handle*/ 0x00, /*data_length_bytes*/ 8,
+ /*add_checksum*/ false, /*checksum*/ 0x00, &payload[0], responsePtr);
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+ rc = pldm_rde_push_get_dictionary_response(
+ manager, base_context, responsePtr, responseMsgSize, dummy_callback);
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+}
+
+
+TEST_F(TestRdeRequester, InitRDEOperationContextSuccess)
+{
+ struct pldm_rde_requester_manager* manager =
+ new pldm_rde_requester_manager();
+
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
+
+ struct pldm_rde_requester_context* base_context =
+ new pldm_rde_requester_context();
+ rc = pldm_rde_create_context(base_context);
+
+ rc = pldm_rde_init_rde_operation_context(
+ base_context, requestId, resourceId, opId, PLDM_RDE_OPERATION_READ,
+ flags, sendTransferHandle, opLocLength, payloadLength, &opLoc,
+ &reqPtr);
+
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+ struct rde_operation* operation =
+ (struct rde_operation*)base_context->operation_ctx;
+ EXPECT_EQ(operation->request_id, requestId);
+ EXPECT_EQ(operation->resource_id, resourceId);
+}
+
+TEST_F(TestRdeRequester, InitRDEOperationContextFailure)
+{
+ struct pldm_rde_requester_manager* manager =
+ new pldm_rde_requester_manager();
+
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
+
+ struct pldm_rde_requester_context* base_context =
+ new pldm_rde_requester_context();
+ rc = pldm_rde_create_context(base_context);
+
+ base_context->context_status = CONTEXT_BUSY;
+ rc = pldm_rde_init_rde_operation_context(
+ base_context, requestId, resourceId, opId, PLDM_RDE_OPERATION_READ,
+ flags, sendTransferHandle, opLocLength, payloadLength, &opLoc,
+ &reqPtr);
+
+ EXPECT_EQ(rc, PLDM_RDE_CONTEXT_INITIALIZATION_ERROR);
+}
+
+TEST_F(TestRdeRequester, GetNextRDEOperationSuccess)
+{
+ struct pldm_rde_requester_manager* manager =
+ new pldm_rde_requester_manager();
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
+
+ struct pldm_rde_requester_context* base_context =
+ new pldm_rde_requester_context();
+ rc = pldm_rde_create_context(base_context);
+
+ rc = pldm_rde_init_rde_operation_context(
+ base_context, requestId, resourceId, opId, PLDM_RDE_OPERATION_READ,
+ flags, sendTransferHandle, opLocLength, payloadLength, &opLoc,
+ &reqPtr);
+
+ size_t requestBytes = 256;
+ std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + requestBytes);
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+ rc = pldm_rde_get_next_rde_operation(instanceId, manager, base_context,
+ request);
+
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+
+ base_context->next_command = PLDM_RDE_OPERATION_COMPLETE;
+ rc = pldm_rde_get_next_rde_operation(instanceId, manager, base_context,
+ request);
+
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+
+ base_context->next_command = PLDM_RDE_MULTIPART_RECEIVE;
+ rc = pldm_rde_get_next_rde_operation(instanceId, manager, base_context,
+ request);
+
+ EXPECT_EQ(rc, PLDM_RDE_REQUESTER_SUCCESS);
+}
+
+TEST_F(TestRdeRequester, GetNextRDEOperationFailure)
+{
+ struct pldm_rde_requester_manager* manager =
+ new pldm_rde_requester_manager();
+
+ int rc = pldm_rde_init_context(devId.c_str(), netId, manager,
+ mcConcurrency, mcTransferSize, &mcFeatures,
+ numberOfResources, &resourceIds.front(),
+ allocate_memory_to_contexts, free_memory);
+
+ struct pldm_rde_requester_context* base_context =
+ new pldm_rde_requester_context();
+ rc = pldm_rde_create_context(base_context);
+
+ rc = pldm_rde_init_rde_operation_context(
+ base_context, requestId, resourceId, opId, PLDM_RDE_OPERATION_READ,
+ flags, sendTransferHandle, opLocLength, payloadLength, &opLoc,
+ &reqPtr);
+
+ size_t requestBytes = 256;
+ std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + requestBytes);
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+ manager->initialized = false;
+ rc = pldm_rde_get_next_rde_operation(instanceId, manager, base_context,
+ request);
+
+ EXPECT_EQ(rc, PLDM_RDE_CONTEXT_INITIALIZATION_ERROR);
+
+ manager->number_of_resources = 0;
+ manager->initialized = true;
+ rc = pldm_rde_get_next_rde_operation(instanceId, manager, base_context,
+ request);
+
+ EXPECT_EQ(rc, PLDM_RDE_NO_PDR_RESOURCES_FOUND);
+
+ manager->number_of_resources = 1;
+ manager->initialized = true;
+ base_context->context_status = CONTEXT_BUSY;
+ rc = pldm_rde_get_next_rde_operation(instanceId, manager, base_context,
+ request);
+
+ EXPECT_EQ(rc, PLDM_RDE_CONTEXT_NOT_READY);
+}
--
2.43.0.rc2.451.g8631bc7472-goog