libpldm: Add firmware update FD responder

This provides a FD responder implementation, with an ops struct to allow
for platform customization. Applications provide incoming messages to
pldm_fd_handle_msg(), and periodically call pldm_fd_progress() for
asynchronous events.

Change-Id: I034262e8b2c45b5bea61369d5f966dd7e530ba9e
Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
diff --git a/src/firmware_device/fd-internal.h b/src/firmware_device/fd-internal.h
new file mode 100644
index 0000000..3873c80
--- /dev/null
+++ b/src/firmware_device/fd-internal.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <libpldm/pldm.h>
+#include <libpldm/firmware_update.h>
+#include <libpldm/firmware_fd.h>
+#include <libpldm/utils.h>
+
+typedef uint64_t pldm_fd_time_t;
+
+struct pldm_fd_req {
+	enum pldm_fd_req_state {
+		// pldm_fd_req instance is unused
+		PLDM_FD_REQ_UNUSED = 0,
+		// Ready to send a request
+		PLDM_FD_REQ_READY,
+		// Waiting for a response
+		PLDM_FD_REQ_SENT,
+		// Completed and failed, will not send more requests.
+		// Waiting for a cancel from the UA.
+		PLDM_FD_REQ_FAILED,
+	} state;
+
+	/* Set once when ready to move to next state, will return
+     * this result for TransferComplete/VerifyComplete/ApplyComplete request. */
+	bool complete;
+	/* Only valid when complete is set */
+	uint8_t result;
+
+	/* Only valid in SENT state */
+	uint8_t instance_id;
+	uint8_t command;
+	pldm_fd_time_t sent_time;
+};
+
+struct pldm_fd_download {
+	uint32_t offset;
+};
+
+struct pldm_fd_verify {
+	uint8_t progress_percent;
+};
+
+struct pldm_fd_apply {
+	uint8_t progress_percent;
+};
+
+struct pldm_fd {
+	enum pldm_firmware_device_states state;
+	enum pldm_firmware_device_states prev_state;
+
+	/* Reason for last transition to idle state,
+     * only valid when state == PLDM_FD_STATE_IDLE */
+	enum pldm_get_status_reason_code_values reason;
+
+	/* State-specific content */
+	union {
+		struct pldm_fd_download download;
+		struct pldm_fd_verify verify;
+		struct pldm_fd_apply apply;
+	} specific;
+	/* Details of the component currently being updated.
+     * Set by UpdateComponent, available during download/verify/apply.
+     * Also used as temporary storage for PassComponentTable */
+	struct pldm_firmware_update_component update_comp;
+	bitfield32_t update_flags;
+
+	/* Used for download/verify/apply requests */
+	struct pldm_fd_req req;
+
+	/* Address of the UA */
+	pldm_tid_t ua_address;
+	bool ua_address_set;
+
+	/* Maximum size allowed by the UA or platform implementation */
+	uint32_t max_transfer;
+
+	/* Timestamp for FD T1 timeout, milliseconds */
+	pldm_fd_time_t update_timestamp_fd_t1;
+
+	pldm_fd_time_t fd_t1_timeout;
+	pldm_fd_time_t fd_t2_retry_time;
+
+	const struct pldm_fd_ops *ops;
+	void *ops_ctx;
+};