platform: Add decode API for File Descriptor PDR

Add decode API to decode File Descriptor PDR raw data to
`pldm_file_descriptor_pdr` struct. The referred File Descriptor PDR is
based on DSP0248 1.3.0 Section 28.30 Table 108.

Change-Id: Ifcfae68d8bf6a723cf132b851621b068e2118d0e
Signed-off-by: Chau Ly <chaul@amperecomputing.com>
diff --git a/src/dsp/platform.c b/src/dsp/platform.c
index 0d5d917..18de641 100644
--- a/src/dsp/platform.c
+++ b/src/dsp/platform.c
@@ -3264,3 +3264,68 @@
 {
 	return event->event_data;
 }
+
+LIBPLDM_ABI_TESTING
+int decode_pldm_file_descriptor_pdr(const void *data, size_t data_length,
+				    struct pldm_file_descriptor_pdr *pdr)
+{
+	PLDM_MSGBUF_DEFINE_P(buf);
+	int rc;
+
+	if (!data || !pdr) {
+		return -EINVAL;
+	}
+
+	rc = pldm_msgbuf_init_errno(buf,
+				    PLDM_PDR_FILE_DESCRIPTOR_PDR_MIN_LENGTH,
+				    data, data_length);
+	if (rc) {
+		return rc;
+	}
+
+	rc = pldm_msgbuf_extract_value_pdr_hdr(
+		buf, &pdr->hdr, PLDM_PDR_FILE_DESCRIPTOR_PDR_MIN_LENGTH,
+		data_length);
+	if (rc) {
+		return pldm_msgbuf_discard(buf, rc);
+	}
+
+	pldm_msgbuf_extract(buf, pdr->terminus_handle);
+	pldm_msgbuf_extract(buf, pdr->file_identifier);
+	pldm_msgbuf_extract(buf, pdr->container.entity_type);
+	pldm_msgbuf_extract(buf, pdr->container.entity_instance_num);
+	pldm_msgbuf_extract(buf, pdr->container.entity_container_id);
+	pldm_msgbuf_extract(buf, pdr->superior_directory_file_identifier);
+	pldm_msgbuf_extract(buf, pdr->file_classification);
+	pldm_msgbuf_extract(buf, pdr->oem_file_classification);
+	pldm_msgbuf_extract(buf, pdr->file_capabilities.value);
+	pldm_msgbuf_extract(buf, pdr->file_version.alpha);
+	pldm_msgbuf_extract(buf, pdr->file_version.update);
+	pldm_msgbuf_extract(buf, pdr->file_version.minor);
+	pldm_msgbuf_extract(buf, pdr->file_version.major);
+	pldm_msgbuf_extract(buf, pdr->file_maximum_size);
+	pldm_msgbuf_extract(buf, pdr->file_maximum_file_descriptor_count);
+	rc = pldm_msgbuf_extract_uint8_to_size(buf, pdr->file_name.length);
+	if (rc) {
+		return pldm_msgbuf_discard(buf, rc);
+	}
+
+	pldm_msgbuf_span_required(buf, pdr->file_name.length,
+				  (void **)&pdr->file_name.ptr);
+
+	pdr->oem_file_classification_name.length = 0;
+
+	if (pdr->oem_file_classification) {
+		rc = pldm_msgbuf_extract_uint8_to_size(
+			buf, pdr->oem_file_classification_name.length);
+		if (rc) {
+			return pldm_msgbuf_discard(buf, rc);
+		}
+
+		pldm_msgbuf_span_required(
+			buf, pdr->oem_file_classification_name.length,
+			(void **)&pdr->oem_file_classification_name.ptr);
+	}
+
+	return pldm_msgbuf_complete_consumed(buf);
+}