libpldm: Add decode API for ComponentParameterTable entry

ComponentParameterTable is present in the response of
GetFirmwareParameters command. ComponentParameterTable is a table that
contains component entries for all of the updateable components which
reside on the firmware device.

decode_get_firmware_parameters_resp_comp_entry decodes each entry in
the ComponentParameterTable.

Tested: Unit tests passed

Signed-off-by: gokulsanker <gokul.sanker.v.g@intel.com>
Change-Id: I3698b268cf42345d80d7d218919d42ffad0b011f
diff --git a/libpldm/firmware_update.c b/libpldm/firmware_update.c
index b0daddb..58dd21f 100644
--- a/libpldm/firmware_update.c
+++ b/libpldm/firmware_update.c
@@ -1,5 +1,6 @@
 #include "firmware_update.h"

 #include <endian.h>

+#include <string.h>

 

 int encode_query_device_identifiers_req(uint8_t instance_id,

 					size_t payload_length,

@@ -154,3 +155,77 @@
 

 	return PLDM_SUCCESS;

 }

+

+int decode_get_firmware_parameters_resp_comp_entry(

+    const uint8_t *data, size_t length,

+    struct pldm_component_parameter_entry *component_data,

+    struct variable_field *active_comp_ver_str,

+    struct variable_field *pending_comp_ver_str)

+{

+	if (data == NULL || component_data == NULL ||

+	    active_comp_ver_str == NULL || pending_comp_ver_str == NULL) {

+		return PLDM_ERROR_INVALID_DATA;

+	}

+

+	if (length < sizeof(struct pldm_component_parameter_entry)) {

+		return PLDM_ERROR_INVALID_LENGTH;

+	}

+

+	struct pldm_component_parameter_entry *entry =

+	    (struct pldm_component_parameter_entry *)(data);

+	if (entry->active_comp_ver_str_len == 0) {

+		return PLDM_ERROR_INVALID_LENGTH;

+	}

+

+	size_t entry_length = sizeof(struct pldm_component_parameter_entry) +

+			      entry->active_comp_ver_str_len +

+			      entry->pending_comp_ver_str_len;

+

+	if (length != entry_length) {

+		return PLDM_ERROR_INVALID_LENGTH;

+	}

+

+	component_data->comp_classification =

+	    le16toh(entry->comp_classification);

+	component_data->comp_identifier = le16toh(entry->comp_identifier);

+	component_data->comp_classification_index =

+	    entry->comp_classification_index;

+	component_data->active_comp_comparison_stamp =

+	    le32toh(entry->active_comp_comparison_stamp);

+	component_data->active_comp_ver_str_type =

+	    entry->active_comp_ver_str_type;

+	component_data->active_comp_ver_str_len =

+	    entry->active_comp_ver_str_len;

+	memcpy(component_data->active_comp_release_date,

+	       entry->active_comp_release_date,

+	       sizeof(entry->active_comp_release_date));

+	component_data->pending_comp_comparison_stamp =

+	    le32toh(entry->pending_comp_comparison_stamp);

+	component_data->pending_comp_ver_str_type =

+	    entry->pending_comp_ver_str_type;

+	component_data->pending_comp_ver_str_len =

+	    entry->pending_comp_ver_str_len;

+	memcpy(component_data->pending_comp_release_date,

+	       entry->pending_comp_release_date,

+	       sizeof(entry->pending_comp_release_date));

+	component_data->comp_activation_methods.value =

+	    le16toh(entry->comp_activation_methods.value);

+	component_data->capabilities_during_update.value =

+	    le32toh(entry->capabilities_during_update.value);

+

+	active_comp_ver_str->ptr =

+	    data + sizeof(struct pldm_component_parameter_entry);

+	active_comp_ver_str->length = entry->active_comp_ver_str_len;

+

+	if (entry->pending_comp_ver_str_len != 0) {

+

+		pending_comp_ver_str->ptr =

+		    data + sizeof(struct pldm_component_parameter_entry) +

+		    entry->active_comp_ver_str_len;

+		pending_comp_ver_str->length = entry->pending_comp_ver_str_len;

+	} else {

+		pending_comp_ver_str->ptr = NULL;

+		pending_comp_ver_str->length = 0;

+	}

+	return PLDM_SUCCESS;

+}