| 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 |
| |